I'm attempting to use 2 rows of an array to add large numbers, using each column of the array as a digit, then going element-wise through each column to determine if a 1 needs to be carried over.
I'm trying to employ a list comprehension along with a map in order to not have to iterate. The issue I'm having is how to handle the syntax such that I can return both the current element and the next higher element (x[y] and x[y+1]):
targdigit = 1000
ind = 2
n = np.zeros((3,targdigit + 1))
def adder(intup):
global targdigit, ind
x = intup[0]
y = intup[1]
ind +=1
if y == targdigit - 1 and x[y] > 0:
print('targ index is ' + str(ind))
sys.exit()
if x[y] >= 10:
x[y] %= 10
x[y+1] += 1
return x
for i in range (2):
n[i][0] = 1
while True:
n[2] = n[0] + n[1]
n[2] = np.array([adder((n[2], xi)) for xi in range(n.shape[1])])
n[0], n[1] = n[1], n[2]
What is the appropriate syntax for the map and the return statement (and perhaps function arguments?) to apply both changes to x[y] and x[y+1]?
Related
Details:
There are two strings x and y.
Count the number of occurrence of y in x as follows:
Length of y is 3.
Increment the "count" value when y == x[i] x[i+2] x[i+4]
Example:
x = "aabbcc"
y = "abc"
output: 2
My Code:
def solution(x, y):
i, count = 0, 0
j = i + 2
k = i + 4
while i+4 < len(x):
cur = x[i]
while i < len(x) and i != j:
i += 1
while i < len(x) and i != k:
i += 1
count += 1
return count
solution(x, y)
I am getting count = 1. It should give count = 2
There's a couple of logic errors in your code.
The problem happens here:
while i < len(x) and i != j:
i += 1
res.append(x[i])
You keep increasing i until it is either len(x) or greater, or until it is the same as j. But since you set j to be 2 at the start (and never update it), it will simply end up setting i to len(x). And x[i] will thus fail, since x[len(x)] tries to index an element just outside x.
However, there's a few more remarks to make:
you collect what you find in res, but really only want a number (e.g. 2) as a result
you define count but don't use it
you track the coordinates in the string in three separate variables (i, j, k) and have a lot of logic to increment the first, but really all you need is to step through the string one position at a time, and look at the offsets directly
Given all that and the problem description, you were probably going for something like this:
x = "aabbcc"
y = "abc"
def solution(x, y):
i, count = 0, 0
while i + 4 < len(x):
if (x[i], x[i+2], x[i+4]) == (y[0], y[1], y[2]):
count += 1
i += 1
return count
print(solution(x, y))
However, Python has some cleverness that would make it even simpler (or at least shorter):
def solution(x, y):
count = 0
for i in range(len(x)-4):
if x[i:i+5:2] == y: # slicing with a stride of two, instead of direct indexing
count += 1
return count
Or even:
def solution(x, y):
return len([x for i in range(len(x)-4) if x[i:i+5:2] == y])
But that's favouring brevity over readability a bit too much, I feel.
A generator expression solution, taking advantage of True/False == 1/0 in a numeric context:
def solution(x, y):
return sum(y == x[i:i+5:2] for i in range(len(x)-4))
Increment the "count" value when y == x[i] x[i+2] x[i+4]
This is the same as simply creating the string consisting of x[0], x[2], x[4]... (every even-numbered character) and the string consisting of x[1], x[3], x[5]... (every odd-numbered character); counting the occurrences of y in each; and adding those two results together.
Creating the strings is trivial, and a common duplicate. Counting occurrences of a substring is also well-trodden ground. Putting these tools together:
def spread_substrings(needle, haystack):
even_haystack = haystack[::2]
odd_haystack = haystack[1::2]
return even_haystack.count(needle) + odd_haystack.count(needle)
Suppose we have an array: x = [10,0,30,40]. I would like to extract the first non zero element and store it in a different variable, say y. In this example, y = 10. We can also have many zeros, x = [0,0,30,40], which should give y = 30 as the extracted value.
I tried a Python snippet like this:
i = 0
while x[i] != 0:
y = arr[i]
if x[i] == 0:
break
This only works if the array is [10,0,30,40]. It does not work if I have 0,20,30,40. The loop would stop before that. What is an efficient way to implement this? I try not to use any special Numpy functions, just generic common loops because I might need to port it to other languages.
You can do this
x = [10,0,30,40]
for var in x:
if var != 0:
y = var
break
You could use list comprehension to get all the non-zero values, then provided there are some non-zero values extract the first one.
x = [10,0,30,40]
lst = [v for v in x if v != 0]
if lst:
y = lst[0]
print(y)
The problem with your code is that you don't increment i so it's stuck on the first element. So what you could do to keep the code portable is:
while x[i] != 0:
y = x[i]
if x[i] == 0:
break
i+=1
This code is still not clean, because if there is no 0 in your array then you will get an IndexError as soon as you reach the end.
I'm kind of new to this but i think this should work:
x = [0, 12, 24, 32, 0, 11]
y = []
for num in x:
if num != 0:
y.append(num)
break
print(y)
You can use the next function:
x = [10,0,30,40]
next(n for n in x if n) # 10
x = [0,0,30,40]
next(n for n in x if n) # 30
if you need to support the absence of zero in the list, you can use the second parameter of the next() function:
x = [0,0,0,0]
next((n for n in x if n),0) # 0
How to check whether a list and an element of a list with such an index exist in the list itself?
I have a list [[10,10,9], [10,10,10], [10,10,10]]
Then I enter the number of coordinates (k) and the coordinates themselves. At these coordinates, I have to subtract 8 from the cell and 4 with each cell standing next to it. But what if there are no cells nearby?
When checking if field [r + f] [c + s] in field: it always gives a negative answer. How to make a check?
for i in range(k):
for j in range(1):
f = drops[i][j]
s = drops[i][j + 1]
field[f][s] -= 8
for r in range(-1, 1):
for c in range(-1, 1):
if not (r == c == 1):
if field[r + f][c + s] in field:
field[r + f][c + s] -= 4
You just have to check whether the index isn't at the start or the end of the list.
n = 2
mylist = [4, 5, 8, 9, 12]
if len(mylist) > n+1:
mylist[n+1] -= 1
if n > 0:
mylist[n-1] -= 1
Slice assignment might help. You have to avoid letting an index go negative, but something like
s = slice(max(n-1,0), n+2)
x[s] = [v-1 for v in x[s]]
isn't too repetitive, while handling the edge cases n == 0 and n == len(s) - 1. (It won't work ifn` is explicitly set to a negative index, though.)
Im trying to solve the following Codewars problem: https://www.codewars.com/kata/sum-of-pairs/train/python
Here is my current implementation in Python:
def sum_pairs(ints, s):
right = float("inf")
n = len(ints)
m = {}
dup = {}
for i, x in enumerate(ints):
if x not in m.keys():
m[x] = i # Track first index of x using hash map.
elif x in m.keys() and x not in dup.keys():
dup[x] = i
for x in m.keys():
if s - x in m.keys():
if x == s-x and x in dup.keys():
j = m[x]
k = dup[x]
else:
j = m[x]
k = m[s-x]
comp = max(j,k)
if comp < right and j!= k:
right = comp
if right > n:
return None
return [s - ints[right],ints[right]]
The code seems to produce correct results, however the input can consist of array with up to 10 000 000 elements, so the execution times out for large inputs. I need help with optimizing/modifying the code so that it can handle sufficiently large arrays.
Your code inefficient for large list test cases so it gives timeout error. Instead you can do:
def sum_pairs(lst, s):
seen = set()
for item in lst:
if s - item in seen:
return [s - item, item]
seen.add(item)
We put the values in seen until we find a value that produces the specified sum with one of the seen values.
For more information go: Referance link
Maybe this code:
def sum_pairs(lst, s):
c = 0
while c<len(lst)-1:
if c != len(lst)-1:
x= lst[c]
spam = c+1
while spam < len(lst):
nxt= lst[spam]
if nxt + x== s:
return [x, nxt]
spam += 1
else:
return None
c +=1
lst = [5, 6, 5, 8]
s = 14
print(sum_pairs(lst, s))
Output:
[6, 8]
This answer unfortunately still times out, even though it's supposed to run in O(n^3) (since it is dominated by the sort, the rest of the algorithm running in O(n)). I'm not sure how you can obtain better than this complexity, but I thought I might put this idea out there.
def sum_pairs(ints, s):
ints_with_idx = enumerate(ints)
# Sort the array of ints
ints_with_idx = sorted(ints_with_idx, key = lambda (idx, num) : num)
diff = 1000000
l = 0
r = len(ints) - 1
# Indexes of the sum operands in sorted array
lSum = 0
rSum = 0
while l < r:
# Compute the absolute difference between the current sum and the desired sum
sum = ints_with_idx[l][1] + ints_with_idx[r][1]
absDiff = abs(sum - s)
if absDiff < diff:
# Update the best difference
lSum = l
rSum = r
diff = absDiff
elif sum > s:
# Decrease the large value
r -= 1
else:
# Test to see if the indexes are better (more to the left) for the same difference
if absDiff == diff:
rightmostIdx = max(ints_with_idx[l][0], ints_with_idx[r][0])
if rightmostIdx < max(ints_with_idx[lSum][0], ints_with_idx[rSum][0]):
lSum = l
rSum = r
# Increase the small value
l += 1
# Retrieve indexes of sum operands
aSumIdx = ints_with_idx[lSum][0]
bSumIdx = ints_with_idx[rSum][0]
# Retrieve values of operands for sum in correct order
aSum = ints[min(aSumIdx, bSumIdx)]
bSum = ints[max(aSumIdx, bSumIdx)]
if aSum + bSum == s:
return [aSum, bSum]
else:
return None
I am a beginner to programming. I always encounter this problem for matrices. Please help me to correct this code and understand the concept behind this. Thank you.
def new_matrix(matrix_size, center_num):
c = matrix_size / 2
if matrix_size % 2 != 0:
p = matrix_size
print("enter a valid size for matrix")
else:
matrix = [[0] * matrix_size for z in range(matrix_size)]
for counting in range(center_num, (matrix_size ** 2) + center_num):
for i in range(2, matrix_size+1):
row = int(c)
column = int(c)
if (i % 2 == 0):
for k in range(1, i + 1): # moving right
column += 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving up
row += 1
matrix[column][row] = counting
else:
for k in range(1, i + 1): # moving left
column -= 1
matrix[column][row] = counting
for k in range(1, i + 1): # moving down
row -= 1
matrix[column][row] = counting
print(matrix)
new_matrix(6, 2)
This issue here seems to be that your indexing is off. The end value in range(n) is n-1, which means that in your for loop when i = matrix_size and then you try to increment the column beyond this, you're trying to assign a value to an index in the matrix that doesn't exist.
You can either try and fix your loop, i.e. reduce it by one, or you can do something like the following,
try:
<your code goes here>
except IndexError:
pass
And then anytime the loop hits an index error it will skip that index and try the next. It's better to fix the code though!