I have a problem with making a spiral list.
The program should output a table of size n × n, filled with numbers from 1 to n * n in a spiral coming from the upper-left corner in a clockwise fashion, as shown in the example (here n = 5)
It works when n is even and doesn't work when n is odd
n = int(input())
arr = [[0 for i in range(n)] for j in range(n)]
stop = 0
start = 0
elem = 1
while elem <= n*n:
stop += 1
for j in range(start, n-stop):
i = start
arr[i][j] = elem
elem += 1
for i in range(start, n-stop):
j = n-stop
arr[i][j] = elem
elem += 1
for j in range(n-stop, start, -1):
i = n-stop
arr[i][j] = elem
elem += 1
for i in range(n-stop, start, -1):
j = start
arr[i][j] = elem
elem += 1
start += 1
for i in range(len(arr)):
for j in range(len(arr)):
print(arr[i][j], end=' ')
print()
Help please, where can be problem here?
You can use numpy:
import numpy as np
def spiral(n=5):
a = np.arange(n*n)
b = a.reshape((n,n))
m = None
for i in range(n, 0, -2):
m = np.r_[m, b[0, :], b[1:, -1], b[-1, :-1][::-1], b[1:-1, 0][::-1]]
b = b[1:-1, 1:-1]
a[list(m[1:])]=list(a)
return a.reshape((n,n)) + 1
spiral()
array([[ 1, 2, 3, 4, 5],
[16, 17, 18, 19, 6],
[15, 24, 25, 20, 7],
[14, 23, 22, 21, 8],
[13, 12, 11, 10, 9]])
spiral(10)
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 36, 37, 38, 39, 40, 41, 42, 43, 44, 11],
[ 35, 64, 65, 66, 67, 68, 69, 70, 45, 12],
[ 34, 63, 84, 85, 86, 87, 88, 71, 46, 13],
[ 33, 62, 83, 96, 97, 98, 89, 72, 47, 14],
[ 32, 61, 82, 95, 100, 99, 90, 73, 48, 15],
[ 31, 60, 81, 94, 93, 92, 91, 74, 49, 16],
[ 30, 59, 80, 79, 78, 77, 76, 75, 50, 17],
[ 29, 58, 57, 56, 55, 54, 53, 52, 51, 18],
[ 28, 27, 26, 25, 24, 23, 22, 21, 20, 19]])
A better way would be to import pdb and step through your program with a debugger. Instead, I just added some extra print statements:
n = 5
arr = [[0 for i in range(n)] for j in range(n)]
stop = 0
start = 0
elem = 1
count = 0
while elem <= n*n:
stop += 1
for j in range(start, n-stop):
i = start
arr[i][j] = elem
print('a')
elem += 1
for i in range(start, n-stop):
j = n-stop
arr[i][j] = elem
print('b')
elem += 1
for j in range(n-stop, start, -1):
i = n-stop
arr[i][j] = elem
print('c')
elem += 1
for i in range(n-stop, start, -1):
j = start
arr[i][j] = elem
print('d')
elem += 1
print('e')
count +=1
if count > 50:
break
start += 1
for i in range(len(arr)):
for j in range(len(arr)):
print(arr[i][j], end=' ')
print()
Here's the output I got:
a
a
a
a
b
b
b
b
c
c
c
c
d
d
d
d
e
a
a
b
b
c
c
d
d
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
e
1 2 3 4 5
16 17 18 19 6
15 24 0 20 7
14 23 22 21 8
13 12 11 10 9
It looks like something about odd values of n is allowing each for loop to complete, but elem doesn't get incremented enough so your while loop is running forever.
This looks like homework or a coding challenge, so I'm not going to go too deep into why, but I hope I've given you a hint.
Related
I found this question in my test today, I have been trying to find correct answer for this but failing to do so.
Question is:
Imagine we have range of page numbers lets say 0, 100. When we click on page lets say 15, we only what to show 10 pages on UI i.e. from page 10 to 20
more example input: 50 output: returns list
[46,47,48,49,50,51,52,53,54,55]
input: 15
output: returns list
[11,12,13,14,15,16,17,18,19,20]
also list should include first page and last page i.e. 0 and 50
so the actual output would be for first example
[0,46,47,48,49,50,51,52,53,54,55,100]
Below is what I have tried
def get_thread_page_num(num, max_page_num):
# Returns 10 numbers dynamically
new_lst =[1,50]
# default list
# defult_lst = [1,2,3,4,5,6,7,8,9,10]
num -4 > 0
num+5 <max_page_num
i = 10
m = 4
p = 5
while i != 0:
if num-1 >0 and m !=0:
new_lst.append(num-m)
i=i-1
m = m-1
elif num+1<max_page_num and p != 0:
new_lst.append(num+p)
i=i-1
p = p-1
print(sorted(new_lst))
get_thread_page_num(9, 50)
In your code m and p starts with value 4 and 5 respectively. In every iteration, either of them decreases by 1. So, after 9 iteration both of them are 0 and new_lst contains 9 elements. Also i becomes 10-9 = 1.
But i never becomes 0 and the loop becomes infinite.
You can try below code instead. Please refer to the comments.
def get_thread_page_num(num, max_page_num):
# low and high denotes the low and high end of the list
# where middle element is num
low = max(0, num - 4)
high = min(num + 5, max_page_num)
lst = []
if max_page_num < 9:
# 10 element list is not possible
return lst
# In case high is same as max, just make the list as
# high-9, high -8, ..., high
if high == max_page_num:
lst = list(range(max(0, high - 9), high + 1))
else:
# Just create a list starting from low like -
# low, low + 1, ..., low + 9
lst = list(range(low, low+10))
# Add 0 and max if not already present
if 0 not in lst:
lst.append(0)
if max_page_num not in lst:
lst.append(max_page_num)
# return sorted lst
return sorted(lst)
Call to get_thread_page_num():
print(get_thread_page_num(15, 50))
print(get_thread_page_num(0, 50))
print(get_thread_page_num(2, 50))
print(get_thread_page_num(50, 50))
print(get_thread_page_num(43, 50))
Output:
[0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 50]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 50]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 50]
[0, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
[0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50]
I want to append elements in a list using a for loop. This is the code:
outdoor_temp_list = []
indoor_temp_list = []
energy_cons_list = []
outdoor_temp_list.append(30+i)
indoor_temp_list.append(20+i)
energy_cons_list.append(200+i)
However, it is not appending in each iteration (30, 31, 32, 33, ...), but this the output:
[34] [24] [204]
I did not understand how it is working, I would appreciate any help!
Define list outside.other wise if you are running the code like
for i in range(5):
outdoor_temp_list = []
indoor_temp_list = []
energy_cons_list = []
outdoor_temp_list.append(30 + i)
indoor_temp_list.append(20 + i)
energy_cons_list.append(200 + i)
print(outdoor_temp_list,indoor_temp_list,energy_cons_list)
you will get output only for the last iteration. because during each iteration you are initializing it by []
[34] [24] [204]
so you have to initialize it before the for loop
outdoor_temp_list = []
indoor_temp_list = []
energy_cons_list = []
for i in range(5):
outdoor_temp_list.append(30 + i)
indoor_temp_list.append(20 + i)
energy_cons_list.append(200 + i)
print(outdoor_temp_list,indoor_temp_list,energy_cons_list)
then you will get the desire output like
[30, 31, 32, 33, 34] [20, 21, 22, 23, 24] [200, 201, 202, 203, 204]
def quicksort(array):
print(array)
n = 0
pivot = len(array) - 1
while n < pivot:
if array[pivot] > array[n]:
n+=1
elif array[pivot] <= array[n]:
array[n],array[pivot-1] = array[pivot-1], array[n]
array[pivot],array[pivot-1] = array[pivot-1], array[pivot]
pivot -= 1
if len(array[:pivot]) >1:
array[:pivot] = quicksort(array[:pivot])
if len(array[pivot+1:])> 1:
array[pivot+1:] = quicksort(array[pivot+1:])
return array
test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print(quicksort(test))
raises the following error:
Error: Traceback (most recent call last):
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 18, in <module>
print(quicksort(test))
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 14, in quicksort
array[pivot:] = quicksort(array[pivot:])
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 14, in quicksort
array[pivot:] = quicksort(array[pivot:])
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 12, in quicksort
array[:pivot] = quicksort(array[:pivot])
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 14, in quicksort
array[pivot:] = quicksort(array[pivot:])
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 14, in quicksort
array[pivot:] = quicksort(array[pivot:])
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 14, in quicksort
array[pivot:] = quicksort(array[pivot:])
[Previous line repeated 987 more times]
File "C:\Users\admin\AppData\Local\Programs\Python\Python37-32\idle.py", line 3, in quicksort
pivot = len(array) - 1
RecursionError: maximum recursion depth exceeded while calling a Python object
def quicksort(array):
print(array)
n = 0
pivot = len(array) - 1
while n < pivot:
if array[pivot] > array[n]:
n+=1
elif array[pivot] <= array[n]:
array[n],array[pivot-1] = array[pivot-1], array[n]
array[pivot],array[pivot-1] = array[pivot-1], array[pivot]
pivot -= 1
if len(array[:pivot]) >1:
array[:pivot] = quicksort(array[:pivot])
if len(array[pivot+1:])> 1:
array[pivot+1:] = quicksort(array[pivot+1:])
return array
test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print(quicksort(test))
It was just excluding pivot from the subarrays. So array[pivot:] becomes array[pivot+1: ]
def quicksort(array):
print(array)
n = 0
pivot = len(array) - 1
while n < pivot:
if array[pivot] > array[n]:
n+=1
elif array[pivot] <= array[n]:
array[n],array[pivot-1] = array[pivot-1], array[n]
array[pivot],array[pivot-1] = array[pivot-1], array[pivot]
pivot -= 1
if len(array[:pivot]) >1:
array[:pivot] = quicksort(array[:pivot])
if len(array[pivot:])> 1:
array[pivot:] = quicksort(array[pivot:])
return array
test = [19, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print(quicksort(test))
M Oehm is correct! I tried this modified code and it works on array with distinct elements. The output is:
[19, 4, 1, 3, 9, 20, 25, 6, 21, 14]
[6, 4, 1, 3, 9]
[6, 4, 1, 3]
[3, 4, 6]
[3, 4]
[14, 25, 20, 21, 19]
[19, 20, 21, 25]
[19, 20, 21]
[19, 20]
[1, 3, 4, 6, 9, 14, 19, 20, 21, 25]
If you need a quick sort that works on array with repeated elements, you will have to partition it into 3 (instead of 2) subarrays {{Xi}, {Xk}, {Xj}}, where {Xi} is smaller than pivot, {xk}=pivot and {Xj} > pivot.
I'm trying to merge 5 lists into one 2d matrix in Python. The lists are named a0 ... a4 (all of the same length)
while ( i <= len(a0) ):
while ( k < 5):
matrix[i][k] = #here I want to assign a0[i], a1[i],..., a5[i]
k+=1
i+=1
Is there a way to make this work or do I have to go with something like:
while ( i <= len(a0) ):
matrix[i][0] = a0[i]
matrix[i][1] = a1[i]
....
If a0 through a4 are already lists... you just need to put all of them into ONE BIG list.
Let me know if this works for you:
a0 = [str(x) for x in range(10)]
a1 = [str(x) for x in range(10, 20)]
a2 = [str(x) for x in range(20, 30)]
a3 = [str(x) for x in range(30, 40)]
a4 = [str(x) for x in range(40, 50)]
print("a0: {}".format(", ".join(a0)))
print("a1: {}".format(", ".join(a1)))
print("a2: {}".format(", ".join(a2)))
print("a3: {}".format(", ".join(a3)))
print("a4: {}".format(", ".join(a4)))
matrix = [
a0,
a1,
a2,
a3,
a4
]
# Below is another way:
# matrix = []
# matrix.append(a0)
# matrix.append(a1)
# matrix.append(a2)
# matrix.append(a3)
# matrix.append(a4)
print("matrix[3][4]: {}".format(matrix[3][4]))
Output:
a0: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
a1: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
a2: 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
a3: 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
a4: 40, 41, 42, 43, 44, 45, 46, 47, 48, 49
matrix[3][4]: 34
I have a function I wrote in python that simple makes a horizontal list of int. I modified the print statement so that the list would print with commas, but the function adds one after the last int.
Any ideas as how to get rid of it?
num = list(range(20))
def count(x):
for i in range(len(x)):
# i+1 add in order to remove beginning zero.
print(i+1,end=',')
count(num)
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
Try this:
num = list(range(20))
l = []
def count(x):
for i in range(len(x)):
l.append(i+1)
count(num)
print(l)
Outpout:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20]
You can also modify it to this:
def count(x):
for i in range(len(x)):
# i+1 add in order to remove beginning zero.
if i < len(x)-1:
print(i+1, end=',')
else:
print(i+1)
Output:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
Try this:
num = list(range(20))
def count(x):
for i in range(len(x)-1):
print(i+1,end=',')
print(len(x))
count(num)
Add each number to a string and then print the string minus the last character:
num = list(range(20))
def count(x):
s = ""
for i in range(len(x)):
# i+1 add in order to remove beginning zero.
s += str(i+1) + ","
print(s[:-1])
count(num)
Output:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
A better function name would be display, and the function you want is str.join():
def display(list_data):
print(', '.join(list_data))
The thing to keep in mind is the pieces to join must be strings, so you may need to convert:
', '.join([str(i) for i in list_data])
Rather than creating a function, an output sequence can be processed with the range command:
num = range(1,21,1)
print num
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Print without the braces:
num = range(1,21,1)
print str(num).strip('[]')
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
User chooses start and ending numbers somewhere earlier in the code:
start = 56
end = 69
num = range(start, end + 1)
print str(num).strip('[]')
Output is:
56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
User supplies start and stop interactivly:
start = raw_input('Choose start')
end = raw_input('Choose end')
num = range(start, end + 1)
print str(num).strip('[]')