Where is the error in this python code? - python-3.x

First few examples:
Input:
10
1
4 5 6
Output:
6
another one:
Input:
10
2
3 3 3
7 7 4
Output:
4
I put this code it is correct for some cases but not for all where is the problem?
n = int(input())
q = int(input())
z = 0
repeat = 0
ans = 0
answ = []
arrx = []
arry = []
for i in range(q):
maxi = 0
x,y,w = [int(i) for i in input().split()]
x,y = x+1, y+1
if((arrx.count(x)>=1)):
index = arrx.index(x)
if(y==arry[index]):
if(answ[index]==ans):
repeat += answ[index]
z = answ[index]
arrx.append(x)
arry.append(y)
if((w>x or w>y) or (w>(n-x) or w>(n-y))):
maxi = max(x, y, (n-x), (n-y))
if(((x>=w) or (y>=w)) or (((n-x)>=w) or ((n-y)>=w))):
maxi = w
ans = max(ans, maxi)
answ.append(ans)
if(ans>z):
repeat = 0
print(ans+repeat)

The problem I see with your code is you are handling the data as two one dimensional arrays, arrx and arry, when the problem calls for a two dimensional array. You should be able to print out your data structure and see the heat map for the volcanoes. For the first example, you've got a single hot volcano in the middle of the map:
10
1
4 5 6
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[2, 2, 2, 2, 2, 2, 2, 2, 2, 1]
[2, 3, 3, 3, 3, 3, 3, 3, 2, 1]
[2, 3, 4, 4, 4, 4, 4, 3, 2, 1]
[2, 3, 4, 5, 5, 5, 4, 3, 2, 1]
[2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
[2, 3, 4, 5, 5, 5, 4, 3, 2, 1]
[2, 3, 4, 4, 4, 4, 4, 3, 2, 1]
[2, 3, 3, 3, 3, 3, 3, 3, 2, 1]
[2, 2, 2, 2, 2, 2, 2, 2, 2, 1]
Where the hottest (6) spot is obviously the one volcano itself. For the second example, you've got two cooler volcanos:
10
2
3 3 3
3 3 3
7 7 4
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 1, 1, 1, 1, 0, 0, 0, 0]
[0, 1, 2, 2, 2, 1, 0, 0, 0, 0]
[0, 1, 2, 3, 2, 1, 0, 0, 0, 0]
[0, 1, 2, 2, 3, 2, 1, 1, 1, 1]
[0, 1, 1, 1, 2, 3, 2, 2, 2, 2]
[0, 0, 0, 0, 1, 2, 3, 3, 3, 2]
[0, 0, 0, 0, 1, 2, 3, 4, 3, 2]
[0, 0, 0, 0, 1, 2, 3, 3, 3, 2]
[0, 0, 0, 0, 1, 2, 2, 2, 2, 2]
Where the hot spot will either be the hotter of the two volcanos or potentially some spot that falls in their overlap that gets heated by both. In this case, the overlap spots don't get hotter than the hotest (4) volcano. But if the volcanoes were closer, one or more might have.

Related

partitioning blocks of elements from the indices of a numpy 2D array

I have the indices of a 2D array. I want to partition the indices such that the corresponding entries form blocks (block size is given as input m and n).
For example, if the indices are as given below
(array([0, 0, 0, 0, 1, 1, 1, 1, 6, 6, 6, 6, 7, 7, 7, 7 ]), array([0, 1, 7, 8, 0,1,7,8, 0,1,7,8, 0, 1, 7, 8]))
for the original matrix (from which the indices are generated)
array([[3, 4, 2, 0, 1, 1, 0, 2, 4],
[1, 3, 2, 0, 0, 1, 0, 4, 0],
[1, 0, 0, 1, 1, 0, 1, 1, 3],
[0, 0, 0, 3, 3, 0, 4, 0, 4],
[4, 3, 4, 2, 1, 1, 0, 0, 4],
[0, 1, 0, 4, 4, 2, 2, 2, 1],
[2, 4, 0, 1, 1, 0, 0, 2, 1],
[0, 4, 1, 3, 3, 2, 3, 2, 4]])
and if the block size is (2,2), then the blocks should be
[[3, 4],
[1, 3]]
[[2, 4]
[4, 0]]
[[2, 4]
[0, 4]]
[[2, 1]
[2, 4]]
Any help to do it efficiently?
Does this help? A is your matrix.
row_size = 2
col_size = 3
for i in range(A.shape[0] // row_size):
for j in range(A.shape[1] // col_size):
print(A[row_size*i:row_size*i + row_size, col_size*j:col_size*j + col_size])

How to reshape an array with numpy like this:

I have this:
array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
And I would like to reshape my array like this:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])
How do I do it using python numpy?
You can just split and concatenate:
a = np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
cols = a.shape[1] // 2
np.concatenate((a[:,:cols], a[:,cols:]))
#[[0 0 1 1]
# [0 0 1 1]
# [2 2 3 3]
# [2 2 3 3]]
You can simply swap rows after reshaping it.
a= np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]]).reshape(4,4)
a[[1,2]] = a[[2,1]]
Output:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])

Finding the number of occurrences of various groups in a list

`So,I am given a list-
group = [2,1,3,4]
Each index of this list represents a group.
So group 0 = 2
group 1 = 1
group 2 = 3
group 3 = 4
I am given another list called :
l =[[[0, 0, 3, 3, 3, 3], [0, 0, 1, 3, 3, 3, 3]], [[0, 1]], [[2, 2, 2, 3, 3, 3, 3], [2, 2, 2, 3, 3, 3, 3], [2, 2, 2, 3, 3, 3, 3]], [[0, 0, 2, 2, 2, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3, 3]]]
the output I want is:
dict = {0:[0,3],1;[1],2:[2,3],3:[0,2]}
If the number of times the element appears in each sublist of l ie if both l[0][0] and l[0][1] have 0's appear 2 times, it is added to the index 0 of the dict. Since both l[0][0] and l[0][1] have 3 appear 4 times(this is because group[3] is 4), it is added to the index 0.
now in l[1][0] and 0 appears just once(instead of twice) so its not added to index 1. However 1 just appears once so it is added to index 1.Thanks!
What I have tried so far:
def tryin(l,groups):
for i in range(len(l)):
count = 0
for j in range(len(l[i])):
if j in (l[i][j]):
count+=1
if count == groups[i]:
print(i,j)
try this code :
input:
group = [2,1,3,4]
l =[[[0, 0, 3, 3, 3, 3], [0, 0, 1, 3, 3, 3, 3]], [[0, 1]], [[2, 2, 2, 3, 3, 3, 3], [2, 2, 2, 3, 3, 3, 3], [2, 2, 2, 3, 3, 3, 3]], [[0, 0, 2, 2, 2, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3, 3], [0, 0, 2, 2, 2, 3, 3, 3, 3]]]
def IntersecOfSets(list_):
result = set(list_[0])
for s in list_[1:]:
result.intersection_update(s)
return result
def nb_occ(l,group):
d = {}
for i in l:
l2=[]
for j in i:
l1 = []
for x in group:
if j.count(group.index(x)) >= x :
y=group.index(x)
l1.append(y)
l2.append(l1)
if len(l2)>1:
d[str(l.index(i))]= IntersecOfSets(l2)
else:
d[str(l.index(i))]= l2[0]
return d
print(nb_occ(l,group))
output:
{'2': {2, 3}, '1': [1], '0': {0, 3}, '3': {0, 2}}

Python: finding all pallindromic sequences of length k that sum to n

I'm trying to find all palindromic sequences of length k that sum to n. I have a specific example (k=6):
def brute(n):
J=[]
for a in range(1,n):
for b in range(1,n):
for c in range(1,n):
if (a+b+c)*2==n:
J.append((a,b,c,c,b,a))
return(J)
The output gives me something like:
[(1, 1, 6, 6, 1, 1),
(1, 2, 5, 5, 2, 1),
(1, 3, 4, 4, 3, 1),
(1, 4, 3, 3, 4, 1),
(1, 5, 2, 2, 5, 1),
(1, 6, 1, 1, 6, 1),
(2, 1, 5, 5, 1, 2),
(2, 2, 4, 4, 2, 2),
(2, 3, 3, 3, 3, 2),
(2, 4, 2, 2, 4, 2),
(2, 5, 1, 1, 5, 2),
(3, 1, 4, 4, 1, 3),
(3, 2, 3, 3, 2, 3),
(3, 3, 2, 2, 3, 3),
(3, 4, 1, 1, 4, 3),
(4, 1, 3, 3, 1, 4),
(4, 2, 2, 2, 2, 4),
(4, 3, 1, 1, 3, 4),
(5, 1, 2, 2, 1, 5),
(5, 2, 1, 1, 2, 5),
(6, 1, 1, 1, 1, 6)]
The issue is that I have no idea how to generalize this to any values of n and k. I hear that dictionaries would be helpful. Did I mention I was new to python? any help would be appreciated
thanks
The idea is that we simply count from 0 to 10**k, and consider each of these "integers" as a palindrome sequence. We left pad with 0 where necessary. So, for k==6, 0 -> [0, 0, 0, 0, 0, 0], 1 -> [0, 0, 0, 0, 0, 1], etc. This enumerates over all possible combinations. If it's a palindrome, we also check that it adds up to n.
Below is some code that (should) give a correct result for arbitrary n and k, but is not terribly efficient. I'll leave optimizing up to you (if it's necessary), and give some tips on how to do it.
Here's the code:
def find_all_palindromic_sequences(n, k):
result = []
for i in range(10**k):
paly = gen_palindrome(i, k, n)
if paly is not None:
result.append(paly)
return result
def gen_palindrome(i, k, n):
i_padded = str(i).zfill(k)
i_digits = [int(digit) for digit in i_padded]
if i_digits == i_digits[::-1] and sum(i_digits) == n:
return i_digits
to test it, we can do:
for paly in find_all_palindromic_sequences(n=16, k=6):
print(paly)
this outputs:
[0, 0, 8, 8, 0, 0]
[0, 1, 7, 7, 1, 0]
[0, 2, 6, 6, 2, 0]
[0, 3, 5, 5, 3, 0]
[0, 4, 4, 4, 4, 0]
[0, 5, 3, 3, 5, 0]
[0, 6, 2, 2, 6, 0]
[0, 7, 1, 1, 7, 0]
[0, 8, 0, 0, 8, 0]
[1, 0, 7, 7, 0, 1]
[1, 1, 6, 6, 1, 1]
[1, 2, 5, 5, 2, 1]
[1, 3, 4, 4, 3, 1]
[1, 4, 3, 3, 4, 1]
[1, 5, 2, 2, 5, 1]
[1, 6, 1, 1, 6, 1]
[1, 7, 0, 0, 7, 1]
[2, 0, 6, 6, 0, 2]
[2, 1, 5, 5, 1, 2]
[2, 2, 4, 4, 2, 2]
[2, 3, 3, 3, 3, 2]
[2, 4, 2, 2, 4, 2]
[2, 5, 1, 1, 5, 2]
[2, 6, 0, 0, 6, 2]
[3, 0, 5, 5, 0, 3]
[3, 1, 4, 4, 1, 3]
[3, 2, 3, 3, 2, 3]
[3, 3, 2, 2, 3, 3]
[3, 4, 1, 1, 4, 3]
[3, 5, 0, 0, 5, 3]
[4, 0, 4, 4, 0, 4]
[4, 1, 3, 3, 1, 4]
[4, 2, 2, 2, 2, 4]
[4, 3, 1, 1, 3, 4]
[4, 4, 0, 0, 4, 4]
[5, 0, 3, 3, 0, 5]
[5, 1, 2, 2, 1, 5]
[5, 2, 1, 1, 2, 5]
[5, 3, 0, 0, 3, 5]
[6, 0, 2, 2, 0, 6]
[6, 1, 1, 1, 1, 6]
[6, 2, 0, 0, 2, 6]
[7, 0, 1, 1, 0, 7]
[7, 1, 0, 0, 1, 7]
[8, 0, 0, 0, 0, 8]
Which looks similar to your result, plus the results that contain 0.
Ideas for making it faster (this will slow down a lot as k becomes large):
This is an embarrassingly parallel problem, consider multithreading/multiprocessing.
The palindrome check of i_digits == i_digits[::-1] isn't as efficient as it could be (both in terms of memory and CPU). Having a pointer at the start and end, and traversing characters one by one till the pointers cross would be better.
There are some conditional optimizations you can do on certain values of n. For instance, if n is 0, it doesn't matter how large k is, the only palindrome will be [0, 0, 0, ..., 0, 0]. As another example, if n is 8, we obviously don't have to generate any permutations with 9 in them. Or, if n is 20, and k is 6, then we can't have 3 9's in our permutation. Generalizing this pattern will pay off big assuming n is reasonably small. It works the other way, too, actually. If n is large, then there is a limit to the number of 0s and 1s that can be in each permutation.
There is probably a better way of generating palindromes than testing every single integer. For example, if we know that integer X is a palindrome sequence, then X+1 will not be. It's pretty easy to show this: the first and last digits can't match for X+1 since we know they must have matched for X. You might be able to show that X+2 and X+3 cannot be palindromes either, etc. If you can generalize where you must test for a new palindrome, this will be key. A number theorist could help more in this regard.
HTH.

Removing duplicates with no sets, no for loops, maintain order and update the original list

Ok, so I have to remove duplicates from a list and maintain order at the same time. However, there are certain conditions such as I'm not allowed to use set or for loops. Also when the function mustn't return a new list but update the original list. I have the following code, but it only works partially and yes I know I'm only checking once, but I'm not sure how to proceed further.
def clean_list(values):
i = len(values)-1
while i > 0:
if values[i] == values[i-1]:
values.pop(i)
i -= 1
return values
values = [1, 2, 0, 1, 4, 1, 1, 2, 2, 5, 4, 3, 1, 3, 3, 4, 2, 4, 3, 1, 3, 0, 3, 0, 0]
new_values = clean_list(values)
print(new_values)
Gives me the result:
[1, 2, 0, 1, 4, 1, 2, 5, 4, 3, 1, 3, 4, 2, 4, 3, 1, 3, 0, 3, 0]
Thanks
Try the following.
Using two while loops, the first will get your unique item, the second will then search through the rest of the list for any other matching items and remove them, maintaining order.
def clean_list(lst):
i = 0
while i < len(lst):
item = lst[i] # item to check
j = i + 1 # start next item along
while j < len(lst):
if item == lst[j]:
lst.pop(j)
else:
j += 1
i += 1
values = [1, 2, 0, 1, 4, 1, 1, 2, 2, 5, 4, 3, 1, 3, 3, 4, 2, 4, 3, 1, 3, 0, 3, 0, 0]
clean_list(values)
print(values)
# Output
[1, 2, 0, 4, 5, 3]
Update: Improved function to be faster as worst case the first one was O(n2)
def clean_list(lst):
seen = set()
i = 0
while i < len(lst):
item = lst[i]
if item in seen:
lst.pop(i)
else:
seen.add(item)
i += 1
values = [1, 2, 0, 1, 4, 1, 1, 2, 2, 5, 4, 3, 1, 3, 3, 4, 2, 4, 3, 1, 3, 0, 3, 0, 0]
clean_list(values)
print(values)
# Output
[1, 2, 0, 4, 5, 3]

Resources