I was given the following block of code
def sort(a):
"""Sort list a into ascending order by value.
Adapted from https://en.wikipedia.org/wiki/Gnome_sort#Code.
"""
pos = 0
while pos < len(a):
if pos == 0 or a[pos] >= a[pos-1]:
pos += 1
else:
a[pos], a[pos-1] = a[pos-1], a[pos]
pos -= 1
and need to make implment it the same in python, but recursively instead of iteratively. so far I have
def sort(a,pos=0):
if(pos<len(a)):
return
else:
if(pos==0 or a[pos]>= a[pos-1]):
sort(a,pos+1)
else:
a[pos],a[pos-1]= a[pos-1],a[pos]
pos=pos-1
can anyone help me out
You should not return when pos is less than len(a), and you should make a recursive call with pos - 1 after the swap:
def sort(a, pos=0):
if pos < len(a):
if pos == 0 or a[pos] >= a[pos - 1]:
sort(a, pos + 1)
else:
a[pos], a[pos - 1] = a[pos - 1], a[pos]
sort(a, pos - 1)
Related
I'm trying to code minesweeper in pygame, I am having a problem with auto-clearing the blank spaces due to a recursion error, RecursionError: maximum recursion depth exceeded in comparison, it says it is being repeated 993 more times (this amount doesn't change no matter how many randomly generated positions I create). I've tried doing my own solution and got this problem then I used a solution I found on the internet and still got the same error I'm not sure what to do
import pygame
import random
pygame.init()
size = 800
rows = 8
window = pygame.display.set_mode((size, size))
pygame.display.set_caption("MineSweeper")
mines_needed = 10
num_colour = {
0: (255,255,255), 1:(3,37,126), 2: (0,137,0), 3: (255,0,0), 4: (0,0,255), 5: (128,0,0), 6: (0,128,128), 7: (0,0,0), 8: (128,128,128)
}
font = pygame.font.SysFont('arial', 30)
def board():
global board_array
board_array = []
window.fill((255, 255, 255))
distance = size//rows #100
x = 0
y = 0
for i in range(rows):
pygame.draw.line(window, (0, 0, 0), (x, 0), (x, size))
pygame.draw.line(window, (0, 0, 0), (0, y), (size, y))
x += distance
y += distance
elements = []
for j in range(rows):
elements.append(0)
board_array.append(elements)
def create_mines():
mines_created = 0
while mines_created < mines_needed:
randomr = random.randint(-1,7)
randomc = random.randint(-1,7)
if board_array[randomr][randomc] == -1:
pass
else:
board_array[randomr][randomc] = -1
mines_created += 1
def draw():
number = 0
for x in range(8):
for y in range(8):
if x == 0 and y == 0:
number = 0
if board_array[x + 1][y] == -1:
number += 1
if board_array[x + 1][y + 1] == -1:
number += 1
if board_array[x][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if x == 7 and y == 0:
number = 0
if board_array[x - 1][y] == -1:
number += 1
if board_array[x - 1][y + 1] == -1:
number += 1
if board_array[x][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if x == 0 and y == 7:
number = 0
if board_array[x + 1][y] == -1:
number += 1
if board_array[x + 1][y - 1] == -1:
number += 1
if board_array[x][y - 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if x == 7 and y == 7:
number = 0
if board_array[x - 1][y] == -1:
number += 1
if board_array[x - 1][y - 1] == -1:
number += 1
if board_array[x][y - 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if x == 0 and (y != 0 and y != 7):
number = 0
if board_array[x][y - 1] == -1:
number += 1
if board_array[x + 1][y - 1] == -1:
number += 1
if board_array[x + 1][y] == -1:
number += 1
if board_array[x + 1][y + 1] == -1:
number += 1
if board_array[x][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if x == 7 and (y != 0 and y != 7):
number = 0
if board_array[x][y - 1] == -1:
number += 1
if board_array[x - 1][y - 1] == -1:
number += 1
if board_array[x - 1][y] == -1:
number += 1
if board_array[x - 1][y + 1] == -1:
number += 1
if board_array[x][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if y == 0 and (x != 0 and x != 7):
number = 0
if board_array[x + 1][y] == -1:
number += 1
if board_array[x - 1][y] == -1:
number += 1
if board_array[x][y + 1] == -1:
number += 1
if board_array[x + 1][y + 1] == -1:
number += 1
if board_array[x - 1][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if y == 7 and (x != 0 and x != 7):
number = 0
if board_array[x + 1][y] == -1:
number += 1
if board_array[x - 1][y] == -1:
number += 1
if board_array[x][y - 1] == -1:
number += 1
if board_array[x + 1][y - 1] == -1:
number += 1
if board_array[x - 1][y - 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
if (x != 7 and x != 0) and (y != 7 and y != 0):
number = 0
if board_array[x][y + 1] == -1:
number += 1
if board_array[x][y - 1] == -1:
number += 1
if board_array[x + 1][y] == -1:
number += 1
if board_array[x - 1][y] == -1:
number += 1
if board_array[x - 1][y - 1] == -1:
number += 1
if board_array[x + 1][y - 1] == -1:
number += 1
if board_array[x - 1][y + 1] == -1:
number += 1
if board_array[x + 1][y + 1] == -1:
number += 1
if board_array[x][y] != -1:
board_array[x][y] = number
def click(x,y):
dug = set()
dug.add((x,y))
centre_x = (x * 100) + 50
centre_y = (y * 100) + 50
if board_array[x][y] != -1:
number_text = font.render(str(board_array[x][y]), True, num_colour[board_array[x][y]])
window.blit(number_text, (centre_x - 10, centre_y - 10))
elif board_array[x][y] != 0:
pygame.draw.circle(window, (0, 0, 0), (centre_x, centre_y), 10)
if board_array[x][y] == 0:
pygame.draw.rect(window, (128,128,128), (x*100+2, y*100+2, 97, 97))
for i in range(max(0,x-1), min(6,x+1)+1):
for j in range(max(0, y-1), min(6, y+1)+1):
if (x,y) in dug:
pass
click(x,y)
def draw_flag():
pass
board()
create_mines()
draw()
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
x,y = pygame.mouse.get_pos()
x /= 100
y /= 100
click(int(x),int(y))
if event.type == pygame.QUIT:
run = False
print(board_array)
pygame.display.update()
I know my code could be better optimised but I tried to do this with minimal help from the internet and plan on going back to it once I've completed the game
I'm not sure exactly what you are trying to do, but you are passing the original arguments to the recursive call in click, thus running endlessly.
if (x,y) in dug:
pass
click(x,y)
Replace (x,y) with (i,j).
pass does nothing - you probably wanted continue to jump over the recursive click - instead, use:
if (i,j) not in dug:
click(i,j)
It looks like this will still fail as you don't use the dug set in the recursive calls, so you need to pass it to and get it back from the recursive click to skip points you've finished handling.
I have these functions. They are working perfectly, but is there a way to speed them up? I tried to split the dataset, but it takes the same or more time than the original functions. I'm working with big arrays (1Mill+X2504X2). create_needed_pos takes arount 350sec for 1.2millX2054X2 array, but my biggest is around 10bilionx2054x2.
#nb.njit
def create_needed_pos(chr_pos, pos):
needed_pos = nb.typed.List.empty_list(nb.int32)
for i in range(len(chr_pos)):
for k in range(len(pos)):
if chr_pos[i] == pos[k]:
if i == k == 1:
needed_pos = nb.typed.List([pos[k]])
else:
needed_pos.append(pos[k])
return needed_pos
#nb.njit
def create_mat(geno):
# create matrix as np.uint8 (1 byte) instead of list of python integers (8 byte)
# also no need to dynamically resize / increase list size
geno_mat = np.zeros((len(geno[:, 0]), len(geno[1, :])), dtype=np.uint8)
for i in np.arange(len(geno[:, 0])):
for k in np.arange(len(geno[1, :])):
g = geno[i, k]
# nested ifs to avoid duplicate comparisons
if g[0] == 0:
if g[1] == 0:
geno_mat[i, k] = 2
elif g[1] == 1:
geno_mat[i, k] = 1
else:
geno_mat[i, k] = 9
elif g[0] == 1:
if g[1] == 0:
geno_mat[i, k] = 1
elif g[1] == 1:
geno_mat[i, k] = 0
else:
geno_mat[i, k] = 9
else:
geno_mat[i, k] = 9
return geno_mat
I have been coding this problem for HackerRank and I ran into so many problems. The problem is called "Plus Minus" and I am doing it in Python 3. The directions are on https://www.hackerrank.com/challenges/plus-minus/problem. I tried so many things and it says that "there is no response on stdout". I guess a none-type is being returned. Here is the code.:
def plusMinus(arr):
p = 0
neg = 0
z = arr.count(0)
no = 0
for num in range(n):
if arr[num] < 0:
neg+=1
if arr[num] > 0:
p+=1
else:
no += 1
continue
return p/n
The following are the issues:
1) variable n, which represents length of the array, needs to be passed to the function plusMinus
2) No need to maintain the extra variable no, as you have already calculated the zero count. Therefore, we can eliminate the extra else condition.
3) No need to use continue statement, as there is no code after the statement.
4) The function needs to print the values instead of returning.
Have a look at the following code with proper naming of variables for easy understanding:
def plusMinus(arr, n):
positive_count = 0
negative_count = 0
zero_count = arr.count(0)
for num in range(n):
if arr[num] < 0:
negative_count += 1
if arr[num] > 0:
positive_count += 1
print(positive_count/n)
print(negative_count/n)
print(zero_count/n)
if __name__ == '__main__':
n = int(input())
arr = list(map(int, input().rstrip().split()))
plusMinus(arr, n)
The 6 decimals at the end are needed too :
Positive_Values = 0
Zeros = 0
Negative_Values = 0
n = int(input())
array = list(map(int,input().split()))
if len(array) != n:
print(f"Error, the list only has {len(array)} numbers out of {n}")
else:
for i in range(0,n):
if array[i] == 0:
Zeros +=1
elif array[i] > 0:
Positive_Values += 1
else:
Negative_Values += 1
Proportion_Positive_Values = Positive_Values / n
Proportion_Of_Zeros = Zeros / n
Proportion_Negative_Values = Negative_Values / n
print('{:.6f}'.format(Proportion_Positive_Values))
print('{:.6f}'.format(Proportion_Negative_Values))
print('{:.6f}'.format(Proportion_Of_Zeros))
I come up a solution for leetcode "5. Longest Palindromic Substring" with parts of duplicate codes. One of good ways to solve duplicate code is to make a function. How do I write my check here to a function? I am confused what I should return to make both variables - longest and ans - being updated. Thanks!
The part of duplicate code:
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
Full code:
class Solution:
def longestPalindrome(self, s: str) -> str:
if len(s) == 0:
return ''
if len(s) == 1:
return s
longest = 0
ans = ''
for pos in range(len(s)-1):
l, r = pos, pos
if pos > 0 and pos < len(s) - 1 and s[pos-1] == s[pos+1]:
l, r = pos-1, pos+1
while l > 0 and r < len(s) - 1 and s[l-1] == s[r+1]:
l -= 1
r += 1
# duplicate code 1
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
if s[pos] == s[pos+1]:
l, r = pos, pos+1
while l > 0 and r < len(s) - 1 and s[l-1] == s[r+1]:
l -= 1
r += 1
# duplicate code 2
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
if ans == '' and len(s) > 0:
return s[0]
return ans
The if statements and while loops before the duplicate code blocks are mostly duplicated as well, as is using the longest variable to keep track of the length of ans when you already have ans -- here's one way you could simplify things via another function:
class Solution:
def find_longest(self, s, left, right):
if s[left] == s[right]:
if right - left + 1 > len(self.ans):
self.ans = s[left:right + 1]
if left > 0 and right < len(s) - 1:
self.find_longest(s, left - 1, right + 1)
def longestPalindrome(self, s: str) -> str:
if len(s) == 1:
return s
self.ans = ''
for pos in range(len(s) - 1):
self.find_longest(s, pos, pos)
self.find_longest(s, pos, pos + 1)
return self.ans
I've just started to learn python and I've decided to try and do a bubble sort. I've used the code below which works ok if the numbers to be sorted are 0 to 9. After that, it doesn't sort them correctly. I think, in my limited knowledge that this is because it is a 'list'.
I would like the user to be able to input the numbers but for the program to sort them regardless of the length of the number. Any help would be appreciated.
def bubble_sort(items):
changes=0
for i in range(len(items)):
for j in range(len(items)-1-i):#-i = optimised??
if items[j] > items[j+1]:
items[j], items[j+1] = items[j+1], items[j] # Swap
changes=changes+1
print(items)
print("Number of passes =",i)
print("Number of swaps =",changes)
print("Welcome to a Bubble Sort Algorithm in Python!")
while True:
print("Enter as many numbers as you want.\n You can choose between 0 and 9.\nLeave a space between each one")
numbers=input()
items=numbers.split()
Try this:
print('welcome to the automatic bubble sorter')
inputted_list = input('please enter a list of numbers seperated by commas: ')
list = inputted_list.split(',')
number_of_items = int(len(list))
sorting_method = input('if you would like your list to be sorted in ascending order, press 1, if you would like it to be sorted in descending order, press 2')
print(list)
if sorting_method == '1':
position = 0
Pass = 0
counter = 1
while counter == 1:
number_of_swaps = 1
counter2 = 0
permanent_numbers = []
while number_of_swaps > 0:
counter2 = counter2 + 1
number_of_swaps = 0
while position < number_of_items - 1:
if int(list[position]) > int(list[position + 1]):
number_of_swaps = number_of_swaps + 1
item1 = int(list[position])
item2 = int(list[position + 1])
list[position] = item2
list[position + 1] = item1
position = position + 1
Pass = Pass + 1
print('pass',Pass,':',list)
position = 0
if Pass == number_of_items - 1:
number_of_swaps = 0
permanent_numbers.append(list[number_of_items - counter2])
if number_of_swaps == 0:
counter = 0
print('total number of passes:', Pass)
elif sorting_method == '2':
position = 0
Pass = 0
counter = 1
while counter == 1:
number_of_swaps = 1
while number_of_swaps > 0:
number_of_swaps = 0
while position < number_of_items - 1:
if int(list[position]) > int(list[position + 1]):
number_of_swaps = number_of_swaps + 1
item1 = int(list[position])
item2 = int(list[position + 1])
list[position] = item2
list[position + 1] = item1
position = position + 1
Pass = Pass + 1
print('pass',Pass,':',list)
position = 0
if Pass == number_of_items - 1:
number_of_swaps = 0
if number_of_swaps == 0:
counter = 0
print('total number of passes:', Pass)
try map:
I suggested using map before, but I just remembered that map in python 3.x* yields a generator rather than a list, so that is why you cannot take the length of it. The updated answer is below
numbers = input("Enter as many numbers as you want.\n You can choose between 0 and 9.\nLeave a space between each one")
items = [int(num) for num in numbers.split()]
Modified existing code:
#!/usr/bin
def bubble_sort(items):
changes = passes = 0
last = len(items)
swapped = True
while swapped:
swapped = False
passes += 1
for j in range(1, last):
if items[j - 1] > items[j]:
items[j], items[j - 1] = items[j - 1], items[j] # Swap
changes += 1
swapped = True
last = j
print(items)
print("Number of passes =",passes)
print("Number of swaps =",changes)
print("Welcome to a Bubble Sort Algorithm in Python!")
while True:
print("Enter as many numbers as you want.\n You can choose between 0 and 9.\nLeave a space between each one")
numbers = input()
items = [int(num) for num in numbers.split() if num.isdigit()]
if items: bubble_sort(items)
def b_sort(list):
for iter_num in range(len(list)-1,0,-1):
for idx in range(iter_num):
if list[idx] > list[idx+1]:
temp = list[idx]
list[idx] = list[idx+1]
list[idx+1] = temp
str_input= input("Enter numbers: ")
list = [int(x) for x in str_input.split()]
b_sort(list)
print('sorted elements are: ')
print(list)
def sort():
try:
n = [1,8,6]
l = len(n)
print("Original list:", n)
for i in range(l - 1):
for j in range(0,l - i - 1):
if n[j] > n[j + 1]:
n[j], n[j + 1] = n[j + 1], n[j]
print("List after sorting is:", n)
except:
print("Error in inputing values")
sort()