procedure getone(L) suspend pair(L[1], L[2:0]) every i := 2 to *L do { suspend [L[i], L[1:i]|||L[i+1:0]] } end # Prolog: # getone(X, [X|T], T). # getone(X, [H|T], [H|N]) :- getone(X, T, N). procedure layrow(bricks, rowlen) if rowlen = 0 then return [] pair <- getone(bricks) & suspend row([pair.value ||| layrow(pair.left, 0 <= rowlen - pair.value)], bricks) end record pair(value,left) record row(bricks,left) procedure lay3rows(bricks,len) suspend row1 <- layrow(bricks,len) & row2 <- layrow(row1.left,len) & row3 <- layrow(row2.left, len) & [pair1.bricks, pair2.bricks, pair3.bricks] end $ifdef NEVER getone(X, [X|T], T). getone(X, [H|T], [H|N]) :- getone(X, T, N). layrow(Bricks, 0, Bricks, []). layrow(Bricks, RowLen, Left, [Brick|MoreBricksForRow]) :- getone(Brick, Bricks, Left0), RemLen is RowLen - Brick, RemLen >= 0, layrow(Left0, RemLen, Left, MoreBricksForRow). lay3rows(Bricks, RowLen, [Row1,Row2,Row3]) :- layrow(Bricks, RowLen, LeftAfter1, Row1), layrow(LeftAfter1, RowLen, LeftAfter2, Row2), layrow(LeftAfter2, RowLen, LeftAfter3, Row3), LeftAfter3 = []. laybricks([], 0, _, []). laybricks(Bricks, Nrows, RowLen, [Row|Rows]) :- layrow(Bricks, RowLen, BricksLeft, Row), RowsLeft is Nrows - 1, laybricks(BricksLeft, RowsLeft, RowLen, Rows). % laybricks2 does not require all bricks to be used. laybricks2(_, 0, _, []). laybricks2(Bricks, Nrows, RowLen, [Row|Rows]) :- layrow(Bricks, RowLen, BricksLeft, Row), RowsLeft is Nrows - 1, laybricks2(BricksLeft, RowsLeft, RowLen, Rows). b(1, [7,5,6,4,3,5]). b(2, [5,1,6,2,3,4,3]). b(3, [8,5,1,4,6,6,2,3,4,3,3,6,3,8,6,4]). % 6x12 b(4, [8,5,1,4,6,6,2,3,4,3,3,6,3,8,6,4,1]). % Like 6x12 but obo $endif