Skip to content

Instantly share code, notes, and snippets.

@Koitaro
Created July 3, 2011 10:19
Show Gist options
  • Select an option

  • Save Koitaro/1062128 to your computer and use it in GitHub Desktop.

Select an option

Save Koitaro/1062128 to your computer and use it in GitHub Desktop.
CHR : Project Euler 100-109
:- use_module(library(chr)).
:- chr_option(optimize, full).
:- chr_constraint num(+int,+int), answer(+int), problem100.
problem100 <=> num(3,2).
num(A,B) <=> X is (A+B+1)//2, Y is B//2, X+Y > 10**12 | answer(X).
num(A,B) <=> A1 is A*3+B*4, B1 is A*2+B*3, num(A1,B1).
:- use_module(library(chr)).
:- chr_option(optimize, full).
:- chr_type list(T) ---> []; [T|list(T)].
:- chr_type edge ---> edge(int,int,int).
:- chr_type heap ---> edge-list(heap).
:- chr_constraint
heap(+heap), tail(+list(heap)), pop, top(+edge),
matrix(+int,+list(list(any))),
row(+int,+int,+list(any)),
current_weight(+int),
count(+int),
group(+list(int),+int),
answer(+int),
problem107.
problem107 <=> current_weight(0), data(X), matrix(1,X), count(0), pop.
data(X) :- csv_read_file('network.txt',Rows), maplist(term_list,Rows,X).
term_list(T,X) :- T =.. [_|X].
heap(M-L), heap(N-L1) <=> comp(M,N) | heap(M-[N-L1|L]).
tail([H|T]) <=> heap(H), tail(T).
tail([]) <=> true.
pop, heap(A-L) <=> tail(L), top(A).
comp(edge(_,_,M),edge(_,_,N)) :- M =< N.
matrix(N,[H|T]) <=> row(N,1,H), N1 is N+1, matrix(N1,T).
matrix(_,[]) <=> true.
row(M,N,[-|T]) <=> N1 is N+1, row(M,N1,T).
row(M,N,[_|T]) <=> M >= N | N1 is N+1, row(M,N1,T).
current_weight(X), row(M,N,[H|T])
<=> heap(edge(M,N,H)-[]), X1 is X+H, current_weight(X1), N1 is N+1, row(M,N1,T).
row(_,_,[]) <=> true.
count(39) \ heap(_) <=> true.
count(39) \ current_weight(M), group(_,N) <=> X is M-N, answer(X).
pop, count(39) <=> true.
group(L,_) \ top(edge(A,B,_))
<=> member(A,L), member(B,L) | pop.
group(L,X), group(L1,Y), count(N), top(edge(A,B,Z))
<=> (member(A,L), member(B,L1); member(B,L), member(A,L1))
| ord_union(L,L1,L2), X1 is X+Y+Z, group(L2,X1), N1 is N+1, count(N1), pop.
group(L,X), count(N), top(edge(A,B,Y))
<=> member(A,L)
| ord_add_element(L,B,L1), X1 is X+Y, group(L1,X1), N1 is N+1, count(N1), pop.
group(L,X), count(N), top(edge(A,B,Y))
<=> member(B,L)
| ord_add_element(L,A,L1), X1 is X+Y, group(L1,X1), N1 is N+1, count(N1), pop.
count(N), top(edge(A,B,X))
<=> list_to_ord_set([A,B],L), group(L,X), N1 is N+1, count(N1), pop.
:- use_module(library(chr)).
:- chr_option(optimize, full).
:- chr_type list(T) ---> []; [T|list(T)].
:- chr_type lli(T) == list(list(T)).
:- chr_constraint
push(+int,+lli(int)), push(+int,+list(int),+lli(int)),
checkout(+lli(int)), score(+lli(int),+int,-int),
count(+int), problem109.
problem109 <=> push(2,[]), count(0).
push(3,L) <=> numlist(1,20,L1), push(3,L1,L).
push(N,L) <=> numlist(1,20,L1), push(N,[25|L1],L).
push(_,[],_) <=> true.
push(N,[H|T],L) <=> checkout([[N,H]|L]), push(N,T,L).
checkout(L) ==> length(L,N), N < 3 | push(1,L), push(2,L), push(3,L).
checkout([A,B,C]) \ checkout([B,A,C]) <=> true.
checkout(L) <=> score(L,0,N), N >= 100 | true.
score([],N,X) <=> X = N.
score([[A,B]|T],N,X) <=> N1 is N+A*B, score(T,N1,X).
count(N), checkout(_) <=> N1 is N+1, count(N1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment