void bilet(int x1, int x2, int x3, int x4, int x5, int x6) { // if ((x1+x2+x3)==(x4+x5+x6)) { qDebug() << x1<< x2<< x3<< x4<< x5<< x6; } // if((x1+1)<3) bilet(x1 + 1, x2, x3, x4, x5, x6); if((x2+1)<10) bilet(x1, x2 + 1, x3, x4, x5, x6); if((x3+1)<10) bilet(x1, x2, x3 + 1, x4, x5, x6); if((x4+1)<10) bilet(x1, x2, x3, x4 + 1, x5, x6); if((x5+1)<10) bilet(x1, x2, x3, x4, x5 + 1, x6); if((x6+1)<3) bilet(x1, x2, x3, x4, x5, x6 + 1); } // bilet(0, 0, 0, 0, 0, 0);
void bilet(int x1, int x2, int x3, int x4, int x5, int x6) { // if ((x1+x2+x3)==(x4+x5+x6)) { qDebug() << x1<< x2<< x3<< x4<< x5<< x6; } // if((x1+1)<3) bilet(x1 + 1, x2, x3, x4, x5, x6); if((x6+1)<3) bilet(x1, x2, x3, x4, x5, x6 + 1); }
000000 200002 100001 200002 200002 100001 200002 200002 200002
-module(we01). -export([sum_money/6, sum_money/1]). sum_money(Itog) -> sum_money(Itog, 0, 0, 0, 0, 0). sum_money(Itog, X1000, X500, X100, X50, X10) -> if ((X1000 + X500 + X100 + X50 + X10) > 100) -> ok; (Itog == ((1000*X1000)+(500*X500)+(100*X100)+(50*X50)+(10*X10))) -> io:format("Itog(~w)(~w) = 1000*~w + 500*~w + 100*~w + 50*~w + 10*~w ~n", [Itog,(X1000 + X500 + X100 + X50 + X10), X1000, X500, X100, X50, X10]); (Itog > ((1000*X1000)+(500*X500)+(100*X100)+(50*X50)+(10*X10))) -> sum_money(Itog, 1+X1000, X500, X100, X50, X10), sum_money(Itog, X1000, 1+X500, X100, X50, X10), sum_money(Itog, X1000, X500, 1+X100, X50, X10), sum_money(Itog, X1000, X500, X100, 1+X50, X10), sum_money(Itog, X1000, X500, X100, X50, 1+X10); (true) -> ok end.
erl
c(we01).
we01:sum_money(120).
Itog(120)(3) = 1000*0 + 500*0 + 100*1 + 50*0 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(3) = 1000*0 + 500*0 + 100*1 + 50*0 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(3) = 1000*0 + 500*0 + 100*1 + 50*0 + 10*2 Itog(120)(4) = 1000*0 + 500*0 + 100*0 + 50*2 + 10*2 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(8) = 1000*0 + 500*0 + 100*0 + 50*1 + 10*7 Itog(120)(12) = 1000*0 + 500*0 + 100*0 + 50*0 + 10*12 ok ^ | +----
QHash hash; // void bilet(int x1, int x2, int x3, int x4, int x5, int x6) { int result = x1*100000+x2*10000+x3*1000+x4*100+x5*10+x6; if(hash.contains(result)) { // . //qDebug() << x1<< x2<< x3<< x4<< x5<< x6 << "skip"; return; } else { //. hash.insert(result, ((x1+x2+x3)==(x4+x5+x6))); } // if ((x1+x2+x3)==(x4+x5+x6)) { //, //qDebug() << x1<< x2<< x3<< x4<< x5<< x6 << "*"; } else { //, //qDebug() << x1<< x2<< x3<< x4<< x5<< x6; } // if((x1+1)<10) bilet(x1 + 1, x2, x3, x4, x5, x6); if((x2+1)<10) bilet(x1, x2 + 1, x3, x4, x5, x6); if((x3+1)<10) bilet(x1, x2, x3 + 1, x4, x5, x6); if((x4+1)<10) bilet(x1, x2, x3, x4 + 1, x5, x6); if((x5+1)<10) bilet(x1, x2, x3, x4, x5 + 1, x6); if((x6+1)<10) bilet(x1, x2, x3, x4, x5, x6 + 1); }
start "00:19:04.394" 0 0 0 0 0 0 * 1 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 * 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 0 0 1 1 1 0 1 0 0 1 1 0 1 1 0 * 1 1 0 1 1 1 1 1 0 1 0 1 * 1 1 0 0 1 0 1 1 0 0 1 1 * 1 1 0 0 0 1 1 0 1 0 0 0 1 0 1 1 0 0 1 0 1 1 1 0 * 1 0 1 1 1 1 1 0 1 1 0 1 * 1 0 1 0 1 0 1 0 1 0 1 1 * 1 0 1 0 0 1 1 0 0 1 0 0 * 1 0 0 1 1 0 1 0 0 1 1 1 1 0 0 1 0 1 1 0 0 0 1 0 * 1 0 0 0 1 1 1 0 0 0 0 1 * 0 1 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 1 1 1 0 * 0 1 1 1 1 1 0 1 1 1 0 1 * 0 1 1 0 1 0 0 1 1 0 1 1 * 0 1 1 0 0 1 0 1 0 1 0 0 * 0 1 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 * 0 1 0 0 1 1 0 1 0 0 0 1 * 0 0 1 0 0 0 0 0 1 1 0 0 * 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 1 0 1 0 0 1 0 1 0 * 0 0 1 0 1 1 0 0 1 0 0 1 * 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 end "00:19:04.407"
% ( , ) world_server(World_list) -> receive finished -> io:format("World server is down~n", []); list -> io:format("World list ~w ~n", [World_list]), world_server(World_list); {new_world, PID, New_world, Par} -> % case lists:keymember(New_world, 1, World_list) of true -> PID ! world_exist, world_server(World_list); % false -> PID ! world_new, world_server([{New_world, Par}|World_list]) % end end. world_server_start() -> register(ws, spawn(?MODULE, world_server, [[]])). world_server_stop() -> ws ! finished.
world_server_start()
function is world_server_start()
. It runs the world_server function in a new thread and associates it with the name ws
. The function calls itself recursively, and passes a list of worlds as a parameter. Initially, it is passed to []
, that is, an empty array. During operation, the function waits all the time for messages from other processes:finished
, then the function displays a message about stopping and does not call itself recursively, thereby the server stops.list
, then a list of worlds is displayed and work continues (used for debugging){new_world, PID, New_world, Par}
then this means that the server is asked if there is such a world in the list? If there is a world, then the process returns the message world_exist
or world_new
, and the function is performed further with the addition of a new world to the list (if there isn’t already).world_exist
, then do not work further (return ok
). Otherwise, we display information about the world (with an asterisk, if it is a target, the ticket is happy). new_ww(X1, X2, X3, X4, X5, X6) -> ws ! {new_world, self(), X1*10+X2*100+X3*1000+X4*10000+X5*100000+X6*1000000, (X1+X2+X3 == X4+X5+X6) }, receive world_exist -> ok; world_new -> if (X1+X2+X3 == X4+X5+X6) -> io:format("~w ~w ~w ~w ~w ~w *~n", [X1, X2, X3, X4, X5, X6]); true-> io:format("~w ~w ~w ~w ~w ~w ~n", [X1, X2, X3, X4, X5, X6]) end, if ((X1+1) < 10) -> new_ww(X1+1, X2, X3, X4, X5, X6); true -> ok end, if ((X2+1) < 10) -> new_ww(X1, X2+1, X3, X4, X5, X6); true -> ok end, if ((X3+1) < 10) -> new_ww(X1, X2, X3+1, X4, X5, X6); true -> ok end, if ((X4+1) < 10) -> new_ww(X1, X2, X3, X4+1, X5, X6); true -> ok end, if ((X5+1) < 10) -> new_ww(X1, X2, X3, X4, X5+1, X6); true -> ok end, if ((X6+1) < 10) -> new_ww(X1, X2, X3, X4, X5, X6+1); true -> ok end end.
{0,0,0,0,0,0}
{0,0,1,0,2}
true
. Otherwise false
. true
. Otherwise false
. At the same time, if the further development of the world is a dead end, this does not mean that the world cannot be targeted. %% w2hash(Wrld) -> erlang:phash2(Wrld).
erlang:phash2
function erlang:phash2
a hash number for the passed tuple. But the exact correspondence of one world to another is not always required. About it is written in the articles [1, 2], the point is that regardless of which intermediate decisions were made, you can come to the same result and the branches of development will converge. Worlds will not converge “up to the atom,” but will converge in the context of solving the problem. If the task is to get to work by car, then you can come along different roads, but at 12 o'clock we will be at the meeting. The difference, of course, will be in the mileage of the car, but this moment does not matter for us. -module(wf1). -export([start/0, stop/0, br/1, is_target/1, is_dead/1, ent/1, lib/0]). %% w2hash(Wrld) -> erlang:phash2(Wrld). %% lib() -> lib([]). lib(List) -> receive stop -> ok; {Wrld, Pid} -> WHash = w2hash(Wrld), NewList = case lists:member(WHash, List) of false -> Pid ! ok, [WHash]++List; true -> Pid ! exist, List end, lib(NewList); _ -> ok end. ent([]) -> ok; %% , Wrld %% Tail ent([Wrld|Tail]) -> try spawn(?MODULE, ent, [Wrld]) of _Pid -> ent(Tail) catch _:_ -> io:format("spawn overload~n", []), ent(Wrld), ent(Tail) end; %% ent(Wrld) -> lib_srv ! {Wrld, self()}, %% receive ok -> is_target(Wrld), %% Is_dead = is_dead(Wrld), %% if (Is_dead==false) -> %% - NewBranches = br(Wrld), ent(NewBranches); true -> ok end; exist -> ok end. stop() -> lib_srv ! stop. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% , %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% ? is_target(Wrld) -> true. %% - is_dead(Wrld) -> false. %% br(Wrld) -> []. %% start() -> register(lib_srv, spawn(?MODULE, lib, [])), io:format("start~n", []), %% [] spawn(?MODULE, ent, [[]]).
{0,0,0,0,0}
%% ? is_target(Wrld) -> {X1000,X500,X100,X50,X10} = Wrld, if ((X1000*1000 + X500*500 + X100*100 + X50*50 + X10*10)==120) -> io:format("120 (~w) = 1000p*~w 500p*~w 100p*~w 50p*~w 10p*~w~n", [X1000+X500+X100+X50+X10,X1000,X500,X100,X50,X10]); true -> ok end, (X1000*1000 + X500*500 + X100*100 + X50*50 + X10*10)==120.
Wrld
variable Wrld
tuple with five elements. During the operation, the values of the elements in the tuple are assigned to the variables X1000, X500, X100, X50, X10
. For more information about matching in Erlang, please read on your own. Or just accept this syntax as a way to pull values from a tuple. %% - is_dead(Wrld) -> {X1000,X500,X100,X50,X10} = Wrld, (X1000*1000 + X500*500 + X100*100 + X50*50 + X10*10)>120.
%% br(Wrld) -> {X1000,X500,X100,X50,X10} = Wrld, [ {X1000+1,X500,X100,X50,X10}, {X1000,X500+1,X100,X50,X10}, {X1000,X500,X100+1,X50,X10}, {X1000,X500,X100,X50+1,X10}, {X1000,X500,X100,X50,X10+1} ].
%% start() -> register(lib_srv, spawn(?MODULE, lib, [])), io:format("start~n", []), %% [] spawn(?MODULE, ent, [{0,0,0,0,0}]).
1> c(wf1). {ok,wf1} 2> wf1:start(). start <0.455.0> 120 (3) = 1000x0 500x0 100x1 50x0 10x2 120 (4) = 1000x0 500x0 100x0 50x2 10x2 120 (8) = 1000x0 500x0 100x0 50x1 10x7 120 (12) = 1000x0 500x0 100x0 50x0 10x12
{0,0,0,0,0,0}
%% ? is_target(Wrld) -> {X1,X2,X3,X4,X5,X6} = Wrld, if ((X1+X2+X3)==(X4+X5+X6)) -> cnt_srv ! inc, cnt_srv ! {cnt, self()}, receive X -> ok end, io:format("~w ~w ~w ~w ~w ~w (~w)~n", [X1,X2,X3,X4,X5,X6, X]); true -> ok end, ((X1+X2+X3)==(X4+X5+X6)).
%% - is_dead(Wrld) -> {X1,X2,X3,X4,X5,X6} = Wrld, if (X1>9)-> true; (X2>9)-> true; (X3>9)-> true; (X4>9)-> true; (X5>9)-> true; (X6>9)-> true; true -> false end.
%% br(Wrld) -> {X1,X2,X3,X4,X5,X6} = Wrld, [ {X1+1,X2,X3,X4,X5,X6}, {X1,X2+1,X3,X4,X5,X6}, {X1,X2,X3+1,X4,X5,X6}, {X1,X2,X3,X4+1,X5,X6}, {X1,X2,X3,X4,X5+1,X6}, {X1,X2,X3,X4,X5,X6+1} ].
%%- cnt() -> cnt(0). cnt(N) -> receive inc -> cnt(N+1); {cnt,Pid} -> Pid ! N, cnt(N) end.
%% start() -> register(lib_srv, spawn(?MODULE, lib, [])), register(cnt_srv, spawn(?MODULE, cnt, [])), io:format("start~n", []), %% [] spawn(?MODULE, ent, [{0,0,0,0,0,0}]).
{0,999999,0,0,0,0,0,0}
%% ? is_target(Wrld) -> {_St_d,_En_d,X1,X2,X3,X4,X5,X6} = Wrld, if ((X1+X2+X3)==(X4+X5+X6)) -> cnt_srv ! inc, cnt_srv ! {cnt, self()}, receive X -> ok end, io:format("~w ~w ~w ~w ~w ~w (~w)~n", [X1,X2,X3,X4,X5,X6, X]); true -> ok end, ((X1+X2+X3)==(X4+X5+X6)).
%% - is_dead(Wrld) -> {St_d,En_d,_X1,_X2,_X3,_X4,_X5,_X6} = Wrld, (St_d == En_d).
%% br(Wrld) -> {St_d,En_d,X1,X2,X3,X4,X5,X6} = Wrld, THalf = round((St_d + En_d) / 2), if (St_d == En_d) -> []; ((En_d - St_d) == 1) -> XX6 = En_d rem 10, XX5 = trunc((En_d rem 100)/10), XX4 = trunc((En_d rem 1000)/100), XX3 = trunc((En_d rem 10000)/1000), XX2 = trunc((En_d rem 100000)/10000), XX1 = trunc((En_d rem 1000000)/100000), [{St_d,St_d,XX1,XX2,XX3,XX4,XX5,XX6}] ++ [{En_d,En_d,XX1,XX2,XX3,XX4,XX5,XX6}]; true -> br({St_d,THalf,X1,X2,X3,X4,X5,X6}) ++ br({THalf,En_d,X1,X2,X3,X4,X5,X6}) end.
%% w2hash(Wrld) -> {_St_d,_En_d,X1,X2,X3,X4,X5,X6} = Wrld, X1*100000 + X2*10000 + X3*1000 + X4*100 + X5*10 + X6.
%% w2hash(Wrld) -> {_St_d,_En_d,X1,X2,X3,X4,X5,X6} = Wrld, erlang:phash2({X1,X2,X3,X4,X5,X6}).
%% start() -> register(lib_srv, spawn(?MODULE, lib, [])), register(cnt_srv, spawn(?MODULE, cnt, [])), io:format("start~n", []), %% [] spawn(?MODULE, ent, [{0,999999,0,0,0,0,0,0}]).
length([ [A,B,C,D,E,F] || A <- [0,1,2,3,4,5,6,7,8,9], B<-[0,1,2,3,4,5,6,7,8,9], C<-[0,1,2,3,4,5,6,7,8,9], D <- [0,1,2,3,4,5,6,7,8,9], E <- [0,1,2,3,4,5,6,7,8,9], F <- [0,1,2,3,4,5,6,7,8,9], (A+B+C==D+E+F)]).
r
— , l
— ) — , , , , ([] — ). ? , . {{ded,r},{koza,r},{volk,r},{kapusta,r},[]}
%% ? is_target(Wrld) -> {{ded,DedBereg},{koza,KozaBereg},{volk,VolkBereg},{kapusta,KapustaBereg},History} = Wrld, if ((DedBereg==r) and (KozaBereg==r) and (VolkBereg==r) and (KapustaBereg==r)) -> cnt_srv ! inc, cnt_srv ! {cnt, self()}, receive X -> ok end, io:format("~w) movs=~w ~w ~n", [X, length(History),History]); true -> ok end, ((DedBereg==r) and (KozaBereg==r) and (VolkBereg==r) and (KapustaBereg==r)).
%% - is_dead(Wrld) -> {{ded,DedBereg},{koza,KozaBereg},{volk,VolkBereg},{kapusta,KapustaBereg},History} = Wrld, if (length(History) > 8) -> true; ((KozaBereg==VolkBereg)and(DedBereg/=KozaBereg)) -> true; %% , ((KozaBereg==KapustaBereg)and(DedBereg/=KozaBereg)) -> true; %% , true -> false end.
na_drugoi_bereg(l) -> r; na_drugoi_bereg(r) -> l.
%% br(Wrld) -> {{ded,DedBereg},{koza,KozaBereg},{volk,VolkBereg},{kapusta,KapustaBereg},History} = Wrld, NewHistory = History ++ [{{ded,DedBereg},{koza,KozaBereg},{volk,VolkBereg},{kapusta,KapustaBereg}}], %% , %% , %% , %% - , if (DedBereg==KozaBereg) -> Variant1 = {{ded,na_drugoi_bereg(DedBereg)},{koza,na_drugoi_bereg(KozaBereg)},{volk,VolkBereg},{kapusta,KapustaBereg},NewHistory}; true -> Variant1 = [] end, %% - , if (DedBereg==VolkBereg) -> Variant2 = {{ded,na_drugoi_bereg(DedBereg)},{koza,KozaBereg},{volk,na_drugoi_bereg(VolkBereg)},{kapusta,KapustaBereg},NewHistory}; true -> Variant2 = [] end, %% - , if (DedBereg==KapustaBereg) -> Variant3 = {{ded,na_drugoi_bereg(DedBereg)},{koza,KozaBereg},{volk,VolkBereg},{kapusta,na_drugoi_bereg(KapustaBereg)},NewHistory}; true -> Variant3 = [] end, %% - - Variant4 = {{ded,na_drugoi_bereg(DedBereg)},{koza,KozaBereg},{volk,VolkBereg},{kapusta,KapustaBereg},NewHistory}, %% [Variant1]++[Variant2]++[Variant3]++[Variant4].
%% w2hash(Wrld) -> erlang:phash2(Wrld).
%% start() -> register(lib_srv, spawn(?MODULE, lib, [])), register(cnt_srv, spawn(?MODULE, cnt, [])), io:format("start~n", []), %% [] spawn(?MODULE, ent, [{{ded,l},{koza,l},{volk,l},{kapusta,l},[]}]).
1) movs=7 [ {{ded,l},{koza,l},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,l},{kapusta,l}}, - {{ded,l},{koza,r},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,r},{kapusta,l}}, - {{ded,l},{koza,l},{volk,r},{kapusta,l}}, - {{ded,r},{koza,l},{volk,r},{kapusta,r}}, - {{ded,l},{koza,l},{volk,r},{kapusta,r}}] - ,
5) movs=7 [ {{ded,l},{koza,l},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,l},{kapusta,l}}, - {{ded,l},{koza,r},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,l},{kapusta,r}}, - {{ded,l},{koza,l},{volk,l},{kapusta,r}}, - {{ded,r},{koza,l},{volk,r},{kapusta,r}}, - {{ded,l},{koza,l},{volk,r},{kapusta,r}}] - ,
2) movs=9 [ {{ded,l},{koza,l},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,l},{kapusta,l}}, - {{ded,l},{koza,r},{volk,l},{kapusta,l}}, - {{ded,r},{koza,r},{volk,r},{kapusta,l}}, - {{ded,l},{koza,l},{volk,r},{kapusta,l}}, - {{ded,r},{koza,l},{volk,r},{kapusta,r}}, - {{ded,l},{koza,l},{volk,r},{kapusta,l}}, - {{ded,r},{koza,l},{volk,r},{kapusta,r}}, - {{ded,l},{koza,l},{volk,r},{kapusta,r}}] -
Source: https://habr.com/ru/post/217031/
All Articles