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; @.=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
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; wp= w + 1 /*cut the rectangle in half. */
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.2= 1; next.3= wp /*direction & distance.*/
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; _= t + next.j /*try each of 4 directions.*/
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; @._= @._ - 1; return</lang>
_= len - t; @._= @._ - 1; return</lang>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
Line 2,802: Line 2,802:
===optimized===
===optimized===
This version replaced the (first) multiple clause &nbsp; '''if''' &nbsp; instructions in the &nbsp; '''walk''' &nbsp; subroutine with a
This version replaced the (first) multiple clause &nbsp; '''if''' &nbsp; instructions in the &nbsp; '''walk''' &nbsp; subroutine with a
<br>''short circuit'' version. &nbsp; Other optimizations were also made. &nbsp; This made the program about 20% faster.
<br>''short circuit'' version. &nbsp; Other optimizations were also made. &nbsp; This made the program about &nbsp; '''20%''' &nbsp; faster.
<br><br>A test run was executed to determine the order of the &nbsp; '''if''' &nbsp; statements &nbsp; (by counting which
<br><br>A test run was executed to determine the order of the &nbsp; '''if''' &nbsp; statements &nbsp; (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 /*cut the [XY] rectangle in half. */
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 /*direction & distance.*/
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 /* │ordered by most likely ►──┐*/
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.*/