2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
41
Task/Cut-a-rectangle/Elixir/cut-a-rectangle-1.elixir
Normal file
41
Task/Cut-a-rectangle/Elixir/cut-a-rectangle-1.elixir
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import Integer
|
||||
|
||||
defmodule Rectangle do
|
||||
def cut_it(h, w) when is_odd(h) and is_odd(w), do: 0
|
||||
def cut_it(h, w) when is_odd(h), do: cut_it(w, h)
|
||||
def cut_it(_, 1), do: 1
|
||||
def cut_it(h, 2), do: h
|
||||
def cut_it(2, w), do: w
|
||||
def cut_it(h, w) do
|
||||
grid = List.duplicate(false, (h + 1) * (w + 1))
|
||||
t = div(h, 2) * (w + 1) + div(w, 2)
|
||||
if is_odd(w) do
|
||||
grid = grid |> List.replace_at(t, true) |> List.replace_at(t+1, true)
|
||||
walk(h, w, div(h, 2), div(w, 2) - 1, grid) + walk(h, w, div(h, 2) - 1, div(w, 2), grid) * 2
|
||||
else
|
||||
grid = grid |> List.replace_at(t, true)
|
||||
count = walk(h, w, div(h, 2), div(w, 2) - 1, grid)
|
||||
if h == w, do: count * 2,
|
||||
else: count + walk(h, w, div(h, 2) - 1, div(w, 2), grid)
|
||||
end
|
||||
end
|
||||
|
||||
defp walk(h, w, y, x, grid, count\\0)
|
||||
defp walk(h, w, y, x,_grid, count) when y in [0,h] or x in [0,w], do: count+1
|
||||
defp walk(h, w, y, x, grid, count) do
|
||||
blen = (h + 1) * (w + 1) - 1
|
||||
t = y * (w + 1) + x
|
||||
grid = grid |> List.replace_at(t, true) |> List.replace_at(blen-t, true)
|
||||
Enum.reduce(next(w), count, fn {nt, dy, dx}, cnt ->
|
||||
if Enum.at(grid, t+nt), do: cnt, else: cnt + walk(h, w, y+dy, x+dx, grid)
|
||||
end)
|
||||
end
|
||||
|
||||
defp next(w), do: [{w+1, 1, 0}, {-w-1, -1, 0}, {-1, 0, -1}, {1, 0, 1}] # {next,dy,dx}
|
||||
end
|
||||
|
||||
Enum.each(1..9, fn w ->
|
||||
Enum.each(1..w, fn h ->
|
||||
if is_even(w * h), do: IO.puts "#{w} x #{h}: #{Rectangle.cut_it(w, h)}"
|
||||
end)
|
||||
end)
|
||||
77
Task/Cut-a-rectangle/Elixir/cut-a-rectangle-2.elixir
Normal file
77
Task/Cut-a-rectangle/Elixir/cut-a-rectangle-2.elixir
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
defmodule Rectangle do
|
||||
def cut(h, w, disp\\true) when rem(h,2)==0 or rem(w,2)==0 do
|
||||
limit = div(h * w, 2)
|
||||
start_link
|
||||
grid = make_grid(h, w)
|
||||
walk(h, w, grid, 0, 0, limit, %{}, [])
|
||||
if disp, do: display(h, w)
|
||||
result = Agent.get(__MODULE__, &(&1))
|
||||
Agent.stop(__MODULE__)
|
||||
MapSet.to_list(result)
|
||||
end
|
||||
|
||||
defp start_link do
|
||||
Agent.start_link(fn -> MapSet.new end, name: __MODULE__)
|
||||
end
|
||||
|
||||
defp make_grid(h, w) do
|
||||
for i <- 0..h-1, j <- 0..w-1, into: %{}, do: {{i,j}, true}
|
||||
end
|
||||
|
||||
defp walk(h, w, grid, x, y, limit, cut, select) do
|
||||
grid2 = grid |> Map.put({x,y}, false) |> Map.put({h-x-1,w-y-1}, false)
|
||||
select2 = [{x,y} | select] |> Enum.sort
|
||||
unless cut[select2] do
|
||||
if length(select2) == limit do
|
||||
Agent.update(__MODULE__, fn set -> MapSet.put(set, select2) end)
|
||||
else
|
||||
cut2 = Map.put(cut, select2, true)
|
||||
search_next(grid2, select2)
|
||||
|> Enum.each(fn {i,j} -> walk(h, w, grid2, i, j, limit, cut2, select2) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp dirs(x, y), do: [{x+1, y}, {x-1, y}, {x, y-1}, {x, y+1}]
|
||||
|
||||
defp search_next(grid, select) do
|
||||
(for {x,y} <- select, {i,j} <- dirs(x,y), grid[{i,j}], do: {i,j})
|
||||
|> Enum.uniq
|
||||
end
|
||||
|
||||
defp display(h, w) do
|
||||
Agent.get(__MODULE__, &(&1))
|
||||
|> Enum.each(fn select ->
|
||||
grid = Enum.reduce(select, make_grid(h,w), fn {x,y},grid ->
|
||||
%{grid | {x,y} => false}
|
||||
end)
|
||||
IO.puts to_string(h, w, grid)
|
||||
end)
|
||||
end
|
||||
|
||||
defp to_string(h, w, grid) do
|
||||
text = for x <- 0..h*2, into: %{}, do: {x, String.duplicate(" ", w*4+1)}
|
||||
text = Enum.reduce(0..h, text, fn i,acc ->
|
||||
Enum.reduce(0..w, acc, fn j,txt ->
|
||||
to_s(txt, i, j, grid)
|
||||
end)
|
||||
end)
|
||||
Enum.map_join(0..h*2, "\n", fn i -> text[i] end)
|
||||
end
|
||||
|
||||
defp to_s(text, i, j, grid) do
|
||||
text = if grid[{i,j}] != grid[{i-1,j}], do: replace(text, i*2, j*4+1, "---"), else: text
|
||||
text = if grid[{i,j}] != grid[{i,j-1}], do: replace(text, i*2+1, j*4, "|"), else: text
|
||||
replace(text, i*2, j*4, "+")
|
||||
end
|
||||
|
||||
defp replace(text, x, y, replacement) do
|
||||
len = String.length(replacement)
|
||||
Map.update!(text, x, fn str ->
|
||||
String.slice(str, 0, y) <> replacement <> String.slice(str, y+len..-1)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
Rectangle.cut(2, 2) |> length |> IO.puts
|
||||
Rectangle.cut(3, 4) |> length |> IO.puts
|
||||
66
Task/Cut-a-rectangle/Java/cut-a-rectangle.java
Normal file
66
Task/Cut-a-rectangle/Java/cut-a-rectangle.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import java.util.*;
|
||||
|
||||
public class CutRectangle {
|
||||
|
||||
private static int[][] dirs = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
|
||||
|
||||
public static void main(String[] args) {
|
||||
cutRectangle(2, 2);
|
||||
cutRectangle(4, 3);
|
||||
}
|
||||
|
||||
static void cutRectangle(int w, int h) {
|
||||
if (w % 2 == 1 && h % 2 == 1)
|
||||
return;
|
||||
|
||||
int[][] grid = new int[h][w];
|
||||
Stack<Integer> stack = new Stack<>();
|
||||
|
||||
int half = (w * h) / 2;
|
||||
long bits = (long) Math.pow(2, half) - 1;
|
||||
|
||||
for (; bits > 0; bits -= 2) {
|
||||
|
||||
for (int i = 0; i < half; i++) {
|
||||
int r = i / w;
|
||||
int c = i % w;
|
||||
grid[r][c] = (bits & (1 << i)) != 0 ? 1 : 0;
|
||||
grid[h - r - 1][w - c - 1] = 1 - grid[r][c];
|
||||
}
|
||||
|
||||
stack.push(0);
|
||||
grid[0][0] = 2;
|
||||
int count = 1;
|
||||
while (!stack.empty()) {
|
||||
|
||||
int pos = stack.pop();
|
||||
int r = pos / w;
|
||||
int c = pos % w;
|
||||
|
||||
for (int[] dir : dirs) {
|
||||
|
||||
int nextR = r + dir[0];
|
||||
int nextC = c + dir[1];
|
||||
|
||||
if (nextR >= 0 && nextR < h && nextC >= 0 && nextC < w) {
|
||||
|
||||
if (grid[nextR][nextC] == 1) {
|
||||
stack.push(nextR * w + nextC);
|
||||
grid[nextR][nextC] = 2;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count == half) {
|
||||
printResult(grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void printResult(int[][] arr) {
|
||||
for (int[] a : arr)
|
||||
System.out.println(Arrays.toString(a));
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
|
@ -63,13 +63,11 @@ sub solve(Int $hh, Int $ww, Int $recur) returns Int {
|
|||
return $cnt;
|
||||
}
|
||||
|
||||
sub MAIN {
|
||||
my ($y, $x);
|
||||
loop ($y = 1; $y <= 10; $y++) {
|
||||
loop ($x = 1; $x <= $y; $x++) {
|
||||
if (!($x +& 1) || !($y +& 1)) {
|
||||
printf("%d x %d: %d\n", $y, $x, solve($y, $x, 1));
|
||||
}
|
||||
my ($y, $x);
|
||||
loop ($y = 1; $y <= 10; $y++) {
|
||||
loop ($x = 1; $x <= $y; $x++) {
|
||||
if (!($x +& 1) || !($y +& 1)) {
|
||||
printf("%d x %d: %d\n", $y, $x, solve($y, $x, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*────────────────────────────── 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*/
|
||||
dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*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.*/
|
||||
|
|
@ -11,35 +11,35 @@ dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*four directions*/
|
|||
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
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
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 rect. coördinates*/
|
||||
parse arg hh 1 h,ww 1 w,recur /*obtain the values for some arguments.*/
|
||||
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 & 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: 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
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
/*────────────────────────────── 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*/
|
||||
dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*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.*/
|
||||
|
|
@ -11,45 +11,45 @@ dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*four directions*/
|
|||
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
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
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 rect. coördinates*/
|
||||
parse arg hh 1 h,ww 1 w,recur /*obtain the values for some arguments.*/
|
||||
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 & 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: 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 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue