Cut a rectangle: Difference between revisions
Content added Content deleted
m (→idiomatic: added whitespace.) |
m (→{{header|REXX}}: added.changed whitespace and comments, optimized the SOLVE functions, addhighlighting to the REXX section header.) |
||
Line 2,720: | Line 2,720: | ||
s: if arg(1)=1 then return arg(3); return word( arg(2) 's', 1) /*pluralizer.*/ |
s: if arg(1)=1 then return arg(3); return word( arg(2) 's', 1) /*pluralizer.*/ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
solve: procedure expose # dir. @. h len next. w; @.= |
solve: procedure expose # dir. @. h len next. w; @.= 0 /*zero rectangle coördinates.*/ |
||
parse arg h,w,recur /*get values for some args. */ |
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 |
||
Line 2,727: | Line 2,727: | ||
if w==2 then return h |
if w==2 then return h |
||
if h==2 then return w /* [↓] % is REXX's integer ÷*/ |
if h==2 then return w /* [↓] % is REXX's integer ÷*/ |
||
cy= h % 2; cx= w % 2; |
cy= h % 2; cx= w % 2; wp= w + 1 /*cut the rectangle in half. */ |
||
len= (h+1) * wp - 1 /*extend area of rectangle. */ |
len= (h+1) * wp - 1 /*extend area of rectangle. */ |
||
next.0= -1; next.1= -wp; |
next.0= '-1'; next.1= -wp; next.2= 1; next.3= wp /*direction & distance*/ |
||
if recur then #= 0 |
if recur then #= 0 |
||
do x=cx+1 to w-1; t= x + cy*wp; @.t= 1 |
do x=cx+1 to w-1; t= x + cy*wp; @.t= 1 |
||
Line 2,735: | Line 2,735: | ||
end /*x*/ |
end /*x*/ |
||
#= # + 1 |
#= # + 1 |
||
if h==w then #= # + # /*double rectangle cut count. |
if h==w then #= # + # /*double rectangle cut count.*/ |
||
else if w//2==0 & recur then call solve w, h, 0 |
else if w//2==0 & recur then call solve w, h, 0 |
||
return # |
return # |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
walk: procedure expose # dir. @. h len next. w wp; parse arg y,x |
walk: procedure expose # dir. @. h len next. w wp; parse arg y,x |
||
if y==h | x==0 | x==w | y==0 then do; #= # + 2; return; end |
if y==h | x==0 | x==w | y==0 then do; #= # + 2; return; end |
||
t= x + y*wp; @.t= @.t + 1; _= len - t |
t= x + y*wp; @.t= @.t + 1; _= len - t |
||
@._= @._ + 1 |
@._= @._ + 1 |
||
do j=0 for 4; |
do j=0 for 4; _= t + next.j /*try each of 4 directions.*/ |
||
if @._==0 then call walk y + dir.j.0, x + dir.j.1 |
if @._==0 then call walk y + dir.j.0, x + dir.j.1 |
||
end /*j*/ |
end /*j*/ |
||
@.t= @.t - 1 |
@.t= @.t - 1 |
||
_= len - t; |
_= len - t; @._= @._ - 1; return</lang> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre> |
<pre> |
||
Line 2,802: | Line 2,802: | ||
===optimized=== |
===optimized=== |
||
This version replaced the (first) multiple clause '''if''' instructions in the '''walk''' subroutine with a |
This version replaced the (first) multiple clause '''if''' instructions in the '''walk''' subroutine with a |
||
<br>''short circuit'' version. Other optimizations were also made. This made the program about 20% faster. |
<br>''short circuit'' version. Other optimizations were also made. This made the program about '''20%''' faster. |
||
<br><br>A test run was executed to determine the order of the '''if''' statements (by counting which |
<br><br>A test run was executed to determine the order of the '''if''' statements (by counting which |
||
<br>comparison would yield the most benefit by placing it first). |
<br>comparison would yield the most benefit by placing it first). |
||
Line 2,824: | Line 2,824: | ||
solve: procedure expose # dir. @. h len next. w; @.= 0 /*zero rectangle coördinates.*/ |
solve: procedure expose # dir. @. h len next. w; @.= 0 /*zero rectangle coördinates.*/ |
||
parse arg h,w,recur /*get values for some args. */ |
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 |
end |
||
if w==1 then return 1 |
if w==1 then return 1 |
||
if w==2 then return h |
if w==2 then return h |
||
if h==2 then return w /* [↓] % is REXX's integer division.*/ |
if h==2 then return w /* [↓] % is REXX's integer division.*/ |
||
cy= h % 2; cx= w % 2; wp= w + 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. */ |
len= (h+1) * wp - 1 /*extend the area of the rectangle. */ |
||
next.0= -1; next.1= -wp; next.2= 1; next.3= wp |
next.0= '-1'; next.1= -wp; next.2= 1; next.3= wp /*direction & distance*/ |
||
if recur then #= 0 |
if recur then #= 0 |
||
do x=cx+1 to w-1; t= x + cy*wp; @.t= 1 |
do x=cx+1 to w-1; t= x + cy*wp; @.t= 1 |
||
Line 2,846: | Line 2,846: | ||
if x==w then do; #= #+2; return; end /* ◄──┤ " " " */ |
if x==w then do; #= #+2; return; end /* ◄──┤ " " " */ |
||
if y==0 then do; #= #+2; return; end /* ◄──┤ " " " */ |
if y==0 then do; #= #+2; return; end /* ◄──┤ " " " */ |
||
t= x + y*wp; @.t= @.t + 1; _= len - t |
t= x + y*wp; @.t= @.t + 1; _= len - t /* │ordered by most likely ►──┐*/ |
||
@._= @._ + 1 /* └──────────────────────────┘*/ |
@._= @._ + 1 /* └──────────────────────────┘*/ |
||
do j=0 for 4; _= t + next.j /*try each of the four directions.*/ |
do j=0 for 4; _= t + next.j /*try each of the four directions.*/ |