3

I got a problem with this exercise. I've been trying to solve it for a long time searching for stuff, but I am unable to.

Define functions:

addLnat :: [Int] -> [Int] -> [Int]
mulLnat :: [Int] -> [Int] -> [Int]

addLnat adds numbers from two arrays eg.

addLnat [4,5,6] [8,5,2] ->  [2,1,9]

as [4+8 gives 2 carry 1, 5+5+1 gives 1 carry 1, 6+2+1 = 9]

Lnat, is a "list natural number", represented as a list of base-10 digits, least significant first. So the number 654 is [4,5,6].

What I got is:

addLnat :: [Int] -> [Int] -> [Int]
addLnat _ [] = []
addLnat [] _ = []
addLnat (x:xs) (y:ys) = (if (x+y) > 9 then x+y-10 else (x+y)):(addLnat xs ys)

I adding number and ignoring carry. Not sure how to solve it. Any help would be much appreciated.


I have improved the solution as per user5402 comment, so created addLnat' cr xs ys, but when I what to pass carry as a parameter it fails to load - most probable that I am getting the syntax wrong:( (cr is 0 only for now and it will be replaced by maths).

addLnat' c (x:xs) (y:ys) = d : addLnat' cr xs ys 
where d = if c+x+y < 9 then x+y else c+x+y-((quot (c+x+y) 10)*10) 
cr = 0 

Any ideas?

3
  • Here's a hint: try defining a helper function addLnatCarry :: Int -> [Int] -> [Int] -> [Int] which takes as a first argument a carry digit (or a Bool telling whether there's a carry if you prefer). Commented Jan 11, 2015 at 23:42
  • Pro-tip: [Int] is not an array. It's a list. Commented Jan 12, 2015 at 9:08
  • Thanks - changed array to list in the topic. It's what I thought , but that was what I was given by someone who knows the stuff. Commented Jan 12, 2015 at 12:20

2 Answers 2

2

I am not very good at haskell but maybe this can help ;

add::[Int]->[Int]->[Int]
add x y = add' 0 x y

There we define a function add that will use add' to add two lists The main idea is to "save" carry and carefully work with corner cases. Here carry is saved in "variable" rest

    add'::Int->[Int]->[Int]->[Int]
    add' 0 x []      = x 
    add' rest (x:[]) (y:[]) = [(r `mod` 10),(r `div` 10)]
       where r = x+y+rest
    add' y (x:xs) [] = add' (r `div` 10) ((r `mod` 10):xs) [] 
       where r = x+y
    add' rest (x:xs) (y:ys) = (r `mod` 10) : (add' (r `div` 10) xs ys)
       where r = x+y+rest 

List x must be bigger than list y but that's not a problem

add [5,7,8] [4,3,2]  => [9,0,1,1] (correct)
add [1,2,3] [4,5,6]  => [5,7,9,0] (correct)
Sign up to request clarification or add additional context in comments.

Comments

2

You need to write a version of addLnat which accepts a carry parameter:

addLnat' c (x:xs) (y:ys) = d : addLnat c' xs ys
  where d = if c+x+y > 9 then ... else ...
        c' = ... the next carry bit ...

There are a lot more details and corner cases to consider, but this is the basic idea. Finally,

addLnat xs ys = addLnat' 0 xs ys  -- initially the carry is 0

1 Comment

Thanks a lot for your help :-) That's the way I took when I was starting with it. It's what I got working (what doesn't include real carry) addLnat' c (x:xs) (y:ys) = d : addLnat' 0 xs ys where d = if c+x+y < 9 then x+y else c+x+y-((quot (c+x+y) 10)*10) When I want to include real carry as a variable, it doesn't work addLnat' c (x:xs) (y:ys) = d : addLnat' cr xs ys where d = if c+x+y < 9 then x+y else c+x+y-((quot (c+x+y) 10)*10) cr = 0 My guess is wrong syntax, but I cannot get it right :-(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.