recursionprolog

How to code this mathematical formula in Prolog


I'm trying to code this formula in Prolog :

"str" is input number as a string "base" is the base of the input number.

Result is,

(base)^0 * str[len-1] + (base)^1 * str[len-2] + (base)^2 * str[len-3] + ...

I'm new to Prolog and I have this right now:

calc([],_,0):-  !.
calc([H|T],Base,Res):-
    length([H|T],Long),
    Long >= 0,
    Size is Long - 1,
    power(Base , Size, Res),
    Res1 is Res * H,
    calc(T,Base,Res1).

but it doesn't work properly.


Solution

  • You can do something like this:

    value(String, Base, Value) :-
        string_chars(String, Digits),
        value(Digits, Base, 0, Value).
    
    value([], _, Value, Value).
    value([Digit|Digits], Base, Accumulator, Value) :-
         atoi(Digit, Number),
         NewAccumulator is Base*Accumulator + Number,
         value(Digits, Base, NewAccumulator, Value).
    
    atoi(Char, Int) :-  % convert ASCII code to integer
        char_code(Char, Code) ,
        Int is Code - 48.
    
    

    The predefined predicate string_chars converts a string into a list of chars:

    ?- string_chars("1101", Chars).
    Chars = ['1', '1', '0', '1'].
    

    The predicate atoi converts a character representing a digit into a corresponding integer:

    ?- atoi('3', Integer).
    Integer = 3.
    

    Supposing that [1,1,0,1] is a list of integers (representing a number in base 2), its corresponding value in base 10 can be computed as following:

    Digit Accumulator
    -     0
    1     2 x 0 + 1 = 1
    1     2 x 1 + 1 = 3
    0     2 x 3 + 0 = 6
    1     2 x 6 + 1 = 13
    

    Here are some examples:

    ?- value("1101", 2, V).
    V = 13.
    
    ?- value("1201", 3, V).
    V = 46.
    

    Alternative solution Suppossing that you already have a list of integers representing the digits of a number, the solution is even simpler:

    value_integers(Digits, Base, Value) :-
        value_integers(Digits, Base, 0, Value).
    
    value_integers([], _, Value, Value).
    value_integers([Digit|Digits], Base, Accumulator, Value) :-
         NewAccumulator is Base*Accumulator + Digit,
         value_integers(Digits, Base, NewAccumulator, Value).
    

    Here are some examples:

    ?- value_integers([1,1,0,1], 2, Value).
    Value = 13.
    
    ?- value_integers([1,2,0,1], 3, Value).
    Value = 46.
    
    ?- value_integers([1,2,0,1], 10, Value).
    Value = 1201.