I am working with this problem (https://open.kattis.com/problems/whowantstoliveforever). As the problem states, my program has to determine if the universe lives or dies based on the input 0s and 1s.
to determine the next value of the i-th bit, look at the current value of the bits at positions i−1 and i+1 (if they exist; otherwise assume them to be 0). If you see exactly one 1, then the next value of the i-th bit is 1, otherwise it is 0. All the bits change at once, so the new values in the next state depend only on the values in the previous state. We consider the universe dead if it contains only zeros.
My current solution works on the example input file, however it fails when submitting it to Kattis. (Wrong Answer)
Below is my code.
import sys
def get_bit(bits, i):
if 0 <= i < len(bits):
return int(bits[i])
else:
return 0
def get_new_state(old_state):
new_state = []
for index in range(len(old_state)):
if (get_bit(old_state, index-1) == 0 and get_bit(old_state, index+1) == 0) or (get_bit(old_state, index-1) == 1 and get_bit(old_state, index+1) == 1):
new_state.append(0)
elif(get_bit(old_state, index-1) == 0 and get_bit(old_state, index+1) == 1) or (get_bit(old_state, index-1) == 1 and get_bit(old_state, index+1) == 0):
new_state.append(1)
return new_state
def is_dead(state):
if len(set(state)) == 1:
return True
else:
return False
def foresee_fate(state):
seen = []
while True:
if is_dead(state):
return False
if state in seen:
return True
seen.append(state)
state = get_new_state(state)
def print_result(boolean):
print("LIVES" if boolean else "DIES")
num_cases = int(sys.stdin.readline().strip())
for i in range(num_cases):
cur_state = []
case = sys.stdin.readline().strip()
for char in case:
cur_state.append(char)
print_result(foresee_fate(cur_state))
Please let me know what I can do to improve this program.
As suggested, I have added the following to my code and IT works now. However, I ran into a new problem. now I'm getting "Time Limit Exceeded" > 3.00 s.
def is_dead(state):
if set(state).pop() == 1:
return False
elif len(set(state)) == 1:
return True
else:
return False
Please let me know if there is any suggestion on getting around this problem
Related
I have to do the following:
Define a function called isSymmetricalVec that takes a list of elements, checks if each element in a list is palindrome, then returns their results in a list. For example, given ["1441", "Apple", "radar", "232", "plane"] the function returns [TRUE, FALSE, TRUE, TRUE, FALSE].
I wrote the following code but I'm stuck at the point where I cannot return the result in a list.
def isSymmetricalVec(myList):
for myString in myList:
myList = []
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
print(bool(1))
else:
print(bool(0))
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
isSymmetricalVec(myList)
My function returns the following but the result is not in a list format:
True
False
True
False
How can I modify my code to return a result in a list format?
You function should return value instead of printing it.
Created an empty list new_list and appended result to it.
def isSymmetricalVec(myList):
new_lst = []
for myString in myList:
mid = (len(myString) - 1) // 2
start = 0
last = len(myString) - 1
flag = 0
while (start < mid):
if (myString[start] == myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
new_lst.append(True)
else:
new_lst.append(False)
return new_lst
# Enter a list of strings to check whether it is symmetrical or not
Your function is actually not returning anything. What you see are only being printed and not returned.
You would want to keep each answer in a list like this.
def isSymmetricalVec(myList):
list_of_answers = []
for myString in myList:
...
while(start<mid):
...
if flag == 0:
print(bool(1))
list_of_answers.append(True)
else:
print(bool(0))
list_of_answers.append(False)
return list_of_answers
This way your answers are printed and returned.
Finally, you would need a variable to hold the returned list.
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
list_of_answers = isSymmetricalVec(myList)
def isSymmetricalVec(myString):
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
return True
else:
return False
test = ["1221", "madam", "hello world"]
final = [isSymmetricalVec(i) for i in test]
print(final)
I rewrote the code a bit and this would be my solution. It retains the original functionality and is stylish as well as efficient. It also makes the original function more flexible and makes it easily migratable.
Your function doesn't return anything, just printing values.
There is a good way to shorten your algorithm with python slices. Also this function returns list of boolean objects.
from math import ceil, floor
def isSymmetricalVec(myList):
list_of_answers = []
for string in myList:
strLength = len(string)
#There is a string palindrome check
if string[:floor(strLength//2)] == string[ceil(strLength/2):][::-1]:
toAppend = True
else:
toAppend = False
list_of_answers.append(toAppend)
return list_of_answers
It is worth adding that it's better to use True and False instead of bool(1) and bool(0).
An example:
>>> isSymmetricalVec(['11211', 'AbbA', '12f23'])
>>> [True, True, False]
I'm trying to create Tetris for an university project. But I'm having a quite difficult time on doing the collisions. Actually, they work, until I try to rotate a piece. After I rotate a piece the collision always returns True.
This is the code:
def constraint(self):
if self.shape_y + len(self.shape) == configuration.config['rows']:
return True
for shape_row, row in enumerate(self.shape):
column_index = -1
for x in range(self.shape_x, self.shape_x + len(self.shape[0])):
column_index += 1
if self.shape[shape_row][column_index] != 0:
if shape_row+1 < len(self.shape):
if self.shape[shape_row+1][column_index] == 0:
if self.board.board[self.shape_y + 1][x] != 0:
return True
else:
if self.board.board[self.shape_y + len(self.shape)][x] != 0:
print("qui")
return True
return False
shape_y is the row where the shape is located. len(self.shape) returns how many rows is the shape because it's coded like a matrix:
Example:
[[0, 1, 0],
[1, 1, 1]],
Is the piece with one block on top and three under.
Shape is the matrix that represent the piece.
Shape_x is the column where the shape is located.
The board is a matrix like this:
self.board = np.array([[0 for _ in range(configuration.config["cols"])]
for _ in range(configuration.config['rows'])])
where 0 is free, others numbers are block that are not free.
Here a screenshot that show the problem:
The blue and the green pieces get stuck like a collision occurred but are in "mid air" and nothing really occurred.
EDIT1:
This is the code for the rotation
def rotate(self):
self.board.remove_piece(self)
self.shape = np.rot90(self.shape)
self.board.add_piece(self)
Where self.board.remove_piece(self) and self.board.add_piece(self) just remove and add the values inside the board so that i can draw it again. So, basically, the rotation code is just self.shape = np.rot90(self.shape)
I should have actually fixed the problem, the error was inside an index to check on the board.
def constraint(self):
if self.shape_y + len(self.shape) == configuration.config['rows']:
return True
for shape_row, row in enumerate(self.shape):
column_index = -1
for x in range(self.shape_x, self.shape_x + len(self.shape[0])):
column_index += 1
if self.shape[shape_row][column_index] != 0:
if shape_row+1 < len(self.shape):
if self.shape[shape_row+1][column_index] == 0:
if self.board.board[self.shape_y + shape_row + 1][x] != 0:
return True
else:
if self.board.board[self.shape_y + len(self.shape)][x] != 0:
return True
return False
I'm programming Clarke and Wright's savings algorithm to design vehicle routes from a depot to a set of customers. Right now, the code gets stuck in the final if statement if none of the conditions is met. What I want is that if ALL the cust_pairs have been checked and there is NO unserved cust_pair left which is either at the start or end of the previous route The code should break out of the second for loop. And then, go back to the first for loop to find a customer pair for starting a new route.
I've tried some things with 'break' and 'continue' but can not get it working.
def inPrevious(new,existing):
start = existing[0]
end = existing[len(existing)-1]
if new == start:
return 1
elif new == end:
return 0
else:
return -1
idx = -1
while not(allCustomersServed):
for c in cust_pairs:
# find initial cust_pair with high savings
idx += 1
routes[idx] = ([c[0],c[1]])
break
#finding a cust that is either at the start or end of previous route
for c in cust_pairs:
# find feasible cust_pair that is either at the start or end of previous route
res = inPrevious(c[0], routes[idx])
if res == 0:
# append c[1] to route
elif res == 1:
# insert c[1] at position 0 in route
elif res == -1:
res = inPrevious(c[1], routes[idx])
if res == 0:
# append c[0] to route
elif res == 1:
# insert c[0] at position 0 in route
In short, I need to test some functions by creating 100 random integer lists of each specified length (500, 1000, 10000) and store the results. Eventually, I need to be able to calculate an average execution time for each test but I've yet to get that far with the code.
I assumed the following was the best way to approach this:
Create a dictionary to store the required list length values.
For each value in that dictionary, generate a new list of random integers (list_tests).
Create another dictionary for storing the results of each function test (test_results).
Use a while loop to create 100 lists of each length.
Run the tests by calling each function in the while loop and storing each result in the results dictionary.
The program appears to run but I have a couple problems:
It never reaches the other list_tests values; never proceeds beyond 500.
It's overwriting the values for the test_results dictionary
I don't quite understand where I've gone wrong with the loop in main(). Is my process to test these functions feasible? If so, I'm lost as to how I can fix this looping problem. Thank you in advance for any assistance you can offer!
Here is my program:
import time
import random
def sequential_search(a_list, item):
start = time.time()
pos = 0
found = False
while pos < len(a_list) and not found:
if a_list[pos] == item:
found = True
else:
pos = pos+1
end = time.time()
return found, end-start
def ordered_sequential_search(a_list, item):
start = time.time()
pos = 0
found = False
stop = False
while pos < len(a_list) and not found and not stop:
if a_list[pos] == item:
found == True
else:
if a_list[pos] > item:
stop = True
else:
pos = pos+1
end = time.time()
return found, end-start
def num_gen(value):
myrandom = random.sample(xrange(0, value), value)
return myrandom
def main():
#new_list = num_gen(10000)
#print(sequential_search(new_list, -1))
list_tests = {'t500': 500, 't1000': 1000, 't10000': 10000}
for i in list_tests.values():
new_list = num_gen(i)
count = 0
test_results = {'seq': 0, 'ordseq': 0}
while count < 100:
test_results['seq'] += sequential_search(new_list, -1)[1]
test_results['ordseq'] += ordered_sequential_search(new_list, -1)[1]
count += 1
if __name__ == '__main__':
main()
I think you meant
found = True
Instead of
found == True
On line 47
Also a for loop is much cleaner try this, it should be what your looking for:
def ordered_sequential_search(a_list, item):
start = time.time()
found = False
stop = False
for i in range(len(a_list)):
if a_list[i] == item:
found = True
else:
if a_list[i] > item:
stop = True
if found: break
if stop: break
end = time.time()
return found, end-start
It is overwriting values in the dictionary because you have specified the key to overwrite values. You are not appending to the dictionary which you should have done.
Your while loop might not be breaking, that why your for loop cannot iterate to another value.
I am implementing a Python version of the game Othello / Reversi. However, my algorithm seems to be having trouble when searching in the southwest direction.
Here are some important functions to understand how my current code works:
def _new_game_board(self)->[[str]]:
board = []
for row in range(self.rows):
board.append([])
for col in range(self.columns):
board[-1].append(0)
return board
def _is_valid_position(self, turn:list)->bool:
'''return true if the turn is a valid row and column'''
row = int(turn[0]) - 1
column = int(turn[1]) - 1
if row >= 0:
if row < self.rows:
if column >= 0:
if column < self.columns:
return True
else:
return False
def _is_on_board(self, row:int, col:int)->bool:
'''returns true is coordinate is on the board'''
if row >=0:
if row < self.rows:
if col >=0:
if col < self.columns:
return True
def _searchNorthEast(self)->None:
'''Search the board NorthEast'''
print("NorthEast")
row = self.move_row
column = self.move_column
should_be_flipped = list()
row += 1
column -= 1
if self._is_on_board(row, column):
print("column searching NorthEast on board")
if self.board[row][column] == self._opponent:
should_be_flipped.append([row, column])
while True:
row += 1
column -= 1
if self._is_on_board(row, column):
if self.board[row][column] == self._opponent:
should_be_flipped.append([row, column])
continue
elif self.board[row][column] == self.turn:
self._to_be_flipped.extend(should_be_flipped)
break
else:
break
else:
self._to_be_flipped.extend(should_be_flipped)
else:
pass
def _searchSouthWest(self)->None:
'''Search the board SouthWest'''
print("in SouthWest")
row = self.move_row
column = self.move_column
should_be_flipped = list()
row -= 1
column += 1
if self._is_on_board(row, column):
print("column searching SouthWest on board")
if self.board[row][column] == self._opponent:
should_be_flipped.append([row, column])
while True:
row -= 1
column += 1
if self._is_on_board(row, column):
if self.board[row][column] == self._opponent:
should_be_flipped.append([row, column])
continue
elif self.board[row][column] == self.turn:
self._to_be_flipped.extend(should_be_flipped)
break
else:
break
else:
self._to_be_flipped.extend(should_be_flipped)
else:
pass
def _move_is_valid(self, turn:list)->bool:
'''Verify move is valid'''
self._to_be_flipped = list()
self._opponent = self._get_opposite(self.turn)
if self._is_valid_position(turn):
self.move_row = int(turn[0]) - 1
self.move_column = int(turn[1]) - 1
self._searchRight()
self._searchLeft()
self._searchUp()
self._searchDown()
self._searchNorthWest()
self._searchNorthEast
self._searchSouthEast()
self._searchSouthWest()
if len(self._to_be_flipped) > 0:
return True
else:
return False
Now let's say the current board looks like the following:
. . . .
W W W .
. B B .
. B . .
Turn: B
and the player makes a move to row 1 column 4, it says invalid because it does not detect the white piece in row 2 column 3 to be flipped. All my other functions are written the same way. I can get it to work in every other direction except in this case.
Any ideas why it is not detecting the piece in this diagonal direction?
Don't Repeat Yourself. The _search* methods are extremely redundant which makes it difficult to see that the signs in
row -= 1
column += 1
are correct. Since you've given only two directions (NE, SW) and no documentation of the board orientation, I cannot tell if the signs agree with the board layout or even agree with themselves.
The _search* methods are also too long and should be divided into multiple functions, but that's a secondary concern.
I agree with msw about not repeating stuff. It is tempting to go ahead and do what you can once you see it, but generalizing will save you the headaches of debugging.
Here is some pseudocode that should give the general idea. I might not be able to finagle working with your code, but hopefully this shows how to reduce repetitive code. Note it doesn't matter if -1 is up or down. The board class is simply a 2x2 array of (open square/player 1's piece/player 2's piece,) along with whose turn it is to move.
# x_delta and y_delta are -1/0/1 each based on which of the up to 8 adjacent squares you are checking. Player_num is the player number.
def search_valid(x_candidate, y_candidate, x_delta, y_delta, board, player_num):
y_near = y_candidate + y_delta
x_near = x_candidate + x_delta
if x_near < 0 or x_near >= board_width:
return False
if y_near < 0 or y_near >= board_width:
return False # let's make sure we don't go off the board and throw an exception
if board.pieces[x_candidate+x_delta][y_candidate+y_delta] == 0:
return False #empty square
if board.pieces[x_candidate+x_delta][y_candidate+y_delta] == player_num:
return False #same color piece
return True #if you wanted to detect how many flips, you could use a while loop
Now a succinct function can loop this search_valid to see whether a move is legal or not e.g.
def check_valid_move(x_candidate, y_candidate, board, player_num):
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if not x and not y:
continue # this is not a move. Maybe we don't strictly need this, since board.pieces[x_candidate+x_delta][y_candidate+y_delta] == player_num anyway, but it seems like good form.
if search_valid(x_candidate, y_candidate, dx, dy, board, player_num):
return True
return False
A similar function could actually flip all the opposing pieces, but that's a bit trickier. You'd need a while function inside the for loops. But you would not have to rewrite code for each direction.