Python variable length 2d arrays - python

Today is my first day learning Python and have a question about 2-dimensional arrays. I need to create a 2 dimensional array but don't know the size of each of them. Is there something similar to the arraylist like in Java? Here's my code so you can see what I mean. It's for day 3 of last year's Advent of Code. So I guess a slight spoiler ahead if you haven't done it and want to see the way I'm thinking of setting it up.
f=open('directions.txt')
houses = [0][0]
rows = 0
column = 0
total = 0
for line in f:
for c in line:
if (str(c) == '^'):
rows += 1
houses[rows][column] += 1
elif (str(c) == '>'):
column += 1
houses[rows][column] +=1
elif (str(c)=='<'):
column -= 1
houses[rows][column-=1] +=1
else:
rows -= 1
houses[rows][column] +=1
Thanks for any help.

I believe you want something like this
houses = dict()
rows = 0
column = 0
total = 0
for line in f:
for c in line:
houses.setdefault(rows,dict())
houses[rows].setdefault(column, 0)
if (str(c) == '^'):
houses[rows][column] += 1
rows += 1
elif (str(c) == '>'):
houses[rows][column] +=1
column += 1
elif (str(c)=='<'):
houses[rows][column] +=1
column -= 1
else:
houses[rows][column] +=1
rows -= 1

Related

Writing a "Chessboard" function in Python that prints out requested length of binary

I have an assignment for my Python course that I'm struggling with.
We are supposed to make a function that prints out binary as follows:
If the input is:
chessboard(3)
It should print out:
101
010
101
And so forth..
Its a "simple" program but I'm really new to coding.
I can produce a while loop that writes out the correct length and amount of lines but I'm struggling to produce variation between the lines.
This is what I have come up with so far:
def chessboard(n):
height = n
length = n
while height > 0:
while length > 0:
print("1", end="")
length -= 1
if length > 0:
print("0", end="")
length -= 1
height -= 1
if length == 0:
break
else:
print()
length = n
With the input:
chessboard(3)
It prints out:
101
101
101
Could someone help me figure out how I could start every other line with zero instead of one?
As I understand it, it is simple :
print("stackoverflow")
def chessboard(n):
finalSentence1 = ""
finalSentence2 = ""
for i in range(n): #we add 0 and 1 as much as we have n
if i%2 == 0: #
finalSentence1 += "1"
finalSentence2 += "0"
else:
finalSentence1 += "0"
finalSentence2 += "1"
for i in range(n): #we print as much as we have n
if i%2 == 0:
print(finalSentence1)
else:
print(finalSentence2)
chessboard(3)
returns :
stackoverflow
101
010
101
I am working on the same kind of assignment, but as we have only covered conditional statements and while loops so far, following the same logic, here is my solution:
def chessboard(size):
output_1 = ''
output_2 = ''
i = 1
j = 1
while j <= size:
while i <= size:
if i % 2 == 0:
output_1 += '1'
output_2 += '0'
i += 1
else:
output_1 += '0'
output_2 += '1'
i += 1
if j % 2 == 0:
print(output_1)
j += 1
else:
print(output_2)
j += 1
chessboard(5)
returns:
10101
01010
10101
01010
10101
def chessboard(x):
i = 0
while i < x:
if i % 2 == 0:
row = "10"*x
else:
row = "01"*x
print(row[0:x])
i += 1

Very Beginner Problem in Python While Loop

Why this While loop is not breaking or stopping
I have added some output screenshot
term = 0
i = 13
while True:
print i > 1
print "i = ",i
if i == 1:
term += 1
break
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
Output
I also tried This way too
term = 1
i = 13
while i > 1:
print i > 1
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
Use elif to make the cases mutually exclusive. You don't want multiple if statements to execute in the same loop iteration.
if i%2 == 0:
i = i / 2
term += 1
elif i%2 != 0:
i = i * 3 + 1
term += 1
Or just make it else since the second condition is redundant.
if i%2 == 0:
i = i / 2
term += 1
else:
i = i * 3 + 1
term += 1
The reason it oscillates between 2 and 4 as written is because 2 causes both if statements to run. 2 is even so the first one runs and halves i, making it 1. Now it's odd and the second one triggers, turning 1 into 4.
if i%2 == 0:
i = i / 2 # 2 --> 1
term += 1
if i%2 != 0:
i = i * 3 + 1 # 1 --> 4
term += 1
The next iteration 4 becomes 2.
if i%2 == 0:
i = i / 2 # 4 --> 2
term += 1
These two iterations repeat over and over in an endless cycle.
Let's say your i is 2. It is divisible by 2, so if i % 2 == 0 fires, and i becomes 1. And the code continues to execute, so now we are at if i % 2 != 0 line, and this condition is also true, because you just modified i and it's now 1. So i becomes 4.
Your modified second attempt, which prevents the second condition from being checked if the first one succeeds, is below:
term = 1
i = 13
while i > 1:
print(i > 1)
if i % 2 == 0:
i = i / 2
term += 1
elif i % 2 != 0:
i = i * 3 + 1
term += 1
Also notice that you actually don't need to check the second condition, as it is definitely true if the first one is not, so elif ... line can be replaced just with else:
You can also use continue keyword to stop the rest of the loop from executing if the first condition is true:
term = 1
i = 13
while i > 1:
print(i > 1)
if i % 2 == 0:
i = i / 2
term += 1
continue
if i % 2 != 0:
i = i * 3 + 1
term += 1
Your first attempt has exactly the same problem; fixing it I leave as an exercise for the reader :)
P.S. do not learn Python 2
The problem is:
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
The problem is that, if i % 2 == 0 is true, it will remain true until i = 1. Once i = 1, i % 2 != 0 executes and makes i = 4.

Working with recursion but not with for loop

I have written a code using recursion, but later realized that the depth is too high and does not work for higher level input values. It works completely fine without any issue.
def checkCount(first_window, index=0,reference_list=None):
reference_list = []
count = 0
while index<=len(first_window)-2:
if first_window[index] < first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(int((count*(count+1))/2))
count = 0
while index <= len(first_window)-2:
if first_window[index] > first_window[index+1]:
index += 1
count += 1
else: break
if count != 0:
reference_list.append(-int((count*(count+1))/2))
if index > len(first_window)-2: return reference_list
elif first_window[index] == first_window[index+1] and index<len(first_window)-2: index += 1
reference_list = reference_list + checkCount(first_window, index, reference_list)
return reference_list
import random
import time
start = time.clock()
input_array = list(map(int,"188930 194123 201345 154243 154243".split(" ")))
input_array = random.sample(range(1,100),10)
def main():
N = len(input_array)
K = 8
if K == 1: return None
print("Input array: ",input_array)
print("First Window",input_array[:K])
print("Real Output", checkCount(input_array[:K]))
if __name__ == "__main__":main()
Now no matter how I try without recursion, it ends with an infinite loop. I have tried different ways but no progress.
One way I have tried is taking out the recursion statement and returning the referencelist + index:
def checkCount(..):
....
....
return referencelist,index
while index <= K-2:
print("While",index)
reference_list, index = checkCount(new_input, index=0, reference_list=[])
referencelist += reference_list
The application is similar to the here. But we have to deal with tons of data where recursion cannot help. Assume that the input array is greater than 100,000. I am really struck here, I do not understand what logic am I missing. Any help will be grateful.
The first_window variable is only read, and the index variable is only incremented. There is no need for recursion, a simple loop can work.
def check_count(first_window):
reference_list = []
index = 0
while index < len(first_window) - 2:
count = 0
while index <= len(first_window) - 2:
if first_window[index] < first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(int((count * (count + 1)) / 2))
count = 0
while index <= len(first_window) - 2:
if first_window[index] > first_window[index + 1]:
index += 1
count += 1
else:
break
if count != 0:
reference_list.append(-int((count * (count + 1)) / 2))
if index < len(first_window) - 2 and first_window[index] == first_window[index + 1]:
index += 1
return reference_list
Of course, this algorithm can be optimised, for instance, we can avoid repetitions like: len(first_window) - 2.

Locating max value in a list

I'm very new to Python programming and I've been tasked by an online friend to write code to solve the following problem:
'imagine a board game and you have to roll 2 dices.Write a program to roll the dices 100 times and find out which value (of both dices) appears most'
My attempt below kind of works in the sense that I'm able to ascertain the max frequency of two dice faces added together but not the actual dice thrown.(e.g. the total '9' was the most frequently thrown).
I'm sure there are plenty of ways of accomplishing the above so do excuse my very first attempt at coding!
import random
results = []
freq_2 = 0
freq_3 = 0
freq_4 = 0
freq_5 = 0
freq_6 = 0
freq_7 = 0
freq_8 = 0
freq_9 = 0
freq_10 = 0
freq_11 = 0
freq_12 = 0
for i in range(100):
face1 = random.randrange(1,7)
face2 = random.randrange(1,7)
value = face1 + face2
if value == 2:
freq_2 += 1
if value == 3:
freq_3 += 1
if value == 4:
freq_4 += 1
if value == 5:
freq_5 += 1
if value == 6:
freq_6 += 1
if value == 7:
freq_7 += 1
if value == 8:
freq_8 += 1
if value == 9:
freq_9 += 1
if value == 10:
freq_10 += 1
if value == 11:
freq_11 += 1
if value == 12:
freq_12 += 1
results.append(freq_2)
results.append(freq_3)
results.append(freq_4)
results.append(freq_5)
results.append(freq_6)
results.append(freq_7)
results.append(freq_8)
results.append(freq_9)
results.append(freq_10)
results.append(freq_11)
results.append(freq_12)
print max(results)
print freq_2, freq_3, freq_4, freq_5, freq_6, freq_7, freq_8, freq_9, freq_10, freq_11, freq_12
collections provides Counter which makes this task easy:
from random import choice
from collections import Counter
dice = range(1,7)
freq = Counter([choice(dice) + choice(dice) for i in range(100)])
print freq
print freq.most_common(1)
I would redo much of it, reducing the amount of variables you're using.
rather than a separate variable for each freq_#, use a list:
freqs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 12 zeroes
for i in range(100):
face1 = random.randrange(1,7)
face2 = random.randrange(1,7)
value = face1 + face2
freqs[value] += 1
This way, you also will not have to individually append each freq_# to a list afterwards.
Once this list is filled with its values, you can use a few simple python calls to find the data you'd like:
'The most frequent throw was 9 and it occurred 21 times'
The most frequent throw will be the index with the highest number in the list.
max_freq = max(freqs) # amount of times this number was thrown
the number that was rolled will be represented by the index of the max
most_frequent_roll = freqs.indexOf(max_freq) # the number that was thrown that many times.
You don't need to write explicitly all the cases. For such a task python dictionaries are very useful.
I won't solve the problem for you, but give you a hint how you could implement this using dictionaries:
# define a dictionary to hold the counts (just for a single dice here)
counts = {nbr_dots: 0 for nbr_dots in range(1, 7)}
# this will look like {1:0, 2:0, ...}
# now whenever you get a certain count (say 2 here) you can increment the value of
# this count by 1 like so:
counts[2] += 1
# now counts looks like: {1:0, 2:1, ...}
If then you want to get the key (so the count) that appeared the most:
most_frequent = max(counts, key=lambda k: counts[k])
# and the number of times it appeared:
nbr_observations = counts[most_frequent]
Hope this minimal example helps to get you started.
The other answers are good, but if for some reason you don't want to use them, then here is a simple loop that does the job after you have calculated the result.
maximum = 0
for i in range(len(results)):
if results[i] > maximum:
maximum = results[i]
itemAt = i
print('The most frequent throw was: '+ str(results[itemAt]))
print('It occured %d times' % maximum)
What you must do to find the value of each die is you must compose another for loop which records when the value of each face is a certain number, and then increase the frequency of that value:
face_freq_2 = 0
face_freq_3 = 0
face_freq_4 = 0
face_freq_5 = 0
face_freq_6 = 0
face_freq_7 = 0
face_freq_8 = 0
face_freq_9 = 0
face_freq_10 = 0
face_freq_11 = 0
face_freq_12 = 0
for j in range(100):
face_value1 = random.randrange(1,7)
face_value2 = random.randrange(1,7)
value1 = face_value1
value2 = face_value2
if (value1 == value2) and (value1 == 1):
face_freq_2 += 1
if (value1 == 1 and value2 == 2) or (value1 == 2 and value2 == 1):
face_freq_3 += 1
if (value1 == value2) and (value1 == 2):
face_freq_4 += 1
elif (value1 == 1 and value2 == 3) or (value1 == 3 and value2 == 1):
face_freq_4 += 1
if (value1 == 1 and value2 == 4) or (value1 == 4 and value2 == 1):
face_freq_5 += 1
elif (value1 == 2 and value2 == 3) or (value1 == 3 and value2 == 2):
face_freq_5 += 1
if (value1 == value2 and value1 == 3):
face_freq_6 += 1
elif (value1 == 1 and value2 == 5) or (value1 == 5 and value2 == 1):
face_freq_6 += 1
elif (value1 == 2 and value2 == 4) or (value1 == 4 and value2 == 2):
face_freq_6 += 1
From this you get the picture of what you must do, for as the values increase you will need more elif statements in addition to the initial if statement. Yes, it is a bit tedious but it should yield the desired results.

ConnectFour in python: embedding a while loop under a for loop

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.

Categories