2009 LP Programming Contest


flag.pi

 
main => test.

test => flag(5).

flag(N) =>
    printf("  _\n (_)\n<___>\n"),
    NR = 2*N+4,
    NC = 5*N+5,
    A = new_array(NR,NC),
    p(A,1,5,N),
    foreach(I in 1..NR)
        A[I,2] = '|', 
        A[I,4] = '|',
        foreach (J in 1..NC)
            (var(A[I,J]) -> print(' ') ; print(A[I,J])),
            (J == NC -> nl ; true )
        end
    end.

p(A,I,J,1) =>
    foreach(C in 0..4) 
        A[I,J+C] = '_', 
        A[I+4,J+C] = '~'
    end,
    foreach(C in 1..3)
        A[I+C,J+4] = '|'
    end.
p(A,I,J,N) =>
    foreach(C in 0..4) A[I,J+C] = '_' end,
    foreach(C in 0..3) A[I+4,J+C] = '~' end,
    A[I+1,J+5] = ')',
    A[I+2,J+4] = '(',
    A[I+3,J+4] = '|',
    A[I+4,J+4] = '|',
    A[I+5,J+4] = '|',
    A[I+6,J+4] = '~',
    p(A,I+2,J+5,N-1).

split.pi

 
main => test.

test => split([i,i,c,l,c,f,p,p],[i,c,l,p],[i,c,f,p],H), writeln(H).

split(L,S1,S2,H) => split(L,S1,S2,0,H,_).

table (+,+,+,+,-,min)
split([],[],[],_,How,Count) => How = [], Count = 0.
split([X|Xs],[X|S1],S2,PrevT,How,Count) ?=>
    How = [1|HowR],
    split(Xs,S1,S2,1,HowR,Count1),
    Count = cond(PrevT == 1, Count1, Count1 + 1).
split([X|Xs],S1,[X|S2],PrevT,How,Count) =>
    How = [2|HowR],    
    split(Xs,S1,S2,2,HowR,Count1),
    Count = cond(PrevT == 2, Count1, Count1 + 1).

panoz.pi

 
import cp.

main => test.

test =>
    panoz([(0,1),(0,2),(4,0),(4,3)],Sol),writeln(Sol).

panoz(Ps, Sol) =>
    Xs = [X : (X,_) in Ps],
    Ys = [Y : (_,Y) in Ps],
    X :: min(Xs)..max(Xs),
    Y :: min(Ys)..max(Ys),
    Sol = (X,Y),
    Max #= max([max(X1-X,X-X1)+max(Y1-Y,Y-Y1) : (X1,Y1) in Ps]),
    solve($[min(Max)],[X,Y]).

circ.pi

 
main => test.

test =>
   circ($[edge(a,b), edge(a,h), edge(a,i), edge(b,c), edge(b,g),
	  edge(i,k), edge(c,d), edge(c,e), edge(c,f), edge(k,l), edge(k,m)],
	Three, Len),
   writeln((Len,Three)). %Len = 14 Three = [d,e,l]

circ(Es, Three, Len) =>
    cl_facts(Es,$[edge(+,-),edge(-,+),edge(+,+)]),
    Nodes = [A : $edge(A,_) in Es] ++ [B : $edge(_,B) in Es],
    sort_remove_dups(Nodes) = Ns,
    L = [$three(Dist,A,B,C) : A in Ns, B in Ns, C in Ns, (A@<B, B@<C, circ(A,B,C,Dist))],
    sort_down(L) = [$three(Len,A,B,C)|_],
    Three=[A,B,C].

circ(A, B, C, Dist) =>
    path(A,B,Dab), 
    path(A,C,Dac), 
    path(B,C,Dbc),
    Dist = Dab+Dac+Dbc.

table (+, +, min)
path(A,B,Dist) ?=> (edge(A,B); edge(B,A)), Dist=1.
path(A,B,Dist) =>
    (edge(A,C); edge(C,A)),
    path(C,B,Dist1),
    Dist = Dist1+1.

bishop.pi

 
import sat.

main => test.

test =>
    bishop(8, NR),
    writeln(NR).

bishop(N, NR) =>
    N>1,
    NB :: 2..N,
    NR+NB #= N+1,
    Rs = new_array(N,N),
    Bs = new_array(N,N),
    Rs :: 0..1,
    Bs :: 0..1,
    %
    sum([Rs[I,J] : I in 1..N, J in 1..N]) #= NR,
    sum([Bs[I,J] : I in 1..N, J in 1..N]) #= NB,
    foreach(I in 1..N, J in 1..N, I1 in 1..N, J1 in 1..N) 
        if (I==I1 || J==J1) then
            if (I,J) != (I1,J1) then Rs[I,J] #=> #~ Rs[I1,J1] end,
            Rs[I,J] #=> #~ Bs[I1,J1]
        end,
        if (I+J==I1+J1 || I-J == I1-J1) then
            if (I,J) != (I1,J1) then Bs[I,J] #=> #~ Bs[I1,J1] end,
            Bs[I,J] #=> #~ Rs[I1,J1] 
        end
    end,
    solve([$max(NR)],vars((Rs,Bs))),
    write_matrix(Rs),
    nl,nl,
    write_matrix(Bs).

write_matrix(M) =>
    foreach(I in 1..M.length)
        foreach(J in 1..M[1].length)
            print(M[I,J])
	end,
        nl
    end.