How to add 2 singly-linked lists together? - python

I am trying to write a Python function that adds two linked lists together. Each node contains one digit of a potentially large integer, with the least-significant digit coming first
Ex Function: add_linked_list_integers(a, b) - where a and b are singly-linked list whose nodes each contain one digit of a positive integer.
Ex Problem: 617 + 295 = 912 would be represented in linked-lists as (7->1->6) + (5->9->2) = (2->1->9).
I am provided with a basic ListNode class, and sample functions to print and create a linked-list of integers.
class ListNode:
'''Simple node for singly-linked list with _value and _next fields'''
def __init__(self, value, next=None):
'''Create a new node, with _value field and optional _next node pointer'''
self._value = value
self._next = next
def print_helper(l):
'''Prints the value of the integer represented by the linked-list l, without trailing carriage return'''
if l:
if (l._value < 0) or (l._value > 9):
raise Exception('digit out of range')
print_helper(l._next)
print(l._value, end="")
def print_linked_list_integer(l):
'''Prints the value of the integer represented by the linked-list l, with trailing carriage return'''
print_helper(l)
print()
def create_linked_list_integer(i):
'''Returns the linked-list representation of the integer i, least-significant digit first'''
result = ListNode(i % 10)
if i >= 10:
result._next = create_linked_list_integer(i // 10)
return result
def add_linked_list_integers(a, b):
'''Return the sum of two integers represented as linked lists
Currently my function looks like this:
def add_linked_list_integers(a, b):
'''Return the sum of two integers represented as linked lists'''
answer = ListNode()
if a == None:
return b
elif b == None:
return a
carry = 0
result = (a.data + b.data + carry)
if result > 9:
result = result - 10
carry = 1
answer.push(result)
return answer

def add_linked_list_integers(a, b):
'''Return the sum of two integers represented as linked lists'''
pre_head = ListNode(-1)
carry = 0
head = pre_head
while a is not None and b is not None:
digit = (a._value + b._value + carry) % 10
carry = (a._value + b._value + carry) // 10
head._next = ListNode(digit)
head = head._next
a = a._next
b = b._next
while a is not None:
digit = (a._value + carry) % 10
carry = (a._value + carry) // 10
head._next = ListNode(digit)
head = head._next
a = a._next
while b is not None:
digit = (b._value + carry) % 10
carry = (b._value + carry) // 10
head._next = ListNode(digit)
head = head._next
b = b._next
if carry != 0:
head._next = ListNode(carry)
return pre_head._next
This is what I would do

Just perform the equivalent of base-10 addition. This means looping over the digits!
from itertools import zip_longest
def add_linked_list_integers(xs, ys):
carry = 0
result = []
for x, y in zip_longest(xs, ys, fillvalue=0):
s = x + y + carry
carry = s // 10
result.append(s % 10)
if carry > 0:
result.append(carry)
return result
Example runs:
>>> add_linked_list_integers([7, 1, 6], [5, 9, 2])
[2, 1, 9]
>>> to_list = lambda y: [int(x) for x in reversed(str(y))]
>>> to_int = lambda xs: int(''.join(str(x) for x in xs)[::-1])
>>> a, b = 3192097619, 999999998472534892
>>> a + b
1000000001664632511
>>> to_int(add_linked_list_integers(to_list(a), to_list(b)))
1000000001664632511

Related

Algorithm not passing tests even when I get correct results on my end

The question is mostly about base conversion. Here's the question.
Start with a random minion ID n, which is a nonnegative integer of length k in base b
Define x and y as integers of length k. x has the digits of n in descending order, and y has the digits of n in ascending order
Define z = x - y. Add leading zeros to z to maintain length k if necessary
Assign n = z to get the next minion ID, and go back to step 2
For example, given minion ID n = 1211, k = 4, b = 10, then x = 2111, y = 1112 and z = 2111 - 1112 = 0999. Then the next minion ID will be n = 0999 and the algorithm iterates again: x = 9990, y = 0999 and z = 9990 - 0999 = 8991, and so on.
Depending on the values of n, k (derived from n), and b, at some point the algorithm reaches a cycle, such as by reaching a constant value. For example, starting with n = 210022, k = 6, b = 3, the algorithm will reach the cycle of values [210111, 122221, 102212] and it will stay in this cycle no matter how many times it continues iterating. Starting with n = 1211, the routine will reach the integer 6174, and since 7641 - 1467 is 6174, it will stay as that value no matter how many times it iterates.
Given a minion ID as a string n representing a nonnegative integer of length k in base b, where 2 <= k <= 9 and 2 <= b <= 10, write a function solution(n, b) which returns the length of the ending cycle of the algorithm above starting with n. For instance, in the example above, solution(210022, 3) would return 3, since iterating on 102212 would return to 210111 when done in base 3. If the algorithm reaches a constant, such as 0, then the length is 1.
Here's my code
def solution(n, b): #n(num): str, b(base): int
#Your code here
num = n
k = len(n)
resList = []
resIdx = 0
loopFlag = True
while loopFlag:
numX = "".join(x for x in sorted(num, reverse=True))
numY = "".join(y for y in sorted(num))
xBaseTen, yBaseTen = getBaseTen(numX, b), getBaseTen(numY, b)
xMinusY = xBaseTen - yBaseTen
num = getBaseB(xMinusY, b, k)
resListLen = len(resList)
for i in range(resListLen - 1, -1, -1):
if resList[i] == num:
loopFlag = False
resIdx = resListLen - i
break
if loopFlag:
resList.append(num)
if num == 0:
resIdx = 1
break
return resIdx
def getBaseTen(n, b): #n(number): str, b(base): int -> int
nBaseTenRes = 0
n = str(int(n)) # Shave prepending zeroes
length = len(n) - 1
for i in range(length + 1):
nBaseTenRes += int(n[i]) * pow(b, length - i)
return nBaseTenRes
def getBaseB(n, b, k): #(number): int, b(base): int, k:(len): int -> str
res = ""
r = 0 # Remainder
nCopy = n
while nCopy > 0:
r = nCopy % b
nCopy = floor(nCopy / b)
res += str(r)
res = res[::-1]
resPrependZeroesLen = k - len(res)
if resPrependZeroesLen > 0:
for i in range(resPrependZeroesLen):
res = "0" + res
return res
The two test that are available to me and are not passing, are ('1211', 10) and ('210022', 3). But I get the right answers for them (1, 3).
Why am I failing? Is the algo wrong? Hitting the time limit?
The problem arose between the differences of the execution environments.
When I executed on my machine on Python 3.7 this
r = nCopy % n
gave me an answer as an int.
While Foobar runs on 2.7, and the answer above is given as a float

Recursion gives me completely wrong answers

I want to find the number of ways, a given integer X can be decomposed into sums of numbers which are N-th powers and every summand must be unique. For example if X = 10 and N=3, I can decompose this number like that:
10 = 2^3+1^3+1^3 ,but this is not a valid decomposition, because the number 1 appears twice. A valid decomposition for X = 10 and N = 2 would be 10 = 3^2+1^2, since no summand is repeating here.
Now I tried it to use recursion and created the following Python Code
st = set(range(1,int(pow(X,1/float(N))))) # generate set of unique numbers
print(str(ps(X, N, st)))
def ps(x, n, s):
res = 0
for c in s:
chk = x-pow(c,n) # test validity
if chk > 0:
ns = s-set([c])
res += ps(chk,n,ns)
elif chk == 0:
res += 1 # one result is found
else:
res += 0 # no valid result
return res
I used a set called st and then I recursively called the function ps that includes the base case "decomposition found" and "decomposition not found". Moreover it reduces a larger number to a smaller one by considering only the ways how to decompose a given number into only two summands.
Unfortunately, I get completely wrong results, e.g.
X = 100, N = 3: Outputs 0, Expected 1
X = 100, N = 2: Outputs 122, Expected 3
X = 10, N = 2: Outputs 0, Expected 1
My thoughts are correct, but I think the Problem is anywhere in the recursion. Does anybody see what I make wrong? Any help would be greatly appreciated.
Hint:
>>> X = 100
>>> N = 3
>>> int(pow(X, 1/float(N)))
4
>>> list(range(1, 4))
[1, 2, 3]
The output is indeed correct for the input you are feeding it.
The problem is line res += 1 # one result is found in conjuction with res += ps(chk,n,ns) will make the algorithm add twice.
E.g X = 10, N = 2: Outputs 0, Expected 1 because:
c=1:
10 - 1^2 > 0 -> res += ps(chk,n,ns)
c=3:
9 - 3^2 == 0 -> res += 1 # one result is found ... return res
So, in c=3 res=1 is returned to the c=1 call, which will
res += ps(chk,n,ns), and ps(chk,n,ns) = 1, making res = 2 and doubling the result expected.
E.g. X = 29, N = 2.
29 = 2^2 + 3^2 + 4^2
Solving from bottom to top (the algorithm flow):
c=4 -> res += 1... return res
c=3 -> res += ps() -> res += 1 -> res = 2 ... return res
c=2 -> res += ps() -> res += 2 -> res = 4 ... return res
But res is supposed to be 1.
Solution: You cannot add res to res. And you must remove the previous iterated objects to avoid path repetition. Check the solution below (with prints for better understanding):
def ps(x, n, s):
print(s)
print("")
return ps_aux(x, n, s, 0) # level
def ps_aux(x, n, s, level):
sum = 0
for idx, c in enumerate(s):
print("----> " * level + "C = {}".format(c))
chk = x - pow(c,n) # test validity
if chk > 0:
ns = s[idx + 1:]
sum += ps_aux(chk,n,ns, level + 1)
elif chk == 0:
print("OK!")
sum += 1 # one result is found
else:
sum += 0 # no valid result
return sum
Try with:
X=10 # 1 solution
N=2
st = list(range(1,int(pow(X,1/float(N))) + 1 )) # generate set of unique numbers
print(str(ps(X, N, st)))
X=25 # 2 solutions [3,4], [5]
N=2
st = list(range(1,int(pow(X,1/float(N))) + 1 )) # generate set of unique numbers
print(str(ps(X, N, st)))

Accessing a variable value from a python function inside another function

I have one function that calls for the function rlEncode which is supposed to take the data list and compress it so it counts how many values in a row there are and would output for example [1, 5, 3, 2, 5, 6] and so on. But when I run it just out puts the [1,5] again and again and not moving the n value over however so many spaces in the list. How would I get the n value from the function rlEncode to be used in the other function?
def rlEncode(n, z, data_list):
while data_list[n] == data_list[n+1]:
z = z + 1
n = n + 1
while data_list[n] != data_list[n+1]:
return n
return z
def unitTest( ):
c = 0
n = 0
z = 1
data_list = [1,1,1,1,1,3,3,5,5,5,5,5,5,6,8,8,1,1,1,5,5,5,5,13,14, 14]
compress_list = [ ]
while c < (len(data_list)):
n = rlEncode(n, 1, data_list)
z = rlEncode(0, z, data_list)
rlEncode(0, 1, data_list)
compress = [data_list[n], z]
c = c + 1
compress_list = compress_list + compress
print(compress_list)
n = n+1
Python passes immutable objects by value. See this previous answer: How do I pass a variable by reference?
The simplest solution in your case is to have the inner function return the value of n to the outer function, which assigns it to its local n.
compress is a list, which is mutable, so you can use += to mutate the list in place rather than creating a new local variable.
I also added a check against the list length, otherwise the references to n+1 will cause IndexError.
I also don't think you need the second while loop in rlEncode but I'll leave that up to you to sort out... :)
def rlEncode(n, z, data_list, compress):
while (n < len(data_list)-1) and (data_list[n] == data_list[n+1]):
z = z + 1
n = n + 1
while (n < len(data_list)-1) and (data_list[n] != data_list[n+1]):
compress += [data_list[n], z]
n = n + 1
return n
def unitTest(data_list):
c = 0
n = 0
compress = []
while c < (len(data_list)):
n = rlEncode(n, 1, data_list, compress)
c = c + 1
return ('list: ', data_list, "compressed list: ", compress)
sample_data = [1,1,1,1,1,3,3,5,5,5,5,5,5,6,8,8,1,1,1,5,5,5,5,13, 14, 14]
unitTest(sample_data)
I like doing these things recursively. Python isn't great with recursion but I wanted to see how it's done so I guess I'll share:
def compress(lst):
if not lst:
return []
current = lst[0]
result = compress(lst[1:])
if not result:
# item is last
return [(1, current)]
nxt = result[0][1]
if current == nxt:
# items is same as next
return [(result[0][0] + 1, current)] + result[1:]
# different items
return [(1, current)] + result
To use it:
print [x[0] for x in compress(lst)]
The obvious and efficient way would be a generator:
def group_gen(lst):
buff = []
for item in lst:
if buff and item == buff[0]:
buff.append(item)
else:
if buff:
yield buff
buff = [item]
if buff:
yield buff
print list(map(len, group_gen(lst)))
Check it using:
print list(map(len, group_gen(lst)))

Factoring, Substituting and printing roots of a polynomial

We've been asked to make a program that takes in polynomial coefficients(i.e. [1, 2, 1] representing x^2 + 2x + 1 and use the rational root theorem to find and print the roots in a list of fractional strings. We were only allowed to use import math. The problem with my code is it only works if I input [1, 2, 1] and when I input other polynomials, it prints a blank list.
import math
roots = []
pr = []
pf = []
qf = []
count = 1
t = 0
co = raw_input('Input Coefficients: ')
co = co.split(' ')
p = co[0]
q = co[-1]
def gcd(a,b): #function for computing gcf between two numbers. will be used to simplify fractions into lowest terms
r = a%b
if r == 0:
return b
else:
return gcd(b,r)
def rmvvalues(coefficients, val): #remove the zeroes from the list because zero is not factorable
for i in range(coefficients.count(val)):
coefficients.remove(val)
while int(p) == 0: #if the constant was 0, it means 0 is automatically a root
roots.append(0)
rmvvalues(co, str('0'))
p = co[0]
q = co[-1]
while count <= math.fabs(int(p)): #factors of the constant
if int(p) % count == 0:
pf.append(count)
pf.append(count*(-1))
count = count + 1
else:
count = count + 1
count = 1
while count <= math.fabs(int(q)): #factors of the last term
if int(q) % count == 0:
qf.append(count)
qf.append(count*(-1))
count = count + 1
else:
count = count + 1
count = 1
for i in range(len(pf)): #every element in the first list of factors is to be divided by every element of the other list of factors
for j in range(len(qf)):
result = 0
for c in range(len(co)): #and each pf/qf is to be checked if it would make the polynomial zero
result = int(result) * (int(pf[i])/int(qf[j])) + int(co[c])
if result == 0: #if it makes it zero, it appends the answer in fraction string to the list of roots
if (int(pf[i]) / int(qf[j])) == 1: #add 1 to the list of roots if p/q == 1 and would make the equation zero
roots.append(1)
elif int(pf[i])/int(qf[j]) == -1: #add -1 to the list of roots if p/q == -1 and would make the equation zero
roots.append(-1)
else: #if they would be fractions
a = int(pf[i]) / int(gcd(int(pf[i]),int(qf[j])))
b = int(qf[j]) / int(gcd(int(pf[i]),int(qf[j])))
roots.append(str(a) + '/' +str(b))
roots = sorted(set(roots))
print roots
p.s.(I just copy/pasted the code from my editor so the indentation may be a little off)
I have an implementation to propose, but not a debugging of yours.
The fact is that you are writing a big one bloc code that I don't understand.
As I want to help you I give you an example of implementation that I hope you will find helpful AND readable. My big suggest when coding is to split the code in little function easy to understand with meaningful name, and then add an algorithm function that call all the sub-functions. This make the algorithm to looks like pseudocode and be mode understandable.
Additionally, more specifically related to python, your code is supposed to follow some rule. Runtime code is supposed to be placed after if __name__ == "__main__": bloc.
Hope it helps you (take a look at the findSolution method):
class Polynom():
""" A class representing a polynom that provides methods to find roots of the polynom. """
#-----------------------------------------------------------------------------------------
def __init__(self, coefficients):
"""
Constructor of the class.
Takes a coeficient list [n, n-1, ..., n1, n0] that are the coefficients of a polynom.
Example :
Polynom([1,2,3]) stand for : x² + 2x + 3
"""
self.coefficients = coefficients
#-----------------------------------------------------------------------------------------
def _dividers(self, coefficient):
"""Returns the list of the divider of a number by filtering the values in [1, 2, ... , |coefficient| ] that divide coefficient. """
def filter_dividers(coefficient, candidate_values):
# lambda function explanations : http://www.diveintopython.net/power_of_introspection/lambda_functions.html
return filter(lambda number : coefficient%number == 0, candidate_values)
return list(filter_dividers(coefficient, range(1, abs(coefficient)+1)))
#-----------------------------------------------------------------------------------------
def _gcd(self, x, y):
""" Returns the greatest common diviser of the integers x and y """
if y == 0:
return abs(x)
else:
r = x%y
return self._gcd(y, r)
#-----------------------------------------------------------------------------------------
def _positiveAndNegativeCombinations(self, p_values, q_values):
"""
Returns the list of positives and negatives combination of (p,q) pairs.
Example :
[1,2]
-> [(1,4), (-1,4), (2,4), (-2,4), (1,5), (-1,5), (2,5), (-2,5)]
[4,5]
"""
def combinations(p, q_values):
if len(q_values) == 1:
return [(p, q_values[0])]
else:
return [(p, q_values[0])] + combinations(p, q_values[1:])
result = []
for p in p_values:
p_combinations = combinations(p, q_values)
for combination in p_combinations:
result += [combination, (-1*combination[0], combination[1])]
return result
#-----------------------------------------------------------------------------------------
def __repr__(self):
""" Representation of the object in a string for printing purpose."""
def from_number_to_string_exposant(number):
"""
Returns a string that is the number given as exposant.
Example : 1 -> "¹"
"""
utf8_exposant = {"0":"⁰", "1":"¹", "2":"²", "3": "³", "4":"⁴", "5":"⁵", "6":"⁶", "7":"⁷", "8":"⁸", "9":"⁹"}
string = str(number)
result = ""
for digit in string:
result += utf8_exposant[digit]
return result
result = ""
degree = 0
coefficients = self.coefficients
while coefficients != [] :
coef, coefficients = coefficients[-1], coefficients[0:-1]
result = "+ " +str(coef)+"x"+ from_number_to_string_exposant(degree) + result
degree+=1
return "<Polynom :" + result[1:] + " = 0 >"
#-----------------------------------------------------------------------------------------
def valueFor(self, value):
""" Returns ture or false depending on the fact that the given value is or not a polunom's solution. """
total_value = 0
degree = 0
coefficients = self.coefficients
while coefficients != [] :
coef, coefficients = coefficients[-1], coefficients[0:-1]
total_value += coef*(value**degree)
degree += 1
return total_value
#-----------------------------------------------------------------------------------------
def isSolution(self, value):
""" Returns true or false depending if the given value is a polynom solution or not """
return (self.valueFor(value) == 0)
#-----------------------------------------------------------------------------------------
def findSolution(self):
"""
Return a pair (p,q) that verify that p/q is a solution of this polynom. If no valid pair is find, return None.
Call to this function come with log printing.
"""
print("Search solution for ", self)
a0 = self.coefficients[-1]
aN = self.coefficients[0]
if a0 == 0 or aN == 0:
return None #algorithm is not applicable in this case.
else:
p_values = self._dividers(a0)
q_values = self._dividers(aN)
print("finded dividers of p :", p_values)
print("finded dividers of q :", q_values)
candidate_solutions = self._positiveAndNegativeCombinations(p_values,q_values)
print("(p,q) pairs to evaluate are : \n\t",candidate_solutions)
for candidate in candidate_solutions :
candidate_value = 1.0 * candidate[0] / candidate[1]
print("pair : ",candidate, " | value : ", candidate_value)
if self.isSolution(candidate_value):
print()
return candidate
else:
print("The pair ", candidate, "is invalid, replacing x by it leads to say that 0=", self.valueFor(candidate_value))
return None
#-----------------------------------------------------------------------------------------
if __name__ == "__main__":
poly = Polynom([2,1,-6])
print(poly.findSolution())
Execute it with python3 (or change the print calls).
Arthur.
https://code.activestate.com/recipes/577974-polynomial-factoring-using-rational-root-theorem/
Here's a working link.
from math import ceil
listOfFactors = lambda n: {i for i in range(1,ceil(abs(n)/2)+1) if n%i == 0}
def removeDuplicates(mylist):
if mylist:
mylist.sort()
last = mylist[-1]
for i in range(len(mylist)-2, -1, -1):
if last == mylist[i]:
del mylist[i]
else:
last = mylist[i]
return mylist
def polyRoots(polyListCoeff):
allFactors = set()
allFactorsListOld = list(allFactors.union(listOfFactors(polyListCoeff[0]),{polyListCoeff[0]},listOfFactors(polyListCoeff[-1]),{polyListCoeff[-1]}))
allFactorsListOld.extend([-1*i for i in allFactorsListOld])
allFactorsList = list()
for k in allFactorsListOld:
for j in allFactorsListOld:
allFactorsList.append(k/j)
allFactorsList = removeDuplicates(allFactorsList)
polyListCoeff.reverse()
roots = [i for i in allFactorsList if sum([pow(i,j)*polyListCoeff[j] for j in range(0,len(polyListCoeff))]) == 0]
factorList = list()
for i in roots:
if i<0:
factorList.append("(x+{})".format(-i))
else:
factorList.append("(x-{})".format(i))
return "".join(factorList)
if __name__ == "__main__":
polyRoots([1,0,-4])
# '(x+2.0)(x-2.0)'

Difference of decimal numbers with another base

I am using Python. I have several pairs of numbers and I want to find their difference, but their base is on 42. For example,
5.39->5.40->5.41->5.42->6.00
So, 10.38 with 10.24 has 0.14, but 10.41 with 11.02 has 0.03
Is there any way to do this with Python? The only way I can imagine is to take several IF for every case.
Example of my data:
[3.08,3.15] --> 0.07
[4.39,5.10] --> 0.13
[13.00,14.12] --> 1.12
[40.42,41.01] --> 0.02
Like this? Subtracts A from B using 0.42 as cap for decimal part.
base = 42
a = (5,10)
b = (4,39)
if a > b:
b, a = a, b
overflow = int(b[1] < a[1])
c = (b[0]-a[0]-overflow, b[1]+base*overflow-a[1])
print(c)
Question is not very clear. Also I used tuples to avoid parsing.
Edit: added the if guard
This might be overkill, but...
digits = '0123456789abcdefghijklmnopqrstuvwxyzABCDEF'
assert len(digits) == 42
def base(n, b=2, digits=digits):
if n < 0:
raise ValueError("no negative numbers")
if n < b:
return digits[n]
res = []
q = n
while q:
q, r = divmod(q, b)
res.append(digits[r])
return ''.join(reversed(res))
def debase(s, base=2, digits=digits):
if not (2 <= base <= len(digits)):
raise ValueError("base must be >= 2 and <= %d" % len(digits))
res = 0
for i, v in enumerate(reversed(s)):
digit = digits.index(v)
res += digit * (base ** i)
return res
class Val(object):
def __init__(self, a, b):
self.a = a
self.b = base(b, 42)
def __sub__(self, other):
a = self.a - other.a
b = debase(self.b, 42) - debase(other.b, 42)
if b < 0:
b += 42
a -= 1
return Val(a, b)
def __repr__(self):
return "Val({a}, {b})".format(a=self.a, b=debase(self.b, 42))
def __str__(self):
return "%d.%02d" % (self.a, debase(self.b, 42))
print Val(4,20) - Val(4,10)
# 0.10
print Val(11,2) - Val(10,41)
# 0.03
I would have suggested simply setting the base parameter in int, but that only applies for numbers n in [2, 36]. Instead you can convert to and from any base with something like:
def frombase(numbers, n):
return sum(float(a)*n**i for i, a in izip(count(len(numbers)-1, -1), numbers))
def tobase(number, n):
numbers = []
while number:
numbers.append(int(number % n))
number = int(number / n)
return numbers
You could then produce the result per pair by doing:
converted = map(lambda x: frombase(str(x).split('.'), 42), numbers)
print('.'.join(tobase(abs(converted[1] - converted[0]))))
I'll leave it to you to generalize this into any set of symbols --> any other set of symbols.
First of all, there cant be an element 5.42 with base 42, i think the base should be 43.
I think this is it you want
a=11.02
b=10.41
base=43
def diff(a,b,base):
x=int(a)*base+int(round((a%1)*100))
y=int(b)*base+int(round((b%1)*100))
print x
print y
return (x-y)/base+((x-y)%base)/100.0
c=diff(a,b,base)
print c

Categories

Resources