September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
1
Task/Cut-a-rectangle/00META.yaml
Normal file
1
Task/Cut-a-rectangle/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
68
Task/Cut-a-rectangle/Julia/cut-a-rectangle.julia
Normal file
68
Task/Cut-a-rectangle/Julia/cut-a-rectangle.julia
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
const count = [0]
|
||||
const dir = [[0, -1], [-1, 0], [0, 1], [1, 0]]
|
||||
|
||||
function walk(y, x, h, w, grid, len, next)
|
||||
if y == 0 || y == h || x == 0 || x == w
|
||||
count[1] += 2
|
||||
return
|
||||
end
|
||||
t = y * (w + 1) + x
|
||||
grid[t + 1] += UInt8(1)
|
||||
grid[len - t + 1] += UInt8(1)
|
||||
for i in 1:4
|
||||
if grid[t + next[i] + 1] == 0
|
||||
walk(y + dir[i][1], x + dir[i][2], h, w, grid, len, next)
|
||||
end
|
||||
end
|
||||
grid[t + 1] -= 1
|
||||
grid[len - t + 1] -= 1
|
||||
end
|
||||
|
||||
function cutrectangle(hh, ww, recur)
|
||||
if isodd(hh)
|
||||
h, w = ww, hh
|
||||
else
|
||||
h, w = hh, ww
|
||||
end
|
||||
if isodd(h)
|
||||
return 0
|
||||
elseif w == 1
|
||||
return 1
|
||||
elseif w == 2
|
||||
return h
|
||||
elseif h == 2
|
||||
return w
|
||||
end
|
||||
cy = div(h, 2)
|
||||
cx = div(w, 2)
|
||||
len = (h + 1) * (w + 1)
|
||||
grid = zeros(UInt8, len)
|
||||
len -= 1
|
||||
next = [-1, -w - 1, 1, w + 1]
|
||||
if recur
|
||||
count[1] = 0
|
||||
end
|
||||
for x in cx + 1:w - 1
|
||||
t = cy * (w + 1) + x
|
||||
grid[t + 1] = 1
|
||||
grid[len - t + 1] = 1
|
||||
walk(cy - 1, x, h, w, grid, len, next)
|
||||
end
|
||||
count[1] += 1
|
||||
if h == w
|
||||
count[1] *= 2
|
||||
elseif iseven(w) && recur
|
||||
cutrectangle(w, h, false)
|
||||
end
|
||||
return count[1]
|
||||
end
|
||||
|
||||
function runtest()
|
||||
for y in 1:10, x in 1:y
|
||||
if iseven(x) || iseven(y)
|
||||
println("$y x $x: $(cutrectangle(y, x, true))")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
runtest()
|
||||
114
Task/Cut-a-rectangle/Phix/cut-a-rectangle.phix
Normal file
114
Task/Cut-a-rectangle/Phix/cut-a-rectangle.phix
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
integer show = 2, -- max number to show
|
||||
-- (nb mirrors are not shown)
|
||||
chance = 1000 -- 1=always, 2=50%, 3=33%, etc
|
||||
|
||||
sequence grid
|
||||
|
||||
integer gh, -- = length(grid),
|
||||
gw -- = length(grid[1])
|
||||
|
||||
integer ty1, ty2, tx1, tx2 -- target {y,x}s
|
||||
|
||||
procedure mirror(integer y, x, ch)
|
||||
-- plant/reset ch and the symmetric copy
|
||||
grid[y,x] = ch
|
||||
grid[gh-y+1,gw-x+1] = ch
|
||||
end procedure
|
||||
|
||||
enum RIGHT, UP, DOWN, LEFT
|
||||
constant dyx = {{0,+1},{-1,0},{+1,0},{0,-1}},
|
||||
chx = "-||-"
|
||||
|
||||
function search(integer y, x, d, level)
|
||||
integer count = 0
|
||||
if level=0 or grid[y,x]!='x' then
|
||||
mirror(y,x,'x')
|
||||
integer {dy,dx} = dyx[d],
|
||||
{ny,nx} = {y+dy,x+dx},
|
||||
{yy,xx} = {y+dy*2,x+dx*3}
|
||||
if grid[ny,nx]=' ' then
|
||||
integer c = chx[d]
|
||||
mirror(ny,nx,c)
|
||||
if c='-' then
|
||||
mirror(ny,nx+dx,c)
|
||||
end if
|
||||
integer meet = (yy=ty1 or yy=ty2) and (xx=tx1 or xx=tx2)
|
||||
if meet then
|
||||
count = 1
|
||||
if show and rand(chance)=chance then
|
||||
show -= 1
|
||||
sequence g = grid -- (make copy/avoid reset)
|
||||
-- fill in(/overwrite) the last cut, if any
|
||||
if ty1!=ty2 then g[ty1+1,tx1] = '|'
|
||||
elsif tx1!=tx2 then g[ty1][tx1+1..tx1+2] = "--"
|
||||
end if
|
||||
puts(1,join(g,'\n')&"\n\n")
|
||||
end if
|
||||
else
|
||||
if grid[yy,xx]='+' then -- (minor gain)
|
||||
for d=RIGHT to LEFT do -- (kinda true!)
|
||||
count += search(yy,xx,d,level+1)
|
||||
end for
|
||||
end if
|
||||
end if
|
||||
mirror(ny,nx,' ')
|
||||
if c='-' then
|
||||
mirror(ny,nx+dx,' ')
|
||||
end if
|
||||
end if
|
||||
if level!=0 then
|
||||
-- ((level=0)==leave outer edges 'x' for next iteration)
|
||||
mirror(y,x,'+')
|
||||
end if
|
||||
end if
|
||||
return count
|
||||
end function
|
||||
|
||||
function odd(integer n) return remainder(n,2)=1 end function
|
||||
function even(integer n) return remainder(n,2)=0 end function
|
||||
|
||||
procedure make_grid(integer w,h)
|
||||
-- The outer edges are 'x'; the inner '+' become 'x' when visited.
|
||||
-- Likewise edges are cuts but the inner ones get filled in later.
|
||||
sequence tb = join(repeat("x",w+1),"--"),
|
||||
hz = join('x'&repeat("+",w-1)&'x'," ")&"\n",
|
||||
vt = "|"&repeat(' ',w*3-1)&"|\n"
|
||||
grid = split(tb&"\n"&join(repeat(vt,h),hz)&tb,'\n')
|
||||
-- set size (for mirroring) and target info:
|
||||
gh = length(grid) gw = length(grid[1])
|
||||
ty1 = h+even(h) ty2 = ty1+odd(h)*2
|
||||
tx1 = floor(w/2)*3+1 tx2 = tx1+odd(w)*3
|
||||
end procedure
|
||||
|
||||
function side(integer w, h)
|
||||
make_grid(w,h)
|
||||
-- search top to mid-point
|
||||
integer count = 0, last = 0
|
||||
for r=3 to h+1 by 2 do
|
||||
last = search(r,1,RIGHT,0) -- left to right
|
||||
count += 2*last
|
||||
end for
|
||||
if even(h) then
|
||||
count -= last -- (un-double the centre line)
|
||||
end if
|
||||
return count
|
||||
end function
|
||||
|
||||
--atom t0 = time()
|
||||
-- nb sub-optimal: obviously "grid" was designed for easy display, rather than speed.
|
||||
for y=1 to 9 do -- 24s
|
||||
--for y=1 to 10 do -- (gave up on >10x8)
|
||||
for x=1 to y do
|
||||
-- for x=1 to min(y,8) do -- 4 mins 16s (with y to 10)
|
||||
if even(x*y) then
|
||||
integer count = side(x,y)
|
||||
if x=y then
|
||||
count *= 2
|
||||
else
|
||||
count += side(y,x)
|
||||
end if
|
||||
printf(1,"%d x %d: %d\n", {y, x, count})
|
||||
end if
|
||||
end for
|
||||
end for
|
||||
--?elapsed(time()-t0)
|
||||
|
|
@ -2,54 +2,53 @@
|
|||
/*────────────────────────────────────────────────── unit dimensions and may be rotated.*/
|
||||
numeric digits 20 /*be able to handle some big integers. */
|
||||
parse arg N .; if N=='' | N=="," then N=10 /*N not specified? Then use default.*/
|
||||
dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*the four directions.*/
|
||||
dir.=0; dir.0.1= -1; dir.1.0= -1; dir.2.1= 1; dir.3.0= 1 /*the 4 directions.*/
|
||||
|
||||
do y=2 to N; say /*calculate rectangles up to size NxN.*/
|
||||
do x=1 for y; if x//2 & y//2 then iterate /*not if both X&Y odd.*/
|
||||
z=solve(y,x,1); _=comma(z); _=right(_, max(14, length(_))) /*align the output. */
|
||||
say right(y,9) "x" right(x,2) 'rectangle can be cut' _ "way"s(z).
|
||||
do y=2 to N; yEven= y//2; say /*calculate rectangles up to size NxN.*/
|
||||
do x=1 for y; if x//2 then if yEven then iterate /*not if both X&Y odd*/
|
||||
z= solve(y,x,1); _=comma(z); _=right(_, max(14, length(_))) /*align the output. */
|
||||
say right(y, 9) "x" right(x, 2) 'rectangle can be cut' _ "way"s(z).
|
||||
end /*x*/
|
||||
end /*y*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
comma: procedure; arg _; do k=length(_)-3 to 1 by -3; _=insert(',',_,k); end; return _
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
s: if arg(1)=1 then return arg(3); return word(arg(2) 's', 1) /*pluralizer.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
solve: procedure expose # dir. @. h len next. w; @.=0 /*zero rectangle coördinates.*/
|
||||
parse arg h,w,recur /*get values for some args. */
|
||||
if h//2 then do; t=w; w=h; h=t; if h//2 then return 0
|
||||
if h//2 then do; t= w; w= h; h= t; if h//2 then return 0
|
||||
end
|
||||
if w==1 then return 1
|
||||
if w==2 then return h
|
||||
if h==2 then return w /* [↓] % is REXX's integer division.*/
|
||||
cy=h % 2; cx=w % 2; wp=w + 1 /*cut the [XY] rectangle in half. */
|
||||
len=(h+1) * wp - 1 /*extend the area of the rectangle. */
|
||||
next.0=-1; next.1=-wp; next.2=1; next.3=wp /*direction & distance.*/
|
||||
if recur then #=0
|
||||
do x=cx+1 to w-1; t=x + cy*wp; @.t=1; _=len - t; @._=1
|
||||
cy= h % 2; cx= w % 2; wp= w + 1 /*cut the [XY] rectangle in half. */
|
||||
len= (h+1) * wp - 1 /*extend the area of the rectangle. */
|
||||
next.0= -1; next.1= -wp; next.2= 1; next.3= wp /*direction & distance.*/
|
||||
if recur then #= 0
|
||||
do x=cx+1 to w-1; t= x + cy*wp; @.t= 1; _= len - t; @._= 1
|
||||
call walk cy-1, x
|
||||
end /*x*/
|
||||
#=#+1
|
||||
if h==w then #=# + # /*double the count of rectangle cuts. */
|
||||
else if w//2==0 & recur then call solve w, h, 0
|
||||
#= #+1
|
||||
if h==w then #= # + # /*double the count of rectangle cuts. */
|
||||
else if w//2==0 then if recur then call solve w, h, 0
|
||||
return #
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
walk: procedure expose # dir. @. h len next. w wp; parse arg y,x
|
||||
if y==h then do; #=#+2; return; end /* ◄──┐ REXX short circuit. */
|
||||
if x==0 then do; #=#+2; return; end /* ◄──┤ " " " */
|
||||
if x==w then do; #=#+2; return; end /* ◄──┤ " " " */
|
||||
if y==0 then do; #=#+2; return; end /* ◄──┤ " " " */
|
||||
t=x + y*wp; @.t=@.t + 1; _=len - t /* │ordered by most likely ►──┐*/
|
||||
@._=@._+1 /* └──────────────────────────┘*/
|
||||
do j=0 for 4; _=t + next.j /*try each of the four directions.*/
|
||||
if @._==0 then do; yn=y + dir.j.0; xn=x + dir.j.1
|
||||
if yn==h then do; #=#+2; iterate; end
|
||||
if xn==0 then do; #=#+2; iterate; end
|
||||
if xn==w then do; #=#+2; iterate; end
|
||||
if yn==0 then do; #=#+2; iterate; end
|
||||
if y==h then do; #= #+2; return; end /* ◄──┐ REXX short circuit. */
|
||||
if x==0 then do; #= #+2; return; end /* ◄──┤ " " " */
|
||||
if x==w then do; #= #+2; return; end /* ◄──┤ " " " */
|
||||
if y==0 then do; #= #+2; return; end /* ◄──┤ " " " */
|
||||
t= x + y*wp; @.t= @.t + 1; _= len - t /* │ordered by most likely ►──┐*/
|
||||
@._= @._+1 /* └──────────────────────────┘*/
|
||||
do j=0 for 4; _= t + next.j /*try each of the four directions.*/
|
||||
if @._==0 then do; yn= y + dir.j.0; xn= x + dir.j.1
|
||||
if yn==h then do; #= #+2; iterate; end
|
||||
if xn==0 then do; #= #+2; iterate; end
|
||||
if xn==w then do; #= #+2; iterate; end
|
||||
if yn==0 then do; #= #+2; iterate; end
|
||||
call walk yn, xn
|
||||
end
|
||||
end /*j*/
|
||||
@.t=@.t - 1
|
||||
_=len - t; @._=@._ - 1; return
|
||||
@.t= @.t - 1
|
||||
_= len - t; @._= @._ - 1; return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue