bin_search(Elt,List,Result):-
  length(List,N), bin_search_inner(Elt,List,1,N,Result).

bin_search_inner(Elt,List,J,J,J):-
  nth(J,List,Elt).
bin_search_inner(Elt,List,Begin,End,Mid):-
  Begin < End,
  Mid is (Begin+End) div 2,
  nth(Mid,List,Elt).
bin_search_inner(Elt,List,Begin,End,Result):-
  Begin < End,
  Mid is (Begin+End) div 2,
  nth(Mid,List,MidElt),
  MidElt < Elt,
  NewBegin is Mid+1,
  bin_search_inner(Elt,List,NewBegin,End,Result).
bin_search_inner(Elt,List,Begin,End,Result):-
  Begin < End,
  Mid is (Begin+End) div 2,
  nth(Mid,List,MidElt),
  MidElt > Elt,
  NewEnd is Mid-1,
  bin_search_inner(Elt,List,Begin,NewEnd,Result).

Output examples:
 ?- bin_search(4,[1,2,4,8,16,32,64,128],Result).
Result = 3.

?- bin_search(5,[1,2,4,8],Result).
Result = -1.

The code implements a binary search algorithm, which divides a range of values into halves to find an unknown value. It includes both recursive and iterative versions of the traditional algorithm, as well as versions that return the leftmost and rightmost insertion points for the given value. The code also handles potential overflow bugs. The binary search is performed on a sorted integer array, and the index of the found number is returned, along with a message indicating whether the number was found in the array.


:-
    current_prolog_flag(os_argv, Args),
    write(Args).

:-
    current_prolog_flag(argv, Args),
    write(Args).

"Code retrieves and prints the list of command-line arguments given to the program. It uses os_argv or argv to access arguments not consumed by the Prolog interpreter, excluding the interpreter name, input Prolog filename, and any other arguments directed at the Prolog interpreter."


:- use_module(library(pce)).

pendulum :-
	new(D, window('Pendulum')),
	send(D, size, size(560, 300)),
	new(Line, line(80, 50, 480, 50)),
	send(D, display, Line),
	new(Circle, circle(20)),
	send(Circle, fill_pattern,  colour(@default, 0, 0, 0)),
	new(Boule, circle(60)),
	send(Boule, fill_pattern,  colour(@default, 0, 0, 0)),
	send(D, display, Circle, point(270,40)),
	send(Circle, handle, handle(h/2, w/2, in)),
	send(Boule, handle, handle(h/2, w/2, out)),
	send(Circle, connect, Boule, link(in, out, line(0,0,0,0,none))),
	new(Anim, animation(D, 0.0, Boule, 200.0)),
	send(D, done_message, and(message(Anim, free),
				  message(Boule, free),
				  message(Circle, free),
				  message(@receiver,destroy))),
	send(Anim?mytimer, start),
	send(D, open).

:- pce_begin_class(animation(window, angle, boule, len_pendulum), object).
variable(window, object,  both, "Display window").
variable(boule,  object, both,  "bowl of the pendulum").
variable(len_pendulum,    object, both,  "len of the pendulum").
variable(angle,  object, both,  "angle with the horizontal").
variable(delta,    object, both,  "increment of the angle").
variable(mytimer, timer, both, "timer of the animation").

initialise(P, W:object, A:object, B : object, L:object) :->
        "Creation of the object"::
        send(P, window, W),
        send(P, angle, A),
        send(P, boule, B),
        send(P, len_pendulum, L),
        send(P, delta, 0.01),
	send(P, mytimer, new(_, timer(0.01,message(P, anim_message)))).

% method called when the object is destroyed
% first the timer is stopped
% then all the resources are freed
unlink(P) :->
	send(P?mytimer, stop),
	send(P, send_super, unlink).

% message processed by the timer
anim_message(P) :->
	get(P, angle, A),
	get(P, len_pendulum, L),
	calc(A, L, X, Y),
	get(P, window, W),
	get(P, boule, B),
	send(W, display, B, point(X,Y)),
	% computation of the next position
	get(P, delta, D),
	next_Angle(A, D, NA, ND),
	send(P, angle, NA),
	send(P, delta, ND).

:- pce_end_class.

% computation of the position of the bowl.
calc(Ang, Len, X, Y) :-
	X is Len * cos(Ang)+ 250,
	Y is Len * sin(Ang) + 20.

% computation of the next angle
% if we reach 0 or pi, delta change.
next_Angle(A, D, NA, ND) :-
	NA is D + A,
	(((D > 0,   abs(pi-NA) < 0.01); (D < 0, abs(NA) < 0.01))->
	  ND = - D;
	  ND = D).

simulate and animate a simple gravity pendulum using SWI-Prolog's graphic interface XPCE.


:- use_module([ library(http/json),
                library(func) ]).

test_json('{"widget": { "debug": "on", "window": { "title": "Sample Konfabulator Widget", "name": "main_window", "width": 500, "height": 500 }, "image": { "src": "Images/Sun.png", "name": "sun1", "hOffset": 250, "vOffset": 250, "alignment": "center" }, "text": { "data": "Click Here", "size": 36, "style": "bold", "name": "text1", "hOffset": 250, "vOffset": 100, "alignment": "center", "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;" }}}').

reading_JSON_term :-
    atom_json_dict(test_json(~), Dict, []), %% This accomplishes reading in the JSON data
    writeln( 'JSON as Prolog dict: ~w~n'
           $ Dict),
    writeln( 'Access field "widget.text.data": ~s~n'
           $ Dict.widget.text.data),
    writeln( 'Alter field "widget": ~w~n'
           $ Dict.put(widget, "Altered")).

searalize_a_JSON_term :-
    Dict = _{book:_{title:"To Mock a Mocking Bird",
                    author:_{first_name:"Ramond",
                             last_name:"Smullyan"},
                    publisher:"Alfred A. Knopf",
                    year:1985
                   }},
    json_write(current_output, Dict). %% This accomplishes serializing the JSON object.

utilize SWI-Prolog 7's library(http/json) and the new dict datatype to handle JSON objects. They load a JSON string into a data structure and create a new data structure, serializing it into JSON. The code ensures the JSON is valid and uses objects and arrays as appropriate for the language. The serialization and parsing are accomplished with two predicates.


iroot(_, 0, 0) :- !.
iroot(M, N, R) :-
    M > 1,
    (N > 0 ->
        irootpos(M, N, R)
    ;
        N /\ 1 =:= 1,
        NegN is -N, irootpos(M, NegN, R0), R is -R0).

irootpos(N, A, R) :-
    X0 is 1 << (msb(A) div N),  % initial guess is 2^(log2(A) / N)
    newton(N, A, X0, X1),
    iroot_loop(A, X1, N, A, R).

iroot_loop(X1, X2, _, _, X1) :- X1 =< X2, !.
iroot_loop(_, X1, N, A, R) :-
    newton(N, A, X1, X2),
    iroot_loop(X1, X2, N, A, R).

newton(2, A, X0, X1) :- X1 is (X0 + A div X0) >> 1, !.  % fast special case
newton(N, A, X0, X1) :- X1 is ((N - 1)*X0 + A div X0**(N - 1)) div N.

Implement an algorithm to compute the principal nth root of a positive real number using integer math, with the ability to approximate non-integral roots to arbitrary precision.


Works with: GNU Prolog
:- initialization(main).

answer(24).
play :- round, play ; true.

round :-
    prompt(Ns), get_line(Input), Input \= "stop"
  , ( phrase(parse(Ns,[]), Input) -> Result = 'correct'
                                   ; Result = 'wrong'
    ), write(Result), nl, nl
  . % where
    prompt(Ns)  :- length(Ns,4), maplist(random(1,10), Ns)
                 , write('Digits: '), write(Ns), nl
                 .

parse([],[X])     --> { answer(X) }.
parse(Ns,[Y,X|S]) --> "+", { Z is X  +  Y }, parse(Ns,[Z|S]).
parse(Ns,[Y,X|S]) --> "-", { Z is X  -  Y }, parse(Ns,[Z|S]).
parse(Ns,[Y,X|S]) --> "*", { Z is X  *  Y }, parse(Ns,[Z|S]).
parse(Ns,[Y,X|S]) --> "/", { Z is X div Y }, parse(Ns,[Z|S]).
parse(Ns,Stack)   --> " ", parse(Ns,Stack).
parse(Ns,Stack)   --> { select(N,Ns,Ns1), number_codes(N,[Code]) }
                    , [Code], parse(Ns1,[N|Stack])
                    .

get_line(Xs) :- get_code(X)
              , ( X == 10 -> Xs = [] ; Xs = [X|Ys], get_line(Ys) )
              .
main :- randomize, play, halt.

Digits: [9,4,6,9]
46*9-9+
correct

Digits: [7,4,7,8]
8 4 7 7 / - *
correct

Digits: [7,2,8,2]
7282---
wrong

Digits: [2,6,7,1]
4611***
wrong

Digits: [3,6,5,8]
+
wrong

Digits: [2,1,7,7]
stop

The code generates four random digits from 1 to 9, prompts the player to form an arithmetic expression using those digits exactly once each, and checks if the expression evaluates to 24. The code supports addition, subtraction, multiplication, and division operations, and allows the use of brackets. It does not allow forming multiple digit numbers from the given digits. The order of the digits does not need to be preserved. The code does not generate or test the validity of the expression.


% the test
run_length :-
	L = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW",
	writef('encode %s\n', [L]),
	encode(L, R),
	writeln(R), nl,
	writef('decode %w\n', [R]),
	decode(R, L1),
	writeln(L1).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  encode
%
%  translation
%  from
%  "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
%  to
%  "12W1B12W3B24W1B14W"
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encode(In, Out) :-
	% Because of the special management of the "strings" by Prolog
	( is_list(In) -> I = In; string_to_list(In, I)),
	packList(I, R1),
	dcg_packList2List(R1,R2, []),
	string_to_list(Out,R2).

dcg_packList2List([[N, V]|T]) -->
	{ number_codes(N, LN)},
	LN,
	[V],
	dcg_packList2List(T).

dcg_packList2List([]) --> [].

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  decode
%
%  translation
%  from
%  "12W1B12W3B24W1B14W"
%  to
%  "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
decode(In, Out) :-
	% Because of the special management of the "strings" by Prolog
	( is_list(In) -> I = In; string_to_list(In, I)),
	dcg_List2packList(I, R1, []),
	packList(L1, R1),
	string_to_list(Out, L1).

dcg_List2packList([H|T]) -->
	{code_type(H, digit)},
	parse_number([H|T], 0).

dcg_List2packList([]) --> [].

parse_number([H|T], N) -->
	{code_type(H, digit), !,
	N1 is N*10 + H - 48 },
	parse_number(T, N1).

parse_number([H|T], N) -->
	[[N, H]],
	dcg_List2packList(T).

% use of library clpfd allows packList(?In, ?Out) to works
% in both ways In --> Out and In <-- Out.

:- use_module(library(clpfd)).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ?- packList([a,a,a,b,c,c,c,d,d,e], L).
%  L = [[3,a],[1,b],[3,c],[2,d],[1,e]] .
% ?- packList(R,  [[3,a],[1,b],[3,c],[2,d],[1,e]]).
% R = [a,a,a,b,c,c,c,d,d,e] .
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
packList([],[]).

packList([X],[[1,X]]) :- !.

packList([X|Rest],[XRun|Packed]):-
    run(X,Rest, XRun,RRest),
    packList(RRest,Packed).

run(Var,[],[1,Var],[]).

run(Var,[Var|LRest],[N1, Var],RRest):-
    N #> 0,
    N1 #= N + 1,
    run(Var,LRest,[N, Var],RRest).

run(Var,[Other|RRest], [1,Var],[Other|RRest]):-
    dif(Var,Other).

 ?- run_length.
encode WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
12W1B12W3B24W1B14W

decode 12W1B12W3B24W1B14W
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
true .

implement a run-length encoding and decoding system. The system takes a string of uppercase characters, compresses repeated characters by storing the length of the character run, and provides a function to reverse the compression. The output can be any format that can recreate the original input.


determine the optimal selection of items a thief can carry in his knapsack, given a weight limit of 15 kg. The items can be cut, with their value decreasing proportionally to their weight. The goal is to maximize the total value of the items in the knapsack. The items available, their weights and values are provided. The solution uses SWI-Prolog and the simplex library.


Works with: SWI-Prolog version 5.10.0
:- use_module(library( http/http_open )).

anagrams:-
        % we read the URL of the words
	http_open('http://wiki.puzzlers.org/pub/wordlists/unixdict.txt',	In, []),
	read_file(In, [], Out),
	close(In),

        % we get a list of pairs key-value where key = a-word value = <list-of-its-codes>
        % this list must be sorted
	msort(Out, MOut),

        % in order to gather values with the same keys
	group_pairs_by_key(MOut, GPL),

        % we sorted this list in decreasing order of the length of values
	predsort(my_compare, GPL, GPLSort),

	% we extract the first 6 items
        GPLSort = [_H1-T1, _H2-T2, _H3-T3, _H4-T4, _H5-T5, _H6-T6 | _],

        % Tnn are lists of codes (97 for 'a'), we create the strings
	maplist(maplist(atom_codes), L, [T1, T2, T3, T4, T5, T6] ),

	maplist(writeln, L).

read_file(In, L, L1) :-
	read_line_to_codes(In, W),
	(   W == end_of_file ->
               % the file is read
	       L1 = L
	       ;
               % we sort the list of codes of the line
	       msort(W, W1),

               % to create the key in alphabetic order
	       atom_codes(A, W1),

               % and we have the pair Key-Value in the result list
	       read_file(In, [A-W | L], L1)).

% predicate for sorting list of pairs Key-Values
% if the lentgh of values is the same
% we sort the keys in alhabetic order
my_compare(R, K1-V1, K2-V2) :-
	length(V1, L1),
	length(V2, L2),
	(   L1 < L2 -> R = >; L1 > L2 -> R = <; compare(R, K1, K2)).

[abel,able,bale,bela,elba]
[caret,carte,cater,crate,trace]
[angel,angle,galen,glean,lange]
[alger,glare,lager,large,regal]
[elan,lane,lean,lena,neal]
[evil,levi,live,veil,vile]
true

find the largest sets of anagrams from the word list provided at http://wiki.puzzlers.org/pub/wordlists/unixdict.txt.


Works with: SWI Prolog

main:-
    write_sierpinski_carpet('sierpinski_carpet.svg', 486, 4).

write_sierpinski_carpet(File, Size, Order):-
    open(File, write, Stream),
    format(Stream,
           "<svg xmlns='http://www.w3.org/2000/svg' width='~d' height='~d'>\n",
           [Size, Size]),
    write(Stream, "<rect width='100%' height='100%' fill='white'/>\n"),
    Side is Size/3.0,
    sierpinski_carpet(Stream, 0, 0, Side, Order),
    write(Stream, "</svg>\n"),
    close(Stream).

sierpinski_carpet(Stream, X, Y, Side, 0):-
    !,
    X0 is X + Side,
    Y0 is Y + Side,
    write_square(Stream, X0, Y0, Side).
sierpinski_carpet(Stream, X, Y, Side, Order):-
    Order1 is Order - 1,
    Side1 is Side / 3.0,
    X0 is X + Side,
    Y0 is Y + Side,
    X1 is X0 + Side,
    Y1 is Y0 + Side,
    write_square(Stream, X0, Y0, Side),
    sierpinski_carpet(Stream, X, Y, Side1, Order1),
    sierpinski_carpet(Stream, X0, Y, Side1, Order1),
    sierpinski_carpet(Stream, X1, Y, Side1, Order1),
    sierpinski_carpet(Stream, X, Y0, Side1, Order1),
    sierpinski_carpet(Stream, X1, Y0, Side1, Order1),
    sierpinski_carpet(Stream, X, Y1, Side1, Order1),
    sierpinski_carpet(Stream, X0, Y1, Side1, Order1),
    sierpinski_carpet(Stream, X1, Y1, Side1, Order1).

write_square(Stream, X, Y, Side):-
    format(Stream,
           "<rect fill='black' x='~g' y='~g' width='~g' height='~g'/>\n",
           [X, Y, Side, Side]).

generate a graphical or ASCII-art representation of a Sierpinski carpet of a given order N. The representation uses whitespace and non-whitespace characters, specifically the '#' character. The program also produces an SVG format image file of the Sierpinski carpet.


huffman :-
	L = 'this is an example for huffman encoding',
	atom_chars(L, LA),
	msort(LA, LS),
	packList(LS, PL),
	sort(PL, PLS),
	build_tree(PLS, A),
	coding(A, [], C),
	sort(C, SC),
	format('Symbol~t   Weight~t~30|Code~n'),
	maplist(print_code, SC).

build_tree([[V1|R1], [V2|R2]|T], AF) :-
	V is V1 + V2,
	A = [V, [V1|R1], [V2|R2]],
	(   T=[] -> AF=A ;  sort([A|T], NT), build_tree(NT, AF) ).

coding([_A,FG,FD], Code, CF) :-
	(   is_node(FG) ->  coding(FG, [0 | Code], C1)
			 ;  leaf_coding(FG, [0 | Code], C1) ),
	(   is_node(FD) ->  coding(FD, [1 | Code], C2)
			 ;  leaf_coding(FD, [1 | Code], C2) ),
	append(C1, C2, CF).

leaf_coding([FG,FD], Code, CF) :-
	reverse(Code, CodeR),
	CF = [[FG, FD, CodeR]] .

is_node([_V, _FG, _FD]).

print_code([N, Car, Code]):-
	format('~w :~t~w~t~30|', [Car, N]),
	forall(member(V, Code), write(V)),
	nl.

packList([], []).
packList([X], [[1,X]]) :- !.
packList([X|Rest], [XRun|Packed]):-
    run(X, Rest, XRun, RRest),
    packList(RRest, Packed).

run(V, [], [1,V], []).
run(V, [V|LRest], [N1,V], RRest):-
    run(V, LRest, [N, V], RRest),
    N1 is N + 1.
run(V, [Other|RRest], [1,V], [Other|RRest]):-
    dif(V, Other).

The code generates a Huffman encoding for each character in the given string "this is an example for huffman encoding". It first creates a priority queue with a leaf node for each character symbol based on their frequency of occurrence. It then constructs a binary tree by removing the two nodes with the highest priority (lowest probability) from the queue and creating a new internal node with these two nodes as children. This process continues until there is only one node left in the queue, which becomes the root node. The code then traverses the binary tree from root to leaves, assigning '0' for one branch and '1' for the other at each node. The accumulated zeros and ones at each leaf constitute the Huffman encoding for the corresponding symbol. The result is a table of Huffman encodings for each character in the string. The code is compatible with SWI-Prolog.


:- dynamic click/1.

dialog('Simple windowed application',
       [ object        :=
	   Simple_windowed_application,
	 parts         :=
	   [ Simple_windowed_application :=
	       dialog('Simple windowed application'),
	     Name                       :=
	       label(name, 'There have been no clicks yet'),
	     BtnClick                     :=
	       button(button)
	   ],
	 modifications :=
	   [ BtnClick := [ label := 'Click me !'
		       ]
	   ],
	 layout        :=
	   [ area(Name,
		  area(40, 20, 200, 18)),
	     area(BtnClick,
		  area(90, 60, 80, 24))
	   ],
	 behaviour :=
	 [
	  BtnClick := [message := message(@prolog, btnclick, Name)]
	 ]
       ]).

btnclick(Label) :-
	retract(click(V)),
	V1 is V+1,
	assert(click(V1)),
	sformat(A, '~w click(s)', [V1]),
	send(Label, selection, A).

simple_windowed :-
	retractall(click(_)),
	assert(click(0)),
	make_dialog(D, 'Simple windowed application'),
	send(D, open).

"Implements a simple windowed application using SWI-Prolog and XPCE. The application features a window with a label displaying the text 'There have been no clicks yet' and a button labeled 'click me'. The label updates to show the number of times the button has been clicked each time the button is pressed."


rfor(Hi,Lo,Hi) :- Hi >= Lo.
rfor(Hi,Lo,Val) :- Hi > Lo, H is Hi - 1, !, rfor(H,Lo,Val).

reverse_iter :-
  rfor(10,0,Val), write(Val), nl, fail.
reverse_iter.
?- reverse_iter.
10
9
8
7
6
5
4
3
2
1
0
true.

implement a for loop that counts down from 10 to 0 using Prolog, which doesn't have a built-in iterator for descending values.


for(Lo,Hi,Step,Lo)  :- Step>0, Lo=<Hi.
for(Lo,Hi,Step,Val) :- Step>0, plus(Lo,Step,V), V=<Hi, !, for(V,Hi,Step,Val).

example :-
  for(0,10,2,Val), write(Val), write(' '), fail.
example.
?- example.
0 2 4 6 8 10
true.

for(Hi,Lo,Step,Hi)  :- Step<0, Lo=<Hi.
for(Hi,Lo,Step,Val) :- Step<0, plus(Hi,Step,V), Lo=<V, !, for(V,Lo,Step,Val).

demonstrate a for-loop with a step-value greater than one and also include a stepping iterator that allows backward iteration.


xor_pattern :-
	new(D, window('XOR Pattern')),
	send(D, size, size(512,512)),
	new(Img, image(@nil, width := 512, height := 512 , kind := pixmap)),

	forall(between(0,511, I),
	       (   forall(between(0,511, J),
			  (   V is I xor J,
			      R is (V * 1024) mod 65536,
			      G is (65536 - V * 1024) mod 65536,
			      (	  V mod 2 =:= 0
			      ->  B is  (V * 4096) mod 65536
			      ;	   B is  (65536 - (V * 4096)) mod 65536),
			      send(Img, pixel(I, J, colour(@default, R, G, B))))))),

	new(Bmp, bitmap(Img)),
	send(D, display, Bmp, point(0,0)),
	send(D, open).

The code generates a graphical pattern where each pixel's color is determined by the 'x xor y' value from a color table, using SWI-Prolog and its GUI XPCE for rendering munching squares.


:- dynamic cell/2.

maze(Lig,Col) :-
	retractall(cell(_,_)),

	new(D, window('Maze')),

	% creation of the grid
	forall(between(0,Lig, I),
	       (XL is  50, YL is I * 30 + 50,
		XR is Col * 30 + 50,
		new(L, line(XL, YL, XR, YL)),
		send(D, display, L))),

	forall(between(0,Col, I),
	       (XT is  50 + I * 30, YT is 50,
		YB is Lig * 30 + 50,
		new(L, line(XT, YT, XT, YB)),
		send(D, display, L))),

	SX is Col * 30 + 100,
	SY is Lig * 30 + 100,
	send(D, size, new(_, size(SX, SY))),

	% choosing a first cell
	L0 is random(Lig),
	C0 is random(Col),
	assert(cell(L0, C0)),
	\+search(D, Lig, Col, L0, C0),
	send(D, open).

search(D, Lig, Col, L, C) :-
	Dir is random(4),
	nextcell(Dir, Lig, Col, L, C, L1, C1),
	assert(cell(L1,C1)),
	assert(cur(L1,C1)),
	erase_line(D, L, C, L1, C1),
	search(D, Lig, Col, L1, C1).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
erase_line(D, L, C, L, C1) :-
	(   C < C1 -> C2 = C1; C2 = C),
	XT is C2  * 30 + 50,
	YT is L * 30 + 51, YR is (L+1) * 30 + 50,
	new(Line, line(XT, YT, XT, YR)),
	send(Line, colour, white),
	send(D, display, Line).

erase_line(D, L, C, L1, C) :-
	XT is  51 + C * 30, XR is 50 + (C + 1) * 30,
	(   L < L1 -> L2 is L1; L2 is L),
	YT is L2 * 30 + 50,
	new(Line, line(XT, YT, XR, YT)),
	send(Line, colour, white),
	send(D, display, Line).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nextcell(Dir, Lig, Col, L, C, L1, C1) :-
	next(Dir, Lig, Col, L, C, L1, C1);
	(   Dir1 is (Dir+3) mod 4,
	    next(Dir1, Lig, Col, L, C, L1, C1));
	(   Dir2 is (Dir+1) mod 4,
	    next(Dir2, Lig, Col, L, C, L1, C1));
	(   Dir3 is (Dir+2) mod 4,
	    next(Dir3, Lig, Col, L, C, L1, C1)).

% 0 => northward
next(0, _Lig, _Col, L, C, L1, C) :-
	L > 0,
	L1 is L - 1,
	\+cell(L1, C).

% 1 => rightward
next(1, _Lig, Col, L, C, L, C1) :-
	C < Col - 1,
	C1 is C + 1,
	\+cell(L, C1).

% 2 => southward
next(2, Lig, _Col, L, C, L1, C) :-
	L < Lig - 1,
	L1 is L + 1,
	\+cell(L1, C).

% 3 => leftward
next(2, _Lig, _Col, L, C, L, C1) :-
	C > 0,
	C1 is C - 1,
	\+cell(L, C1).

generate and display a maze using the Depth-first search algorithm. The process begins at a random cell, marks it as visited, and retrieves a list of its neighboring cells. For each neighbor, starting with a randomly selected one, if the neighbor hasn't been visited, the wall between the current cell and the neighbor is removed, and the process is recursively repeated with the neighbor as the current cell. The codes are compatible with SWI-Prolog and XPCE.


The code continually calculates and outputs the next decimal digit of Pi, starting from 3.14159265. The process continues indefinitely until interrupted by the user. The code does not use built-in Pi constants but calculates Pi from scratch. It utilizes a coroutine with freeze/2 predicate for this task.


Works with: SWI Prolog
:- table ack/3. % memoization reduces the execution time of ack(4,1,X) from several
                % minutes to about one second on a typical desktop computer.
ack(0, N, Ans) :- Ans is N+1.
ack(M, 0, Ans) :- M>0, X is M-1, ack(X, 1, Ans).
ack(M, N, Ans) :- M>0, N>0, X is M-1, Y is N-1, ack(M, Y, Ans2), ack(X, Ans2, Ans).

ack(0,N,s(N)).
ack(s(M),0,P):- ack(M,s(0),P).
ack(s(M),s(N),P):- ack(s(M),N,S), ack(M,S,P).

% Peano's first axiom in Prolog is that s(0) AND s(s(N)):- s(N)
% Thanks to this we don't need explicit N > 0 checks.
% Nor explicit arithmetic operations like X is M-1.
% Recursion and unification naturally decrement s(N) to N.
% But: Prolog clauses are relations and cannot be replaced by their result, like functions.
% Because of this we do need an extra argument to hold the output of the function.
% And we also need an additional call to the function in the last clause.

% Example input/output:
% ?- ack(s(0),s(s(0)),P).
% P = s(s(s(s(0)))) ;
% false.

The code implements the Ackermann function, a non-primitive recursive function. It takes two non-negative arguments and returns their Ackermann value. The function handles large numbers but doesn't necessarily require arbitrary precision.


implement an algorithm to compute the Gamma function in the real field, comparing the results with built-in or library functions if available. The Gamma function is computed through numerical integration, with the Lanczos approximation and Stirling's approximation suggested for better efficiency. The accuracy of the computation is checked against Wolfram Alpha.


solution([]).

solution([X/Y|Others]) :-
 solution(Others),
 member(Y, [1,2,3,4,5,6,7,8]),
 noattack(X/Y, Others).

noattack(_,[]).

noattack(X/Y,[X1/Y1|Others]) :-
 Y =\= Y1,
 Y1 - Y =\= X1 - X,
 Y1 - Y =\= X - X1,
 noattack(X/Y,Others).

member(Item,[Item|Rest]).

member(Item,[First|Rest]) :-
 member(Item,Rest).

template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).

solution(Queens) :-
 permutation([1,2,3,4,5,6,7,8], Queens),
 safe(Queens).

permutation([],[]).

permutation([Head|Tail],PermList) :-
 permutation(Tail,PermTail),
 del(Head,PermList,PermTail).

del(Item,[Item|List],List).

del(Item,[First|List],[First|List1]) :-
 del(Item,List,List1).

safe([]).

safe([Queen|Others]) :-
 safe(Others),
 noattack(Queen,Others,1).

noattack(_,[],_).

noattack(Y,[Y1|Ylist],Xdist) :-
 Y1-Y=\=Xdist,
 Y-Y1=\=Xdist,
 Dist1 is Xdist + 1,
 noattack(Y,Ylist,Dist1).

solution(Ylist) :-
 sol(Ylist,[1,2,3,4,5,6,7,8],
    [1,2,3,4,5,6,7,8],
    [-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7],
    [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]).

sol([],[],[],Du,Dv).

sol([Y|Ylist],[X|Dx1],Dy,Du,Dv) :-
 del(Y,Dy,Dy1),
 U is X-Y,
 del(U,Du,Du1),
 V is X+Y,
 del(V,Dv,Dv1),
 sol(Ylist,Dx1, Dy1,Du1,Dv1).

del(Item,[Item|List],List).

del(Item,[First|List],[First|List1]) :-
 del(Item,List,List1).

  ?- findall(S, solution(S), LS), length(LS,N), write(N).
  92

Alternative version[edit]

:- initialization(main).

queens(N,Qs) :- bagof(X, between(1,N,X), Xs), place(Xs,[],Qs).

place(Xs,Qs,Res) :-
    Xs = [] -> Res = Qs
  ; select(Q,Xs,Ys), not_diag(Q,Qs,1), place(Ys,[Q|Qs],Res)
  .

not_diag(_, []     , _).
not_diag(Q, [Qh|Qs], D) :-
     abs(Q - Qh) =\= D, D1 is D + 1, not_diag(Q,Qs,D1).

main :- findall(Qs, (queens(8,Qs), write(Qs), nl), _), halt.

Alternative Solution[edit]

Works with: SWI Prolog version version 6.2.6 by Jan Wielemaker, University of Amsterdam
% 8 queens problem.
%  q(Row) represents a queen, allocated one per row. No rows ever clash.
%  The columns are chosen iteratively from available columns held in a
%  list, reduced with each allocation, so we need never check verticals.
%  For diagonals, we check prior to allocation whether each newly placed
%  queen will clash with any of the prior placements. This prevents
%  most invalid permutations from ever being attempted.
can_place(_, []) :- !.	   % success for empty board
can_place(q(R,C),Board) :- % check diagonals against allocated queens
	member(q(Ra,Ca), Board), abs(Ra-R) =:= abs(Ca-C), !, fail.
can_place(_,_).            % succeed if no diagonals failed

queens([], [], Board, Board).                            % found a solution
queens([q(R)|Queens], Columns, Board, Solution) :-
	nth0(_,Columns,C,Free), can_place(q(R,C),Board), % find all solutions
	queens(Queens,Free,[q(R,C)|Board], Solution).    % recursively

queens :-
  findall(q(N), between(0,7,N), Queens), findall(N, between(0,7,N), Columns),
  findall(B, queens(Queens, Columns, [], B), Boards),     % backtrack over all
  length(Boards, Len), writef('%w solutions:\n', [Len]),  % Output solutions
  member(R,Boards), reverse(R,Board), writef('  - %w\n', [Board]), fail.
queens.

solve the N-Queens problem, extending the traditional eight queens puzzle to a board of size NxN. It uses backtracking, a highly efficient mechanism in Prolog, to find all solutions. The code utilizes non-ISO predicates between/3 and select/3, and the CLP(FD): Constraint Logic Programming over Finite Domain Library. The code runs in SWI-Prolog 7.2.3 and v8.0.2, providing the number of solutions for small values of N.


demonstrate how to concatenate two arrays.


Works with: SWI-Prolog
Using the clpfd library[edit]
Library: clpfd
:- use_module(library(clpfd)).

knapsack :-
        L = [
             item(map,  9,      150),
             item(compass,      13,     35),
             item(water,        153,    200),
             item(sandwich, 50,         160),
             item(glucose,      15,     60),
             item(tin,  68,     45),
             item(banana,       27,     60),
             item(apple,        39,     40),
             item(cheese,       23,     30),
             item(beer,         52,     10),
             item('suntan cream',       11,     70),
             item(camera,       32,     30),
             item('t-shirt',    24,     15),
             item(trousers, 48,         10),
             item(umbrella, 73,         40),
             item('waterproof trousers',        42,     70),
             item('waterproof overclothes',     43,     75),
             item('note-case',22,       80),
             item(sunglasses,   7,      20),
             item(towel,        18,     12),
             item(socks,        4,      50),
             item(book,         30,     10 )],
        length(L, N),
        length(R, N),
        R ins 0..1,
        maplist(arg(2), L, LW),
        maplist(arg(3), L, LV),
        scalar_product(LW, R, #=<, 400),
        scalar_product(LV, R, #=, VM),
        labeling([max(VM)], R),
        scalar_product(LW, R, #=, WM),
        %% affichage des résultats
        compute_lenword(L, 0, Len),
        sformat(A1, '~~w~~t~~~w|', [Len]),
        sformat(A2, '~~t~~w~~~w|', [4]),
        sformat(A3, '~~t~~w~~~w|', [5]),
        print_results(A1,A2,A3, L, R, WM, VM).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% to show the results in a good way
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
compute_lenword([], N, N).
compute_lenword([item(Name, _, _)|T], N, NF):-
        atom_length(Name, L),
        (   L > N -> N1 = L; N1 = N),
        compute_lenword(T, N1, NF).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
print_results(A1,A2,A3, [], [], WM, WR) :-
        sformat(W1, A1, [' ']),
        sformat(W2, A2, [WM]),
        sformat(W3, A3, [WR]),
        format('~w~w~w~n', [W1,W2,W3]).

print_results(A1,A2,A3, [_H|T], [0|TR], WM, VM) :-
        print_results(A1,A2,A3, T, TR, WM, VM).

print_results(A1, A2, A3, [item(Name, W, V)|T], [1|TR], WM, VM) :-
        sformat(W1, A1, [Name]),
        sformat(W2, A2, [W]),
        sformat(W3, A3, [V]),
        format('~w~w~w~n', [W1,W2,W3]),
        print_results(A1, A2, A3, T, TR, WM, VM).

The code determines the optimal combination of items, with a maximum weight of 4kg, that a tourist can carry in his knapsack for a trip to maximize the total value. The items, their weights, and their importance values are given in a list. The solution does not allow for fractional items. The code uses a library written by Markus Triska and solves the problem in about 3 seconds.


Works with: SWI-PrologLibrary: XPCE

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% facts
prefere(abe,[ abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay]).
prefere(  bob,[ cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay]).
prefere(  col,[ hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan]).
prefere(  dan,[ ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi]).
prefere(   ed,[ jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay]).
prefere( fred,[ bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay]).
prefere(  gav,[ gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay]).
prefere(  hal,[ abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee]).
prefere(  ian,[ hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve]).
prefere(  jon,[ abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope]).

prefere(  abi,[ bob, fred, jon, gav, ian, abe, dan, ed, col, hal]).
prefere(  bea,[ bob, abe, col, fred, gav, dan, ian, ed, jon, hal]).
prefere( cath,[ fred, bob, ed, gav, hal, col, ian, abe, dan, jon]).
prefere(  dee,[ fred, jon, col, abe, ian, hal, gav, dan, bob, ed]).
prefere(  eve,[ jon, hal, fred, dan, abe, gav, col, ed, ian, bob]).
prefere(  fay,[ bob, abe, ed, ian, jon, dan, fred, gav, col, hal]).
prefere(  gay,[ jon, gav, hal, fred, bob, abe, col, ed, dan, ian]).
prefere( hope,[ gav, jon, bob, abe, ian, dan, hal, ed, col, fred]).
prefere(  ivy,[ ian, col, hal, gav, fred, bob, abe, ed, jon, dan]).
prefere(  jan,[ ed, hal, gav, abe, bob, jon, col, ian, fred, dan]).

man(abe).
man(bob).
man(col).
man(dan).
man(ed).
man(fred).
man(gav).
man(hal).
man(ian).
man(jon).

woman(abi).
woman(bea).
woman(cath).
woman(dee).
woman(eve).
woman(fay).
woman(gay).
woman(hope).
woman(ivy).
woman(jan).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rules

stable_mariage :-
	new(LstMan, chain),
	forall(man(X),
	       (   prefere(X, Lst),
		   new(P, man(X, Lst)),
		   send(LstMan, append, P))),

	new(LstWoman, chain),
	forall(woman(X),
	       (   prefere(X, Lst),
		   new(P, woman(X, Lst)),
		   send(LstWoman, append, P))),
	send(LstMan, for_all, message(@arg1, init_liste, LstWoman)),
	send(LstWoman, for_all, message(@arg1, init_liste, LstMan)),

	round(LstMan, LstWoman),
	new(LstCouple, chain),
	% creation of the couple.
	send(LstWoman, for_all, and(message(@prolog, create_couple, @arg1, LstCouple),
				   message(@pce, write_ln, @arg1?name, with, @arg1?elu?name))),

	nl,

	% test of the stability of couples
	stability(LstCouple),
	nl,

	% Perturbation of couples
	get(LstCouple, size, Len),
	get_two_random_couples(Len, V1, V2),

	get(LstCouple, nth0, V1, C1),
	get(LstCouple, nth0, V2, C2),
	new(NC1, tuple(C1?first, C2?second)),
	new(NC2, tuple(C2?first, C1?second)),
	send(LstCouple, nth0, V1, NC1),
	send(LstCouple, nth0, V2, NC2),

	send(@pce, write_ln, 'perturbation of couples'),
	send(@pce, write_ln, NC1?second, with, NC1?first),
	send(@pce, write_ln, NC2?second, with, NC2?first),
	nl,

	stability(LstCouple).

get_two_random_couples(Len, C1, C2) :-
	C1 is random(Len),
	repeat,
	C2 is random(Len),
	C1 \= C2.

create_couple(Woman, LstCouple ) :-
	send(LstCouple, append, new(_, tuple(Woman?elu?name, Woman?name))).

% iterations of the algorithm
round(LstMan, LstWoman) :-
	send(LstMan, for_some, message(@arg1, propose)),
	send(LstWoman, for_some, message(@arg1, dispose)),
	(   \+send(LstWoman, for_all, @arg1?status == maybe)
	->
	    round(LstMan, LstWoman)
	;
	    true
	).

:-pce_begin_class(person, object, "description of a person").
variable(name, object, both, "name of the person").
variable(preference, chain, both, "list of priority").
variable(status, object, both, "statut of engagement : maybe / free").

initialise(P, Name, Pref) :->
	send(P, send_super, initialise),
	send(P, slot, name, Name),
	send(P, slot, preference, Pref),
	send(P, slot, status, free).

% reception of the list of partners
init_liste(P, Lst) :->
	% we replace the list of name of partners
	% with the list of persons partners.
	new(NLP, chain),
	get(P, slot, preference, LP),
	send(LP, for_all, message(@prolog, find_person,@arg1, Lst, NLP)),
	send(P, slot, preference, NLP).

:- pce_end_class(person).

find_person(Name, LstPerson, LstPref) :-
	get(LstPerson, find, @arg1?name == Name, Elem),
	send(LstPref, append, Elem).

:-pce_begin_class(man, person, "description of a man").

initialise(P, Name, Pref) :->
	send(P, send_super, initialise, Name, Pref).

% a man propose "la botte" to a woman
propose(P) :->
	get(P, slot, status, free),
	get(P, slot, preference, XPref),
	get(XPref, delete_head, Pref),
	send(P, slot, preference, XPref),
	send(Pref, proposition, P).

refuse(P) :->
	send(P, slot, status, free).

accept(P) :->
	send(P, slot, status, maybe).

:- pce_end_class(man).

:-pce_begin_class(woman, person, "description of a woman").
variable(elu, object, both, "name of the elu").
variable(contact, chain, both, "men that have contact this woman").

initialise(P, Name, Pref) :->
	send(P, send_super, initialise, Name, Pref),
	send(P, slot, contact, new(_, chain)),
	send(P, slot, elu, @nil).

% a woman decide Maybe/No
dispose(P) :->
	get(P, slot, contact, Contact),
	get(P, slot, elu, Elu),

	(   Elu \= @nil
	->
	    send(Contact, append, Elu)
	;
	    true),

	new(R, chain),
	send(Contact, for_all, message(P, fetch, @arg1, R)),
	send(R, sort, ?(@arg1?first, compare, @arg2?first)),
	get(R, delete_head, Tete),
	send(Tete?second, accept),
	send(P, slot, status, maybe),
	send(P, slot, elu, Tete?second),
	send(R, for_some, message(@arg1?second, refuse)),
	send(P, slot, contact, new(_, chain)) .

% looking for the person of the given name  Contact
% Adding it in the chain Chain
fetch(P, Contact, Chain) :->
	get(P, slot, preference, Lst),
	get(Lst, find, @arg1?name == Contact?name, Elem),
	get(Lst, index, Elem, Ind),
	send(Chain, append, new(_, tuple(Ind, Contact))).

% a woman receive a proposition from a man
proposition(P, Name) :->
	get(P, slot, contact, C),
	send(C, append, Name),
	send(P, slot, contact, C).

:- pce_end_class(woman).

% computation of the stability od couple
stability(LstCouple) :-
	chain_list(LstCouple, LstPceCouple),
	maplist(transform, LstPceCouple, PrologLstCouple),
	study_couples(PrologLstCouple, [], UnstableCouple),
	(   UnstableCouple = []
	->
	    writeln('Couples are stable')
	;
	    sort(UnstableCouple, SortUnstableCouple),
	    writeln('Unstable couples are'),
	    maplist(print_unstable_couple, SortUnstableCouple),
	    nl
	).

print_unstable_couple((C1, C2)) :-
	format('~w and ~w~n', [C1, C2]).

transform(PceCouple, couple(First, Second)):-
	get(PceCouple?first, value, First),
	get(PceCouple?second, value, Second).

study_couples([], UnstableCouple, UnstableCouple).

study_couples([H | T], CurrentUnstableCouple, UnstableCouple):-
	include(unstable_couple(H), T, Lst),
	(   Lst \= []
	->
	    maplist(build_one_couple(H), Lst, Lst1),
	    append(CurrentUnstableCouple, Lst1,CurrentUnstableCouple1)
	;
	    CurrentUnstableCouple1 = CurrentUnstableCouple
	),
	study_couples(T, CurrentUnstableCouple1, UnstableCouple).

build_one_couple(C1, C2, (C1, C2)).

unstable_couple(couple(X1, Y1), couple(X2, Y2)) :-
	prefere(X1, PX1),
	prefere(X2, PX2),
	prefere(Y1, PY1),
	prefere(Y2, PY2),

	% index of women for X1
	nth0(IY12, PX1, Y2),
	nth0(IY11, PX1, Y1),
	% index of men for Y2
	nth0(IX21, PY2, X1),
	nth0(IX22, PY2, X2),

	% index of women for X2
	nth0(IY21, PX2, Y1),
	nth0(IY22, PX2, Y2),
	% index of men for Y1
	nth0(IX11, PY1, X1),
	nth0(IX12, PY1, X2),

	% A couple is unstable
	( (IY12 < IY11 , IX21 < IX22);
	  (IY21 < IY22 , IX12 < IX11)).

The code uses the Gale-Shapley algorithm to solve the Stable Marriage Problem. It takes as input preferences of ten males and ten females for potential partners. It then generates a stable set of engagements where no individual prefers someone else over their current partner. The code also perturbs this stable set to create an unstable set and checks its stability.


short_circuit :-
	(   a_or_b(true, true) -> writeln('==> true'); writeln('==> false')) , nl,
	(   a_or_b(true, false)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_or_b(false, true)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_or_b(false, false)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_and_b(true, true)-> writeln('==> true'); writeln('==> false')) , nl,
	(   a_and_b(true, false)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_and_b(false, true)-> writeln('==>  true'); writeln('==> false')) , nl,
	(   a_and_b(false, false)-> writeln('==>  true'); writeln('==> false')) .

a_and_b(X, Y) :-
	format('a(~w) and b(~w)~n', [X, Y]),
	(   a(X), b(Y)).

a_or_b(X, Y) :-
	format('a(~w) or b(~w)~n', [X, Y]),
	(   a(X); b(Y)).

a(X) :-
	format('a(~w)~n', [X]),
	X.

b(X) :-
	format('b(~w)~n', [X]),
	X.

The code defines two functions, 'a' and 'b', which both take and return the same boolean value and print their names when called. The code then calculates the values of two equations, 'x' and 'y', using short-circuit evaluation to ensure that function 'b' is only called when necessary. In the case that the language does not support short-circuit evaluation, nested 'if' statements are used to achieve the same result. The code is tested with SWI-Prolog and should work with other dialects.


% convert text to morse
% query text2morse(Text, Morse)
% where
% Text is string to convert
% Morse is Morse representation
% There is a space between chars and double space between words
%
text2morse(Text, Morse) :-
	string_lower(Text, TextLower),			% rules are in lower case
	string_chars(TextLower, Chars),			% convert string into list of chars
	chars2morse(Chars, MorseChars),			% convert each char into morse
	string_chars(MorsePlusSpace, MorseChars),	% append returned string list into single string
	string_concat(Morse, ' ', MorsePlusSpace).	% Remove trailing space

chars2morse([], "").
chars2morse([H|CharTail], Morse) :-
	morse(H, M),
	chars2morse(CharTail, MorseTail),
	string_concat(M,' ', MorseSpace),
	string_concat(MorseSpace, MorseTail, Morse).

% space
morse(' ', " ").
% letters
morse('a', ".-").
morse('b', "-...").
morse('c', "-.-.").
morse('d', "-..").
morse('e', ".").
morse('f', "..-.").
morse('g', "--.").
morse('h', "....").
morse('i', "..").
morse('j', ".---").
morse('k', "-.-").
morse('l', ".-..").
morse('m', "--").
morse('n', "-.").
morse('o', "---").
morse('p', ".--.").
morse('q', "--.-").
morse('r', ".-.").
morse('s', "...").
morse('t', "-").
morse('u', "..-").
morse('v', "...-").
morse('w', ".--").
morse('x', "-..-").
morse('y', "-.--").
morse('z', "--..").
% numbers
morse('1', ".----").
morse('2', "..---").
morse('3', "...--").
morse('4', "....-").
morse('5', ".....").
morse('6', "-....").
morse('7', "--...").
morse('8', "---..").
morse('9', "----.").
morse('0', "-----").
% common punctuation
morse('.', ".-.-.-").
morse(',', "--..--").
morse('/', "-..-.").
morse('?', "..--..").
morse('=', "-...-").
morse('+', ".-.-.").
morse('-', "-....-").
morse('@', ".--.-.").

text2morse("Hello World", Morse).

The code converts a given string into audible Morse code and sends it to an audio device, such as a PC speaker. It either ignores or indicates unknown characters not included in the standard Morse code, possibly through a different pitch. The code is written in SWI Prolog, Edinburgh syntax.


Traditional[edit]

abc_problem :-
	maplist(abc_problem, ['', 'A', bark, bOOk, treAT, 'COmmon', sQuaD, 'CONFUSE']).

abc_problem(Word) :-
	L = [[b,o],[x,k],[d,q],[c,p],[n,a],[g,t],[r,e],[t,g],[q,d],[f,s],
	     [j,w],[h,u],[v,i],[a,n],[o,b],[e,r],[f,s],[l,y],[p,c],[z,m]],

	(   abc_problem(L, Word)
	->  format('~w OK~n', [Word])
	;   format('~w KO~n', [Word])).

abc_problem(L, Word) :-
	atom_chars(Word, C_Words),
	maplist(downcase_atom, C_Words, D_Words),
	can_makeword(L, D_Words).

can_makeword(_L, []).

can_makeword(L, [H | T]) :-
	(   select([H, _], L, L1); select([_, H], L, L1)),
	can_makeword(L1, T).

The code is a function that checks if a given word can be spelled using a specific collection of ABC blocks. Each block has two letters and can only be used once. The function is case-insensitive and tests the functionality with seven different words. The code uses the CHR library and a module for composing predicates in SWI-Prolog.


Works with: SWI Prolog
main:-
    sort_oid_list(["1.3.6.1.4.1.11.2.17.19.3.4.0.10",
    "1.3.6.1.4.1.11.2.17.5.2.0.79",
    "1.3.6.1.4.1.11.2.17.19.3.4.0.4",
    "1.3.6.1.4.1.11150.3.4.0.1",
    "1.3.6.1.4.1.11.2.17.19.3.4.0.1",
    "1.3.6.1.4.1.11150.3.4.0"], Sorted_list),
    foreach(member(oid(_, Oid), Sorted_list), writeln(Oid)).

sort_oid_list(Oid_list, Sorted_list):-
    parse_oid_list(Oid_list, Parsed),
    sort(1, @=<, Parsed, Sorted_list).

parse_oid_list([], []):-!.
parse_oid_list([Oid|Oid_list], [oid(Numbers, Oid)|Parsed]):-
    parse_oid(Oid, Numbers),
    parse_oid_list(Oid_list, Parsed).

parse_oid(Oid, Numbers):-
    split_string(Oid, ".", ".", Strings),
    number_strings(Numbers, Strings).

number_strings([], []):-!.
number_strings([Number|Numbers], [String|Strings]):-
    number_string(Number, String),
    number_strings(Numbers, Strings).

sort a list of Object Identifiers (OIDs) in their natural lexicographical order. The OIDs are strings of non-negative integers separated by dots.


start(Port) :- socket('AF_INET',Socket),
               socket_connect(Socket, 'AF_INET'(localhost,Port), Input, Output),
               write(Output, 'hello socket world'),
               flush_output(Output),
               close(Output),
               close(Input).

The code opens a socket to localhost on port 256, sends the message "hello socket world", and then closes the socket. It is compatible with Gnu Prolog and does not handle any exceptions or errors.


o(O) :- member(O, [0,1,2,3,4,5,6,7]).

octal([O]) :- o(O).
octal([A|B]) :-
	octal(O),
	o(T),
	append(O, [T], [A|B]),
	dif(A, 0).

octalize :-
	forall(
		octal(X),
		(maplist(write, X), nl)
	).

generate a sequence of octal numbers, starting from zero and incrementing by one each time. The sequence continues until the program is terminated or the maximum value of the numeric type in use is reached. Each octal number is printed on a separate line. The code also includes a function to validate if a number is a valid octal number.


implement a generic swap function or operator that can interchange the values of two variables or storage places, regardless of their types. The function is designed to work with both statically and dynamically typed languages, with certain limitations based on language semantics and support for parametric polymorphism.


palindrome(Word) :- name(Word,List), reverse(List,List).

Works with: SWI Prolog
pali(Str) :- sub_string(Str, 0, 1, _, X), string_concat(Str2, X, Str), string_concat(X, Mid, Str2), pali(Mid).
pali(Str) :- string_length(Str, Len), Len < 2.

Works with: GNU Prolog
pali(Str) :- sub_atom(Str, 0, 1, _, X), atom_concat(Str2, X, Str), atom_concat(X, Mid, Str2), pali(Mid).
pali(Str) :- atom_length(Str, Len), Len < 2.

The code includes a function to check if a given sequence of characters is a palindrome. It supports Unicode characters and has an additional function to detect inexact palindromes, ignoring white-space, punctuation and case differences. It uses string reversal and can be tested using the 'Test a function' task. The code can also run on GNU Prolog when the string is changed into an atom.


demonstrate how to retrieve a specific environment variable from the process's environment in SWI-Prolog using the built-in function getenv. The variables that can be accessed may differ based on the system, but commonly include PATH, HOME, and USER on Unix systems.


int fib(int n) {
  if (n==0 || n==1) {
    return n;
  }
  var prev=1;
  var current=1;
  for (var i=2; i<n; i++) {
    var next = prev + current;
    prev = current;
    current = next;
  }
  return current;
}

int fibRec(int n) => n==0 || n==1 ? n : fibRec(n-1) + fibRec(n-2);

main() {
  print(fib(11));
  print(fibRec(11));
}

generate the nth Fibonacci number, using either an iterative or recursive approach. The function also has an optional feature to support negative Fibonacci sequences.


String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);

import 'package:unittest/unittest.dart';

String reverse(String s) => new String.fromCharCodes(s.runes.toList().reversed);

main() {
  group("Reverse a string -", () {
    test("Strings with ASCII characters are reversed correctly.", () {
      expect(reverse("hello, world"), equals("dlrow ,olleh"));
    });
    test("Strings with non-ASCII BMP characters are reversed correctly.", () {
      expect(reverse("\u4F60\u4EEC\u597D"), equals("\u597D\u4EEC\u4F60"));
    });
    test("Strings with non-BMP characters are reversed correctly.", () {
      expect(reverse("hello, \u{1F310}"), equals("\u{1F310} ,olleh"));
    });
  });
}

are designed to reverse a given string, including handling Unicode combining characters and UTF-16 surrogate pairs. The Dart language's "runes" feature is utilized to convert strings into sequences of Unicode code points, which can then be easily reversed to create new strings.


void main(){
  //Set Creation
  Set A = new Set.from([1,2,3]);
  Set B = new Set.from([1,2,3,4,5]);
  Set C = new Set.from([1,2,4,5]);

  print('Set A = $A');
  print('Set B = $B');
  print('Set C = $C');
  print('');
  //Test if element is in set
  int m = 3;
  print('m = 5');
  print('m in A = ${A.contains(m)}');
  print('m in B = ${B.contains(m)}');
  print('m in C = ${C.contains(m)}');
  print('');
  //Union of two sets
  Set AC = A.union(C);
  print('Set AC = Union of A and C = $AC');
  print('');
  //Intersection of two sets
  Set A_C = A.intersection(C);
  print('Set A_C = Intersection of A and C = $A_C');
  print('');
  //Difference of two sets
  Set A_diff_C = A.difference(C);
  print('Set A_diff_C = Difference between A and C = $A_diff_C');
  print('');
  //Test if set is subset of another set
  print('A is a subset of B = ${B.containsAll(A)}');
  print('C is a subset of B = ${B.containsAll(C)}');
  print('A is a subset of C = ${C.containsAll(A)}');
  print('');
  //Test if two sets are equal
  print('A is equal to B  = ${B.containsAll(A) && A.containsAll(B)}');
  print('B is equal to AC = ${B.containsAll(AC) && AC.containsAll(B)}');
}

demonstrate various set operations such as creation, checking if an element is present in a set, union, intersection, difference, subset and equality of sets. The code also optionally shows other set operations and methods to modify a mutable set. It may implement a set using an associative array, binary search tree, hash table, or an ordered array of binary bits. The code also discusses the time complexity of the basic test operation in different scenarios.


quickSort(List a) {
  if (a.length <= 1) {
    return a;
  }

  var pivot = a[0];
  var less = [];
  var more = [];
  var pivotList = [];

  // Partition
  a.forEach((var i){
    if (i.compareTo(pivot) < 0) {
      less.add(i);
    } else if (i.compareTo(pivot) > 0) {
      more.add(i);
    } else {
      pivotList.add(i);
    }
  });

  // Recursively sort sublists
  less = quickSort(less);
  more = quickSort(more);

  // Concatenate results
  less.addAll(pivotList);
  less.addAll(more);
  return less;
}

void main() {
  var arr=[1,5,2,7,3,9,4,6,8];
  print("Before sort");
  arr.forEach((var i)=>print("$i"));
  arr = quickSort(arr);
  print("After sort");
  arr.forEach((var i)=>print("$i"));
}

implement the Quicksort algorithm to sort an array or list of elements. The algorithm works by choosing a pivot element and dividing the rest of the elements into two partitions - one with elements less than the pivot and the other with elements greater than the pivot. It then recursively sorts these partitions and joins them with the pivot to get the sorted array. The codes also include an optimized version of Quicksort that works in place by swapping elements within the array to avoid memory allocation of more arrays. The pivot selection method is not specified.


main(){
	// Dart uses Lists which dynamically resize by default
	final growable = [ 1, 2, 3 ];

        // Add to the list using the add method
	growable.add(4);

	print('growable: $growable');

	// You can pass an int to the constructor to create a fixed sized List
	final fixed = List(3);

	// We must assign each element individually using the Subscript operator
	// using .add would through an error
	fixed[0] = 'one';
	fixed[1] = 'two';
	fixed[2] = 'three';

	print('fixed: $fixed');

	// If we want to create a fixed list all at once we can use the of constructor
	// Setting growable to false is what makes it fixed
	final fixed2 = List.of( [ 1.5, 2.5, 3.5 ], growable: false);

	print('fixed2: $fixed2');

	// A potential gotcha involving the subscript operator [] might surprise JavaScripters
	// One cannot add new elements to a List using the subscript operator
	// We can only assign to existing elements, even if the List is growable

	final gotcha = [ 1, 2 ];
	// gotcha[2] = 3 would cause an error in Dart, but not in JavaScript
	// We must first add the new element using .add
	gotcha.add(3);
	// Now we can modify the existing elements with the subscript
	gotcha[2] = 4;

	print('gotcha: $gotcha');

}

demonstrate the basic syntax of arrays in the specific programming language, including creating an array, assigning a value to it, and retrieving an element. It also showcases the use of both fixed-length and dynamic arrays, and includes the functionality of pushing a value into the array.


String capitalize(String string) {
  if (string.isEmpty) {
    return string;
  }
  return string[0].toUpperCase() + string.substring(1);
}

void main() {
  var s = 'alphaBETA';
  print('Original string: $s');
  print('To Lower case:   ${s.toLowerCase()}');
  print('To Upper case:   ${s.toUpperCase()}');
  print('To Capitalize:   ${capitalize(s)}');
}

demonstrate the conversion of the string "alphaBETA" to upper-case and lower-case using the default string literal or ASCII encoding. The code also showcases additional case conversion functions such as swapping case or capitalizing the first letter if available in the language's library. Note that in some languages, the toLower and toUpper functions may not be reversible.


String loopPlusHalf(start, end) {
  var result = '';
  for(int i = start; i <= end; i++) {
    result += '$i';
    if(i == end) {
      break;
    }
    result += ', ';
  }
  return result;
}

void main() {
  print(loopPlusHalf(1, 10));
}

The code writes a comma-separated list from 1 to 10, using separate output statements for the number and the comma within a loop. The loop executes a partial body in its last iteration.


import 'dart:math';

factors(n)
{
 var factorsArr = [];
 factorsArr.add(n);
 factorsArr.add(1);
 for(var test = n - 1; test >= sqrt(n).toInt(); test--)
  if(n % test == 0)
  {
   factorsArr.add(test);
   factorsArr.add(n / test);
  }
 return factorsArr;
}

void main() {
  print(factors(5688));
}

compute the factors of a given positive integer, excluding zero and negative numbers. The factors are the positive integers that can divide the input number to yield a positive integer. For prime numbers, the factors are 1 and the number itself.


demonstrate how to use nested for loops to print a specific pattern. The number of iterations in the inner loop is controlled by the outer loop, resulting in a pattern of increasing asterisks.


main() {
	var rosettaCode = { // Type is inferred to be Map<String, String>
		'task': 'Associative Array Creation'
	};

	rosettaCode['language'] = 'Dart';

	// The update function can be used to update a key using a callback
	rosettaCode.update( 'is fun',  // Key to update
		(value) => "i don't know", // New value to use if key is present
		ifAbsent: () => 'yes!' // Value to use if key is absent
	);

	assert( rosettaCode.toString() == '{task: Associative Array Creation, language: Dart, is fun: yes!}');

	// If we type the Map with dynamic keys and values, it is like a JavaScript object
	Map<dynamic, dynamic> jsObject = {
		'key': 'value',
		1: 2,
		1.5: [ 'more', 'stuff' ],
		#doStuff: () => print('doing stuff!') // #doStuff is a symbol, only one instance of this exists in the program. Would be :doStuff in Ruby
	};

	print( jsObject['key'] );
	print( jsObject[1] );

	for ( var value in jsObject[1.5] )
		print('item: $value');

	jsObject[ #doStuff ](); // Calling the function

	print('\nKey types:');
	jsObject.keys.forEach( (key) => print( key.runtimeType ) );
}

"Create an associative array, also known as a dictionary, map, or hash."


Recursive[edit]
int fact(int n) {
  if(n<0) {
    throw new IllegalArgumentException('Argument less than 0');
  }
  return n==0 ? 1 : n*fact(n-1);
}

main() {
  print(fact(10));
  print(fact(-1));
}
Iterative[edit]
int fact(int n) {
  if(n<0) {
    throw new IllegalArgumentException('Argument less than 0');
  }
  int res=1;
  for(int i=1;i<=n;i++) {
    res*=i;
  }
  return res;
}

main() {
  print(fact(10));
  print(fact(-1));
}

The code defines a function that calculates the factorial of a given number. The factorial is the product of all positive integers from the given number down to 1. The function can be implemented either iteratively or recursively. It optionally includes error handling for negative input numbers. It is related to the task of generating primorial numbers.


num dot(List<num> A, List<num> B){
  if (A.length != B.length){
    throw new Exception('Vectors must be of equal size');
  }
  num result = 0;
  for (int i = 0; i < A.length; i++){
    result += A[i] * B[i];
  }
  return result;
}

void main(){
  var l = [1,3,-5];
  var k = [4,-2,-1];
  print(dot(l,k));
}

Implement a function to calculate the dot product of two vectors of arbitrary length. The function multiplies corresponding elements from each vector and sums the products. The vectors must be of the same length. Example vectors used are [1, 3, -5] and [4, -2, -1].


Translation of: Kotlin
import 'dart:math';
import 'dart:io';

main() {
  final n = (1 + new Random().nextInt(10)).toString();
  print("Guess which number I've chosen in the range 1 to 10");
  do { stdout.write(" Your guess : "); } while (n != stdin.readLineSync());
  print("\nWell guessed!");
}

"Implement a number guessing game where the computer selects a number between 1 and 10. The player is repeatedly prompted to guess the number until the correct number is guessed, upon which a 'Well guessed!' message is displayed and the program terminates. A conditional loop is used to facilitate repeated guessing."


String binary(int n) {
  if(n<0)
    throw new IllegalArgumentException("negative numbers require 2s complement");
  if(n==0) return "0";
  String res="";
  while(n>0) {
    res=(n%2).toString()+res;
    n=(n/2).toInt();
  }
  return res;
}

main() {
  print(binary(0));
  print(binary(1));
  print(binary(5));
  print(binary(10));
  print(binary(50));
  print(binary(9000));
  print(binary(65535));
  print(binary(0xaa5511ff));
  print(binary(0x123456789abcde));
  // fails due to precision limit
  print(binary(0x123456789abcdef));
}

generate a sequence of binary digits for a given non-negative integer. The output displays only the binary digits of each number, followed by a newline, without any whitespace, radix, sign markers, or leading zeros. The conversion can be achieved using built-in radix functions or a user-defined function.


Translation of: Java
import 'dart:math';

class Haversine {
  static final R = 6372.8; // In kilometers

  static double haversine(double lat1, lon1, lat2, lon2) {
    double dLat = _toRadians(lat2 - lat1);
    double dLon = _toRadians(lon2 - lon1);
    lat1 = _toRadians(lat1);
    lat2 = _toRadians(lat2);
    double a = pow(sin(dLat / 2), 2) + pow(sin(dLon / 2), 2) * cos(lat1) * cos(lat2);
    double c = 2 * asin(sqrt(a));
    return R * c;
  }

  static double _toRadians(double degree) {
    return degree * pi / 180;
  }

  static void main() {
    print(haversine(36.12, -86.67, 33.94, -118.40));
  }
}

Implement a function to calculate the great-circle distance between two points on a sphere using the Haversine formula. The function takes the coordinates of Nashville International Airport (BNA) and Los Angeles International Airport (LAX) as input and returns the distance between them. The calculation uses the recommended earth radius of 6372.8 km or 6371 km, depending on the level of precision required.


import 'dart:io';
void main(){
  var url = 'http://rosettacode.org';
  var client = new HttpClient();
  client.getUrl(Uri.parse(url))
        .then((HttpClientRequest request)   => request.close())
        .then((HttpClientResponse response) => response.pipe(stdout));
}

"Code accesses and prints the content of a specified URL to the console using a stand-alone VM. Note: This does not cover HTTPS requests."


RegExp regexp = new RegExp(r'\w+\!');

String capitalize(Match m) => '${m[0].substring(0, m[0].length-1).toUpperCase()}';

void main(){
  String hello = 'hello hello! world world!';
  String hellomodified = hello.replaceAllMapped(regexp, capitalize);
  print(hello);
  print(hellomodified);
}

"Matches a string with a regular expression and performs substitution on a part of the string using the same regular expression."


main() {
  moveit(from,to) {
    print("move ${from} ---> ${to}");
  }

  hanoi(height,toPole,fromPole,usePole) {
    if (height>0) {
      hanoi(height-1,usePole,fromPole,toPole);
      moveit(fromPole,toPole);
      hanoi(height-1,toPole,usePole,fromPole);
    }
  }

  hanoi(3,3,1,2);
}

main() {
  String say(String from, String to) => "$from ---> $to";

  hanoi(int height, int toPole, int fromPole, int usePole) {
    if (height > 0) {
      hanoi(height - 1, usePole, fromPole, toPole);
      print(say(fromPole.toString(), toPole.toString()));
      hanoi(height - 1, toPole, usePole, fromPole);
    }
  }

  hanoi(3, 3, 1, 2);
}

implement a recursive solution to solve the Towers of Hanoi problem, adhering to the style guide provided by dartlang.org and optionally including static type annotations.


void main() {
    List<int> a = shellSort([1100, 2, 56, 200, -52, 3, 99, 33, 177, -199]);
    print('$a');
}

shellSort(List<int> array) {
	int n = array.length;

        // Start with a big gap, then reduce the gap
        for (int gap = n~/2; gap > 0; gap ~/= 2)
        {
            // Do a gapped insertion sort for this gap size.
            // The first gap elements a[0..gap-1] are already
            // in gapped order keep adding one more element
            // until the entire array is gap sorted
            for (int i = gap; i < n; i += 1)
            {
                // add a[i] to the elements that have been gap
                // sorted save a[i] in temp and make a hole at
                // position i
                int temp = array[i];

                // shift earlier gap-sorted elements up until
                // the correct location for a[i] is found
                int j;
                for (j = i; j >= gap && array[j - gap] > temp; j -= gap)
                    array[j] = array[j - gap];

                // put temp (the original a[i]) in its correct
                // location
                array[j] = temp;
            }
        }
  return array;
}

implement the Shell sort algorithm to sort an array of elements. The algorithm, invented by Donald Shell in 1959, uses a diminishing increment sequence for interleaved insertion sorts. The increment size reduces with each pass until it reaches 1, turning the sort into a basic insertion sort. The data is almost sorted at this point, which is the best case scenario for insertion sort. The algorithm works with any sequence that ends in 1, but sequences with a geometric increment ratio of about 2.2 have been found to be most effective.


Flutter[edit]
Library: Flutter

import 'package:flutter/material.dart';
import 'dart:async' show Timer;

void main() {

  var timer = const Duration( milliseconds: 75 ); // How often to update i.e. how fast the animation is

  runApp(MaterialApp (
    home: Scaffold (
      body: Center (
        child: AnimatedText( timer )
      )
    )
  ));
}

class AnimatedText extends StatefulWidget {

  final Duration period; // Time period for update

  AnimatedText( this.period );
  @override
  _AnimatedText createState() => _AnimatedText( period );
}

class _AnimatedText extends State<AnimatedText> {

  bool forward = true; // Text should go forward?

  Timer timer; // Timer Objects allow us to do things based on a period of time
  // We want to get an array of characters, but Dart does not have a char type
  // Below is the equivalent code
  var _text =  'Hello World!      '.runes // .runes gives us the unicode number of each character
    .map( (code) => String.fromCharCode(code) ) // Map all these codes to Strings containing the single character
    .toList(); // Conver to a List

  _AnimatedText( Duration period ){
    timer = Timer.periodic( period , (_){
      setState((){ // Set state forces the gui elements to be redrawn
        shiftText();

      });
    });
  }

  String get text => _text.join(''); // Getter, joins the list of chars into a string

  void shiftText() {
    if (forward) { // If we should go forward
      var last = _text.removeLast(); // Remove the last char

      _text.insert( 0, last); // Insert it at the front

    } else { // If we should go backward
      var first = _text.removeAt(0); // Remove the first char

      _text.insert( _text.length, first ); // Insert it at the end
    }

 }

  @override
  Widget build(BuildContext context) {
    return GestureDetector( // GestureDetector lets us capture events
      onTap: () => forward = !forward, // on Tap (Click in browser) invert the forward bool
      child: Text(
        text, // Call the text getter to get the shifted string
        style: TextStyle( // Styling
          fontSize: 50,
          color: Colors.grey[600]
        )
      )

    );
  }

}

HTML DOM[edit]
Library: Html Dom
import 'dart:html';
import 'dart:async';

const frameTime = const Duration(milliseconds: 100);

void main() {
  String text = "Hello World! ";
  bool rotateRight = true;

  Element writeHere =
      querySelector('#output'); // assumes you have a pre with that ID
  writeHere.onClick.listen((event) => rotateRight = !rotateRight);

  new Timer.periodic(frameTime, (_) {
    text = changeText(text, rotateRight);
    writeHere.text = text;
  });
}

String changeText(extt, rotateRight) {
  if (rotateRight) {
    return extt.substring(extt.length - 1) + extt.substring(0, extt.length - 1);
  } else {
    return extt.substring(1) + extt.substring(0, 1);
  }
}

Creates an animated GUI window displaying the text "Hello World!". The text appears to rotate right by periodically shifting the last letter to the front. The direction of rotation reverses when the user clicks on the text.


void main() {
  int val = 0;
  do {
    val++;
    print(val);
  } while (val % 6 != 0);
}

The code initializes a value to 0, then enters a do-while loop where it increments the value by 1 and prints it, continuing as long as the value modulo 6 is not 0. The loop is guaranteed to execute at least once.


void main() {
  String word = "Premier League";
  print("Without first letter: ${word.substring(1)} !");
  print("Without last letter: ${word.substring(0, word.length - 1)} !");
  print("Without first and last letter: ${word.substring(1, word.length - 1)} !");
}

The code demonstrates how to remove the first, last, and both the first and last characters from a string. It works with any valid Unicode code point in UTF-8 or UTF-16, referencing logical characters, not code units. It doesn't necessarily support all Unicode characters for other encodings like 8-bit ASCII or EUC-JP.


import 'dart:io';

void main() {
  stdout.write("Goodbye, World!");
}

"Display the string 'Goodbye, World!' without appending a newline at the end."


Library: Flutter

import 'package:flutter/material.dart';

main() => runApp( OutputLabel() );

class OutputLabel extends StatefulWidget {
  @override
  _OutputLabelState createState() => _OutputLabelState();
}

class _OutputLabelState extends State<OutputLabel> {
  String output = "output"; // This will be displayed in an output text field

  TextEditingController _stringInputController = TextEditingController(); // Allows us to get the text from a text field
  TextEditingController _numberInputController = TextEditingController();

  @override
  Widget build( BuildContext context ) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // Disable debug banner in top right
      home: Scaffold ( // Scaffold provides a layout for the app
        body: Center ( // Everything in the center widget will be centered
          child: Column ( // All the widgets will be in a column
            children: <Widget> [
              SizedBox( height: 25 ), // Space between top and text field

              TextField ( // String input Text Field
                controller: _stringInputController, // Add input controller so we can grab text
                textAlign: TextAlign.center, // Center text
                decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Enter a string...'), // Border and default text
              ), // end TextField

              SizedBox( height: 10 ), // Space between text fields

              TextField ( // Number input Text Field
                controller: _numberInputController, // Add input controller so we can grab text
                textAlign: TextAlign.center, // Center text
                decoration: InputDecoration( border: OutlineInputBorder(), labelText: 'Enter 75000'), // Border and default text
              ), // end TextField

              FlatButton ( // Submit Button
                child: Text('Submit Data'), // Button Text
                color: Colors.blue[400] // button color
                onPressed: () { // On pressed Callback for button
                  setState( () {
                    output = ''; // Reset output

                    int number; // Int to store number in

                    var stringInput = _stringInputController.text ?? ''; // Get the input from the first field, if it is null set it to an empty string

                    var numberString = _numberInputController.text ?? ''; // Get the input from the second field, if it is null set it to an empty string

                    if ( stringInput == '')  { // If first field is empty
                      output = 'Please enter something in field 1\n';
                      return;
                    }

                    if (_numberInputController.text == '') { // If second field is empty
                      output += 'Please enter something in field 2';
                      return;
                    } else { // If we got an input in the second field

                      try {
                        number = int.parse( numberString ); // Parse numberString into an int

                        if ( number == 75000 )
                          output = 'text output: $stringInput\nnumber: $number'; // Grabs the text from the input controllers and changes the string
                        else
                          output = '$number is not 75000!';

                      } on FormatException { // If a number is not entered in second field
                          output = '$numberString is not a number!';
                      }

                    }

                  });
                }
              ), // End FlatButton

              Text( output ) // displays output

            ]
          )
        )
      )
    );
  }
}

The code enables the input of a string and the integer 75000 via a graphical user interface. It features two text fields, a button, and an output label. The code can be viewed on Dartpad.


class Caesar {
  int _key;

  Caesar(this._key);

  int _toCharCode(String s) {
    return s.charCodeAt(0);
  }

  String _fromCharCode(int ch) {
    return new String.fromCharCodes([ch]);
  }

  String _process(String msg, int offset) {
    StringBuffer sb=new StringBuffer();
    for(int i=0;i<msg.length;i++) {
      int ch=msg.charCodeAt(i);
      if(ch>=_toCharCode('A')&&ch<=_toCharCode('Z')) {
        sb.add(_fromCharCode(_toCharCode("A")+(ch-_toCharCode("A")+offset)%26));
      }
      else if(ch>=_toCharCode('a')&&ch<=_toCharCode('z')) {
        sb.add(_fromCharCode(_toCharCode("a")+(ch-_toCharCode("a")+offset)%26));
      } else {
        sb.add(msg[i]);
      }
    }
    return sb.toString();
  }

  String encrypt(String msg) {
    return _process(msg, _key);
  }

  String decrypt(String msg) {
    return _process(msg, 26-_key);
   }
}

void trip(String msg) {
  Caesar cipher=new Caesar(10);

  String enc=cipher.encrypt(msg);
  String dec=cipher.decrypt(enc);
  print("\"$msg\" encrypts to:");
  print("\"$enc\" decrypts to:");
  print("\"$dec\"");
  Expect.equals(msg,dec);
}

main() {
  Caesar c2=new Caesar(2);
  print(c2.encrypt("HI"));
  Caesar c20=new Caesar(20);
  print(c20.encrypt("HI"));

  // try a few roundtrips

  trip("");
  trip("A");
  trip("z");
  trip("Caesar cipher");
  trip(".-:/\"\\!");
  trip("The Quick Brown Fox Jumps Over The Lazy Dog.");
}

implement both encoding and decoding functions of a Caesar cipher. The cipher rotates the alphabet letters based on a key ranging from 1 to 25, replacing each letter with the corresponding next letter in the alphabet. The codes also handle cases of wrapping from Z to A. The codes illustrate that Caesar cipher provides minimal security as it is vulnerable to frequency analysis and brute force attacks. The codes also demonstrate that Caesar cipher is identical to Vigenère cipher with a key length of 1 and to Rot-13 with a key of 13.


main() {
	int x=8;
  int y=12;
int z= gcd(x,y);
  var lcm=(x*y)/z;
  print('$lcm');
  }

int gcd(int a,int b)
{
  if(b==0)
    return a;
  if(b!=0)
    return gcd(b,a%b);
}

calculate the least common multiple (LCM) of two integers m and n. The LCM is the smallest positive integer that has both m and n as factors. If either m or n is zero, the LCM is zero. The LCM can be calculated by iterating all the multiples of m until finding one that is also a multiple of n, or by using the formula lcm(m, n) = |m × n| / gcd(m, n), where gcd is the greatest common divisor. The LCM can also be found by merging the prime decompositions of both m and n.


main() {
  for (int i = 1; i <= 100; i++) {
    List<String> out = [];
    if (i % 3 == 0)
      out.add("Fizz");
    if (i % 5 == 0)
      out.add("Buzz");
    print(out.length > 0 ? out.join("") : i);
  }
}

print numbers from 1 to 100, replacing multiples of three with 'Fizz', multiples of five with 'Buzz', and multiples of both three and five with 'FizzBuzz'.


class Complex {
  double _r,_i;

  Complex(this._r,this._i);
  double get r => _r;
  double get i => _i;
  String toString() => "($r,$i)";

  Complex operator +(Complex other) => new Complex(r+other.r,i+other.i);
  Complex operator *(Complex other) =>
      new Complex(r*other.r-i*other.i,r*other.i+other.r*i);
  double abs() => r*r+i*i;
}

void main() {
  double start_x=-1.5;
  double start_y=-1.0;
  double step_x=0.03;
  double step_y=0.1;

  for(int y=0;y<20;y++) {
    String line="";
    for(int x=0;x<70;x++) {
      Complex c=new Complex(start_x+step_x*x,start_y+step_y*y);
      Complex z=new Complex(0.0, 0.0);
      for(int i=0;i<100;i++) {
        z=z*(z)+c;
        if(z.abs()>2) {
          break;
        }
      }
      line+=z.abs()>2 ? " " : "*";
    }
    print(line);
  }
}

generate and draw the Mandelbrot set using various algorithms and functions. The code is implemented in Google Dart and operates on http://try.dartlang.org/. It utilizes an incomplete Complex class that supports operator overloading. Note that due to the novelty of the language, the code may become obsolete in the future.


class Leap {
  bool leapYear(num year) {
    return (year % 400 == 0) || (( year % 100 != 0) && (year % 4 == 0));

  bool isLeapYear(int year) =>
    (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
  // Source: https://api.flutter.dev/flutter/quiver.time/isLeapYear.html
  }
}

"Determines if a specified year is a leap year in the Gregorian calendar."


implement two mutually recursive functions to compute the Hofstadter Female and Male sequences. If the programming language does not support mutual recursion, it should be stated.


Translation of: C
import 'dart:math';

void main() {
  final array = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
  int i;

  for (i = 1; i < 30; i++) {
    var intValue = Random().nextInt(i) % 10;
    print(array[intValue]);
  }
}

demonstrate how to select a random element from a list.


main(List<String> args) {
    for(var arg in args)
        print(arg);
}

The code retrieves and prints the list of command-line arguments provided to the program, such as 'myprogram -c "alpha beta" -h "gamma"'. It also includes functionalities for intelligent parsing of these arguments.


import 'dart:convert' show jsonDecode, jsonEncode;

main(){
	var json_string = '''
	{
		"rosetta_code": {
			"task": "json",
			"language": "dart",
			"descriptions": [ "fun!", "easy to learn!", "awesome!" ]
		}
	}
	''';

	// decode string into Map<String, dynamic>
	var json_object = jsonDecode(json_string);

	for ( var description in json_object["rosetta_code"]["descriptions"] )
		print( "dart is $description" );

	var dart = {
		"compiled": true,
		"interpreted": true,
		"creator(s)":[ "Lars Bak", "Kasper Lund"],
		"development company": "Google"
	};

	var as_json_text = jsonEncode(dart);

	assert(as_json_text == '{"compiled":true,"interpreted":true,"creator(s)":["Lars Bak","Kasper Lund"],"development company":"Google"}');
}

"Load a JSON string into a data structure, create a new data structure, serialize it into JSON, and validate the JSON."


void main() {
  for (var i = 10; i >= 0; --i) {
    print(i);
  }
}

The code performs a countdown from 10 to 0 using a downward for loop.


demonstrate a for-loop with a step-value greater than one.


Implement the Ackermann function, a non-primitive recursive function that takes two non-negative arguments and returns a rapidly growing value. The function should ideally support arbitrary precision due to its fast growth rate, but it's not mandatory. The function does not utilize caching, resulting in longer execution times for larger inputs.


/**
Return true if queen placement q[n] does not conflict with
other queens q[0] through q[n-1]
*/
isConsistent(List q, int n) {
  for (int i=0; i<n; i++) {
    if (q[i] == q[n]) {
      return false; // Same column
    }

    if ((q[i] - q[n]) == (n - i)) {
      return false; // Same major diagonal
    }

    if ((q[n] - q[i]) == (n - i)) {
      return false; // Same minor diagonal
    }
  }

  return true;
}

/**
Print out N-by-N placement of queens from permutation q in ASCII.
*/
printQueens(List q) {
  int N = q.length;
  for (int i=0; i<N; i++) {
    StringBuffer sb = new StringBuffer();
    for (int j=0; j<N; j++) {
      if (q[i] == j) {
        sb.write("Q ");
      } else {
        sb.write("* ");
      }
    }
    print(sb.toString());
  }
  print("");
}

/**
Try all permutations using backtracking
*/
enumerate(int N) {
  var a = new List(N);
  _enumerate(a, 0);
}

_enumerate(List q, int n) {
  if (n == q.length) {
    printQueens(q);
  } else {
    for (int i = 0; i < q.length; i++) {
      q[n] = i;
      if (isConsistent(q, n)){
        _enumerate(q, n+1);
      }
    }
  }
}

void main() {
  enumerate(4);
}

"Solve the N-queens problem for an NxN board and provide the number of solutions for small values of N."


List solveKnapsack(items, maxWeight) {
  int MIN_VALUE=-100;
  int N = items.length; // number of items
  int W = maxWeight; // maximum weight of knapsack

  List profit = new List(N+1);
  List weight = new List(N+1);

  // generate random instance, items 1..N
  for(int n = 1; n<=N; n++) {
    profit[n] = items[n-1][2];
    weight[n] = items[n-1][1];

  }

  // opt[n][w] = max profit of packing items 1..n with weight limit w
  // sol[n][w] = does opt solution to pack items 1..n with weight limit w include item n?
  List<List<int>> opt = new List<List<int>>(N+1);
  for (int i=0; i<N+1; i++) {
    opt[i] = new List<int>(W+1);
    for(int j=0; j<W+1; j++) {
      opt[i][j] = MIN_VALUE;
    }
  }

  List<List<bool>> sol = new List<List<bool>>(N+1);
  for (int i=0; i<N+1; i++) {
    sol[i] = new List<bool>(W+1);
    for(int j=0; j<W+1; j++) {
      sol[i][j] = false;
    }
  }

  for(int n=1; n<=N; n++) {
    for (int w=1; w <= W; w++) {
      // don't take item n
      int option1 = opt[n-1][w];

      // take item n
      int option2 = MIN_VALUE;
      if (weight[n] <= w) {
        option2 = profit[n] + opt[n-1][w - weight[n]];
      }

      // select better of two options
      opt[n][w] = Math.max(option1, option2);
      sol[n][w] = (option2 > option1);
    }
  }

  // determine which items to take
  List<List> packItems = new List<List>();
  List<bool> take = new List(N+1);
  for (int n = N, w = W; n > 0; n--) {
    if (sol[n][w]) {
      take[n] = true;
      w = w - weight[n];
      packItems.add(items[n-1]);
    } else {
      take[n] = false;
    }
  }

  return packItems;

}

main() {
  List knapsackItems = [];
  knapsackItems.add(["map", 9, 150]);
  knapsackItems.add(["compass", 13, 35]);
  knapsackItems.add(["water", 153, 200]);
  knapsackItems.add(["sandwich", 50, 160]);
  knapsackItems.add(["glucose", 15, 60]);
  knapsackItems.add(["tin", 68, 45]);
  knapsackItems.add(["banana", 27, 60]);
  knapsackItems.add(["apple", 39, 40]);
  knapsackItems.add(["cheese", 23, 30]);
  knapsackItems.add(["beer", 52, 10]);
  knapsackItems.add(["suntan cream", 11, 70]);
  knapsackItems.add(["camera", 32, 30]);
  knapsackItems.add(["t-shirt", 24, 15]);
  knapsackItems.add(["trousers", 48, 10]);
  knapsackItems.add(["umbrella", 73, 40]);
  knapsackItems.add(["waterproof trousers", 42, 70]);
  knapsackItems.add(["waterproof overclothes", 43, 75]);
  knapsackItems.add(["note-case", 22, 80]);
  knapsackItems.add(["sunglasses", 7, 20]);
  knapsackItems.add(["towel", 18, 12]);
  knapsackItems.add(["socks", 4, 50]);
  knapsackItems.add(["book", 30, 10]);
  int maxWeight = 400;
  Stopwatch sw = new Stopwatch.start();
  List p = solveKnapsack(knapsackItems, maxWeight);
  sw.stop();
  int totalWeight = 0;
  int totalValue = 0;
  print(["item","profit","weight"]);
  p.forEach((var i) { print("${i}"); totalWeight+=i[1]; totalValue+=i[2]; });
  print("Total Value = ${totalValue}");
  print("Total Weight = ${totalWeight}");
  print("Elapsed Time = ${sw.elapsedInMs()}ms");

}

The code determines the optimal combination of items a tourist can carry in his knapsack, given a maximum weight limit of 4kg (400 dag), such that the total value of the items is maximized. The items cannot be divided or diminished.


bool isPalindrome(String s){
  for(int i = 0; i < s.length/2;i++){
    if(s[i] != s[(s.length-1) -i])
      return false;
  }
  return true;
}

implement a function to check if a given sequence of characters is a palindrome. It also supports Unicode characters. Additionally, it includes a second function to detect inexact palindromes, ignoring white-space, punctuation, and case-sensitivity. It may also be useful for testing a function.


Translation of: C++
int F(int n, int x, int y) {
  if (n == 0) {
    return x + y;
  } else if (y == 0) {
    return x;
  }

  return F(n - 1, F(n, x, y - 1), F(n, x, y - 1) + y);
}

void main() {
  print('F(1,3,3) = ${F(1, 3, 3)}');
}

Implement the Sudan function, a non-primitive recursive function. The function takes two arguments, x and y, and returns a value based on the defined recursive rules.


import std.array;

class Stack(T) {
    private T[] items;

    @property bool empty() { return items.empty(); }

    void push(T top) { items ~= top; }

    T pop() {
        if (this.empty)
            throw new Exception("Empty Stack.");
        auto top = items.back;
        items.popBack();
        return top;
    }
}

void main() {
    auto s = new Stack!int();
    s.push(10);
    s.push(20);
    assert(s.pop() == 20);
    assert(s.pop() == 10);
    assert(s.empty());
}

Implement a stack class supporting basic operations such as push (adding an element to the top of the stack), pop (removing and returning the topmost element), and empty (checking if the stack is empty). The stack follows a last in, first out (LIFO) access policy.


import std.stdio, std.conv, std.algorithm, std.math;

long sgn(alias unsignedFib)(int n) { // break sign manipulation apart
    immutable uint m = (n >= 0) ? n : -n;
    if (n < 0 && (n % 2 == 0))
        return -unsignedFib(m);
    else
        return unsignedFib(m);
}

long fibD(uint m) { // Direct Calculation, correct for abs(m) <= 84
    enum sqrt5r =  1.0L / sqrt(5.0L);         //  1 / sqrt(5)
    enum golden = (1.0L + sqrt(5.0L)) / 2.0L; // (1 + sqrt(5)) / 2
    return roundTo!long(pow(golden, m) * sqrt5r);
}

long fibI(in uint m) pure nothrow { // Iterative
    long thisFib = 0;
    long nextFib = 1;
    foreach (i; 0 .. m) {
        long tmp = nextFib;
        nextFib += thisFib;
        thisFib  = tmp;
    }
    return thisFib;
}

long fibR(uint m) { // Recursive
    return (m < 2) ? m : fibR(m - 1) + fibR(m - 2);
}

long fibM(uint m) { // memoized Recursive
    static long[] fib = [0, 1];
    while (m >= fib.length )
        fib ~= fibM(m - 2) + fibM(m - 1);
    return fib[m];
}

alias sgn!fibD sfibD;
alias sgn!fibI sfibI;
alias sgn!fibR sfibR;
alias sgn!fibM sfibM;

auto fibG(in int m) { // generator(?)
    immutable int sign = (m < 0) ? -1 : 1;
    long yield;

    return new class {
        final int opApply(int delegate(ref int, ref long) dg) {
            int idx = -sign; // prepare for pre-increment
            foreach (f; this)
                if (dg(idx += sign, f))
                    break;
            return 0;
        }

        final int opApply(int delegate(ref long) dg) {
            long f0, f1 = 1;
            foreach (p; 0 .. m * sign + 1) {
                if (sign == -1 && (p % 2 == 0))
                    yield = -f0;
                else
                    yield = f0;
                if (dg(yield)) break;
                auto temp = f1;
                f1 = f0 + f1;
                f0 = temp;
            }
            return 0;
        }
    };
}

void main(in string[] args) {
    int k = args.length > 1 ? to!int(args[1]) : 10;
    writefln("Fib(%3d) = ", k);
    writefln("D : %20d <- %20d + %20d",
             sfibD(k), sfibD(k - 1), sfibD(k - 2));
    writefln("I : %20d <- %20d + %20d",
             sfibI(k), sfibI(k - 1), sfibI(k - 2));
    if (abs(k) < 36 || args.length > 2)
        // set a limit for recursive version
        writefln("R : %20d <- %20d + %20d",
                 sfibR(k), sfibM(k - 1), sfibM(k - 2));
    writefln("O : %20d <- %20d + %20d",
             sfibM(k), sfibM(k - 1), sfibM(k - 2));
    foreach (i, f; fibG(-9))
        writef("%d:%d | ", i, f);
}

The code includes four versions of functions to calculate the nth Fibonacci number, supporting both positive and negative inputs. The traditional recursive approach is optimized with static storage for intermediate results. The functions have a limit of 84 for FibD due to floating point precision, and 92 for the others due to long overflow. The code performs faster than the matrix exponentiation version for large inputs.


void main() {
    import std.algorithm: filter, equal;

    immutable data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    auto evens = data.filter!(x => x % 2 == 0); // Lazy.
    assert(evens.equal([2, 4, 6, 8, 10]));
}

Tango Version[edit]
Library: Tango
import tango.core.Array, tango.io.Stdout;

void main() {
    auto array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // removeIf places even elements at the beginnig of the array and returns number of found evens
    auto evens = array.removeIf( ( typeof(array[0]) i ) { return (i % 2) == 1; } );
    Stdout("Evens - ")( array[0 .. evens] ).newline; // The order of even elements is preserved
    Stdout("Odds - ")( array[evens .. $].sort ).newline; // Unlike odd elements
}

select certain elements from an array into a new array in a generic way. Specifically, it selects all even numbers from an array. Optionally, it can also filter destructively by modifying the original array instead of creating a new one.


Works with: D version 2
import std.stdio, std.string;

void main() {
    const s = "the quick brown fox jumps over the lazy dog";
    enum n = 5, m = 3;

    writeln(s[n .. n + m]);

    writeln(s[n .. $]);

    writeln(s[0 .. $ - 1]);

    const i = s.indexOf("q");
    writeln(s[i .. i + m]);

    const j = s.indexOf("qu");
    writeln(s[j .. j + m]);
}

- Extracts a substring starting from the nth character of a specific length m.
- Extracts a substring starting from the nth character up to the end of the string.
- Returns the entire string excluding the last character.
- Extracts a substring starting from a known character within the string of length m.
- Extracts a substring starting from a known substring within the string of length m.
- Supports any valid Unicode code point, including those in the Basic Multilingual Plane or above it.
- References logical characters (code points), not 8-bit code units for UTF-8 or 16-bit code units for UTF-16.
- Does not necessarily support all Unicode characters for other encodings like 8-bit ASCII, or EUC-JP.


void main() {
	import std.range, std.conv;

	string s1 = "hello"; // UTF-8
	assert(s1.retro.text == "olleh");

	wstring s2 = "hello"w; // UTF-16
	assert(s2.retro.wtext == "olleh"w);

	dstring s3 = "hello"d; // UTF-32
	assert(s3.retro.dtext == "olleh"d);

	// without using std.range:
	dstring s4 = "hello"d;
	assert(s4.dup.reverse == "olleh"d); // simple but inefficient (copies first, then reverses)
}

Reverses a given string while preserving Unicode combining characters. For instance, it transforms "asdf" to "fdsa" and "as⃝df̅" to "f̅ds⃝a".


Translation of: Python
import std.stdio, std.array, std.algorithm, std.range, std.ascii,
       std.conv, std.string, std.regex, std.typecons;

string unique(in string s) pure nothrow @safe {
    string result;
    foreach (immutable char c; s)
        if (!result.representation.canFind(c)) // Assumes ASCII string.
            result ~= c;
    return result;
}

struct Playfair {
    string from, to;
    string[string] enc, dec;

    this(in string key, in string from_ = "J", in string to_ = null)
    pure /*nothrow @safe*/ {
        this.from = from_;
        if (to_.empty)
            this.to = (from_ == "J") ? "I" : "";

        immutable m = _canonicalize(key ~ uppercase)
                      .unique
                      .chunks(5)
                      .map!text
                      .array;
        auto I5 = 5.iota;

        foreach (immutable R; m)
            foreach (immutable i, immutable j; cartesianProduct(I5, I5))
                if (i != j)
                    enc[[R[i], R[j]]] = [R[(i + 1) % 5], R[(j+1) % 5]];

        foreach (immutable r; I5) {
            immutable c = m.transversal(r).array;
            foreach (immutable i, immutable j; cartesianProduct(I5, I5))
                if (i != j)
                    enc[[c[i], c[j]]] = [c[(i + 1) % 5], c[(j+1) % 5]];
        }

        foreach (i1, j1, i2, j2; cartesianProduct(I5, I5, I5, I5))
            if (i1 != i2 && j1 != j2)
                enc[[m[i1][j1], m[i2][j2]]] = [m[i1][j2], m[i2][j1]];

        dec = enc.byKeyValue.map!(t => tuple(t.value, t.key)).assocArray;
    }

    private string _canonicalize(in string s) const pure @safe {
        return s.toUpper.removechars("^A-Z").replace(from, to);
    }

    string encode(in string s) const /*pure @safe*/ {
        return _canonicalize(s)
               .matchAll(r"(.)(?:(?!\1)(.))?")
               .map!(m => enc[m[0].leftJustify(2, 'X')])
               .join(' ');
    }

    string decode(in string s) const pure @safe {
        return _canonicalize(s).chunks(2).map!(p => dec[p.text]).join(' ');
    }
}

void main() /*@safe*/ {
    /*immutable*/ const pf = Playfair("Playfair example");
    immutable orig = "Hide the gold in...the TREESTUMP!!!";
    writeln("Original: ", orig);
    immutable enc = pf.encode(orig);
    writeln(" Encoded: ", enc);
    writeln(" Decoded: ", pf.decode(enc));
}

Implement the Playfair cipher for both encryption and decryption. It allows the user to choose whether 'J' equals 'I' or there's no 'Q' in the alphabet. The resulting encrypted and decrypted messages are presented in capitalized digraphs, separated by spaces.


Translation of: C++

import std.stdio, std.typecons, std.algorithm, std.container;

alias Vertex = string;
alias Weight = int;

struct Neighbor {
    Vertex target;
    Weight weight;
}

alias AdjacencyMap = Neighbor[][Vertex];

pure dijkstraComputePaths(Vertex source, Vertex target, AdjacencyMap adjacencyMap){
    Weight[Vertex] minDistance;
    Vertex[Vertex] previous;

    foreach(v, neighs; adjacencyMap){
        minDistance[v] = Weight.max;
        foreach(n; neighs) minDistance[n.target] = Weight.max;
    }

    minDistance[source] = 0;
    auto vertexQueue = redBlackTree(tuple(minDistance[source], source));

    foreach(_, u; vertexQueue){
        if (u == target)
            break;

        // Visit each edge exiting u.
        foreach(n; adjacencyMap.get(u, null)){
            const v = n.target;
            const distanceThroughU = minDistance[u] + n.weight;
            if(distanceThroughU < minDistance[v]){
                vertexQueue.removeKey(tuple(minDistance[v], v));
                minDistance[v] = distanceThroughU;
                previous[v] = u;
                vertexQueue.insert(tuple(minDistance[v], v));
            }
        }
    }

    return tuple(minDistance, previous);
}

pure dijkstraGetShortestPathTo(Vertex v, Vertex[Vertex] previous){
    Vertex[] path = [v];

    while (v in previous) {
        v = previous[v];
        if (v == path[$ - 1])
            break;
        path ~= v;
    }

    path.reverse();
    return path;
}

void main() {
    immutable arcs = [tuple("a", "b", 7),
                      tuple("a", "c", 9),
                      tuple("a", "f", 14),
                      tuple("b", "c", 10),
                      tuple("b", "d", 15),
                      tuple("c", "d", 11),
                      tuple("c", "f", 2),
                      tuple("d", "e", 6),
                      tuple("e", "f", 9)];

    AdjacencyMap adj;
    foreach (immutable arc; arcs) {
        adj[arc[0]] ~= Neighbor(arc[1], arc[2]);
        // Add this if you want an undirected graph:
        //adj[arc[1]] ~= Neighbor(arc[0], arc[2]);
    }

    const minDist_prev = dijkstraComputePaths("a", "e", adj);
    const minDistance = minDist_prev[0];
    const previous = minDist_prev[1];

    writeln(`Distance from "a" to "e": `, minDistance["e"]);
    writeln("Path: ", dijkstraGetShortestPathTo("e", previous));
}

Implement Dijkstra's algorithm to find the shortest path from a single source to all other vertices in a graph. The graph is represented by an adjacency matrix or list, and a start node. The algorithm outputs a set of edges depicting the shortest path to each reachable node from the start node. The program also interprets the output to display the shortest path from the start node to specific nodes.


Translation of: Java
import std.stdio, std.algorithm;

class AVLtree {
    private Node* root;

    private static struct Node {
        private int key, balance;
        private Node* left, right, parent;

        this(in int k, Node* p) pure nothrow @safe @nogc {
            key = k;
            parent = p;
        }
    }

    public bool insert(in int key) pure nothrow @safe {
        if (root is null)
            root = new Node(key, null);
        else {
            Node* n = root;
            Node* parent;
            while (true) {
                if (n.key == key)
                    return false;

                parent = n;

                bool goLeft = n.key > key;
                n = goLeft ? n.left : n.right;

                if (n is null) {
                    if (goLeft) {
                        parent.left = new Node(key, parent);
                    } else {
                        parent.right = new Node(key, parent);
                    }
                    rebalance(parent);
                    break;
                }
            }
        }
        return true;
    }

    public void deleteKey(in int delKey) pure nothrow @safe @nogc {
        if (root is null)
            return;
        Node* n = root;
        Node* parent = root;
        Node* delNode = null;
        Node* child = root;

        while (child !is null) {
            parent = n;
            n = child;
            child = delKey >= n.key ? n.right : n.left;
            if (delKey == n.key)
                delNode = n;
        }

        if (delNode !is null) {
            delNode.key = n.key;

            child = n.left !is null ? n.left : n.right;

            if (root.key == delKey) {
                root = child;
            } else {
                if (parent.left is n) {
                    parent.left = child;
                } else {
                    parent.right = child;
                }
                rebalance(parent);
            }
        }
    }

    private void rebalance(Node* n) pure nothrow @safe @nogc {
        setBalance(n);

        if (n.balance == -2) {
            if (height(n.left.left) >= height(n.left.right))
                n = rotateRight(n);
            else
                n = rotateLeftThenRight(n);

        } else if (n.balance == 2) {
            if (height(n.right.right) >= height(n.right.left))
                n = rotateLeft(n);
            else
                n = rotateRightThenLeft(n);
        }

        if (n.parent !is null) {
            rebalance(n.parent);
        } else {
            root = n;
        }
    }

    private Node* rotateLeft(Node* a) pure nothrow @safe @nogc {
        Node* b = a.right;
        b.parent = a.parent;

        a.right = b.left;

        if (a.right !is null)
            a.right.parent = a;

        b.left = a;
        a.parent = b;

        if (b.parent !is null) {
            if (b.parent.right is a) {
                b.parent.right = b;
            } else {
                b.parent.left = b;
            }
        }

        setBalance(a, b);

        return b;
    }

    private Node* rotateRight(Node* a) pure nothrow @safe @nogc {
        Node* b = a.left;
        b.parent = a.parent;

        a.left = b.right;

        if (a.left !is null)
            a.left.parent = a;

        b.right = a;
        a.parent = b;

        if (b.parent !is null) {
            if (b.parent.right is a) {
                b.parent.right = b;
            } else {
                b.parent.left = b;
            }
        }

        setBalance(a, b);

        return b;
    }

    private Node* rotateLeftThenRight(Node* n) pure nothrow @safe @nogc {
        n.left = rotateLeft(n.left);
        return rotateRight(n);
    }

    private Node* rotateRightThenLeft(Node* n) pure nothrow @safe @nogc {
        n.right = rotateRight(n.right);
        return rotateLeft(n);
    }

    private int height(in Node* n) const pure nothrow @safe @nogc {
        if (n is null)
            return -1;
        return 1 + max(height(n.left), height(n.right));
    }

    private void setBalance(Node*[] nodes...) pure nothrow @safe @nogc {
        foreach (n; nodes)
            n.balance = height(n.right) - height(n.left);
    }

    public void printBalance() const @safe {
        printBalance(root);
    }

    private void printBalance(in Node* n) const @safe {
        if (n !is null) {
            printBalance(n.left);
            write(n.balance, ' ');
            printBalance(n.right);
        }
    }
}

void main() @safe {
    auto tree = new AVLtree();

    writeln("Inserting values 1 to 10");
    foreach (immutable i; 1 .. 11)
        tree.insert(i);

    write("Printing balance: ");
    tree.printBalance;
}

implement an AVL tree, a self-balancing binary search tree where the heights of the two child subtrees of any node differ by at most one. The code ensures this by rebalancing the tree after each insertion or deletion. The operations of lookup, insertion, and deletion all take O(log n) time. The code does not allow duplicate node keys. The AVL tree implemented can be compared with red-black trees for its efficiency in lookup-intensive applications.