NOTE: I CAN NOT use any external module that is not built-in to python.
Problem:
A new and upcoming artist has a unique way to create checkered patterns. The idea is to
use an M-by-N canvas which is initially entirely black. Then the artist repeatedly chooses
a row or column and runs their magic brush along the row or column. The brush changes
the colour of each cell in the row or column from black to gold or gold to black.
Given the artist’s choices, your job is to determine how much gold appears in the pattern
determined by these choices.
Input Specification
The first line of input will be a positive integer M. The second line of input will be a positive
integer N. The third line of input will be a positive integer K. The remaining input will be
K lines giving the choices made by the artist. Each of these lines will either be R followed
by a single space and then an integer which is a row number, or C followed by a single space
and then an integer which is a column number. Rows are numbered top down from 1 to M.
Columns are numbered left to right from 1 to N.
Output Specification
Output one non-negative integer which is equal to the number of cells that are gold in the
pattern determined by the artist’s choices.
Limitations
M and N can be up to 5 000 000
K can be up to 1 000 000
My Solution
import sys
raw_input = sys.stdin.readline
m = int(raw_input())
n = int(raw_input())
brushes = raw_input()
stroke = []
colors = [['B' for _ in range(n)] for _ in range(m)]
for i in range(int(brushes)):
g = raw_input().split(' ')
if stroke.count(g) == 1:
stroke.remove(g)
else:
stroke.append(g)
def changeColumn(num,colors,index):
if num == 0:
return colors
colors[num-1][index] = 'G' if colors[num-1][index] == 'B' else 'B'
num -= 1
changeColumn(num,colors,index)
def countGold(c,options,i):
if options == []:
s = 0
for l in c:
s += l.count("G")
print(s)
return
area = options[i][0]
times = int(options[i][1]) - 1
if area == "R":
c[times] = list(''.join(c[times]).replace("G","A").replace("B","G").replace("A","B"))
elif area == "C":
changeColumn(m,c,times)
options.remove(options[i])
countGold(c,options,i)
countGold(colors,stroke,0)
Got everything right except for some problems. I exceeded the Time Limit of 4 seconds. I know that making colors takes up a lot of time. Is there any way to do this without generating the 2d array?
UPDATED CODE (doesn't work)
import sys
M = int(input())
N = int(input())
K = int(input())
dup = []
numR = 0
numC = 0
for i in range(K):
choice = input().split()
if choice not in dup:
if choice[0] == "R":
numR += 1
elif choice[0] == "C":
numC += 1
dup.append(choice)
print((M * numR) + (N * numC) - (2*numR*numC))
Let me put all that discussion in comments into the code:
import sys
M = int(input())
N = int(input())
K = int(input())
dup = set()
result = {'numR': 0, 'numC': 0}
def update(char, num):
if char == 'R':
result['numR'] += num
elif char == 'C':
result['numC'] += num
for i in range(K):
choice = input().split()
if choice in dup:
dup.remove(choice)
update(choice[0], -1)
else:
dup.add(choice)
update(choice[0], 1)
numR = result['numR']
numC = result['numC']
print((M * numR) + (N * numC) - (2*numR*numC))
The code sent by Freakish still doesn't work for some reason. Here is an updated code that works:
import sys
rw = sys.stdin.readline
M = int(rw())
N = int(rw())
choices = set()
K = int(rw())
for i in range(K):
g = input()
if g in choices:
choices.remove(g)
else:
choices.add(g)
numR = 0
numC = 0
s = 0
for choice in choices:
if choice[0] == "R":
numR += 1
elif choice[0] == "C":
numC += 1
for choice in choices:
if choice[0] == "R":
# numR += 1
s += N - numC
elif choice[0] == "C":
# numC += 1
s += M - numR
print(s)
Related
I'm trying to make a lucky number counter where if there is a number containing either a 6 or an 8 between the two inputs the number is lucky, but if there's both a 6 and an 8 the number is unlucky. I'm having an issue where it's double-counting numbers, like 66, 88, etc., and not calling unlucky numbers like 68, 86, etc. Please help fast :\
l, h = [int(x) for x in input().split()]
count = 0
for i in range(l,h+1):
i = str(i)
for j in range(len(i)):
if i[j] == '6' or i[j] == '8':
count += 1
print(count)
Try this:
import sys
temp1 = ""
while len(temp1) != 2:
temp1 = input("Enter 2 digits: ")
try:
temp2 = int(temp1)
except ValueError:
print("You did not enter valid input")
sys.exit(1)
lucky = False
if "6" in temp1:
lucky = True
if "8" in temp1:
lucky = True
if ("6" in temp1) and ("8" in temp1):
lucky = False
print("Lucky number: "+str(lucky))
Something like this, probably:
number = ''
while len(number) != 2 or any(ch not in '0123456789' for ch in number):
number = input('Enter a 2-digit positive integer:')
print(f'{number} is {"lucky" if ("6" in number) != ("8" in number) else "not lucky"}')
# or, if you meant to say "exactly one 6 or 8":
print(f'{number} is {"lucky" if len([ch for ch in number if ch in "68"]) == 1 else "not lucky"}')
You could try using the count() method for Strings:
numbers = input().split(' ')
count = 0
for num in numbers:
if num.count('6') > 0:
if num.count('8') > 0:
continue
else:
count += 1
elif num.count('8') > 0:
count += 1
print(count)
this, while not as elegant or efficient, seems to be the correct code for the implied question
l, h = [int(x) for x in input().split()]
count = 0
for i in range(l,h+1):
i = str(i)
if ('6' in i and '8' in i):
continue
if i.count('6') > 0 or i.count('8') > 0:
count += 1
print(count)
I have made this simple password generator with the option to choose the length of the password. It seems to randomly add the length to itself however, so if I keep choosing a length of 5 it will occasionally output a password of 10 characters and then go back to 5.
import random
randomnums = []
checker = [0, 0, 0, 0] ##Make sure there are upper, lower case, symbols and numbers.
while True:
length = input("How long do you want your password?: ")
if length.isdigit() == False:
print("please enter a number..\n")
elif int(int(length)) < 4:
print("Please enter a length of 4 or greater...\n")
else:
break
while checker[0] == 0 or checker[1] == 0 or checker[2] == 0 or checker[3] == 0:
for i in range(0,int(length)):
x = random.randrange(0, 4)
if x == 1:
randomnums.append(random.randrange(0, 10))
checker[0] = 1
elif x == 2:
randomnums.append(random.choice('abcdefghijklmnopqrstuvwxyz'))
checker[1] = 1
elif x == 3:
randomnums.append(random.choice('ABCDEFGHIJKLMNPQRSTUVWXYZ'))
checker[2] = 1
else:
randomnums.append(random.choice('!##$%^&*()_+:"}|<>?'))
checker[3] = 1
password = ''.join(map(str, randomnums)) ##join list to string
print(password)`
You could get any multiple of length with this code. It adds length characters in the body until you got the required length. You should instead generate a password and check it, and if it is bad, repeat.
I was just wondering how do I split this into different functions say like maybe 2 or 3 functions? I'm not that good with passing parameters with functions yet. Would you recommend doing that or should I keep it the way it is in one function since it's a while loop? By the way it's for a beginner programming class so that's why its pretty long.
def sumOfDoublePlace(userChoice):
lenChecker = len(str(userChoice))
counter = 0
sumNumber = 0
userChoice = int(userChoice)
while counter < lenChecker-1:
counter += 1
endDigit, userChoice = divmod(userChoice, 10)
if counter % 2 == 0:
evenNumber = endDigit * 2
if evenNumber < 10:
sumNumber = sumNumber + evenNumber
else:
oddDigit = endDigit % 10
firstDigit = endDigit // 10
oddSum = oddDigit + firstDigit
sumNumber = sumNumber + oddSum
else:
sumNumber = sumNumber + endDigit
if sumNumber % 10 == 0:
print('This card is valid')
else:
print('This card is invalid')
Overall, I think this should be a single routine. However, you are taking a somewhat tortuous path to the solution. You're doing a lot of work to pull digits out of the integer version of the card number, when they're perfectly accessible in the original text.
Here's a start on accessing the string positions you need:
def isValidCardNumber(cardNumber):
num_len = len(cardNumber)
last = int(cardNumber[-1]) # grab the last digit; convert to integer
odds = cardNumber[0:-1:2] # positions 0, 2, 4, ... last-1
evens = cardNumber[1:-1:2] # positions 1, 3, 5, ... last-1
# For each list of digits, make a list of their integer equivalents.
# ... and immediately take the sum of those integers.
odd_sum = sum([int(digit) for digit in odds])
even_sum = sum([int(digit) for digit in evens])
I leave the rest of this to you. :-)
I have attempted this problem like this :
a = input("Enter number : ")
s = 3
w = 1
while a>0:
digit=a%10
if n%2 == 0:
p = p*digit
else:
s = s+digit
a=a/10
n=n+1
print "The sum is",s
it works perfectly for even no of digits but for odd no of digits like for 234 it shows the sum as 6 and product 3
No explicit loop:
import operator
from functools import reduce # in Python 3 reduce is part of functools
a = input("Enter number : ")
lst = [int(digit) for digit in a]
add = sum(lst[1::2])
mul = reduce(operator.mul, lst[::2],1)
print("add =",add,"mul =",mul,"result =",add+mul)
Producing:
Enter number : 234
add = 3 mul = 8 result = 11
You have to start with n = 0 for this to work
a = int(input("Enter number"))
s = 0
p = 1
n = 0
while a>0:
digit=a%10
if n%2 == 0:
p *= digit
else:
s += digit
a /= 10
n += 1
print "The sum is",s
print "Product is",p
Easy mistake to make about the numbering. The first item of any string, list or array is always index 0. For example, be careful in future to take away 1 from the value returned from len(list) if you are iterating through a list's items with a for loop e.g.
for x in range(len(list)-1):
#your code using list[x]
Here's the mathematical version:
n = input('Enter a number: ')
digits = []
while n > 0:
digits.append(n%10)
n //= 10
s = 0
p = 1
i = 0
for digit in reversed(digits):
if i%2 == 0:
s += digit
else:
p *= digit
i += 1
print 'Sum of even digits:', s
print 'Product of odd digits:', p
print 'Answer:', s+p
I have tried to make this as simple as possible for you.
Here's a function that does the same thing:
def foo(n):
s = 0
p = 1
for i, digit in enumerate(str(n)):
if i%2 == 0:
s += digit
else:
p *= digit
return s+p
def foo(num):
lst = [int(digit) for digit in str(num)]
mul, add = 1, 0
for idx, val in enumerate(lst):
if not idx % 2:
mul *= val
else:
add += val
return add, mul
And using it:
>>> foo(1234)
(6, 3)
>>> foo(234)
(3, 8)
This function will take an integer or a string representation of an integer and split it into a list of ints. It will then use enumerate to iterate over the list and preform the required operations. It returns a 2 element tuple.
So I'm trying to implement a ConnectFour game in python, and I'm having some trouble with counting the pieces (from a single player) that are lined up together in a row. My code:
class ConnectFour(object):
def __init__(self):
self.row=6
self.col=7
self.board = []
#initialize the board
for arow in range(self.row):
row = []
for acol in range(self.col):
row.append(None)
self.board.append(row)
#function for counting the number of the same pieces in a row
def count_it(self, row, column, step_row, step_col):
assert row >= 0 and row < 6 and column >= 0 and column < 7
assert step_row != 0 or step_col != 0
counter1 = 0
counter2 = 0
if self.board[row][column] == None:
return 0
elif self.board[row][column] == 1:
for i in range(6):
while self.board[row + (i*step_row)][column + (i*step_col)] == 1:
counter1 += 1
return counter1
else:
for i in range(6):
while self.board[row + (i * step_row)][column + (i*step_col)] == 2:
counter2 += 1
return counter2
When I input a location and "step" in my function, I would like to get the number of pieces player 1 or player 2 has lined up but when I enter:
x= ConnectFour()
x.board[5][6] = 1
x.board[4][6] = 1
x.count_it(5,6,-1,0)
I get no output.
There is no need for that while inside for: whenever the while condition is true, it will become an infinite loop since the body of that loop does not affect the condition, it just keeps incrementing a counter forever.
One approach would be a single while loop:
while self.board[row + (counter1*step_row)][column + (counter1*step_col)] == 1:
counter1 += 1
Another approach is to leave the for loop, but i and counter1 actually serve the same purpose:
for i in range(6):
if self.board[row + (i*step_row)][column + (i*step_col)] != 1:
break
counter1 += 1
In both cases, take care of array boundaries, either by some ifs, or by placing sentinels at the border of the array.