2010 LP Programming Contest


tartan.pi

 
main => test.

test => tartan(5).

tartan(N) =>
    M is 2*N-1,
    A = new_array(M,M),
    fill(A,N,1,M),
    foreach(I in 1..M, J in 1..M)
        (var(A[I,J])->print(' ');printf("%s",A[I,J])), 
        (J==M->nl;true)
    end.	    

fill(A,1,R0,_) =>
    A[R0,R0] = "*".
fill(A,N,R0,Rn),
    N mod 2=:= 0
=>
    foreach(J in R0..Rn) A[R0,J] = "*", A[Rn,J] = "*" end,
    fill(A,N-1,R0+1,Rn-1).
fill(A,N,R0,Rn) =>
    foreach(I in R0..Rn) A[I,R0] = "*", A[I,Rn] = "*" end,
    fill(A,N-1,R0+1,Rn-1).

eric.pi

 
main => test.

test => eric($fork(treasury(10),treasury(20)),7,T),writeln(T).

eric(C, N, T) => eric(C, N, _, T), T>0.

eric(treasury(T), N, NN, NT), N>=2 => NN=2,NT=T.
eric(fork(L,R), N, NN, T),                  % both forks
    N1 is N-2, N1>=0,                       % 1 entry 1 exit
    eric(L, N1, NN1, T1),
    N2 is N1-NN1-1,N2>=0,                   % 1 extra guard
    eric(R, N2, NN2, T2)
=>
    T is max(T1, T2),
    NN is NN1+NN2.
eric(fork(L,_), N, NN, T),                  % left fork only
    N1 is N-2,N1>=0,                        % 1 entry 1 exit
    eric(L, N1, NN, T)
=>
    true.
eric(_, _, NN,T) => NN=0, T=0.

maglev.pi

 
main => test.

test => 
    maglev($[station(a,b,[c,d]), station(b,z,[a,c,d])],a,z,Cost),
    writeln(Cost).

table (+,+,+,min)
maglev(L,S,F,Cost),
    member($station(S,F,_),L)
=> 
    Cost=0.
maglev(L,S,F,Cost) =>
    (    member($station(S,N,Rs),L),
	 maglev(L,N,F,Cost)
    ;
         append(L1,[$station(S,N,Rs)],L2,L),
	 append(Rs1,[R],Rs2,Rs),
	 append(Rs1,[N],Rs2,NRs),  % switch N and R, R becomes the preferred next station
	 append(L1,[$station(S,R,NRs)],L2,NL),
	 maglev(NL,N,F,Cost1),
	 Cost is Cost1+1
    ).

rqueens.pi

 
main => test.

test => rqueens(5,Q), writeln(Q).

rqueens(N, Q) =>
    once((between(1,N,Q),rqueens1(N, Q))).

rqueens1(N, Q) =>
    B = new_array(N,N),
    B :: 0..1,
    sum([B[I,J] : I in 1..N, J in 1..N]) #= Q,
    foreach(I in 1..N, J in 1..N)
        sum([B[I1,J1] : I1 in 1..N, J1 in 1..N, (I == I1 || J == J1 || I+J == I1+J1 || I-J == I1-J1)]) #> 0
    end,
    solve(B).	   

student.pi

 
main => test.

test =>
    student($[rule(append([],L,L),[]),
	      rule(append([X|Xs],Ys,[X|Zs]), [append(Xs,Ys,Zs)])], 
	    $append([1],[2,3],[2,1,3]),N),
    writeln(N).

student(Program,Goal,N),
    between(0,99999,N),
    change(N,Program,Goal)
=>
    true.

change(0,Program,Init) =>
    prov(Program,[Init]).
change(N,Program,Init) =>
    (Goal=Init
     ;
     select_goal(Program,Goal)
    ),
    change_goal(Goal),
    change(N-1,Program,Init).

select_goal([rule(_,Body)|_],Goal) ?=>
    member(Goal,Body).
select_goal([_|Rules],Goal) =>
    select_goal(Rules,Goal).

change_goal(Goal) =>
    Goal.arity = Ari,
    between(1,Ari-1,I1),
    between(I1+1,Ari,I2),
    Goal[I1] = A1, 
    Goal[I2] = A2,
    Goal[I1] := A2,
    Goal[I2] := A1.

prov(_Program,[]) => true.
prov(Program,[G|Gs]) =>
    member(Rule,Program),
    copy_term(Rule) = $rule(G,Body),
    prov(Program,Body++Gs).