new files
This commit is contained in:
parent
3af7344581
commit
86c034bb8b
1364 changed files with 21352 additions and 0 deletions
170
Task/Balanced-ternary/Prolog/balanced-ternary-3.pro
Normal file
170
Task/Balanced-ternary/Prolog/balanced-ternary-3.pro
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
:- module('bt_mult.pl', [op(850, xfx, btmult),
|
||||
btmult/2,
|
||||
multiplication/3
|
||||
]).
|
||||
|
||||
:- use_module('bt_add.pl').
|
||||
|
||||
:- op(850, xfx, btmult).
|
||||
A is B btmult C :-
|
||||
multiplication(B, C, A).
|
||||
|
||||
neg(A, B) :-
|
||||
maplist(opp, A, B).
|
||||
|
||||
opp(48, 48).
|
||||
opp(45, 43).
|
||||
opp(43, 45).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% the multiplication (efficient)
|
||||
% multiplication(+BIn, +QIn, -AOut)
|
||||
% Aout is BIn * QIn
|
||||
% BIn, QIn, AOut are strings
|
||||
multiplication(BIn, QIn, AOut) :-
|
||||
string_to_list(BIn, B),
|
||||
string_to_list(QIn, Q),
|
||||
|
||||
% We work with positive numbers
|
||||
( B = [45 | _] -> Pos0 = false, neg(B,BP) ; BP = B, Pos0 = true),
|
||||
( Q = [45 | _] -> neg(Q, QP), select(Pos0, [true, false], [Pos1]); QP = Q, Pos1 = Pos0),
|
||||
|
||||
multiplication_(BP, QP, [48], A),
|
||||
( Pos1 = false -> neg(A, A1); A1 = A),
|
||||
string_to_list(AOut, A1).
|
||||
|
||||
|
||||
multiplication_(_B, [], A, A).
|
||||
|
||||
multiplication_(B, [H | T], A, AF) :-
|
||||
multiplication_1(B, H, B1),
|
||||
append(A, [48], A1),
|
||||
bt_add1(B1, A1, A2),
|
||||
multiplication_(B, T, A2, AF).
|
||||
|
||||
% by 1 (digit '+' code 43)
|
||||
multiplication_1(B, 43, B).
|
||||
|
||||
% by 0 (digit '0' code 48)
|
||||
multiplication_1(_, 48, [48]).
|
||||
|
||||
% by -1 (digit '-' code 45)
|
||||
multiplication_1(B, 45, B1) :- neg(B, B1).
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% the division (efficient)
|
||||
% division(+AIn, +BIn, -QOut, -ROut)
|
||||
%
|
||||
division(AIn, BIn, QOut, ROut) :-
|
||||
string_to_list(AIn, A),
|
||||
string_to_list(BIn, B),
|
||||
length(B, LB),
|
||||
length(A, LA),
|
||||
Len is LA - LB,
|
||||
( Len < 0 -> Q = [48], R = A
|
||||
; neg(B, NegB), division_(A, B, NegB, LB, Len, [], Q, R)),
|
||||
string_to_list(QOut, Q),
|
||||
string_to_list(ROut, R).
|
||||
|
||||
|
||||
division_(A, B, NegB, LenB, LenA, QC, QF, R) :-
|
||||
% if the remainder R is negative (last number A), we must decrease the quotient Q, annd add B to R
|
||||
( LenA = -1 -> (A = [45 | _] -> positive(A, B, QC, QF, R) ; QF = QC, A = R)
|
||||
; extract(LenA, _, A, AR, AF),
|
||||
length(AR, LR),
|
||||
|
||||
( LR >= LenB -> ( AR = [43 | _] ->
|
||||
bt_add1(AR, NegB, S), Q0 = [43],
|
||||
% special case : R has the same length than B
|
||||
% and his first digit is + (1)
|
||||
% we must do another one substraction
|
||||
( (length(S, LenB), S = [43|_]) ->
|
||||
bt_add1(S, NegB, S1),
|
||||
bt_add1(QC, [43], QC1),
|
||||
Q00 = [45]
|
||||
; S1 = S, QC1 = QC, Q00 = Q0)
|
||||
|
||||
|
||||
; bt_add1(AR, B, S1), Q00 = [45], QC1 = QC),
|
||||
append(QC1, Q00, Q1),
|
||||
append(S1, AF, A1),
|
||||
strip_nombre(A1, A2, []),
|
||||
LenA1 is LenA - 1,
|
||||
division_(A2, B, NegB, LenB, LenA1, Q1, QF, R)
|
||||
|
||||
; append(QC, [48], Q1), LenA1 is LenA - 1,
|
||||
division_(A, B, NegB, LenB, LenA1, Q1, QF, R))).
|
||||
|
||||
% extract(+Len, ?N1, +L, -Head, -Tail)
|
||||
% remove last N digits from the list L
|
||||
% put them in Tail.
|
||||
extract(Len, Len, [], [], []).
|
||||
|
||||
extract(Len, N1, [H|T], AR1, AF1) :-
|
||||
extract(Len, N, T, AR, AF),
|
||||
N1 is N-1,
|
||||
( N > 0 -> AR = AR1, AF1 = [H | AF]; AR1 = [H | AR], AF1 = AF).
|
||||
|
||||
|
||||
|
||||
positive(R, _, Q, Q, R) :- R = [43 | _].
|
||||
|
||||
positive(S, B, Q, QF, R ) :-
|
||||
bt_add1(S, B, S1),
|
||||
bt_add1(Q, [45], Q1),
|
||||
positive(S1, B, Q1, QF, R).
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% "euclidian" division (inefficient)
|
||||
% euclide(?A, +BIn, ?Q, ?R)
|
||||
% A = B * Q + R
|
||||
euclide(A, B, Q, R) :-
|
||||
mult(A, B, Q, R).
|
||||
|
||||
|
||||
mult(AIn, BIn, QIn, RIn) :-
|
||||
( nonvar(AIn) -> string_to_list(AIn, A); A = AIn),
|
||||
( nonvar(BIn) -> string_to_list(BIn, B); B = BIn),
|
||||
( nonvar(QIn) -> string_to_list(QIn, Q); Q = QIn),
|
||||
( nonvar(RIn) -> string_to_list(RIn, R); R = RIn),
|
||||
|
||||
% we use positive numbers
|
||||
( B = [45 | _] -> Pos0 = false, neg(B,BP) ; BP = B, Pos0 = true),
|
||||
( (nonvar(Q), Q = [45 | _]) -> neg(Q, QP), select(Pos0, [true, false], [Pos1])
|
||||
; nonvar(Q) -> Q = QP , Pos1 = Pos0
|
||||
; Pos1 = Pos0),
|
||||
( (nonvar(A), A = [45 | _]) -> neg(A, AP)
|
||||
; nonvar(A) -> AP = A
|
||||
; true),
|
||||
|
||||
% is R instancied ?
|
||||
( nonvar(R) -> R1 = R; true),
|
||||
% multiplication ? we add B to A and substract 1 (digit '-') to Q
|
||||
( nonvar(Q) -> BC = BP, Ajout = [45],
|
||||
( nonvar(R) -> bt_add1(BC, R, AP) ; AP = BC)
|
||||
% division ? we substract B to A and add 1 (digit '+') to Q
|
||||
; neg(BP, BC), Ajout = [43], QP = [48]),
|
||||
|
||||
% do the real job
|
||||
mult_(BC, QP, AP, R1, Resultat, Ajout),
|
||||
|
||||
( var(QIn) -> (Pos1 = false -> neg(Resultat, QT); Resultat = QT), string_to_list(QIn, QT)
|
||||
; true),
|
||||
( var(AIn) -> (Pos1 = false -> neg(Resultat, AT); Resultat = AT), string_to_list(AIn, AT)
|
||||
; true),
|
||||
( var(RIn) -> string_to_list(RIn, R1); true).
|
||||
|
||||
% @arg1 : divisor
|
||||
% @arg2 : quotient
|
||||
% @arg3 : dividend
|
||||
% @arg4 : remainder
|
||||
% @arg5 : Result : receive either the dividend A
|
||||
% either the quotient Q
|
||||
mult_(B, Q, A, R, Resultat, Ajout) :-
|
||||
bt_add1(Q, Ajout, Q1),
|
||||
bt_add1(A, B, A1),
|
||||
( Q1 = [48] -> Resultat = A % a multiplication
|
||||
; ( A1 = [45 | _], Ajout = [43]) -> Resultat = Q, R = A % a division
|
||||
; mult_(B, Q1, A1, R, Resultat, Ajout)) .
|
||||
Loading…
Add table
Add a link
Reference in a new issue