I am trying to find the sum of two lists/arrays in Python.
For example:
You are given with two random integer lists as lst1 and lst2 with size n and m respectively. Both the lists contain numbers from 0 to 9(i.e. single digit integer is present at every index).
The idea here is to represent each list as an integer in itself of digits N and M.
You need to find the sum of both the input list treating them as two integers and put the result in another list i.e. output list will also contain only single digit at every index.
Following is the code which I have tried:
def list_sum(lst1, n, lst2, m) :
i, j, sum, carry = 0, 0, 0, 0
new_lst = []
if n == 0 and m == 0:
new_lst.append(0)
elif n > 0 and m>0:
while n > 0 and m > 0:
sum = lst1[n - 1] + lst2[m - 1] + carry
if sum >= 10:
carry = 1
else:
carry = 0
new_lst.append(sum % 10)
n -= 1
m -= 1
while n > 0:
if (lst1[n-1] + carry) >= 10:
new_lst.append((lst1[n-1] + carry) % 10)
carry = 1
else:
new_lst.append(lst1[n-1])
carry = 0
n -= 1
while m > 0:
if (lst2[m-1] + carry) >= 10:
new_lst.append((lst2[m-1] + carry) % 10)
carry = 1
else:
new_lst.append(lst1[m-1])
carry = 0
m -= 1
if carry == 1:
new_lst.append(1)
new_lst.reverse()
elif n == 0 and m > 0:
new_lst.append(0)
new_lst = new_lst + lst2
elif n > 0 and m == 0:
new_lst.append(0)
new_lst = new_lst + lst1
print(new_lst)
however I feel I am missing something here and which is not giving me proper answer for the combination. Sometimes it errors list out of index error. I don't know why.
The example input:
n = 3
lst1 = [6, 9, 8]
m = 3
lst2 = [5, 9, 2]
output:
[1, 2, 9, 0]
Here, each element is summed and then if the sum >=10 then we get a carry = 1 and which will be added with the next sum.
i.e
1. 8+2= 10 >=10 hence carry=1 in first sum
2. 9+9+1( carry) = 19 >=10 hence carry=1
3. 6+5+1( carry) = 12>=10 hence carry=1
4. upend the carry to next position as 1
Hence resultant list would be [1, 2, 9, 0]
What can I try next?
Well, all other answers are awesome for adding 2 numbers (list of digits).
But in case you want to create a program which can deal with any number of 'numbers',
Here's what you can do...
def addNums(lst1, lst2, *args):
numsIters = [iter(num[::-1]) for num in [lst1, lst2] + list(args)] # make the iterators for each list
carry, final = 0, [] # Initially carry is 0, 'final' will store the result
while True:
nums = [next(num, None) for num in numsIters] # for every num in numIters, get the next element if exists, else None
if all(nxt is None for nxt in nums): break # If all numIters returned None, it means all numbers have exhausted, hence break from the loop
nums = [(0 if num is None else num) for num in nums] # Convert all 'None' to '0'
digit = sum(nums) + carry # Sum up all digits and carry
final.append(digit % 10) # Insert the 'ones' digit of result into final list
carry = digit // 10 # get the 'tens' digit and update it to carry
if carry: final.append(carry) # If carry is non-zero, insert it
return final[::-1] # return the fully generated final list
print(addNums([6, 9, 8], [5, 9, 2])) # [1, 2, 9, 0]
print(addNums([7, 6, 9, 8, 8], [5, 9, 2], [3, 5, 1, 7, 4])) # [1, 1, 2, 7, 5, 4]
Hope that makes sense!
If I understand correctly you want it like this:
[6, 9, 8], [5, 9, 2] -> 698 + 592 = 1290 -> [1, 2, 9, 0]
In that case my first idea would be to turn the numbers into strings, combine them to one string
and turn it into an int, then add both values together and turn into a list of integers again...
you can try this:
def get_sum_as_list(list1, list2):
first_int = int(''.join(map(str,list1)))
second_int = int(''.join(map(str,list2)))
result = [int(num) for num in str(first_int+second_int)]
return result
Here's one possible solution:
(i) join each list to create a pair of string representation of integers
(ii) convert them to integers,
(iii) add them,
(iv) convert the sum to string
(v) separate each digit as ints
def list_sum(lst1, lst2):
out = []
for i, lst in enumerate([lst1, lst2]):
if len(lst) > 0:
out.append(int(''.join(str(x) for x in lst)))
else:
if i == 0:
return lst2
else:
return lst1
return [int(x) for x in str(out[0]+out[1])]
list_sum([6,9,8],[5,9,2])
Output:
[1, 2, 9, 0]
Two other answers show solutions repeatedly converting between lists of int and strings and ints. I think this is a bit cheating and completely hides the algorithm.
Here I present a solution that manipulates the lists of ints directly to build a third list of ints.
from itertools import chain, repeat # pad list with 0 so they are equal size
from operator import add # add(x,y) = x+y
def padded(l1, l2):
"padded([1, 2, 3], [1, 2, 3, 4, 5]) --> [0, 0, 1, 2, 3], [1, 2, 3, 4, 5]"
padded1 = chain( repeat(0, max(0, len(l2)-len(l1))), l1 )
padded2 = chain( repeat(0, max(0, len(l1)-len(l2))), l2 )
return padded1, padded2
def add_without_carry_same_size(l1, l2):
"add_without_carry([6, 9, 8], [5, 9, 2]) --> [11, 18, 10]"
return map(add, l1, l2)
def flatten_carry(l):
"flatten_carry([11, 18, 10]) --> [1, 2, 9, 0]"
c = 0
for i in range(len(l)-1, -1, -1):
c, l[i] = divmod(c + l[i], 10)
if c > 0:
l[:] = [c] + l
def list_add(l1, l2):
'''
list_add([6, 9, 8], [5, 9, 2]) --> [1, 2, 9, 0]
list_add([9, 9, 9, 9, 9], [1]) --> [1, 0, 0, 0, 0, 0]
'''
p1, p2 = padded(l1, l2)
l3 = list(add_without_carry_same_size(p1, p2))
flatten_carry(l3)
return l3
Relevant documentation:
builtin function map;
itertools.chain;
itertools.repeat;
operator.add;
builtin function divmod.
Tried the following logic
def list_sum(lst1, n, lst2, m, output):
i, j, k, carry = n - 1, m - 1, max(n, m), 0
while i >= 0 and j >= 0:
output[k] = (lst1[i] + lst2[j] + carry) % 10
carry = (lst1[i] + lst2[j] + carry) // 10
i = i - 1
j = j - 1
k = k - 1
while i >= 0:
output[k] = (lst1[i] + carry) % 10
carry = (lst1[i] + carry) // 10
i = i - 1
k = k - 1
while j >= 0:
output[k] = (lst2[j] + carry) % 10
carry = (lst2[j] + carry) // 10
j = j - 1
k = k - 1
output[0] = carry
print(output)
where the output parameter in the above code it taken from below
outputSize = (1 + max(n, m))
output = outputSize * [0]
and called the function
list_sum(lst1, n, lst2, m, output)
You don't mention how long your lists will be. So considering they aren't going to be that long (anyway, python can handle bignums), why not making a simple sum operation? In the end that's what the code should emulate.
import numpy as np
lst1 = [6, 9, 8]
lst2 = [5, 9, 2]
lst1_len = len(lst1)
lst2_len = len(lst2)
if lst1_len >= lst2_len:
lst2 = [0] * (lst1_len - lst2_len) + lst2
else:
lst1 = [0] * (lst2_len - lst1_len) + lst1
common_len = len(lst1)
lst1_val = sum(np.array(lst1) * np.array([10**(-x) for x in range(-common_len + 1, 1)]))
lst2_val = sum(np.array(lst2) * np.array([10**(-x) for x in range(-common_len + 1, 1)]))
total = lst1_val + lst2_val
total_as_list = [int(x) for x in str(total)]
where
print(total_as_list)
[1, 2, 9, 0]
Code:
def addNums(*args):
nums=[]
for i in args:
if i:
i = list(map(str,i)) # Converts each element int to string['6', '9', '8'] , ['5', '9', '2']
add=int(''.join(i)) # Joins string and convert to int 698 ,592
nums.append(add) # Appends them to list [698, 592]
Sum = str(sum(nums)) # Sums the values and convert to string '1290'
result=list(map(int,Sum)) # Converts to list with each converted to int[1,2,9,0]
return result
print(addNums([6, 9, 8], [5, 9, 2]))
print(addNums([7, 6], [5, 9], [3, 5],[7, 4]))
print(addNums([]))
Output:
[1, 2, 9, 0]
[2, 4, 4]
[0]
Related
What i'm trying to do is write a code in python which will print a simple Sudoku (solved for now).
I started with a 4 on 4, but planing on 9 on 9 after that.
I managed to make the numbers to not repeat other numbers horizontal and vertical, the problem is how to make them not repeat other numbers within their "box".
Example:
4 3 2 1
3 2 1 4
1 4 3 2
2 1 4 3
Expected:
4 3 2 1
2 1 4 3
1 4 3 2
3 2 1 4
Code:
import random
# preforming 1st check if the giving number already exist in the list sq
# which is created in main
def chk1(num):
while num in sq:
num = random.randint(1,4)
return num
# preforming 2nd check if the giving number already exist in the current index
# of each list that is in sud which is created in main
def chk2(num, i, y):
x = 0
curr = 0
while x != i:
if num != sud[curr][y]:
x +=1
curr +=1
else:
num = random.randint(1,4)
x = 0
curr = 0
return num
# creating the structure of 4 lists in the list sud using the 1st & 2nd check
# each round a unique list is created and is appended to anther list.
def main():
global sq, sud
curry = 0
currx = 0
sq = []
sud = []
for i in range(4):
for y in range(4):
num = random.randint(1,4)
num = chk1(num)
if curry == 1 & currx == 1:
num = chk2(num, i, y)
sq.append(num)
if curry == 0:
curry +=1
sud.append(sq)
if currx == 0:
currx +=1
sq = []
return sud
# printing the final output of main function by line
for line in main():
print(line)
Thanks in advance
Your code may get stuck if it generates a partial set of incompatible numbers. Try this one - it uses recursion and steps back if fails to place another digit:
import numpy as np
def build_sudoku(sudoku=None, i=None):
if sudoku is None:
sudoku = np.zeros((9, 9), dtype=int)
i = 80
if i < 0:
return sudoku
s = sudoku.copy()
r, c = i // 9, i % 9
row, col = s[r, :], s[:, c]
square = g[r//3 * 3:r//3 * 3+3, c//3 * 3:c//3 * 3+3].flatten()
valid = [v for v in np.arange(1, 10) if v not in set([*row, *col, *square])]
np.random.shuffle(valid)
for v in valid:
s[r, c] = v
result = fill_one(s, i-1)
if result is not None:
return result
return None
build_sudoku()
array([[3, 1, 5, 8, 4, 2, 9, 7, 6],
[2, 8, 7, 5, 9, 6, 3, 4, 1],
[9, 4, 6, 1, 7, 3, 2, 8, 5],
[5, 6, 4, 7, 2, 8, 1, 9, 3],
[7, 9, 1, 3, 5, 4, 8, 6, 2],
[8, 2, 3, 6, 1, 9, 4, 5, 7],
[6, 3, 2, 9, 8, 7, 5, 1, 4],
[1, 7, 8, 4, 3, 5, 6, 2, 9],
[4, 5, 9, 2, 6, 1, 7, 3, 8]])
The problem you've presented is much nearer to the Magic Square problem then the actual sudoku (sum of rows, sum of columns + sum in small squares). Therefore, I am providing you example of magic square implementation example from GeeksforGeeks:
def generateSquare(n):
# 2-D array with all
# slots set to 0
magicSquare = [[0 for x in range(n)]
for y in range(n)]
# initialize position of 1
i = n / 2
j = n - 1
# Fill the magic square
# by placing values
num = 1
while num <= (n * n):
if i == -1 and j == n: # 3rd condition
j = n - 2
i = 0
else:
# next number goes out of
# right side of square
if j == n:
j = 0
# next number goes
# out of upper side
if i < 0:
i = n - 1
if magicSquare[int(i)][int(j)]: # 2nd condition
j = j - 2
i = i + 1
continue
else:
magicSquare[int(i)][int(j)] = num
num = num + 1
j = j + 1
i = i - 1 # 1st condition
# Printing magic square
print ("Magic Squre for n =", n)
print ("Sum of each row or column",
n * (n * n + 1) / 2, "\n")
for i in range(0, n):
for j in range(0, n):
print('%2d ' % (magicSquare[i][j]),
end = '')
# To display output
# in matrix form
if j == n - 1:
print()
n = 7
generateSquare(n)
I am given a 1D array of numbers.
I need to go through the array adding each consecutive element to form a sum. Once this sum reaches a certain value, it forms the first element of a new array. The sum is then reset and the process repeats, thus iterating over the whole array.
For example if given:
[1, 3, 4, 5, 2, 5, 3]
and requiring the minimum sum to be 5,
the new array would be:
[8, 5, 7]
Explicity: [1 + 3 + 4, 5, 2 + 5]
I then also need to keep a record of the way the elements were combined for that particular array: I need to be to take a different array of the same length and combine the elements in the same way as above.
e.g. give the array
[1, 2, 1, 1, 3, 2, 1]
I require the output
[4, 1, 5]
Explicity: [1 + 2 + 1, 1, 3 + 2]
I have accomplished this with i loops and increment counters, but it is very ugly. The array named "record" contains the number of old elements summed to make each element of the new array i.e. [3, 1, 2]
import numpy as np
def bin(array, min_sum):
num_points = len(array)
# Create empty output.
output = list()
record = list()
i = 0
while i < num_points:
sum = 0
j = 0
while sum < min_sum:
# Break out if it reaches end of data whilst in loop.
if i+j == num_points:
break
sum += array[i+j]
j += 1
output.append(sum)
record.append(j)
i += j
# The final data point does not reach the min sum.
del output[-1]
return output
if __name__ == "__main__":
array = [1, 3, 4, 5, 2, 5, 3]
print bin(array, 5)
I would advice you to simply walk through the list. Add it to an accumulator like the_sum (do not use sum, since it is a builtin), and in case the_sum reaches a number higher than the min_sum, you add it, and reset the_sum to zero. Like:
def bin(array, min_sum):
result = []
the_sum = 0
for elem in array:
the_sum += elem
if the_sum >= min_sum:
result.append(the_sum)
the_sum = 0
return result
The lines where the accumulator is involved, are put in boldface.
I leave combining the other array the same way as an exercise, but as a hint: use an additional accumulator and zip to iterate over both arrays concurrently.
Here is a straightforward solution. which computes a list of boolean values where the value is true when accumulated element equals or exceeds the target value and calc computes an accumulation using this list.
def which(l, s):
w, a = [], 0
for e in l:
a += e
c = (a >= s)
w.append(c)
if c:
a = 0
return w
def calc(l, w):
a = 0
for (e, c) in zip(l, w):
a += e
if c:
yield a
a = 0
here is an interactive demonstration
>>> l1 = [1, 3, 4, 5, 2, 5, 3]
>>> w = which(l1, 5)
>>> w
[False, False, True, True, False, True, False]
>>> list(calc(l1, w))
[8, 5, 7]
>>> l2 = [1, 2, 1, 1, 3, 2, 1]
>>> list(calc(l2, w))
[4, 1, 5]
You can use short solutions I found out after a long struggle with flattening arrays.
For getting bounded sums use:
f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])<x]
This outputs:
>>> f = lambda a,x,j,l: 0 if j>=l else [a[i] for i in range(j,l) if sum(a[j:i])< x]
>>> a= [1, 3, 4, 5, 2, 5, 3]
>>> f(a,5,0,7)
[1, 3, 4]
>>> sum(f(a,5,0,7))
8
>>> sum(f(a,5,3,7))
5
>>> sum(f(a,5,4,7))
7
>>>
To get your records use the function:
>>> y = lambda a,x,f,j,l: [] if j>=l else list(np.append(j,np.array(y(a,x,f,j+len(f(a,x,j,l)),l))))
From here, you can get both array of records and sums:
>>> listt=y(a,5,f,0,len(a))
>>> listt
[0.0, 3.0, 4.0, 6.0]
>>> [sum(f(a,5,int(listt[u]),len(a))) for u in range(0,len(listt)-1)]
[8, 5, 7]
>>>
Now, the bit of magic you can even use it as an index-conditional boundary for the second vector:
>>> b=[1, 2, 1, 1, 3, 2, 1]
>>> [sum(f(b,5,int(listt[u]),int(listt[u+1]))) for u in range(0,len(listt)-1)]
[4, 1, 5]
>>>
I have a number lets make it a list s = [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
and I have k = 4
What I want is to replace 4-values of list s with number 9 which dont have number 9.
means at position 2 ,we have 9,so skip that and replace next one.
Output should be like: [9,9,9,9,9,2,7,3,6,8,4,1,9,0,0,3,6,8]
With this code I am unable to skip 9's in it:
x= [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
k = 4
def elements_replaced(lst, new_element, indices):
return [new_element if i in indices else e for i, e in enumerate(lst)]
output = elements_replaced(x,9,range(k))
print output
you can try:
>>> s = [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
>>> k = 4
>>> for index,number in enumerate(s):
if k > 0:
if number != 9:
s[index] = 9
k = k-1
else :
break
>>> s
[9, 9, 9, 9, 9, 2, 7, 3, 6, 8, 4, 1, 9, 0, 0, 3, 6, 8]
You can also use list comprehensions. This will get inefficient if your input list is large relative to the number of nines.
from itertools import chain, repeat
s = [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
nines = chain([9] * 4, repeat(None))
result = [x if x == 9 else next(nines) or x for x in s]
print(result)
# [9, 9, 9, 9, 9, 2, 7, 3, 6, 8, 4, 1, 9, 0, 0, 3, 6, 8]
x = [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
k = 4
a = 0
while k and a < len(x):
if x[a] != 9:
x[a] = 9
k -= 1
a += 1
x= [1,6,9,2,3,2,7,3,6,8,4,1,9,0,0,3,6,8]
k = 4
def elements_replaced(lst, new_element, indices):
for index, value in enumerate(lst):
if index in indices and value != new_element:
lst[index] = new_element
return lst
output = elements_replaced(x,9,range(k+1))
print (output)
How do I generate the partitions of a number that have exactly k parts, where each part has a minimum and maximum value?
For example, If I want to select all partitions of 21 with 6 parts with minimum part value 3 and the maximum part value is 6, I should get the following partitions:
[3, 3, 3, 3, 3, 6]
[3, 3, 3, 3, 4, 5]
[3, 3, 3, 4, 4, 4]
I have the following ascending partition code, courtesy of http://jeromekelleher.net/generating-integer-partitions.html
def accel_asc(n):
a = [0 for i in range(n + 1)]
k = 1
y = n - 1
while k != 0:
x = a[k - 1] + 1
k -= 1
while 2 * x <= y:
a[k] = x
y -= x
k += 1
l = k + 1
while x <= y:
a[k] = x
a[l] = y
yield a[:k + 2]
x += 1
y -= 1
a[k] = x + y
y = x + y - 1
yield a[:k + 1]
and a simple fuction I wrote to only get the partitions I want from the function above:
def eligible_partitions(list_of_partitions, min_value, max_value, k):
l = []
for x in list_of_partitions:
if min(x) >= min_value and max(x) <= max_value and len(x) == k:
l.append(x)
return l
Instead of having to generate and loop through all of the partitions of a particular value, I only want to generate those that meet the specified criteria.
Here is one way to do it:
def part(x, n, minval, maxval):
if not n * minval <= x <= n * maxval:
return
elif n == 0:
yield []
else:
for val in range(minval, maxval + 1):
for p in part(x - val, n - 1, val, maxval):
yield [val] + p
for p in part(21, 6, 3, 6):
print p
This produces:
[3, 3, 3, 3, 3, 6]
[3, 3, 3, 3, 4, 5]
[3, 3, 3, 4, 4, 4]
I want to make a script. The program should get some list L with values, and natural number N.
If N>0, the list's objects move N steps to left.
If N<0, the list's objects move abs(N) to the right.
If N=0 the list remain the same...
For example: For N=1 and L=[1,2,3,4,5], the output is [2,3,4,5,1].
For same list and N=-1 the output is [5,1,2,3,4]
I actually did it using collection.deque, but I want to do this with nothing but lists, for loop and 'if'.
I have problem to understand how to make the objects move.
l = input("enter list:")
N = input("enter number of rotations:")
import collections
d = collections.deque(l)
d.rotate(-N)
print d
You can use list slicing:
def rotate(L, N):
if not L or N % len(L) == 0:
return L
return L[N % len(L):] + L[:N % len(L)]
L = [1, 2, 3, 4, 5]
for N in range(-3, 4):
print(rotate(L, N))
Output:
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
[5, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
Note that if you use a list, the time complexity of a rotation is linear to the number of elements in the list in general, since you have to move all existing elements. deque.rotate(), on the other hand, is O(k), with k being the number of steps. Therefore, if you need to rotate more than once deque.rotate() is the way to go.
This works:
result = l[N % len(l):]+l[:N % len(l)]
If using numpy is an option for you, there is a method called roll, which you might want to have a look at:
import numpy as np
array = np.arange(1, 6) # 1 to 5
print array
print np.roll(array, 0)
print np.roll(array, 2)
print np.roll(array, -2)
print np.roll(array, 17)
The result is as expected:
[1 2 3 4 5]
[1 2 3 4 5]
[4 5 1 2 3]
[3 4 5 1 2]
[4 5 1 2 3]
If you're after simple lists here's how you can do it in Python 3 (based on your P2 example).
L = list(map(int, input("Enter numbers: ").split(" ")))
N = int(input("Enter how many rotations to perform: "))
print(L[N:] + L[:N])
If you don't want to create new list, you can try in-place reverse,
def reverse(nums, start, end):
i = start
j = end - 1
while i < j:
tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
i += 1
j -= 1
def rotate(nums, n):
if n == 0:
return nums
length = len(nums)
if n < 0:
n = length + n
reverse(nums, 0, n)
reverse(nums, n, length)
reverse(nums, 0, length)
return nums
>>> rotate([1, 2, 3, 4, 5], 1)
[2, 3, 4, 5, 1]
>>> rotate([1, 2, 3, 4, 5], -1)
[5, 1, 2, 3, 4]
thank you all ! :)
your answers are great and very useful for me.
here is my solution for this question (given that I do these scripts for a basic python course for biologists):
L = input('Enter list of numbers, please: ')
N = input('Enter how many places to rotate: ')
L1 = L[N:]
L2 = L[:N]
L = L1 + L2
print L