algol,n< Program Pentomino begin comment Time: 280782s = 3d 5h 59m 42s No buffer: Time classic: 428386 Time turbo: 408163 4.7pct Buffer: Time classic: 280782 Time turbo: 251104 10.6pct 11 solutions ; integer BOARDX,BOARDY,BOARDX1,BOARDY1,nsolutions; Boolean array transformed pieces[1:13,1:8]; integer array transformedx[1:12,1:8]; integer array ntransformed[1:12]; Boolean array used piece[1:12]; integer ix,iy; real procedure clock count; code clock count; 1, 37; zl , grf p−1 ; RF ≔ clock count; stack[p−1] ≔ RF; e; BOARDX ≔ 8; BOARDY ≔ 9; BOARDX1 ≔ BOARDX−1; BOARDY1 ≔ BOARDY−1; begin Boolean array board[0:BOARDY+4]; Boolean array mask[0:BOARDY1]; integer array solution board[0:BOARDY1,0:BOARDX1]; procedure move up left(itransform); value itransform; integer itransform; begin integer i; for i ≔ i while (integer (transformed pieces[13,itransform]∧ 35 0 5 m))=0 do transformed pieces[13,itransform] ≔ transformed pieces[13,itransform] shift −5; for i ≔ i while (integer (transformed pieces[13,itransform]∧ 15 0 5 1 5 1 5 1 5 1 5 1))=0 do transformed pieces[13,itransform] ≔ transformed pieces[13,itransform] shift −1; end move up left; procedure rotate cw(dst, src); value dst, src; integer dst, src; begin integer i,j; Boolean s; s ≔ 40 0; for i ≔ 0 step 1 until 4 do begin for j ≔ 0 step 1 until 4 do s ≔ s ∨ (((transformed pieces[13,src] shift −j×5) ∧ (40 1 shift i)) shift (4−j−i+i×5)) end; transformed pieces[13,dst] ≔ s; move up left(dst) end rotate cw; procedure mirror(dst, src); value dst, src; integer dst, src; begin integer i; transformed pieces[13,dst] ≔ 40 0; for i ≔ 0 step 1 until 4 do transformed pieces[13,dst] ≔ (transformed pieces[13,dst] shift 5) ∨ ((transformed pieces[13,src] shift −i×5) ∧ 35 0 5 m); move up left(dst) end mirror; Boolean procedure compare pieces(ipiece1, itransform1, ipiece2, itransform2); value ipiece1, itransform1, ipiece2, itransform2; integer ipiece1, itransform1, ipiece2, itransform2; begin integer i; compare pieces ≔ (integer transformed pieces[ipiece1,itransform1]) = (integer transformed pieces[ipiece2,itransform2]); end compare pieces; procedure copy piece(dstpiece, dsttransform, srcpiece, srctransform); value dstpiece, dsttransform, srcpiece, srctransform; integer dstpiece, dsttransform, srcpiece, srctransform; begin transformed pieces[dstpiece,dsttransform] ≔ transformed pieces[srcpiece,srctransform] end copy piece; procedure transform pieces; begin integer i,ipiece,irotate,imirror,itransformed; Boolean piece; for ipiece ≔ 1 step 1 until 12 do begin piece ≔ 40 0; for i ≔ 0 step 1 until 4 do piece ≔ piece ∨ ((Boolean read integer) shift 5×i); transformed pieces[13,1] ≔ piece; ntransformed[ipiece] ≔ 0; for irotate ≔ 0 step 1 until 3 do begin copy piece(13,2,13,1); for imirror ≔ 0 step 1 until 1 do begin if imirror=0 then copy piece(13,3,13,2) else mirror(3,2); for itransformed ≔ 1 step 1 until ntransformed[ipiece] do begin if compare pieces(ipiece,itransformed,13,3) then go_to duplicate end check for duplicate; ntransformed[ipiece] ≔ ntransformed[ipiece]+1; for i ≔ 0 step 1 until 4 do begin if transformed pieces[13,3] shift (−i−1) then begin transformedx[ipiece,ntransformed[ipiece]] ≔ i; go_to found first bit end end look for first bit in first row; found first bit: copy piece(ipiece,ntransformed[ipiece],13,3); duplicate: end imirror; rotate cw(2,1); copy piece(13,1,13,2) end irotate end ipiece end transform pieces; procedure create board; begin integer i,j; board[0] ≔ 24 0 4 m 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 4 m; board[1] ≔ 24 0 4 m 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 4 m; board[2] ≔ 24 0 4 m 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 0 4 m; board[3] ≔ 24 0 4 m 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 4 m; board[4] ≔ 24 0 4 m 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 4 m; board[5] ≔ 24 0 4 m 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 4 m; board[6] ≔ 24 0 4 m 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 4 m; board[7] ≔ 24 0 4 m 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 4 m; board[8] ≔ 24 0 4 m 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 4 m; board[9] ≔ 40 m; board[10] ≔ 40 m; board[11] ≔ 40 m; board[12] ≔ 40 m; for i ≔ 0 step 1 until BOARDY1 do mask[i] ≔ (board[i] shift −4) ∧ 32 0 8 m; for i ≔ 0 step 1 until BOARDY1 do for j ≔ 0 step 1 until BOARDX1 do solution board[i,j] ≔ −1 end create board; procedure find first free; begin next: if board[iy] shift −(ix+5) then begin ix ≔ ix+1; if ix⩾BOARDX then begin ix ≔ 0; iy ≔ iy+1 end next row; go_to next end bit is one end find first free; Boolean procedure piece fit(ix,iy,ipiece,itransform); value ix,iy,ipiece,itransform; integer ix,iy,ipiece,itransform; begin integer i; piece fit ≔ true; for i ≔ 0 step 1 until 4 do begin if (integer(board[iy+i]∧ (((transformed pieces[ipiece,itransform] shift −5×i) ∧ 35 0 5 m)shift (ix+4))))≠0 then begin piece fit ≔ false; go_to not fit end end for; not fit: end piece fit; procedure print piece(ipiece,itransform); value ipiece,itransform; integer ipiece,itransform; begin Boolean s; integer i,j; s ≔ transformed pieces[ipiece,itransform]; writecr; for i ≔ 0 step 1 until 4 do begin for j ≔ 0 step 1 until 4 do begin s ≔ s shift −1; write(«d», if s then 1 else 0) end; writecr end; i ≔ select(17); lyn; select(i) end print piece; procedure print board; begin integer i,j; writecr; for i ≔ 0 step 1 until BOARDY1 do begin for j ≔ 0 step 1 until BOARDX1 do write(«d», if board[i] shift −(j+5) then 1 else 0); writecr end row; lyn end print board; procedure set piece(ix,iy,ipiece,itransform); value ix,iy,ipiece,itransform; integer ix,iy,ipiece,itransform; begin integer i; for i ≔ 0 step 1 until 4 do board[iy+i] ≔ board[iy+i] ∨ (((transformed pieces[ipiece,itransform] shift −5×i) ∧ 35 0 5 m) shift (ix+4)) end set piece; procedure remove piece(ix,iy,ipiece,itransform); value ix,iy,ipiece,itransform; integer ix,iy,ipiece,itransform; begin integer i; for i ≔ 0 step 1 until 4 do board[iy+i] ≔ board[iy+i] ∧ ¬(((transformed pieces[ipiece,itransform] shift −5×i) ∧ 35 0 5 m) shift (ix+4)) end remove piece; procedure set solution(ix,iy,ipiece,itransform); value ix,iy,ipiece,itransform; integer ix,iy,ipiece,itransform; begin integer i,j; for i ≔ 0 step 1 until 4 do for j ≔ 0 step 1 until 4 do begin if transformed pieces[ipiece,itransform] shift −(j+1+5×i) then solution board[iy+i,ix+j] ≔ ipiece end end set solution; procedure print solution; begin integer i,j,k; writecr; write text(«Solution: »); write(«dddd», nsolutions); writecr; writetext(«+−−−»); for j ≔ 1 step 1 until BOARDX1 do begin if mask[0] shift −j−1 then writetext(«XXXX») else if solution board[0,j−1]= solution board[0,j] then writetext(«−−−−») else writetext(«+−−−») end first row; if mask[0] shift −BOARDX1−1 then writetext(«X») else writetext(«+»); writecr; for i ≔ 0 step 1 until BOARDY1 do begin for k ≔ 1 step 1 until 2 do begin writetext(«I »); for j ≔ 1 step 1 until BOARDX1 do begin if mask[i] shift −j−1 then writetext(«XXXX») else if solution board[i,j−1]= solution board[i,j] then writetext(« ») else if mask[i] shift −j then writetext(«X ») else writetext(«I ») end; if mask[i] shift −BOARDX1−1 then writetext(«X») else writetext(«I»); writecr end; if i<BOARDY1 then begin if solution board[i,0]= solution board[i+1,0] then writetext(«I ») else writetext(«+−−−»); for j ≔ 1 step 1 until BOARDX1 do begin if (mask[i] shift −j−1) ∨ (mask[i+1] shift −j−1) then writetext(«XXXX») else if solution board[i,j]= solution board[i+1,j] then begin if solution board[i,j−1]= solution board[i+1,j−1] then begin if solution board[i,j] ≠ solution board[i,j−1] ∨ solution board[i+1,j] ≠ solution board[i+1,j−1] then begin if mask[i] shift −j then writetext(«X ») else writetext(«I ») end else writetext(« ») end else if (mask[i] shift −j) ∨ (mask[i+1] shift −j) then writetext(«X ») else writetext(«+ ») end else begin if solution board[i,j] = solution board[i,j−1] ∧ solution board[i+1,j] = solution board[i+1,j−1] then writetext(«−−−−») else if (mask[i] shift −j) ∨ (mask[i+1] shift −j) then writetext(«X−−−») else writetext(«+−−−») end end first row; if (mask[i] shift −BOARDX1−1) ∨ (mask[i+1] shift −BOARDX1−1) then writetext(«X») else if solution board[i,BOARDX1]= solution board[i+1,BOARDX1] then writetext(«I») else writetext(«+»); writecr end not last row end each row; writetext(«+−−−»); for j ≔ 1 step 1 until BOARDX1 do begin if mask[BOARDY1] shift −j−1 then writetext(«XXXX») else if solution board[BOARDY1,j−1]= solution board[BOARDY1,j] then writetext(«−−−−») else writetext(«+−−−») end first row; if mask[BOARDY1] shift −BOARDX1−1 then writetext(«X») else writetext(«+»); writecr; end print solution; procedure test piece(piece count); value piece count; integer piece count; begin integer ipiece,itransform,saveix,saveiy; for ipiece ≔ 1 step 1 until 12 do begin if ¬ used piece[ipiece] then begin used piece[ipiece] ≔ true; for itransform ≔ 1 step 1 until ntransformed[ipiece] do begin if piece fit(ix−transformedx[ipiece,itransform], iy,ipiece,itransform) then begin set piece(ix−transformedx[ipiece,itransform],iy, ipiece,itransform); set solution(ix−transformedx[ipiece,itransform],iy, ipiece,itransform); if piece count=11 then begin nsolutions ≔ nsolutions+1; print solution end solution found else begin saveix ≔ ix; saveiy ≔ iy; find first free; test piece(piece count+1); ix ≔ saveix; iy ≔ saveiy end next piece; remove piece(ix−transformedx[ipiece,itransform],iy, ipiece,itransform) end piece fit end itransform; used piece[ipiece] ≔ false end unused piece end ipiece end test piece; procedure solve; begin integer ipiece; for ipiece ≔ 1 step 1 until 12 do used piece[ipiece] ≔ false; ix ≔ 0; iy ≔ 0; test piece(0) end solve; select(16); nsolutions ≔ 0; transform pieces; select(17); create board; clock count; solve; writecr; write text(«Solutions: »); write(«dddd», nsolutions); writecr; write text(«Time: »); write(«dddddd», clock count); write text(« sec.»); writecr end end; t<