arraysocaml

Multiply int in array list OCaml


I'm trying to solve this problem in OCaml:

I have two arrays of variable size like [1;4;5] and [3;2;3] that represent two integers: 145 and 323.

I would like to multiply this two numbers 145 * 323. The result is 46835. I want to have the result in an array [4;6;8;3;5].


Solution

  • Doing math on an integer list is going to cause a headache so the first thing is figuring out how to define the multiplication of two lists. I'm going to assume they will always be integers and define a function as follows.

    let mult_int_lists a b =
        list_of_int ((int_of_list a) * (int_of_list b));;
    

    The function takes two lists, turns them into integers, multiplies them, and then converts that result back into a list. So how do we define list_of_int and int_of_list? I'd challenge you to figure this out yourself before looking at my code.

    let int_of_list l =
        let rec exp x = if x = 0 then 1 else 10 * (exp (x - 1)) in
        List.fold_left (+) 0 (List.mapi (fun i x -> x * (exp i)) (List.rev l))
    

    Converting a list to an int requires us to reverse the list, multiply each number by 10^i, and then add all of those numbers together. I used List.rev to put the list in order from least to greatest. Then List.mapi takes each value and converts it to the correct tens place. Finally, List.fold_left takes the list of values and adds them into a single integer value.

    let list_of_int i =
        let rec aux i =
            if i = 0 then [] else (i mod 10) :: aux (i / 10) in
        List.rev (aux i)
    

    To convert an int to a list we need to get each tens place by dividing by ten and only keep the remainder. To get the remainder we can use modulus (mod). We can then keep looping until the number equals zero which is when we return the list value. It will be backwards so that is why List.rev is used.