I am stuck in rewriting Python code to compile it in PyPy. My task is to calculate number of inversions in a list using modification of merge sort. Input data brings from input.txt, the result of the code is written in output.txt. My last attempt to do this looks like:
import sys
def merge(a, b, inverse_num):
n, m = len(a), len(b)
i = 0
j = 0
c = []
while i < n or j < m:
if j == m:
c.append(a[i])
i += 1
# inverse_num += 1
elif i < n and a[i] <= b[j]:
c.append(a[i])
i += 1
elif i < n and a[i] > b[j]:
c.append(b[j])
j += 1
inverse_num += n - i
if j == m and i == n - 1:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
return c, inverse_num
def merge_sort(arr, inverse_num=0):
n = len(arr)
if n == 1:
return arr, inverse_num
l = arr[:(n//2)]
r = arr[(n//2):n]
l, inverse_num_l = merge_sort(l, inverse_num)
r, inverse_num_r = merge_sort(r, inverse_num)
inverse_num = inverse_num_l + inverse_num_r
return merge(l, r, inverse_num)
def main():
with open('input.txt') as f:
n = int(f.readline().split()[0])
in_list = list(map(int, f.readline().split()))
output_file = open('output.txt', 'w')
sorted_arr, inverse_num = merge_sort(in_list, inverse_num=0)
output_file.write(str(inverse_num))
output_file.close()
return 0
def target(*args):
return entry_point, None
def entry_point(argv):
main()
return 0
if __name__ == "__main__":
entry_point(sys.argv)
After compilation it with command pypy "C:/pypy_compile/pypy-src/translate.py" Task2.py
error appears:
[translation:ERROR] TypeError: method_split() takes at least 2 arguments (1 given)
Processing block:
block#27[v4...] is a <class 'rpython.flowspace.flowcontext.SpamBlock'>
in (Task2:44)main
containing the following operations:
v6 = getattr(v5, ('split'))
v7 = simple_call(v6)
--end--
Thanks in advance for helping.
This question already has answers here:
Why Python recursive function returns None [duplicate]
(1 answer)
Recursive function does not return specified value
(2 answers)
Closed 1 year ago.
I have written a maze solver program. I want the PathFinder function to return True if a path is found and then print the path or else simply return False. But my program always keeps returning False even if a path is found. It would be great if you guys can help me figure this out.
def findPaths(m,path,i,j):
r,c = len(m), len(m[0])
if i == r-1 and j == c-1:
print(path)
return True
#explore
path.append(m[i][j])
# move down
if i != r-1 and m[i+1][j] == '↓ ':
findPaths(m,path,i+2,j)
#move up
if i < 0 and m[i-1][j] == '↑ ':
findPaths(m,path,i-2,j)
#move right
if j != c-1 and m[i][j+1] == '→':
findPaths(m,path,i,j+2)
#move left
if j > 0 and m[i][j-1] == '←':
findPaths(m,path,i,j-2)
path.pop()
def maze(r,c):
m = []
for i in range(r):
row = []
for j in range(1, c + (c)):
rand_num = str(randint(1, 99))
if j % 2 != 0:
if len(rand_num) == 1:
row.append(' ' + rand_num)
else:
row.append(rand_num)
else:
row.append('?')
m.append(row)
up_left_count = r * c // 3
down_right_count = r * c * 2 // 3
for v in range(r + (r - 1)):
vertical_lst = []
for each in range(1, c + c):
if each % 2 == 0:
vertical_lst.append(' ')
else:
vertical_lst.append('? ')
if v % 2 != 0:
m.insert(v, vertical_lst)
idx_i = []
idx_j = []
idx_v_i = []
idx_v_j = []
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
idx_i.append(i)
idx_j.append(j)
for v_i in range(len(m)):
for v_j in range(len(m[0])):
if v_i % 2 != 0 and v_j % 2 == 0:
idx_v_i.append(v_i)
idx_v_j.append(v_j)
idx_i = list(set(idx_i))
idx_j = list(set(idx_j))
idx_v_i = list(set(idx_v_i))
idx_v_j = list(set(idx_v_j))
for count in range(up_left_count):
i_int = randint(0, len(idx_i) - 1)
j_int = randint(0, len(idx_j) - 1)
if m[i_int][j_int] != '←':
m[idx_i[i_int]][idx_j[j_int]] = '←'
for count_v in range(up_left_count):
i_v_int = randint(0, len(idx_v_i) - 1)
j_v_int = randint(0, len(idx_v_j) - 1)
if m[i_v_int][j_v_int] != '↑':
m[idx_v_i[i_v_int]][idx_v_j[j_v_int]] = '↑ '
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
if m[i][j] == '?':
m[i][j] = '→'
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 != 0 and j % 2 == 0:
if m[i][j] != '↑ ':
m[i][j] = '↓ '
m[0][0] = "S"
m[-1][-1] = "D"
for i in range(len(m)):
for j in range(len(m[0])):
print(m[i][j], end=" ")
print()
path = []
return findPaths(m, path, 0,0)
if maze(5,6):
print('True')
else:
print('False')
Edit: New code. Both solutions were working perfectly, but for some reason did not improve my time results and that doesn`t make sense to me just yet.
Seeing my desperation, a friend PMed me his solution, which is working fine with the time given, but somehow fails on this specific input:
9
1 2 2 3 3 4 4 5
3 6 6 7 3 8 8 9 9 10
It gives "9" instead of "5". Any ideas why that could be?
maxNum = int(0)
idxArr = []
def ReadInput():
global array
global firstNum
arr = input().split()
firstNum = int(arr[0])
while int(arr[0]) * 2 + 1 > len(arr):
tempArray = input().split()
arr = arr + tempArray
iterator = int(0)
array = [0] * int(arr[0])
for i in range(1, int(arr[0]) * 2, 2):
tempArray = [0] * 3
tempArray[0] = int(arr[i])
tempArray[1] = int(arr[i + 1])
tempArray[2] = None
array[iterator] = tempArray
iterator+=1
def SortArray(array):
array.sort(key=lambda x: x[1])
array.sort(key=lambda x: x[0])
def MergeDominos(array):
tempNum = int(0)
for item in array:
if (item[2] == None):
iterator = tempNum
counter = int(0)
tempBool = False
try:
while item == array[iterator]:
if (tempBool):
array.pop(iterator)
counter += 1
else:
iterator += 1
counter += 1
tempBool = True
except IndexError:
True == True
if (counter % 2 == 1):
item[2] = counter
tempNum += 1
else:
tempItem = item.copy()
array.insert(tempNum + 1, tempItem)
array[tempNum + 1][2] = int(1)
item[2] = counter - 1
tempNum += 1
else:
tempNum += 1
def GetLengthOfArray(array):
counter = int(0)
for item in array:
counter += item[2]
return counter
def SwitchPlaces(item):
item[0], item[1] = item[1], item[0]
def GetMaxLength(array, tempArray, left, right):
global maxNum
# print("This is temp: ", tempArray)
for i in range(len(array)):
# print("Testing: ", array[i], "Iteration: ", i)
# print("IdxArr: ", idxArr)
if (len(array) <= len(idxArr)):
#print("BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE BREAKING HERE ")
break
if (i not in idxArr):
#print("Condition:")
if (left == array[i][0]):
#print("LL")
if (i in idxArr):
break
else:
idxArr.append(i)
SwitchPlaces(array[i])
if (len(array) >= len(idxArr)):
tempArray.insert(0, array[i])
if (GetLengthOfArray(tempArray) > maxNum):
maxNum = GetLengthOfArray(tempArray)
if (len(array) >= len(idxArr)):
GetMaxLength(array, tempArray, tempArray[0][0], tempArray[len(tempArray) - 1][1])
if (left == array[i][1]):
#print("LR")
if (i in idxArr):
break
else:
idxArr.append(i)
if (len(array) >= len(idxArr)):
tempArray.insert(0, array[i])
if (GetLengthOfArray(tempArray) > maxNum):
maxNum = GetLengthOfArray(tempArray)
if (len(array) >= len(idxArr)):
GetMaxLength(array, tempArray, tempArray[0][0], tempArray[len(tempArray) - 1][1])
if (right == array[i][0]):
#print("RL")
if (i in idxArr):
break
else:
idxArr.append(i)
if (len(array) >= len(idxArr)):
tempArray.append(array[i])
if (GetLengthOfArray(tempArray) > maxNum):
maxNum = GetLengthOfArray(tempArray)
if (len(array) >= len(idxArr)):
GetMaxLength(array, tempArray, tempArray[0][0], tempArray[len(tempArray) - 1][1])
if (right == array[i][1]):
#print("RR")
if (i in idxArr):
break
else:
idxArr.append(i)
SwitchPlaces(array[i])
if (len(array) >= len(idxArr)):
tempArray.append(array[i])
if (GetLengthOfArray(tempArray) > maxNum):
maxNum = GetLengthOfArray(tempArray)
if (len(array) >= len(idxArr)):
GetMaxLength(array, tempArray, tempArray[0][0], tempArray[len(tempArray) - 1][1])
#else:
# print("No condition BIG OOOF")
ReadInput()
SortArray(array)
MergeDominos(array)
for i in range(len(array)):
#print("iter num: ", i)
tempArray = []
idxArr = []
idxArr.append(i)
tempArray.append(array[i])
if (GetLengthOfArray(tempArray) > maxNum):
maxNum = GetLengthOfArray(tempArray)
GetMaxLength(array, tempArray, tempArray[0][0], tempArray[len(tempArray) - 1][1])
print(maxNum)
E1: The input is made in this weird way, because the first item of the list gives the number of dominoes, and also, the input can come in multiple rows and then I create list item pairs.
Example input:
5 1 2
1 2
2 3
2
17
2 17
And the dominoes are:
[('1','2'),('1','2'),('2','2'),('2','17'),('2','17')]
Expected result:
5
(3,2)-(2,1)-(1,2)-(2,17)-(17-2)
The following is a rewrite of your solution with one significant change:
if maximum == len(listOfDominos) + len(tempList):
break
This prevents the code from exploring any further once it has a maximum that it knows it can't improve on. For the example input you provided, it reduced the number of searches by 20x:
def find(listOfDominos, tempList):
maximum = len(tempList)
for currentDominoIndex, domino in enumerate(listOfDominos):
if maximum == len(listOfDominos) + len(tempList):
break # we can't do any better, so why try?
remainingDominos = listOfDominos[:currentDominoIndex] + listOfDominos[currentDominoIndex+1:]
if tempList:
backwardDomino = domino[::-1]
head, tail = tempList[0], tempList[-1]
if domino[1] == head[0]:
maximum = max(find(remainingDominos, [domino] + tempList), maximum)
elif backwardDomino[1] == head[0]:
maximum = max(find(remainingDominos, [backwardDomino] + tempList), maximum)
elif domino[0] == tail[1]:
maximum = max(find(remainingDominos, tempList + [domino]), maximum)
elif backwardDomino[0] == tail[1]:
maximum = max(find(remainingDominos, tempList + [backwardDomino]), maximum)
else:
maximum = max(find(remainingDominos, [domino]), maximum)
return maximum
listOfNumbers = input().split()
numberOfDominos = int(listOfNumbers.pop(0))
while numberOfDominos * 2 > len(listOfNumbers):
listOfNumbers += input().split()
listOfDominos = list(zip(listOfNumbers[0::2], listOfNumbers[1::2]))
print(find(listOfDominos, []))
Give this a try to see if it improves performance without introducing any bugs in the process.
Try this solution:
def solution(dominoes):
if len(dominoes) == 0:
return 0
def get_sequence(d, sol=None):
if sol is None:
sol = []
if len(d) == 0:
return
for i in range(len(d)):
rest = d[:i] + d[i+1:]
d1, d2 = d[i], d[i][::-1]
if d1 == d2:
if (not sol) or (sol[-1][1] == d1[0]):
yield sol + [d1]
yield from get_sequence(rest, sol + [d1])
else:
if (not sol) or (sol[-1][1] == d1[0]):
yield sol + [d1]
yield from get_sequence(rest, sol + [d1])
if (not sol) or (sol[-1][1] == d2[0]):
yield sol + [d2]
yield from get_sequence(rest, sol + [d2])
return(len(max(get_sequence(dominoes), key=len)))
dominoes = [('1','2'),('1','2'),('2','2'),('2','17'),('2','17')]
print(solution(dominoes))
Prints:
5
def seq_merge_sort(arr):
rght = 0; wid = 0; rend = 0; left = 0
k = 1
num = len(arr)
temp = [0] * num
while(k < num):
while(left + k < num):
rght = left + k
rend = rght + k
if(rend > num):
rend = num
m = left; i = left; j = rght
while(i < rght and j < rend):
if (arr[i] <= arr[j]):
temp[m] = arr[i]
i += 1
else:
temp[m] = arr[j]
j += 1
m += 1
while(i < rght):
temp[m] = arr[i]
i += 1; m += 1
while(j < rend):
temp[m] = arr[j]
j += 1; m += 1
m = left
while(m < rend):
arr[m] = temp[m]
m += 1
left += k * 2
k *= 2
return arr
I made this code in python with similar code in C#,
but it worked only halfway through. For example, some parts are sorted, but some parts are same as input.
I tried to fix it, but it really make me hard.
It will be thanks to great coder who make this sorting perfect!
While solving this problem in LeetCode, I submitted the following code in Python3 and got Time Limit Exceeded.
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
solutions = []
for i in range(len(nums)-2):
if i > 0 and nums[i] == nums[i - 1]:
continue
l = i + 1
r = len(nums) - 1
while l < r:
if nums[i] + nums[l] + nums[r] == 0:
solutions.append([nums[i], nums[l], nums[r]])
while l < r and nums[l] == nums[l + 1]:
l += 1
l += 1
while l < r and nums[r] == nums[r - 1]:
r -= 1
r -= 1
elif nums[l] + nums[r] + nums[i] > 0:
r -= 1
else:
l += 1
return solutions
but when submitting the same solution in Python2, I got Accepted.
I am new to python and simply fail to understand why this is happening.