Optimize search through array in python 2.7 - python

I'm currently working on a piece of code for a school project, wherein we have to lead customers to an available register within a supermarket. Format is that we get first a string with two numbers "x y", where x is the amount of registers and y is the amount of people coming to/leaving a register. Next there is y lines of either "C X" or "L X" format, where "C X" means a customer arrives at register X, and "L X" would be a customer leaving register X. Now if a customer arrives at an empty register it should just print this register number, but if a customer arrives at an already taken register, it should print out the nearest free register, favoring lower numbers (say nr 4 is taken but a customer arrives and both 3 and 5 is free, it should print 3). I'm currently using an array wherein I'm keeping the amount of registers as 0's and then changing these to ones if the register is taken and if it is I then loop through +- 1, +- 2 and so on till I find a free register. However, for a full grade we need to be able to take inputs of up to a million M, and our code needs to execute within a minute and use up a max of 256 mb of memory. Current code is below, I keep hitting the time limit, probably because of the way I iterate over the array, any ideas on how I could optimize this?
N, M = map(int, raw_input().split())
entries = []
for x in range(0, M):
entries.append(raw_input())
registers = []
for x in range(0,M):
registers.append(0)
for line in entries:
if line[0] == "L":
registers[int(line[2])-1] = 0
elif registers[int(line[2])-1] == 1:
i = 0
n = int(line[2])-1
while True:
if registers[n-i] == 1:
pass
elif n-i >= 0:
registers[n-i] = 1
print n-i+1
break
if registers[n+i] == 1:
pass
else:
registers[n+i] = 1
print n+i+1
break
i += 1
else:
registers[int(line[2])-1] = 1
print int(line[2])

Related

I used return, however the recursion does not end. help me please

I am doing a question that gives me a start coordinate, a end coordinate and the number of times of moving.Every time you can add 1 or minus 1 to x or y coordinate based on previous coordinate and the number of moving limit the time the coordinate can move. At last, I need to identify whether there is a possibility to get to the end coordinate
I decide to use recursion to solve this problem however, it does not end even if I wrote return inside a if else statement. Do you mind to take a look at it.
This is the code
# https://cemc.uwaterloo.ca/contests/computing/2017/stage%201/juniorEF.pdf
# input
start = input()
end = input()
count = int(input())
coo_end = end.split(' ')
x_end = coo_end[0]
y_end = coo_end[1]
end_set = {int(x_end), int(y_end)}
#processing
coo = start.split(' ')
x = int(coo[0])
y = int(coo[1])
change_x = x
change_y = y
sum = x + y+count
set1 = set()
tim = 0
timer = 0
ways = 4** (count-1)
def elit(x, y, tim,timer, ways = ways):
print(tim,timer)
tim = tim +1
co1 = (x, y+1)
co2 = (x+1, y)
co3 = (x, y-1)
co4 = (x-1, y)
if tim == count:
tim =0
set1.add(co1)
set1.add(co2)
set1.add(co3)
set1.add(co4)
print(timer)
timer = timer +1
if timer == ways:
print('hiii')
return co1, co2, co3, co4 #### this is the place there is a problem
elit(co1[0],co1[1],tim,timer)
elit(co2[0],co2[1],tim,timer)
elit(co3[0],co3[1],tim, timer)
elit(co4[0],co4[1],tim, timer)
#print(elit(change_x,change_y,tim)) - none why
elit(change_x,change_y,tim, timer)
#print(list1)
for a in set1:
if end_set != a:
answer = 'N'
continue
else:
answer = "Y"
break
print(answer)
In addition, if you have any suggestions about writing this question, do you mind to tell me since I am not sure I am using the best solution.
one of example is
Sample Input
3 4 (start value)
3 3 (end value)
3 (count)
Output for Sample Input
Y
Explanation
One possibility is to travel from (3, 4) to (4, 4) to (4, 3) to (3, 3).
the detailed question can be seen in this file https://cemc.uwaterloo.ca/contests/computing/2017/stage%201/juniorEF.pdf
It is question 3. Thank you
thank you guys
the function is returning properly however by the time you reach the recursive depth to return anything you have called so many instances of the function that it seems like its in an infinite loop
when you call elite the first time the function calls itself four more times, in the example you have given timer is only incremented every 3 cycles and the function only return once timer hits 16 thus the function will need to run 48 times before returning anything and each time the function will be called 4 more times, this exponential growth means for this example the function will be called 19807040628566084398385987584 times, which depending on your machine may well take until the heat death of the universe
i thought i should add that i think you have somewhat over complicated the question, on a grid to get from one point to another the only options are the minimum distance or that same minimum with a diversion that must always be a multiple of 2 in length, so if t the movement is at least the minimum distance or any multiple of 2 over the result should be 'Y', the minimum distance will just be the difference between the coordinates on each axis this can be found by add in the difference between the x and y coordinates
abs(int(start[0]) - int(end[0])) + abs(int(start[1]) -int(end[1]))
the whole function therefore can just be:
def elit():
start = input('start: ').split(' ')
end = input('end: ').split(' ')
count = int(input('count: '))
distance = abs(int(start[0]) - int(end[0])) + abs(int(start[1]) -int(end[1]))
if (count - distance) % 2 == 0:
print('Y')
else:
print('N')
input:
3 4
3 3
3
output:
Y
input:
10 4
10 2
5
output:
N

Google Kick Start 2020 Round C: Stable Wall. Always WA but can't find the problem

Problem Statement:
Problem
Apollo is playing a game involving polyominos. A polyomino is a shape made by joining together one or more squares edge to edge to form a single connected shape. The game involves combining N polyominos into a single rectangular shape without any holes. Each polyomino is labeled with a unique character from A to Z.
Apollo has finished the game and created a rectangular wall containing R rows and C columns. He took a picture and sent it to his friend Selene. Selene likes pictures of walls, but she likes them even more if they are stable walls. A wall is stable if it can be created by adding polyominos one at a time to the wall so that each polyomino is always supported. A polyomino is supported if each of its squares is either on the ground, or has another square below it.
Apollo would like to check if his wall is stable and if it is, prove that fact to Selene by telling her the order in which he added the polyominos.
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the two integers R and C. Then, R lines follow, describing the wall from top to bottom. Each line contains a string of C uppercase characters from A to Z, describing that row of the wall.
Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is a string of N uppercase characters, describing the order in which he built them. If there is more than one such order, output any of them. If the wall is not stable, output -1 instead.
Limits
Time limit: 20 seconds per test set.
Memory limit: 1GB.
1 ≤ T ≤ 100.
1 ≤ R ≤ 30.
1 ≤ C ≤ 30.
No two polyominos will be labeled with the same letter.
The input is guaranteed to be valid according to the rules described in the statement.
Test set 1
1 ≤ N ≤ 5.
Test set 2
1 ≤ N ≤ 26.
Sample
Input
Output
4
4 6
ZOAAMM
ZOAOMM
ZOOOOM
ZZZZOM
4 4
XXOO
XFFO
XFXO
XXXO
5 3
XXX
XPX
XXX
XJX
XXX
3 10
AAABBCCDDE
AABBCCDDEE
AABBCCDDEE
Case #1: ZOAM
Case #2: -1
Case #3: -1
Case #4: EDCBA
In sample case #1, note that ZOMA is another possible answer.
In sample case #2 and sample case #3, the wall is not stable, so the answer is -1.
In sample case #4, the only possible answer is EDCBA.


Syntax pre-check
Show Test Input
My Code:
class Case:
def __init__(self, arr):
self.arr = arr
def solve(self):
n = len(self.arr)
if n == 1:
return ''.join(self.arr[0])
m = len(self.arr[0])
dep = {}
used = set() # to save letters already used
res = []
for i in range(n-1):
for j in range(m):
# each letter depends on the letter below it
if self.arr[i][j] not in dep:
dep[self.arr[i][j]] = set()
# only add dependency besides itself
if self.arr[i+1][j] != self.arr[i][j]:
dep[self.arr[i][j]].add(self.arr[i+1][j])
for j in range(m):
if self.arr[n-1][j] not in dep:
dep[self.arr[n-1][j]] = set()
# always find and desert the letters with all dependencies met
while len(dep) > 0:
# count how many letters are used in this round, if none is used, return -1
count = 0
next_dep = {}
for letter in dep:
if len(dep[letter]) == 0:
used.add(letter)
count += 1
res.append(letter)
else:
all_used = True
for neigh in dep[letter]:
if neigh not in used:
all_used = False
break
if all_used:
used.add(letter)
count += 1
res.append(letter)
else:
next_dep[letter] = dep[letter]
dep = next_dep
if count == 0:
return -1
if count == 0:
return -1
return ''.join(res)
t = int(input())
for i in range(1, t + 1):
R, C = [int(j) for j in input().split()]
arr = []
for j in range(R):
arr.append([c for c in input()])
case = Case(arr)
print("Case #{}: {}".format(i,case.solve()))
My code successfully passes all sample cases I can think of, but still keeps getting WA when submitted. Can anyone spot what is wrong with my solution? Thanks

PYTHON - "Love for Mathematics"

I just finished a challenge on Dcoder ("Love for Mathematics") using Python. I failed two test-cases, but got one right. I used somewhat of a lower level of Python for the same as I haven't explored more yet, so I'm sorry if it looks a bit too basic.The Challenge reads:
Students of Dcoder school love Mathematics. They love to read a variety of Mathematics books. To make sure they remain happy, their Mathematics teacher decided to get more books for them.
A student would become happy if there are at least X Mathematics books in the class and not more than Y books because they know "All work and no play makes Jack a dull boy".The teacher wants to buy a minimum number of books to make the maximum number of students happy.
The Input
The first line of input contains an integer N indicating the number of students in the class. This is followed up by N lines where every line contains two integers X and Y respectively.
#Sample Input
5
3 6
1 6
7 11
2 15
5 8
The Output
Output two space-separated integers that denote the minimum number of mathematics books required and the maximum number of happy students.
Explanation: The teacher could buy 5 books and keep student 1, 2, 4 and 5 happy.
#Sample Output
5 4
Constraints:
1 <= N <= 10000
1 <= X, Y <= 10^9
My code:
n = int(input())
l = []
mi = []
ma = []
for i in range(n):
x, y = input().split()
mi.append(int(x))
ma.append(int(y))
if i == 0:
h=ma[0]
else:
if ma[i]>h:
h=ma[i]
for i in range(h):
c = 0
for j in range(len(mi)):
if ma[j]>=i and mi[j]<=i:
c+=1
l.append(c)
great = max(l)
for i in range(1,len(l)+1):
if l[i]==great:
print(i,l[i])
break
My Approach:
I first assigned the two minimum and maximum variables to two different lists - one containing the minimum values, and the other, the maximum. Then I created a loop that processes all numbers from 0 to the maximum possible value of the list containing maximum values and increasing the count for each no. by 1 every time it lies within the favorable range of students.
In this specific case, I got that count list to be (for the above given input):
[1,2,3,3,4,4,3,3,2 ...] and so on. So I could finalize that 4 would be the maximum no. of students and that the first index of 4 in the list would be the minimum no. of textbooks required.
But only 1 test-case worked and two failed. I would really appreciate it if anyone could help me out here.
Thank You.
This problem is alike minimum platform problem.
In that, you need to sort the min and max maths books array in ascending order respectively. Try to understand the problem from the above link (platform problem) then this will be a piece of cake.
Here is your solution:
n = int(input())
min_books = []
max_books = []
for i in range(n):
x, y = input().split()
min_books.append(int(x))
max_books.append(int(y))
min_books.sort()
max_books.sort()
happy_st_result = 1
happy_st = 1
books_needed = min_books[0]
i = 1
j = 0
while (i < n and j < n):
if (min_books[i] <= max_books[j]):
happy_st+= 1
i+= 1
elif (min_books[i] > max_books[j]):
happy_st-= 1
j+= 1
if happy_st > happy_st_result:
happy_st_result = happy_st
books_needed = min_books[i-1]
print(books_needed, happy_st_result)
Try this, and let me know if you need any clarification.
#Vinay Gupta's logic and explanation is correct. If you think on those lines, the answer should become immediately clear to you.
I have implemented the same logic in my code below, except using fewer lines and cool in-built python functions.
# python 3.7.1
import itertools
d = {}
for _ in range(int(input())):
x, y = map(int, input().strip().split())
d.setdefault(x, [0, 0])[0] += 1
d.setdefault(y, [0, 0])[1] += 1
a = list(sorted(d.items(), key=lambda x: x[0]))
vals = list(itertools.accumulate(list(map(lambda x: x[1][0] - x[1][1], a))))
print(a[vals.index(max(vals))][0], max(vals))
The above answer got accepted in Dcoder too.

Python Slot Machine: Calculating Line Payouts

I'm a Python newbie attempting to create a slot machine simulator that mimics the payouts of the real machines. I'm running into an issue in calculating the line payouts, and I'm sure there's a smarter way of iterating through the lines and calculating them.
Defining some constants that I'll be using:
SymbolMap = ["Boats","Bonus","Buoys","Clams","Light Houses","Lobsters","Scatter","Seagulls","Starfish","Tuna","Wilds"]
#The ints in reels below are a simpler way to express the SymbolMap above
Reels = [[9,8,3,4,6,3,8,1,5,6,2,3,8,2,3,8,5,4,3,10,7,8,10,1,3,0,8,9,3,8,9,5,3,8,0,4,3,8,0,9,2,7,5,3,8,0,7],
[3,2,4,3,2,4,1,7,3,0,7,9,0,1,8,7,10,1,7,4,5,10,2,3,1,7,3,6,5,9,7,6,8,3,0,5,7,3,1,8,7,2,4,3,9,7,0],
[0,8,3,1,4,0,5,8,1,4,8,1,9,8,3,7,8,10,1,4,7,8,9,3,0,9,8,1,9,4,8,6,4,5,7,8,6,2,9,5,1,8,4,7,2,0,9],
[7,9,2,7,6,2,8,7,9,10,2,9,8,5,7,9,10,5,4,2,7,0,3,8,4,7,0,3,2,7,0,4,8,9,7,2,8,3,2,7,8,3,5,10,2,7,8],
[3,10,0,5,2,8,4,9,8,4,7,10,9,2,0,3,9,2,8,3,6,2,8,9,3,2,0,4,9,5,4,7,3,5,8,0,4,9,7,8,4,3,5,7,8,3,7]]
# Lines are the row to look for on each reel. i.e. Lines[0] is a straight line of the 2nd row.
# Lines[3] starts in top left corner of matrix, and forms inverted V shape.
Lines = [[1,1,1,1,1],
[0,0,0,0,0],
[2,2,2,2,2],
[0,1,2,1,0],
[2,1,0,1,2],
[2,2,1,0,0],
[0,0,1,2,2],
[1,2,1,0,1],
[1,0,1,2,1],
[2,1,1,1,0],
[0,1,1,1,2],
[1,2,2,1,0],
[1,0,0,1,2],
[1,1,2,1,0],
[1,1,0,1,2]]
#Payouts are how many credits won for symbols in a row. For example, Symbols[0] is Boats.
#2 boats is 0 credits, 3 boats is 25 credits, 4 boats is 100 credits, 5 boats is 500 credits.
#They must be continuous and from left to right. I.e. BOAT-BOAT-CLAM-BOAT-BOAT on a payline wins 0.
#Similarly, CLAM-CLAM-BOAT-BOAT-BOAT wins 0.
Payouts = [[0,25,100,500],
[0,0,0,0],
[0,25,100,500],
[0,5,30,200]]
#Initializing a 3X5 matrix to represent reels
SpinValues = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
#Initializing message
Message = ''
#Initializing TotalWin
TotalWin = 0
Spin logic, which properly generates a 3X5 matrix of random numbers. Is there a better way to handle the "if first 3 symbols match" portion, since I'll have to repeat again for 4 symbols and 5 symbols? Since each line is only entitled to one payout, I'll start with the 5 symbol payouts, then work down toward 2. I started with 3 because it's the most common and will be easiest to test. I'll also have to account for a wild equaling any symbol, which I haven't tried to tackle yet. Likewise, there is a scatter pay (meaning if you have X number of Scatter symbols anywhere in the matrix, you get a payout. That part will be easy). There is also a bonus game, which I'll be working on later:
def spin(linesPlayed, wager):
for i, object in enumerate(Reels):
length = len(Reels[i])
StopValue = random.randint(0,length-1)
SpinValues[1][i] = Reels[i][StopValue]
if StopValue == 0:
SpinValues[0][i] = Reels[i][-1]
else:
SpinValues[0][i] = Reels[i][StopValue - 1]
if StopValue == len(Reels[i])-1:
SpinValues[2][i] = Reels[i][0]
else:
SpinValues[2][i] = Reels[i][StopValue +1]
print(SpinValues[0])
print("\n")
print(SpinValues[1])
print("\n")
print(SpinValues[2])
for i in range(linesPlayed):
#if first 3 symbols match
if SpinValues[Lines[i][0]] == SpinValues[Lines[i][1]] == SpinValues[Lines[i][2]]:
PayTable(i,wager,3,SpinValues[Lines[i][0]])
#if first 4 symbols match
#if first 5 symbols match
#handle scatter pay
#wilds?
#handle bonus trigger
Handling wins:
def PayTable(i,wager,symbolCount,symbol):
LineWin = Payouts[symbol][symbolCount] * wager
TotalWin += Payouts[symbol][symbolCount] * wager
Message += "Line " + str(i) +" wins " + str(LineWin) + " credits with " + str(symbolCount) + " " + SymbolMap[symbol] + "!" + "\n"
I'm getting the error that both TotalWin and Message are undefined. I thought that I could defined them globally up top?
You need to use the global keyword in each function to access variables defined in a parent.
For example:
def PayTable(i,wager,symbolCount,symbol):
global TotalWin
global Message

Stop iterating over nested loops and continue with most outest loop

I am coding a heuristic for an optimization problem from the field of production. In this heuristic I have various conditions, stop criteria etc. In order to account for these different criteria, I worked with multiple nested loops, as you can see in the code below:
for tao in PERIODS:
print ("Iteration:", tao)
print ("-----------------------------------------")
print (SETUP_ITEMS)
for z in range(1,periods_count+1-tao):
print("z =",z)
for k in SETUP_ITEMS[tao+z]:
print("k =",k)
#### EXCEPTION 1
if production.loc[k][tao] == 0:
print("There is no setup in this period for product {}.".format(k))
counter =+ 1
continue
#### EXCEPTION 2
if demand.loc[k][tao+z] > spare_capacity[tao]['Spare Capacity']:
print("Capacity in period {} is insufficient to pre-produce demands for product {} from period {}.\n".format(tao, k, tao+z))
counter =+ 1
continue
if counter == k:
print("Stop Criterion is met!")
break
##########################################################################
if SM == 1:
if SilverMeal(k,z) == True:
print("Silver Meal Criterion is", SilverMeal(k,z))
production.loc[k][tao] += demand.loc[k][tao+z]
production.loc[k][tao+z] = 0
else:
print("Else: Silver Meal Criterion is", SilverMeal(k,z))
for t in range(tao,periods_count+1):
for k in PRODUCTS:
spare_capacity[t] = capacity[t][1]-sum(production.loc[k][t] for k in PRODUCTS)
SETUP_ITEMS = [[] for t in range(0,periods_count+1)]
for t in PERIODS:
for k in PRODUCTS:
if production.loc[k][t]==(max(0,demand.loc[k][t]-stock.loc[k][t-1])) > 0:
SETUP_ITEMS[t].append(k)
print(productionplan(production,spare_capacity,CF), '\n\n')
print(productionplan(production,spare_capacity,CF), '\n\n')
The idea is, that if for one tao, there is an exception true for all k, all the loops terminate early, apart from the most outer one, so that we would go to the next tao in PERIODS and it all starts again.
I tried to use it with the counter variable, but this did not turn out to be functioning really well.
I currently have for example this output (extract):
z = 1
k = 1
Capacity in period 1 is insufficient to pre-produce demands for product 1 from period 2.
k = 2
Capacity in period 1 is insufficient to pre-produce demands for product 2 from period 2.
z = 2
k = 2
Capacity in period 1 is insufficient to pre-produce demands for product 2 from period 3.
After the k=2 in z=1the iteration should terminate, but it keeps on checking further z values.
Could anyone give me a tip how to solve this issue? I read about putting loops into functions, so that one can break out of multiple loops, but I am not sure how to formulate this here, as I would have multiple points of exit..
Thanks!
Python does not have control for breaking out of multiple loops at once.
You can set a flag and break out of multiple loops, for more info Link

Categories