Given two lists of digits such as [1, 2, 0] = 120
and [1,0,1] = 101
, my function sub
should return the list [1, 9] = 19
but the function is returning [2, -1]
instead. How do I solve this carry problem? It works fine when there isn't a carry and it only receives positive numbers.
Here's the code I have:
sub_Carry :: Integer -> [Integer] -> [Integer] -> [Integer]
sub_Carry c x []
| c == 0 = x
| otherwise = sub_Carry 0 [c] x
sub_Carry c [] x
| c == 0 = x
| otherwise = sub_Carry 0 x [c]
sub_Carry c (x : xs) (y : ys) = (x - y) : sub_Carry c xs ys
sub :: [Integer] -> [Integer] -> [Integer]
sub op1 op2
| to_Integer(op1) == to_Integer(op2) = [0]
| to_Integer(op1) > to_Integer(op2) = drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
| otherwise = [-1] drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
Other considerations:
- I've have other utility functions such as
to_Integer
that converts the list into it's correspondent integer,drop_Zeros
that removes zeros to the right of the list ([0, 1, 0] = [1, 0]
) - in the case the result is a negative number it should return the list with -1 at the head (
[1, 0, 0] - [1, 0, 1] = [-1, 1]
)
CodePudding user response:
I noticed that you don't use the parameter c
for carrying. It is the central point of the exercise. It is also necessary to solve the case when the list of a parameter y
ends earlier than x
. My program works only for positive results. So I also modified the function sub
to reverse parameters when op1 < op2
. Now there should be always a positive result, which you then negate using the constant -1.
sub_Carry :: Integer -> [Integer] -> [Integer] -> [Integer]
sub_Carry 0 [] [] = []
sub_Carry c x [] = sub_Carry c x [0]
sub_Carry c (x : xs) (y : ys)
| (x - y - c) < 0 = (10 x - y - c) : sub_Carry 1 xs ys
| otherwise = (x - y - c ) : sub_Carry 0 xs ys
sub :: [Integer] -> [Integer] -> [Integer]
sub op1 op2
| to_Integer(op1) == to_Integer(op2) = [0]
| to_Integer(op1) > to_Integer(op2) = drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
| otherwise = [-1] drop_Zeros (reverse (sub_Carry 0 (reverse op2) (reverse op1)))