Find bug in my Knight's Move Python Program - python

Code
I am trying to build a Knight's Move Program everything working fine but there is a hidden bug in this code that I cannot find. Can anybody spot the problem?
from itertools import product
def solution(src, dest):
A = [[0, 1, 2, 3, 4, 5, 6, 7],
[8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29, 30, 31],
[32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55],
[56, 57, 58, 59, 60, 61, 62, 63]]
if (src not in range(0,64) or dest not in range(0,64)) :
raise Exception('out of range')
step = 1
r_s = 0
r_e = 7
str_r = 0
str_c = 0
while src:
if r_s <= src <= r_e:
for i in range(0, 8):
if A[str_r][i] == src:
str_c = i
break
break
str_r += 1
r_s += 8
r_e += 8
moves = list(product([str_r - 1, str_r + 1], [str_c - 2, str_c + 2])) + list(product([str_r - 2, str_r + 2],[str_c - 1, str_c + 1]))
m_s = [(x,y) for x,y in moves if x >= 0 and y >= 0 and x < 8 and y < 8]
for i, j in m_s:
if A[i][j] == dest:
move_counter = step
return move_counter
while True:
step += 1
List_steps = []
for i, j in m_s:
r_s = 0
r_e = 7
str_r = 0
str_c = 0
while True:
if r_s <= A[i][j] <= r_e:
for x in range(0, 8):
if A[str_r][x] == A[i][j]:
str_c = x
break
break
str_r += 1
r_s += 8
r_e += 8
moves = list(product([str_r - 1, str_r + 1], [str_c - 2, str_c + 2])) + list(product([str_r - 2, str_r + 2],[str_c - 1, str_c + 1]))
m_z = [(x,y) for x,y in moves if x >= 0 and y >= 0 and x < 8 and y < 8]
for m, n in m_z:
if A[m][n] == dest:
return step
move_counter = 'Not Found'
List_steps += m_z
if move_counter == 'Not Found':
m_s = list(set(List_steps))
continue
if __name__ == '__main__':
A = int(input())
B = int(input())
print(solution(A, B))
Bug Location
I think the bug is here:
moves = list(product([str_r - 1, str_r + 1], [str_c - 2, str_c + 2])) + list(product([str_r - 2, str_r + 2],[str_c - 1, str_c + 1]))
m_z = [(x,y) for x,y in moves if x >= 0 and y >= 0 and x < 8 and y < 8]

Related

Add count until certain value then reset to zero python

I am trying to change the value of x depending on the length of my list
How can x count up by 5 through each iteration and then back to 0 after the 10th round?
list = {"one", "two".....fifty} #example shortened
listLen = len(list) # 50
for i in range (0, listLen) # 0 - 49
x = ??? # +5 max 45
ops.update(location=x)
Desired outcome:
0. x = 0
1. x = 5
2. x = 10
...
9. x = 45
10. x = 0
11. x = 5
12. x = 10
...
19. x = 45
...
(0,5,10,15,20,25,30,25,40,45,0,5,10,15,20,25,30,25,40,45
0,5,10,15,20,25,30,25,40,45,0,5,10,15,20,25,30,25,40,45
0,5,10,15,20,25,30,25,40,45)
Try this
outcome = []
lst = {1,2,3,...,50}
lstLen = range(0, len(lst), 5)
for a in range(len(lst)):
outcome.append(lstLen[a%10])
print(outcome)
Output
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45,
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45,
0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
Try this:
ans = []
for i in range (0, listLen): # 0 - 49
x += 5
ans.append(x)
if i % 9 == 0:
x = 0

Loop of List into a Tabbed New List

I am a high school student. By observing the inputted sequence, I want to create a program that creates general formulas on quadratic to a polynomial with nth power equations. This posted code will function as a means of validation for inputted sequences. If you have a better code, please help me. Thank You!
The same concept was shown below,
here is my code
def shrink(numbers):
n1 = [(x, numbers[i+1]) for i, x in enumerate(numbers)
if i < len(numbers)-1]
n2 = [x[1]-x[0] for x in n1]
print(n2)
if(len(n2) > 1):
return shrink(n2)
return n
#shrink([1, 8, 27, 64, 125, 216])
a = input()
b = a.split()
for i in range(len(b)):
b[i] = int(b[i])
shrink(b)
"""
The output will be:
[7, 19, 37, 61, 91]
[12, 18, 24, 30]
[6, 6, 6]
[0, 0]
[0]
"""
#I want the output from the top to be like this!
d = [
[7, 19, 37, 61, 91],
[12, 18, 24, 30],
[6, 6, 6],
[0, 0],
[0]
]
if d[2][0] == d[2][1]:
print('cubic sequence')
During the first call you initialize a list variable which you update and pass to the recursive call
def shrink(numbers,return_list = []):
n1 = [(x, numbers[i+1]) for i, x in enumerate(numbers) if i < len(numbers)-1]
n2 = [x[1]-x[0] for x in n1]
return_list.append(n2)
if(len(n2) > 1):
return shrink(n2,return_list)
else:
return return_list
print(shrink([1, 8, 27, 64, 125, 216]))
If you want the values of n1 as well :
def shrink(numbers,n1_list = [], n2_list = []):
n1 = [(x, numbers[i+1]) for i, x in enumerate(numbers) if i < len(numbers)-1]
n2 = [x[1]-x[0] for x in n1]
n1_list.append(n1)
n2_list.append(n2)
# print(n2)
if(len(n2) > 1):
return shrink(n2,n1_list,n2_list)
else:
return n1_list,n2_list
print(shrink([1, 8, 27, 64, 125, 216]))
Thank You Atharva Gundawar.
If you want the list to be inputted, this is the answer:
Take note that input list should be separated by space and not by a comma.
Sample input: 1 8 27 64 125 216
def shrink(numbers, return_list=[]):
n1 = [(x, numbers[i + 1]) for i, x in enumerate(numbers) if i < len(numbers) - 1]
n2 = [x[1] - x[0] for x in n1]
return_list.append(n2)
if (len(n2) > 1):
return shrink(n2, return_list)
else:
return return_list
a = input()
b = a.split()
for i in range(len(b)):
b[i] = int(b[i])
c = shrink(b)
print(shrink(b))
print(c[2][0])
print(c[2][1])
if c[2][0] == c[2][1]:
print('cubic sequence')
Input:
1 8 27 64 125 216
Output:
[[7, 19, 37, 61, 91], [12, 18, 24, 30], [6, 6, 6], [0, 0], [0], [7, 19, 37, 61, 91], [12, 18, 24, 30], [6, 6, 6], [0, 0], [0]]
6
6
cubic sequence
This is the correct answer to eradicate the loop:
https://stackoverflow.com/posts/70423499/revisions
def shrink(numbers, return_list=[]):
n1 = [(x, numbers[i + 1]) for i, x in enumerate(numbers) if i < len(numbers) - 1]
n2 = [x[1] - x[0] for x in n1]
return_list.append(n2)
if (len(n2) > 1):
return shrink(n2, return_list)
else:
return return_list
input_user = input("Enter data:")
b = input_user.split()
for num in range(len(b)):
b[num] = int(b[num])
c = shrink(b)
print(c)

Plotting a sequence of double arrays, and refreshing the graph after each plot, using matplotlib

Each iteration at line 97 gives me arrays for x and y coordinates respectively.
for step in range(N_OF_DTs):
I'd like to plot an iterations result, clear the window, and then plot the next iterations results.
I'm using python 3.
I don't know enough python to display data.
import numpy as np
import matplotlib.pylab as plt
np.random.seed(314159)
N_OF_DTs = 1000
DT = 0.001
DTover6 = DT/6.0
WIDTH = 20
I_EXT = 1.1
WEIGHT = 0.24
grid_u = np.zeros((WIDTH,WIDTH))
fired = np.zeros((WIDTH,WIDTH))
u = np.zeros((WIDTH,WIDTH))
k1 = np.zeros((WIDTH,WIDTH))
k2 = np.zeros((WIDTH,WIDTH))
k3 = np.zeros((WIDTH,WIDTH))
k4 = np.zeros((WIDTH,WIDTH))
spike_data = np.zeros((WIDTH, WIDTH, N_OF_DTs), dtype=object)
def init_grid():
global grid_u
grid_u = np.random.rand(WIDTH,WIDTH)
def clear_fired_grid():
global fired
fired = np.zeros((WIDTH,WIDTH))
def step1_grid():
global grid_u
u = grid_u
k1 = -u + I_EXT
k2 = -(u + 0.5*k1*DT) + I_EXT
k3 = -(u + 0.5*k2*DT) + I_EXT
k4 = -(u + k3*DT) + I_EXT
grid_u = grid_u + DTover6*(k1 + 2*k2 + 2*k3 +k4)
def check_fired_grid():
for i in range(WIDTH-1):
for j in range(WIDTH-1):
check_fired_neuron(j,i)
global fired
spike_data[0,0,step] = fired
def check_fired_neuron(j,i):
if grid_u[j,i] > 1:
grid_u[j,i] = grid_u[j,i] - 1
global fired
fired[j,i] = 1
propagate_to_neighbors(j,i)
check_fired_neighbors(j,i)
def check_fired_neighbors(j,i):
if j > 1:
check_fired_neuron(j-1,i)
else:
check_fired_neuron(WIDTH-1,i)
if j < WIDTH-1:
check_fired_neuron(j+1,i)
else:
check_fired_neuron(1,i)
if i > 1:
check_fired_neuron(j,i-1)
else:
check_fired_neuron(j,WIDTH-1)
if i < WIDTH-1:
check_fired_neuron(j,i+1)
else:
check_fired_neuron(j,1)
def propagate_to_neighbors(j,i):
if j > 1:
grid_u[j-1,i] = grid_u[j-1,i] + WEIGHT
else:
grid_u[WIDTH-1,i] = grid_u[WIDTH-1,i] + WEIGHT
if j < WIDTH-1:
grid_u[j+1,i] = grid_u[j+1,i] + WEIGHT
else:
grid_u[1,i] = grid_u[1,i] + WEIGHT
if i > 1:
grid_u[j,i-1] = grid_u[j,i-1] + WEIGHT
else:
grid_u[j,WIDTH-1] = grid_u[j,WIDTH-1] + WEIGHT
if i < WIDTH-1:
grid_u[j,i+1] = grid_u[j,i+1] + WEIGHT
else:
grid_u[j,1] = grid_u[j,1] + WEIGHT
init_grid()
plt.figure()
for step in range(N_OF_DTs):
clear_fired_grid()
step1_grid()
check_fired_grid()
temp2 = np.nonzero(spike_data[0,0,step])
if not temp2[0].size == 0:
print(temp2)
print('iteration number == '+ str(step) + '\n')
plt.plot(temp2[0], temp2[1], 'ro')
plt.draw()
And here's the current output.
(array([3, 4]), array([17, 17]))
iteration number == 0
(array([12]), array([18]))
iteration number == 7
(array([15, 16]), array([7, 7]))
iteration number == 104
(array([18]), array([7]))
iteration number == 113
(array([ 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6,
6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
10]), array([17, 18, 19, 18, 19, 1, 18, 19, 0, 1, 2, 16, 17, 18, 19, 1, 2,
17, 18, 19, 1, 2, 17, 18, 19, 16, 17, 18, 19, 13, 14, 15, 16, 17,
16]))
iteration number == 122
I expected a 'video' sort of output, because of the iteration, but i got just one 'plot'
enter image description here
In order for the figure to be updated, you can introduce a small pause after plt.draw()
for step in range(N_OF_DTs):
clear_fired_grid()
step1_grid()
check_fired_grid()
temp2 = np.nonzero(spike_data[0,0,step])
if not temp2[0].size == 0:
print(temp2)
print('iteration number == '+ str(step) + '\n')
plt.plot(temp2[0], temp2[1], 'ro')
plt.draw()
plt.pause(0.1) # add a pause so that the events can be drawn on the figure
Which will update the figure on each iteration, producing the desired "video" effect

Python: How to efficiently count the number of "1"s in the binary representation of 1 to n numbers?

E.g. For the input 5, the output should be 7.
(bin(1) = 1, bin(2) = 10 ... bin(5) = 101) --> 1 + 1 + 2 + 1 + 2 = 7
Here's what I've tried, but it isn't a very efficient algorithm, considering that I iterate the loop once for each integer. My code (Python 3):
i = int(input())
a = 0
for b in range(i+1):
a = a + bin(b).count("1")
print(a)
Thank you!
Here's a solution based on the recurrence relation from OEIS:
def onecount(n):
if n == 0:
return 0
if n % 2 == 0:
m = n/2
return onecount(m) + onecount(m-1) + m
m = (n-1)/2
return 2*onecount(m)+m+1
>>> [onecount(i) for i in range(30)]
[0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33, 35, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71]
gmpy2, due to Alex Martella et al, seems to perform better, at least on my Win10 machine.
from time import time
import gmpy2
def onecount(n):
if n == 0:
return 0
if n % 2 == 0:
m = n/2
return onecount(m) + onecount(m-1) + m
m = (n-1)/2
return 2*onecount(m)+m+1
N = 10000
initial = time()
for _ in range(N):
for i in range(30):
onecount(i)
print (time()-initial)
initial = time()
for _ in range(N):
total = 0
for i in range(30):
total+=gmpy2.popcount(i)
print (time()-initial)
Here's the output:
1.7816979885101318
0.07404899597167969
If you want a list, and you're using >Py3.2:
>>> from itertools import accumulate
>>> result = list(accumulate([gmpy2.popcount(_) for _ in range(30)]))
>>> result
[0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33, 35, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71]

Pyschools Number Sequence

So i'm doing pyschools topic 6 question 23:
Write a function getNumbers(number) that takes in a number as argument and return a list of numbers as shown in the samples given below.
Examples
>>> getNumbers(10)
[100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100]
>>> getNumbers(9)
[81, 49, 25, 9, 1, 1, 9, 25, 49, 81]
>>> getNumbers(8)
[64, 36, 16, 4, 0, 4, 16, 36, 64]
>>> getNumbers(0)
[0]
This is my code:
def getNumbers(num):
x = []
y = []
if num % 2 == 0:
x = [i**2 for i in range(0, num+2, 2)]
y = [i**2 for i in range(0, num+2, 2)]
z = sorted(x, reverse=True) + y
if z.count(0) > 1:
z.remove(0)
return z
elif num % 3 == 0:
x = [i**2 for i in range(1, num+2, 2)]
y = [i**2 for i in range(1, num+2, 2)]
return sorted(x, reverse=True) + y
elif num == 1:
x.append(num)
y.append(num)
return sorted(x, reverse=True) + y
Which works but, i'm not passing Private Test Case. Any ideea why?
Private Test Case is something made by them to see if you hard code.
Test Cases Expected Result Returned Result
getNumbers(10) [100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100] [100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100]
getNumbers(9) [81, 49, 25, 9, 1, 1, 9, 25, 49, 81] [81, 49, 25, 9, 1, 1, 9, 25, 49, 81]
Private Test Cases Passed Failed
getNumbers(0) [0] [0]
getNumbers(1) [1, 1] [1, 1]
This was the easiest thing to do:
def getNumbers(num):
x = -num
y = list(range(x, num+1, 2))
return [i**2 for i in y]
getNumbers(10)
[100, 64, 36, 16, 4, 0, 4, 16, 36, 64, 100]
Also please find below a version
def getNumbers(num):
n=list(range(num+1))
num1=[]
x=num
for i in n:
x=num**2
num1.append(x)
num-=2
return num1
def getNumbers(num):
return [i * i for i in range(-num, num + 1, 2)]
Square of a number is always positive. You need to end the range on num + 1 to include number in the result. The range is iterable, so the list around range is spurious.

Categories