# 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).
``````