Another update from ingydotnet^djgoku
This commit is contained in:
parent
91df62d461
commit
948b86eafa
7604 changed files with 108452 additions and 22726 deletions
36
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-1.e
Normal file
36
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-1.e
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
class
|
||||
APPLICATION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Finds solution for cut a rectangle up to 10 x 10.
|
||||
local
|
||||
i, j, n: Integer
|
||||
r: GRID
|
||||
do
|
||||
n := 10
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j > i
|
||||
loop
|
||||
if i.bit_and (1) /= 1 or j.bit_and (1) /= 1 then
|
||||
create r.make (i, j)
|
||||
r.print_solution
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
163
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-2.e
Normal file
163
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-2.e
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
class
|
||||
GRID
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE}
|
||||
|
||||
n: INTEGER
|
||||
|
||||
m: INTEGER
|
||||
|
||||
feature
|
||||
|
||||
print_solution
|
||||
-- Prints solution to cut a rectangle.
|
||||
do
|
||||
calculate_possibilities
|
||||
io.put_string ("Rectangle " + n.out + " x " + m.out + ": " + count.out + " possibilities%N")
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
-- Number of solutions
|
||||
|
||||
make (a_n: INTEGER; a_m: INTEGER)
|
||||
-- Initialize Problem with 'a_n' and 'a_m'.
|
||||
require
|
||||
a_n > 0
|
||||
a_m > 0
|
||||
do
|
||||
n := a_n
|
||||
m := a_m
|
||||
count := 0
|
||||
end
|
||||
|
||||
calculate_possibilities
|
||||
-- Select all possible starting points.
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
if (n = 1 or m = 1) then
|
||||
count := 1
|
||||
end
|
||||
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i > n or (n = 1 or m = 1)
|
||||
loop
|
||||
solve (create {POINT}.make_with_values (i, 0), create {POINT}.make_with_values (n - i, m), create {LINKED_LIST [POINT]}.make, create {LINKED_LIST [POINT]}.make)
|
||||
i := i + 1
|
||||
variant
|
||||
n - i + 1
|
||||
end
|
||||
from
|
||||
i := 0
|
||||
until
|
||||
i > m or (n = 1 or m = 1)
|
||||
loop
|
||||
solve (create {POINT}.make_with_values (n, i), create {POINT}.make_with_values (0, m - i), create {LINKED_LIST [POINT]}.make, create {LINKED_LIST [POINT]}.make)
|
||||
i := i + 1
|
||||
variant
|
||||
m - i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE}
|
||||
|
||||
solve (p, q: POINT; visited_p, visited_q: LINKED_LIST [POINT])
|
||||
-- Recursive solution of cut a rectangle.
|
||||
local
|
||||
possible_next: LINKED_LIST [POINT]
|
||||
next: LINKED_LIST [POINT]
|
||||
opposite: POINT
|
||||
do
|
||||
if p.negative or q.negative then
|
||||
|
||||
elseif p.same (q) then
|
||||
add_solution
|
||||
else
|
||||
possible_next := get_possible_next (p)
|
||||
create next.make
|
||||
across
|
||||
possible_next as x
|
||||
loop
|
||||
if x.item.x >= n or x.item.y >= m then
|
||||
-- Next point cannot be on the border. Do nothing.
|
||||
|
||||
elseif x.item.same (q) then
|
||||
add_solution
|
||||
elseif not contains (x.item, visited_p) and not contains (x.item, visited_q) then
|
||||
next.extend (x.item)
|
||||
end
|
||||
end
|
||||
|
||||
across
|
||||
next as x
|
||||
loop
|
||||
-- Move in one direction
|
||||
-- Calculate the opposite end of the cut by moving into the opposite direction (compared to p -> x)
|
||||
create opposite.make_with_values (q.x - (x.item.x - p.x), q.y - (x.item.y - p.y))
|
||||
|
||||
visited_p.extend (p)
|
||||
visited_q.extend (q)
|
||||
|
||||
solve (x.item, opposite, visited_p, visited_q)
|
||||
|
||||
-- Remove last point again
|
||||
visited_p.finish
|
||||
visited_p.remove
|
||||
|
||||
visited_q.finish
|
||||
visited_q.remove
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_possible_next (p: POINT): LINKED_LIST [POINT]
|
||||
-- Four possible next points.
|
||||
local
|
||||
q: POINT
|
||||
do
|
||||
create Result.make
|
||||
|
||||
--up
|
||||
create q.make_with_values (p.x + 1, p.y)
|
||||
if q.valid and q.x <= n and q.y <= m then
|
||||
Result.extend (q);
|
||||
end
|
||||
|
||||
--down
|
||||
create q.make_with_values (p.x - 1, p.y)
|
||||
if q.valid and q.x <= n and q.y <= m then
|
||||
Result.extend (q)
|
||||
end
|
||||
|
||||
--left
|
||||
create q.make_with_values (p.x, p.y - 1)
|
||||
if q.valid and q.x <= n and q.y <= m then
|
||||
Result.extend (q)
|
||||
end
|
||||
|
||||
--right
|
||||
create q.make_with_values (p.x, p.y + 1)
|
||||
if q.valid and q.x <= n and q.y <= m then
|
||||
Result.extend (q)
|
||||
end
|
||||
end
|
||||
|
||||
add_solution
|
||||
-- Increment count.
|
||||
do
|
||||
count := count + 1
|
||||
end
|
||||
|
||||
contains (p: POINT; set: LINKED_LIST [POINT]): BOOLEAN
|
||||
-- Does set contain 'p'?
|
||||
do
|
||||
set.compare_objects
|
||||
Result := set.has (p)
|
||||
end
|
||||
|
||||
end
|
||||
47
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-3.e
Normal file
47
Task/Cut-a-rectangle/Eiffel/cut-a-rectangle-3.e
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
class
|
||||
POINT
|
||||
|
||||
create
|
||||
make, make_with_values
|
||||
|
||||
|
||||
|
||||
feature
|
||||
|
||||
make_with_values (a_x: INTEGER; a_y: INTEGER)
|
||||
-- Initialize x and y with 'a_x' and 'a_y'.
|
||||
do
|
||||
x := a_x
|
||||
y := a_y
|
||||
end
|
||||
|
||||
make
|
||||
-- Initialize x and y with 0.
|
||||
do
|
||||
x := 0
|
||||
y := 0
|
||||
end
|
||||
|
||||
x: INTEGER
|
||||
|
||||
y: INTEGER
|
||||
|
||||
negative: BOOLEAN
|
||||
-- Are x or y negative?
|
||||
do
|
||||
Result := x < 0 or y < 0
|
||||
end
|
||||
|
||||
same (other: POINT): BOOLEAN
|
||||
-- Does x and y equal 'other's x and y?
|
||||
do
|
||||
Result := (x = other.x) and (y = other.y)
|
||||
end
|
||||
|
||||
valid: BOOLEAN
|
||||
-- Are x and y valid points?
|
||||
do
|
||||
Result := (x > 0) and (y > 0)
|
||||
end
|
||||
|
||||
end
|
||||
45
Task/Cut-a-rectangle/REXX/cut-a-rectangle-1.rexx
Normal file
45
Task/Cut-a-rectangle/REXX/cut-a-rectangle-1.rexx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*REXX program cuts rectangles into two symmetric pieces, the rectangles are */
|
||||
/*────────────────────────────── cut along unit dimensions and may be rotated.*/
|
||||
numeric digits 20 /*be able to handle some big integers. */
|
||||
parse arg N .; if 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 /*four 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.*/
|
||||
_=solve(y,x,1); _=right(_,max(10,length(_))) /*align the output. */
|
||||
say right(y,9) "x" right(x,2) 'rectangle can be cut' _ "way"s(_)'.'
|
||||
end /*x*/
|
||||
end /*y*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────S subroutine──────────────────────────────*/
|
||||
s: if arg(1)=1 then return arg(3); return word(arg(2) 's',1) /*pluralizer.*/
|
||||
/*──────────────────────────────────SOLVE subroutine──────────────────────────*/
|
||||
solve: procedure expose # dir. @. h len next. w
|
||||
parse arg hh 1 h,ww 1 w,recur; @.=0 /*get args; zero rectangle coördinates.*/
|
||||
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 /*cut the [XY] rectangle in half. */
|
||||
len = (h+1) * (w+1) - 1 /*extend the area of the rectangle. */
|
||||
next.0=-1; next.1=-w-1; next.2=1; next.3=w+1 /*direction and distance.*/
|
||||
if recur then #=0
|
||||
do x=cx+1 to w-1; t=x+cy*(w+1)
|
||||
@.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
|
||||
return #
|
||||
/*──────────────────────────────────WALK subroutine───────────────────────────*/
|
||||
walk: procedure expose # dir. @. h len next. w; parse arg y,x
|
||||
if y==h | x==0 | x==w | y==0 then do; #=#=2; return; end
|
||||
t=x + y*(w+1); @.t=@.t+1; _=len-t
|
||||
@._=@._+1
|
||||
do j=0 for 4; _ = t+next.j /*try four directions.*/
|
||||
if @._==0 then call walk y+dir.j.0, x+dir.j.1
|
||||
end /*j*/
|
||||
@.t=@.t-1
|
||||
_=len-t; @._=@._-1
|
||||
return
|
||||
55
Task/Cut-a-rectangle/REXX/cut-a-rectangle-2.rexx
Normal file
55
Task/Cut-a-rectangle/REXX/cut-a-rectangle-2.rexx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*REXX program cuts rectangles into two symmetric pieces, the rectangles are */
|
||||
/*────────────────────────────── cut along unit dimensions and may be rotated.*/
|
||||
numeric digits 20 /*be able to handle some big integers. */
|
||||
parse arg N .; if 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 /*four 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.*/
|
||||
_=solve(y,x,1); _=right(_,max(10,length(_))) /*align the output. */
|
||||
say right(y,9) "x" right(x,2) 'rectangle can be cut' _ "way"s(_)'.'
|
||||
end /*x*/
|
||||
end /*y*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────S subroutine──────────────────────────────*/
|
||||
s: if arg(1)=1 then return arg(3); return word(arg(2) 's',1) /*pluralizer.*/
|
||||
/*──────────────────────────────────SOLVE subroutine──────────────────────────*/
|
||||
solve: procedure expose # dir. @. h len next. w
|
||||
parse arg hh 1 h,ww 1 w,recur; @.=0 /*get args; zero rectangle coördinates.*/
|
||||
if h//2 then do; parse value w h w with t w h; 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 /*cut the [XY] rectangle in half. */
|
||||
len = (h+1) * (w+1) - 1 /*extend the area of the rectangle. */
|
||||
next.0=-1; next.1=-w-1; next.2=1; next.3=w+1 /*direction and distance.*/
|
||||
if recur then #=0
|
||||
do x=cx+1 to w-1; t=x+cy*(w+1)
|
||||
@.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
|
||||
return #
|
||||
/*──────────────────────────────────WALK subroutine───────────────────────────*/
|
||||
walk: procedure expose # dir. @. h len next. w; 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*(w+1); @.t=@.t+1; _=len-t /* │ ordered by most likely ►───┐ */
|
||||
@._=@._+1 /* └─────────────────────────────┘ */
|
||||
do j=0 for 4; _ = t+next.j /*try 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
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*REXX program cuts rectangles into two symmetric pieces, the rectangles*/
|
||||
/*──────────────────── are cut along unit dimensions and may be rotated.*/
|
||||
numeric digits 20 /*be able to handle big integers.*/
|
||||
parse arg N .; if N=='' then N=10 /*N not specified? Use default.*/
|
||||
dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*directions.*/
|
||||
|
||||
do y=2 to N; say /*calculate rectangles up to NxN.*/
|
||||
do x=1 for y; if x//2 & y//2 then iterate /*not if both odd.*/
|
||||
_=solve(y,x,1); _=right(_,max(10,length(_))) /*align the output*/
|
||||
say right(y,9) "x" right(x,2) 'rectangle can be cut' _ "way"s(_)'.'
|
||||
end /*x*/
|
||||
end /*y*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────S subroutine────────────────────────*/
|
||||
s: if arg(1)=1 then return arg(3); return word(arg(2) 's',1) /*plurals*/
|
||||
/*──────────────────────────────────SOLVE subroutine────────────────────*/
|
||||
solve: procedure expose # dir. @. h len next. w
|
||||
parse arg hh 1 h,ww 1 w,recur; @.=0 /*zero the rectangle coördinates.*/
|
||||
|
||||
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
|
||||
cy = h%2; cx=w%2 /*cut the [XY] rectangle in half.*/
|
||||
len = (h+1) * (w+1) - 1 /*extended area of the rectangle.*/
|
||||
next.0=-1; next.1=-w-1; next.2=1; next.3=w+1 /*direction distance.*/
|
||||
if recur then #=0
|
||||
do x=cx+1 to w-1; t=x+cy*(w+1)
|
||||
@.t=1; _=len-t; @._=1; call walk cy-1,x
|
||||
end /*x*/
|
||||
#=#+1
|
||||
if h==w then #=#+# /*double count of rectangle cuts.*/
|
||||
else if w//2==0 & recur then call solve w,h,0
|
||||
return #
|
||||
/*──────────────────────────────────WALK subroutine─────────────────────*/
|
||||
walk: procedure expose # dir. @. h len next. w; 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*(w+1); @.t=@.t+1; _=len-t /* │ ordered by most likely►─┐*/
|
||||
@._=@._+1 /* └─────────────────────────┘*/
|
||||
do j=0 for 4; _ = t+next.j /*try 4 directions*/
|
||||
if @._==0 then call walk y+dir.j.0, x+dir.j.1
|
||||
end /*j*/
|
||||
@.t=@.t-1
|
||||
_=len-t; @._=@._-1
|
||||
return
|
||||
Loading…
Add table
Add a link
Reference in a new issue