Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
67
Task/Balanced-ternary/Prolog/balanced-ternary-1.pro
Normal file
67
Task/Balanced-ternary/Prolog/balanced-ternary-1.pro
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
:- module('bt_convert.pl', [bt_convert/2,
|
||||
op(950, xfx, btconv),
|
||||
btconv/2]).
|
||||
|
||||
:- use_module(library(clpfd)).
|
||||
|
||||
:- op(950, xfx, btconv).
|
||||
|
||||
X btconv Y :-
|
||||
bt_convert(X, Y).
|
||||
|
||||
% bt_convert(?X, ?L)
|
||||
bt_convert(X, L) :-
|
||||
( (nonvar(L), \+is_list(L)) ->string_to_list(L, L1); L1 = L),
|
||||
convert(X, L1),
|
||||
( var(L) -> string_to_list(L, L1); true).
|
||||
|
||||
% map numbers toward digits +, - 0
|
||||
plus_moins( 1, 43).
|
||||
plus_moins(-1, 45).
|
||||
plus_moins( 0, 48).
|
||||
|
||||
|
||||
convert(X, [48| L]) :-
|
||||
var(X),
|
||||
( L \= [] -> convert(X, L); X = 0, !).
|
||||
|
||||
convert(0, L) :-
|
||||
var(L), !, string_to_list(L, [48]).
|
||||
|
||||
convert(X, L) :-
|
||||
( (nonvar(X), X > 0)
|
||||
; (var(X), X #> 0,
|
||||
L = [43|_],
|
||||
maplist(plus_moins, L1, L))),
|
||||
!,
|
||||
convert(X, 0, [], L1),
|
||||
( nonvar(X) -> maplist(plus_moins, L1, LL), string_to_list(L, LL)
|
||||
; true).
|
||||
|
||||
convert(X, L) :-
|
||||
( nonvar(X) -> Y is -X
|
||||
; X #< 0,
|
||||
maplist(plus_moins, L2, L),
|
||||
maplist(mult(-1), L2, L1)),
|
||||
convert(Y, 0, [], L1),
|
||||
( nonvar(X) ->
|
||||
maplist(mult(-1), L1, L2),
|
||||
maplist(plus_moins, L2, LL),
|
||||
string_to_list(L, LL)
|
||||
; X #= -Y).
|
||||
|
||||
mult(X, Y, Z) :-
|
||||
Z #= X * Y.
|
||||
|
||||
|
||||
convert(0, 0, L, L) :- !.
|
||||
|
||||
convert(0, 1, L, [1 | L]) :- !.
|
||||
|
||||
|
||||
convert(N, C, LC, LF) :-
|
||||
R #= N mod 3 + C,
|
||||
R #> 1 #<==> C1,
|
||||
N1 #= N / 3,
|
||||
R1 #= R - 3 * C1, % C1 #= 1,
|
||||
convert(N1, C1, [R1 | LC], LF).
|
||||
123
Task/Balanced-ternary/Prolog/balanced-ternary-2.pro
Normal file
123
Task/Balanced-ternary/Prolog/balanced-ternary-2.pro
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
:- module('bt_add.pl', [bt_add/3,
|
||||
bt_add1/3,
|
||||
op(900, xfx, btplus),
|
||||
op(900, xfx, btmoins),
|
||||
btplus/2,
|
||||
btmoins/2,
|
||||
strip_nombre/3
|
||||
]).
|
||||
|
||||
:- op(900, xfx, btplus).
|
||||
:- op(900, xfx, btmoins).
|
||||
|
||||
% define operator btplus
|
||||
A is X btplus Y :-
|
||||
bt_add(X, Y, A).
|
||||
|
||||
% define operator btmoins
|
||||
% no need to define a predicate for the substraction
|
||||
A is X btmoins Y :-
|
||||
X is Y btplus A.
|
||||
|
||||
|
||||
% bt_add(?X, ?Y, ?R)
|
||||
% R is X + Y
|
||||
% X, Y, R are strings
|
||||
% At least 2 args must be instantiated
|
||||
bt_add(X, Y, R) :-
|
||||
( nonvar(X) -> string_to_list(X, X1); true),
|
||||
( nonvar(Y) -> string_to_list(Y, Y1); true),
|
||||
( nonvar(R) -> string_to_list(R, R1); true),
|
||||
bt_add1(X1, Y1, R1),
|
||||
( var(X) -> string_to_list(X, X1); true),
|
||||
( var(Y) -> string_to_list(Y, Y1); true),
|
||||
( var(R) -> string_to_list(R, R1); true).
|
||||
|
||||
|
||||
|
||||
% bt_add1(?X, ?Y, ?R)
|
||||
% R is X + Y
|
||||
% X, Y, R are lists
|
||||
bt_add1(X, Y, R) :-
|
||||
% initialisation : X and Y must have the same length
|
||||
% we add zeros at the beginning of the shortest list
|
||||
( nonvar(X) -> length(X, LX); length(R, LR)),
|
||||
( nonvar(Y) -> length(Y, LY); length(R, LR)),
|
||||
( var(X) -> LX is max(LY, LR) , length(X1, LX), Y1 = Y ; X1 = X),
|
||||
( var(Y) -> LY is max(LX, LR) , length(Y1, LY), X1 = X ; Y1 = Y),
|
||||
|
||||
Delta is abs(LX - LY),
|
||||
( LX < LY -> normalise(Delta, X1, X2), Y1 = Y2
|
||||
; LY < LX -> normalise(Delta, Y1, Y2), X1 = X2
|
||||
; X1 = X2, Y1 = Y2),
|
||||
|
||||
|
||||
% if R is instancied, it must have, at least, the same length than X or Y
|
||||
Max is max(LX, LY),
|
||||
( (nonvar(R), length(R, LR), LR < Max) -> Delta1 is Max - LR, normalise(Delta1, R, R2)
|
||||
; nonvar(R) -> R = R2
|
||||
; true),
|
||||
|
||||
bt_add(X2, Y2, C, R2),
|
||||
|
||||
( C = 48 -> strip_nombre(R2, R, []),
|
||||
( var(X) -> strip_nombre(X2, X, []) ; true),
|
||||
( var(Y) -> strip_nombre(Y2, Y, []) ; true)
|
||||
; var(R) -> strip_nombre([C|R2], R, [])
|
||||
; ( select(C, [45,43], [Ca]),
|
||||
( var(X) -> strip_nombre([Ca | X2], X, [])
|
||||
; strip_nombre([Ca | Y2], Y, [])))).
|
||||
|
||||
|
||||
% here we actually compute the sum
|
||||
bt_add([], [], 48, []).
|
||||
|
||||
bt_add([H1|T1], [H2|T2], C3, [R2 | L]) :-
|
||||
bt_add(T1, T2, C, L),
|
||||
% add HH1 and H2
|
||||
ternary_sum(H1, H2, R1, C1),
|
||||
% add first carry,
|
||||
ternary_sum(R1, C, R2, C2),
|
||||
% add second carry
|
||||
ternary_sum(C1, C2, C3, _).
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% ternary_sum
|
||||
% @arg1 : V1
|
||||
% @arg2 : V2
|
||||
% @arg3 : R is V1 + V2
|
||||
% @arg4 : Carry
|
||||
ternary_sum(43, 43, 45, 43).
|
||||
|
||||
ternary_sum(43, 45, 48, 48).
|
||||
|
||||
ternary_sum(45, 43, 48, 48).
|
||||
|
||||
ternary_sum(45, 45, 43, 45).
|
||||
|
||||
ternary_sum(X, 48, X, 48).
|
||||
|
||||
ternary_sum(48, X, X, 48).
|
||||
|
||||
|
||||
% if L has a length smaller than N, complete L with 0 (code 48)
|
||||
normalise(0, L, L) :- !.
|
||||
normalise(N, L1, L) :-
|
||||
N1 is N - 1,
|
||||
normalise(N1, [48 | L1], L).
|
||||
|
||||
|
||||
% contrary of normalise
|
||||
% remove leading zeros.
|
||||
% special case of number 0 !
|
||||
strip_nombre([48]) --> {!}, "0".
|
||||
|
||||
% enlève les zéros inutiles
|
||||
strip_nombre([48 | L]) -->
|
||||
strip_nombre(L).
|
||||
|
||||
|
||||
strip_nombre(L) -->
|
||||
L.
|
||||
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