%% Producer provides {peek, pull} interface to a generator
peek( prod(Curr,Next), Curr, prod(Curr,Next)).
peek( prod(Next), C, prod(C,N) ):- next(Next,C,N).
pull( prod(Curr,Next), Curr, prod(Next) ).
pull( prod(Next), C, prod(N) ):- next(Next,C,N).
%% collect N elements produced by producer in a row
take( 0, Prod, Z-Z, Prod).
take( N, Prod, [A|B]-Z, PZ):- N>0, !,
pull
(Prod
, A
, P1
), N1
is N
-1, take(N1,P1,B-Z,PZ).
%% Generator provides specific {next} implementation
next( hamm( A2,B,C3,D,E5,F,[H|G] ), H, hamm(X,U,Y,V,Z,W,G) ):-
H
is min
(A2
, min
(C3
,E5
)), ( A2
=:= H
-> B
=[N2
|U
],X
is N2
*2 ; (X
,U
)=(A2
,B
) ), ( C3
=:= H
-> D
=[N3
|V
],Y
is N3
*3 ; (Y
,V
)=(C3
,D
) ), ( E5
=:= H
-> F
=[N5
|W
],Z
is N5
*5 ; (Z
,W
)=(E5
,F
) ).
mkHamm( prod( hamm(1,X,1,X,1,X,X)) ). % int_overflow @ 20,000 already
main(N) :-
statistics(inferences,I1),
( mkHamm
(P
),take
(20,P
,A
-[],_
),write(A
),nl, take
(1691-1,P
,_
,P2
),take
(2,P2
,B
-[],_
), write(B
), nl, take
( N
-1,P
,_
,P3
),take
(2,P3
,[C1
|_
]-_
,_
), write(C1
), nl ),
statistics(inferences,I2),
/*
ON INTS:
[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36]
[2125764000, 2147483648]
288325195312500000
10k: 288325195312500000 70273 Infs time: 0.06s memory: 6204 kB
ON FLOATS (w/ overwhelming precision errors):
10,000 2.56494e+17 70273 Infs time: 0.06s memory: 6204 kB
100k: 5.14728e+24 610273 Infs time: 0.54s memory: 6204 kB
500k: 1.02580e+28 3010273 Infs time: 4.60s memory: 6204 kB
1mln: 2.46193e+29 6010273 Infs time: 13.64s memory: 6204 kB
*/
JSUgUHJvZHVjZXIgcHJvdmlkZXMge3BlZWssIHB1bGx9IGludGVyZmFjZSB0byBhIGdlbmVyYXRvcgoKcGVlayggcHJvZChDdXJyLE5leHQpLCBDdXJyLCBwcm9kKEN1cnIsTmV4dCkpLgpwZWVrKCBwcm9kKE5leHQpLCAgICAgICAgIEMsIHByb2QoQyxOKSAgKTotIG5leHQoTmV4dCxDLE4pLgpwdWxsKCBwcm9kKEN1cnIsTmV4dCksIEN1cnIsIHByb2QoTmV4dCkgKS4KcHVsbCggcHJvZChOZXh0KSwgICAgICAgICBDLCBwcm9kKE4pICAgICk6LSBuZXh0KE5leHQsQyxOKS4KCiUlIGNvbGxlY3QgTiBlbGVtZW50cyBwcm9kdWNlZCBieSBwcm9kdWNlciBpbiBhIHJvdwoKdGFrZSggMCwgUHJvZCwgWi1aLCBQcm9kKS4KdGFrZSggTiwgUHJvZCwgW0F8Ql0tWiwgUFopOi0gTj4wLCAhLCAKICBwdWxsKFByb2QsIEEsIFAxKSwgTjEgaXMgTi0xLAogIHRha2UoTjEsUDEsQi1aLFBaKS4KCiUlIEdlbmVyYXRvciBwcm92aWRlcyBzcGVjaWZpYyB7bmV4dH0gaW1wbGVtZW50YXRpb24KCm5leHQoIGhhbW0oIEEyLEIsQzMsRCxFNSxGLFtIfEddICksIEgsIGhhbW0oWCxVLFksVixaLFcsRykgKTotIAogIEggaXMgbWluKEEyLCBtaW4oQzMsRTUpKSwKICAoICAgQTIgPTo9IEggLT4gQj1bTjJ8VV0sWCBpcyBOMioyIDsgKFgsVSk9KEEyLEIpICksCiAgKCAgIEMzID06PSBIIC0+IEQ9W04zfFZdLFkgaXMgTjMqMyA7IChZLFYpPShDMyxEKSApLAogICggICBFNSA9Oj0gSCAtPiBGPVtONXxXXSxaIGlzIE41KjUgOyAoWixXKT0oRTUsRikgKS4KCm1rSGFtbSggcHJvZCggaGFtbSgxLFgsMSxYLDEsWCxYKSkgKS4gICAgICAgICAgICAlIGludF9vdmVyZmxvdyBAIDIwLDAwMCBhbHJlYWR5CgptYWluKE4pIDotIAogIHN0YXRpc3RpY3MoaW5mZXJlbmNlcyxJMSksCiAgKCBta0hhbW0oUCksdGFrZSgyMCxQLEEtW10sXyksd3JpdGUoQSksbmwsIAogICAgdGFrZSgxNjkxLTEsUCxfLFAyKSx0YWtlKDIsUDIsQi1bXSxfKSwgICAgd3JpdGUoQiksIG5sLCAgCiAgICB0YWtlKCAgTiAgLTEsUCxfLFAzKSx0YWtlKDIsUDMsW0MxfF9dLV8sXyksICAgd3JpdGUoQzEpLCBubCAKICApLAogIHN0YXRpc3RpY3MoaW5mZXJlbmNlcyxJMiksCiAgSW5mcyBpcyBJMiAtIEkxLCBubCwgd3JpdGUoJyAgICcpLCB3cml0ZShJbmZzKSwgd3JpdGUoJyBJbmZzJykuCgovKgpPTiBJTlRTOgoKWzEsIDIsIDMsIDQsIDUsIDYsIDgsIDksIDEwLCAxMiwgMTUsIDE2LCAxOCwgMjAsIDI0LCAyNSwgMjcsIDMwLCAzMiwgMzZdClsyMTI1NzY0MDAwLCAyMTQ3NDgzNjQ4XQoyODgzMjUxOTUzMTI1MDAwMDAKCjEwazogICAyODgzMjUxOTUzMTI1MDAwMDAgICAgNzAyNzMgSW5mcyAgICB0aW1lOiAgMC4wNnMgICAgbWVtb3J5OiAgNjIwNCBrQgoKT04gRkxPQVRTICh3LyBvdmVyd2hlbG1pbmcgcHJlY2lzaW9uIGVycm9ycyk6CgoxMCwwMDAgICAgIDIuNTY0OTRlKzE3ICAgICAgIDcwMjczIEluZnMgICAgdGltZTogIDAuMDZzICAgIG1lbW9yeTogIDYyMDQga0IKMTAwazogICAgICA1LjE0NzI4ZSsyNCAgICAgIDYxMDI3MyBJbmZzICAgIHRpbWU6ICAwLjU0cyAgICBtZW1vcnk6ICA2MjA0IGtCCjUwMGs6ICAgICAgMS4wMjU4MGUrMjggICAgIDMwMTAyNzMgSW5mcyAgICB0aW1lOiAgNC42MHMgICAgbWVtb3J5OiAgNjIwNCBrQiAgICAgCjFtbG46ICAgICAgMi40NjE5M2UrMjkgICAgIDYwMTAyNzMgSW5mcyAgICB0aW1lOiAxMy42NHMgICAgbWVtb3J5OiAgNjIwNCBrQiAKKi8=