CDE
This commit is contained in:
parent
518da4a923
commit
764da6cbbb
6144 changed files with 83610 additions and 11 deletions
7
Task/Cut-a-rectangle/0DESCRIPTION
Normal file
7
Task/Cut-a-rectangle/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
A given rectangle is made from ''m'' × ''n'' squares. If ''m'' and ''n'' are not both odd, then it is possible to cut a path through the rectangle along the square edges such that the rectangle splits into two connected pieces with the same shape (after rotating one of the pieces by 180°). All such paths for 2 × 2 and 4 × 3 rectangles are shown below.
|
||||
|
||||
[[file:rect-cut.svg]]
|
||||
|
||||
Write a program that calculates the number of different ways to cut an ''m'' × ''n'' rectangle. Optionally, show each of the cuts.
|
||||
|
||||
Possibly related task: [[Maze generation]] for depth-first search.
|
||||
80
Task/Cut-a-rectangle/C/cut-a-rectangle-1.c
Normal file
80
Task/Cut-a-rectangle/C/cut-a-rectangle-1.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
byte *grid = 0;
|
||||
|
||||
int w, h, len;
|
||||
unsigned long long cnt;
|
||||
|
||||
static int next[4], dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
|
||||
void walk(int y, int x)
|
||||
{
|
||||
int i, t;
|
||||
|
||||
if (!y || y == h || !x || x == w) {
|
||||
cnt += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
t = y * (w + 1) + x;
|
||||
grid[t]++, grid[len - t]++;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (!grid[t + next[i]])
|
||||
walk(y + dir[i][0], x + dir[i][1]);
|
||||
|
||||
grid[t]--, grid[len - t]--;
|
||||
}
|
||||
|
||||
unsigned long long solve(int hh, int ww, int recur)
|
||||
{
|
||||
int t, cx, cy, x;
|
||||
|
||||
h = hh, w = ww;
|
||||
|
||||
if (h & 1) t = w, w = h, h = t;
|
||||
if (h & 1) return 0;
|
||||
if (w == 1) return 1;
|
||||
if (w == 2) return h;
|
||||
if (h == 2) return w;
|
||||
|
||||
cy = h / 2, cx = w / 2;
|
||||
|
||||
len = (h + 1) * (w + 1);
|
||||
grid = realloc(grid, len);
|
||||
memset(grid, 0, len--);
|
||||
|
||||
next[0] = -1;
|
||||
next[1] = -w - 1;
|
||||
next[2] = 1;
|
||||
next[3] = w + 1;
|
||||
|
||||
if (recur) cnt = 0;
|
||||
for (x = cx + 1; x < w; x++) {
|
||||
t = cy * (w + 1) + x;
|
||||
grid[t] = 1;
|
||||
grid[len - t] = 1;
|
||||
walk(cy - 1, x);
|
||||
}
|
||||
cnt++;
|
||||
|
||||
if (h == w)
|
||||
cnt *= 2;
|
||||
else if (!(w & 1) && recur)
|
||||
solve(w, h, 0);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int y, x;
|
||||
for (y = 1; y <= 10; y++)
|
||||
for (x = 1; x <= y; x++)
|
||||
if (!(x & 1) || !(y & 1))
|
||||
printf("%d x %d: %llu\n", y, x, solve(y, x, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
40
Task/Cut-a-rectangle/C/cut-a-rectangle-2.c
Normal file
40
Task/Cut-a-rectangle/C/cut-a-rectangle-2.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
2 x 1: 1
|
||||
2 x 2: 2
|
||||
3 x 2: 3
|
||||
4 x 1: 1
|
||||
4 x 2: 4
|
||||
4 x 3: 9
|
||||
4 x 4: 22
|
||||
5 x 2: 5
|
||||
5 x 4: 39
|
||||
6 x 1: 1
|
||||
6 x 2: 6
|
||||
6 x 3: 23
|
||||
6 x 4: 90
|
||||
6 x 5: 263
|
||||
6 x 6: 1018
|
||||
7 x 2: 7
|
||||
7 x 4: 151
|
||||
7 x 6: 2947
|
||||
8 x 1: 1
|
||||
8 x 2: 8
|
||||
8 x 3: 53
|
||||
8 x 4: 340
|
||||
8 x 5: 1675
|
||||
8 x 6: 11174
|
||||
8 x 7: 55939
|
||||
8 x 8: 369050
|
||||
9 x 2: 9
|
||||
9 x 4: 553
|
||||
9 x 6: 31721
|
||||
9 x 8: 1812667
|
||||
10 x 1: 1
|
||||
10 x 2: 10
|
||||
10 x 3: 115
|
||||
10 x 4: 1228
|
||||
10 x 5: 10295
|
||||
10 x 6: 118276
|
||||
10 x 7: 1026005
|
||||
10 x 8: 11736888
|
||||
10 x 9: 99953769
|
||||
10 x 10: 1124140214
|
||||
191
Task/Cut-a-rectangle/C/cut-a-rectangle-3.c
Normal file
191
Task/Cut-a-rectangle/C/cut-a-rectangle-3.c
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
int w = 0, h = 0, verbose = 0;
|
||||
unsigned long count = 0;
|
||||
|
||||
byte **hor, **ver, **vis;
|
||||
byte **c = 0;
|
||||
|
||||
enum { U = 1, D = 2, L = 4, R = 8 };
|
||||
|
||||
byte ** alloc2(int w, int h)
|
||||
{
|
||||
int i;
|
||||
byte **x = calloc(1, sizeof(byte*) * h + h * w);
|
||||
x[0] = (byte *)&x[h];
|
||||
for (i = 1; i < h; i++)
|
||||
x[i] = x[i - 1] + w;
|
||||
return x;
|
||||
}
|
||||
|
||||
void show()
|
||||
{
|
||||
int i, j, v, last_v;
|
||||
printf("%ld\n", count);
|
||||
#if 0
|
||||
for (i = 0; i <= h; i++) {
|
||||
for (j = 0; j <= w; j++)
|
||||
printf("%d ", hor[i][j]);
|
||||
puts("");
|
||||
}
|
||||
puts("");
|
||||
|
||||
for (i = 0; i <= h; i++) {
|
||||
for (j = 0; j <= w; j++)
|
||||
printf("%d ", ver[i][j]);
|
||||
puts("");
|
||||
}
|
||||
puts("");
|
||||
#endif
|
||||
for (i = 0; i < h; i++) {
|
||||
if (!i) v = last_v = 0;
|
||||
else last_v = v = hor[i][0] ? !last_v : last_v;
|
||||
|
||||
for (j = 0; j < w; v = ver[i][++j] ? !v : v)
|
||||
printf(v ? "\033[31m[]" : "\033[33m{}");
|
||||
puts("\033[m");
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void walk(int y, int x)
|
||||
{
|
||||
if (x < 0 || y < 0 || x > w || y > h) return;
|
||||
|
||||
if (!x || !y || x == w || y == h) {
|
||||
++count;
|
||||
if (verbose) show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (vis[y][x]) return;
|
||||
vis[y][x]++; vis[h - y][w - x]++;
|
||||
|
||||
if (x && !hor[y][x - 1]) {
|
||||
hor[y][x - 1] = hor[h - y][w - x] = 1;
|
||||
walk(y, x - 1);
|
||||
hor[y][x - 1] = hor[h - y][w - x] = 0;
|
||||
}
|
||||
if (x < w && !hor[y][x]) {
|
||||
hor[y][x] = hor[h - y][w - x - 1] = 1;
|
||||
walk(y, x + 1);
|
||||
hor[y][x] = hor[h - y][w - x - 1] = 0;
|
||||
}
|
||||
|
||||
if (y && !ver[y - 1][x]) {
|
||||
ver[y - 1][x] = ver[h - y][w - x] = 1;
|
||||
walk(y - 1, x);
|
||||
ver[y - 1][x] = ver[h - y][w - x] = 0;
|
||||
}
|
||||
|
||||
if (y < h && !ver[y][x]) {
|
||||
ver[y][x] = ver[h - y - 1][w - x] = 1;
|
||||
walk(y + 1, x);
|
||||
ver[y][x] = ver[h - y - 1][w - x] = 0;
|
||||
}
|
||||
|
||||
vis[y][x]--; vis[h - y][w - x]--;
|
||||
}
|
||||
|
||||
void cut(void)
|
||||
{
|
||||
if (1 & (h * w)) return;
|
||||
|
||||
hor = alloc2(w + 1, h + 1);
|
||||
ver = alloc2(w + 1, h + 1);
|
||||
vis = alloc2(w + 1, h + 1);
|
||||
|
||||
if (h & 1) {
|
||||
ver[h/2][w/2] = 1;
|
||||
walk(h / 2, w / 2);
|
||||
} else if (w & 1) {
|
||||
hor[h/2][w/2] = 1;
|
||||
walk(h / 2, w / 2);
|
||||
} else {
|
||||
vis[h/2][w/2] = 1;
|
||||
|
||||
hor[h/2][w/2-1] = hor[h/2][w/2] = 1;
|
||||
walk(h / 2, w / 2 - 1);
|
||||
hor[h/2][w/2-1] = hor[h/2][w/2] = 0;
|
||||
|
||||
ver[h/2 - 1][w/2] = ver[h/2][w/2] = 1;
|
||||
walk(h / 2 - 1, w/2);
|
||||
}
|
||||
}
|
||||
|
||||
void cwalk(int y, int x, int d)
|
||||
{
|
||||
if (!y || y == h || !x || x == w) {
|
||||
++count;
|
||||
return;
|
||||
}
|
||||
vis[y][x] = vis[h-y][w-x] = 1;
|
||||
|
||||
if (x && !vis[y][x-1])
|
||||
cwalk(y, x - 1, d|1);
|
||||
if ((d&1) && x < w && !vis[y][x+1])
|
||||
cwalk(y, x + 1, d|1);
|
||||
if (y && !vis[y-1][x])
|
||||
cwalk(y - 1, x, d|2);
|
||||
if ((d&2) && y < h && !vis[y + 1][x])
|
||||
cwalk(y + 1, x, d|2);
|
||||
|
||||
vis[y][x] = vis[h-y][w-x] = 0;
|
||||
}
|
||||
|
||||
void count_only(void)
|
||||
{
|
||||
int t;
|
||||
long res;
|
||||
if (h * w & 1) return;
|
||||
if (h & 1) t = h, h = w, w = t;
|
||||
|
||||
vis = alloc2(w + 1, h + 1);
|
||||
vis[h/2][w/2] = 1;
|
||||
|
||||
if (w & 1) vis[h/2][w/2 + 1] = 1;
|
||||
if (w > 1) {
|
||||
cwalk(h/2, w/2 - 1, 1);
|
||||
res = 2 * count - 1;
|
||||
count = 0;
|
||||
if (w != h)
|
||||
cwalk(h/2+1, w/2, (w & 1) ? 3 : 2);
|
||||
|
||||
res += 2 * count - !(w & 1);
|
||||
} else {
|
||||
res = 1;
|
||||
}
|
||||
if (w == h) res = 2 * res + 2;
|
||||
count = res;
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < c; i++) {
|
||||
if (v[i][0] == '-' && v[i][1] == 'v' && !v[i][2]) {
|
||||
verbose = 1;
|
||||
} else if (!w) {
|
||||
w = atoi(v[i]);
|
||||
if (w <= 0) goto bail;
|
||||
} else if (!h) {
|
||||
h = atoi(v[i]);
|
||||
if (h <= 0) goto bail;
|
||||
} else
|
||||
goto bail;
|
||||
}
|
||||
if (!w) goto bail;
|
||||
if (!h) h = w;
|
||||
|
||||
if (verbose) cut();
|
||||
else count_only();
|
||||
|
||||
printf("Total: %ld\n", count);
|
||||
return 0;
|
||||
|
||||
bail: fprintf(stderr, "bad args\n");
|
||||
return 1;
|
||||
}
|
||||
43
Task/Cut-a-rectangle/Common-Lisp/cut-a-rectangle-1.lisp
Normal file
43
Task/Cut-a-rectangle/Common-Lisp/cut-a-rectangle-1.lisp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
(defun cut-it (w h &optional (recur t))
|
||||
(if (oddp (* w h)) (return-from cut-it 0))
|
||||
(if (oddp h) (rotatef w h))
|
||||
(if (= w 1) (return-from cut-it h))
|
||||
|
||||
(let ((cnt 0)
|
||||
(m (make-array (list (1+ h) (1+ w))
|
||||
:element-type 'bit
|
||||
:initial-element 0))
|
||||
(cy (truncate h 2))
|
||||
(cx (truncate w 2)))
|
||||
|
||||
(setf (aref m cy cx) 1)
|
||||
(if (oddp w) (setf (aref m cy (1+ cx)) 1))
|
||||
|
||||
(labels
|
||||
((walk (y x turned)
|
||||
(when (or (= y 0) (= y h) (= x 0) (= x w))
|
||||
(incf cnt (if turned 2 1))
|
||||
(return-from walk))
|
||||
|
||||
(setf (aref m y x) 1)
|
||||
(setf (aref m (- h y) (- w x)) 1)
|
||||
(loop for i from 0
|
||||
for (dy dx) in '((0 -1) (-1 0) (0 1) (1 0))
|
||||
while (or turned (< i 2)) do
|
||||
(let ((y2 (+ y dy))
|
||||
(x2 (+ x dx)))
|
||||
(when (zerop (aref m y2 x2))
|
||||
(walk y2 x2 (or turned (> i 0))))))
|
||||
(setf (aref m (- h y) (- w x)) 0)
|
||||
(setf (aref m y x) 0)))
|
||||
|
||||
(walk cy (1- cx) nil)
|
||||
(cond ((= h w) (incf cnt cnt))
|
||||
((oddp w) (walk (1- cy) cx t))
|
||||
(recur (incf cnt (cut-it h w nil))))
|
||||
cnt)))
|
||||
|
||||
(loop for w from 1 to 9 do
|
||||
(loop for h from 1 to w do
|
||||
(if (evenp (* w h))
|
||||
(format t "~d x ~d: ~d~%" w h (cut-it w h)))))
|
||||
30
Task/Cut-a-rectangle/Common-Lisp/cut-a-rectangle-2.lisp
Normal file
30
Task/Cut-a-rectangle/Common-Lisp/cut-a-rectangle-2.lisp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
2 x 1: 2
|
||||
2 x 2: 2
|
||||
3 x 2: 3
|
||||
4 x 1: 4
|
||||
4 x 2: 4
|
||||
4 x 3: 9
|
||||
4 x 4: 22
|
||||
5 x 2: 5
|
||||
5 x 4: 39
|
||||
6 x 1: 6
|
||||
6 x 2: 6
|
||||
6 x 3: 23
|
||||
6 x 4: 90
|
||||
6 x 5: 263
|
||||
6 x 6: 1018
|
||||
7 x 2: 7
|
||||
7 x 4: 151
|
||||
7 x 6: 2947
|
||||
8 x 1: 8
|
||||
8 x 2: 8
|
||||
8 x 3: 53
|
||||
8 x 4: 340
|
||||
8 x 5: 1675
|
||||
8 x 6: 11174
|
||||
8 x 7: 55939
|
||||
8 x 8: 369050
|
||||
9 x 2: 9
|
||||
9 x 4: 553
|
||||
9 x 6: 31721
|
||||
9 x 8: 1812667
|
||||
88
Task/Cut-a-rectangle/D/cut-a-rectangle.d
Normal file
88
Task/Cut-a-rectangle/D/cut-a-rectangle.d
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import core.stdc.stdio, core.stdc.stdlib,
|
||||
core.stdc.string, std.typetuple;
|
||||
|
||||
template Range(int stop) { // for manual loop unroll
|
||||
static if (stop <= 0)
|
||||
alias TypeTuple!() Range;
|
||||
else
|
||||
alias TypeTuple!(Range!(stop-1), stop-1) Range;
|
||||
}
|
||||
|
||||
enum int[2][4] dir = [[0, -1], [-1, 0], [0, 1], [1, 0]];
|
||||
|
||||
__gshared ubyte[] grid;
|
||||
__gshared int w, h, len;
|
||||
__gshared ulong cnt;
|
||||
__gshared int[4] next;
|
||||
|
||||
void walk(in int y, in int x) nothrow {
|
||||
if (!y || y == h || !x || x == w) {
|
||||
cnt += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
immutable int t = y * (w + 1) + x;
|
||||
grid[t]++;
|
||||
grid[len - t]++;
|
||||
|
||||
foreach (i; Range!4) // manual loop unroll
|
||||
if (!grid[t + next[i]])
|
||||
walk(y + dir[i][0], x + dir[i][1]);
|
||||
|
||||
grid[t]--;
|
||||
grid[len - t]--;
|
||||
}
|
||||
|
||||
ulong solve(in int hh, in int ww, in bool recur) nothrow {
|
||||
h = (hh & 1) ? ww : hh;
|
||||
w = (hh & 1) ? hh : ww;
|
||||
|
||||
if (h & 1) return 0;
|
||||
if (w == 1) return 1;
|
||||
if (w == 2) return h;
|
||||
if (h == 2) return w;
|
||||
|
||||
immutable int cy = h / 2;
|
||||
immutable int cx = w / 2;
|
||||
|
||||
len = (h + 1) * (w + 1);
|
||||
{
|
||||
// grid = new ubyte[len]; // slower
|
||||
ubyte* ptr = cast(ubyte*)alloca(len);
|
||||
if (ptr == null)
|
||||
exit(1);
|
||||
grid = ptr[0 .. len];
|
||||
}
|
||||
grid[] = 0;
|
||||
len--;
|
||||
|
||||
//next = [-1, -w - 1, 1, w + 1]; // slow
|
||||
next[0] = -1;
|
||||
next[1] = -w - 1;
|
||||
next[2] = 1;
|
||||
next[3] = w + 1;
|
||||
|
||||
if (recur)
|
||||
cnt = 0;
|
||||
foreach (x; cx + 1 .. w) {
|
||||
immutable int t = cy * (w + 1) + x;
|
||||
grid[t] = 1;
|
||||
grid[len - t] = 1;
|
||||
walk(cy - 1, x);
|
||||
}
|
||||
cnt++;
|
||||
|
||||
if (h == w)
|
||||
cnt *= 2;
|
||||
else if (!(w & 1) && recur)
|
||||
solve(w, h, 0);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void main() {
|
||||
foreach (y; 1 .. 11)
|
||||
foreach (x; 1 .. y + 1)
|
||||
if (!(x & 1) || !(y & 1))
|
||||
printf("%d x %d: %llu\n", y, x, solve(y, x, true));
|
||||
}
|
||||
80
Task/Cut-a-rectangle/Haskell/cut-a-rectangle.hs
Normal file
80
Task/Cut-a-rectangle/Haskell/cut-a-rectangle.hs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import qualified Data.Vector.Unboxed.Mutable as V
|
||||
import Data.STRef
|
||||
import Control.Monad (forM_, when)
|
||||
import Control.Monad.ST
|
||||
|
||||
dir :: [(Int, Int)]
|
||||
dir = [(1, 0), (-1, 0), (0, -1), (0, 1)]
|
||||
|
||||
data Env = Env { w, h, len, count, ret :: !Int, next :: ![Int] }
|
||||
|
||||
cutIt :: STRef s Env -> ST s ()
|
||||
cutIt env = do
|
||||
e <- readSTRef env
|
||||
when (odd $ h e) $ modifySTRef env $ \en -> en { h = w e,
|
||||
w = h e }
|
||||
e <- readSTRef env
|
||||
if odd (h e)
|
||||
then modifySTRef env $ \en -> en { ret = 0 }
|
||||
else
|
||||
if w e == 1
|
||||
then modifySTRef env $ \en -> en { ret = 1 }
|
||||
else do
|
||||
let blen = (h e + 1) * (w e + 1) - 1
|
||||
t = (h e `div` 2) * (w e + 1) + (w e `div` 2)
|
||||
modifySTRef env $ \en -> en { len = blen,
|
||||
count = 0,
|
||||
next = [ w e + 1, (negate $ w e) - 1, -1, 1] }
|
||||
grid <- V.replicate (blen + 1) False
|
||||
case odd (w e) of
|
||||
True -> do
|
||||
V.write grid t True
|
||||
V.write grid (t + 1) True
|
||||
walk grid (h e `div` 2) (w e `div` 2 - 1)
|
||||
e1 <- readSTRef env
|
||||
let res1 = count e1
|
||||
modifySTRef env $ \en -> en { count = 0 }
|
||||
walk grid (h e `div` 2 - 1) (w e `div` 2)
|
||||
modifySTRef env $ \en -> en { ret = res1 +
|
||||
(count en * 2) }
|
||||
False -> do
|
||||
V.write grid t True
|
||||
walk grid (h e `div` 2) (w e `div` 2 - 1)
|
||||
e2 <- readSTRef env
|
||||
let count2 = count e2
|
||||
if h e == w e
|
||||
then modifySTRef env $ \en -> en { ret =
|
||||
count2 * 2 }
|
||||
else do
|
||||
walk grid (h e `div` 2 - 1)
|
||||
(w e `div` 2)
|
||||
modifySTRef env $ \en -> en { ret =
|
||||
count en }
|
||||
where
|
||||
walk grid y x = do
|
||||
e <- readSTRef env
|
||||
if y <= 0 || y >= h e || x <= 0 || x >= w e
|
||||
then modifySTRef env $ \en -> en { count = count en + 1 }
|
||||
else do
|
||||
let t = y * (w e + 1) + x
|
||||
V.write grid t True
|
||||
V.write grid (len e - t) True
|
||||
forM_ (zip (next e) [0..3]) $ \(n, d) -> do
|
||||
g <- V.read grid (t + n)
|
||||
when (not g) $
|
||||
walk grid (y + fst (dir !! d)) (x + snd (dir !! d))
|
||||
V.write grid t False
|
||||
V.write grid (len e - t) False
|
||||
|
||||
cut :: (Int, Int) -> Int
|
||||
cut (x, y) = runST $ do
|
||||
env <- newSTRef $ Env { w = y, h = x, len = 0, count = 0, ret = 0, next = [] }
|
||||
cutIt env
|
||||
result <- readSTRef env
|
||||
return $ ret result
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
mapM_ (\(x, y) -> when (even (x * y)) (putStrLn $
|
||||
show x ++ " x " ++ show y ++ ": " ++ show (cut (x, y))))
|
||||
[ (x, y) | x <- [1..10], y <- [1..x] ]
|
||||
53
Task/Cut-a-rectangle/Python/cut-a-rectangle-1.py
Normal file
53
Task/Cut-a-rectangle/Python/cut-a-rectangle-1.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
def cut_it(h, w):
|
||||
dirs = ((1, 0), (-1, 0), (0, -1), (0, 1))
|
||||
if h & 1: h, w = w, h
|
||||
if h & 1: return 0
|
||||
if w == 1: return 1
|
||||
count = 0
|
||||
|
||||
next = [w + 1, -w - 1, -1, 1]
|
||||
blen = (h + 1) * (w + 1) - 1
|
||||
grid = [False] * (blen + 1)
|
||||
|
||||
def walk(y, x, count):
|
||||
if not y or y == h or not x or x == w:
|
||||
return count + 1
|
||||
|
||||
t = y * (w + 1) + x
|
||||
grid[t] = grid[blen - t] = True
|
||||
|
||||
if not grid[t + next[0]]:
|
||||
count = walk(y + dirs[0][0], x + dirs[0][1], count)
|
||||
if not grid[t + next[1]]:
|
||||
count = walk(y + dirs[1][0], x + dirs[1][1], count)
|
||||
if not grid[t + next[2]]:
|
||||
count = walk(y + dirs[2][0], x + dirs[2][1], count)
|
||||
if not grid[t + next[3]]:
|
||||
count = walk(y + dirs[3][0], x + dirs[3][1], count)
|
||||
|
||||
grid[t] = grid[blen - t] = False
|
||||
return count
|
||||
|
||||
t = h // 2 * (w + 1) + w // 2
|
||||
if w & 1:
|
||||
grid[t] = grid[t + 1] = True
|
||||
count = walk(h // 2, w // 2 - 1, count)
|
||||
res = count
|
||||
count = 0
|
||||
count = walk(h // 2 - 1, w // 2, count)
|
||||
return res + count * 2
|
||||
else:
|
||||
grid[t] = True
|
||||
count = walk(h // 2, w // 2 - 1, count)
|
||||
if h == w:
|
||||
return count * 2
|
||||
count = walk(h // 2 - 1, w // 2, count)
|
||||
return count
|
||||
|
||||
def main():
|
||||
for w in xrange(1, 10):
|
||||
for h in xrange(1, w + 1):
|
||||
if not((w * h) & 1):
|
||||
print "%d x %d: %d" % (w, h, cut_it(w, h))
|
||||
|
||||
main()
|
||||
70
Task/Cut-a-rectangle/Python/cut-a-rectangle-2.py
Normal file
70
Task/Cut-a-rectangle/Python/cut-a-rectangle-2.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
try:
|
||||
import psyco
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
psyco.full()
|
||||
|
||||
w, h = 0, 0
|
||||
count = 0
|
||||
vis = []
|
||||
|
||||
def cwalk(y, x, d):
|
||||
global vis, count, w, h
|
||||
if not y or y == h or not x or x == w:
|
||||
count += 1
|
||||
return
|
||||
|
||||
vis[y][x] = vis[h - y][w - x] = 1
|
||||
|
||||
if x and not vis[y][x - 1]:
|
||||
cwalk(y, x - 1, d | 1)
|
||||
if (d & 1) and x < w and not vis[y][x+1]:
|
||||
cwalk(y, x + 1, d|1)
|
||||
if y and not vis[y - 1][x]:
|
||||
cwalk(y - 1, x, d | 2)
|
||||
if (d & 2) and y < h and not vis[y + 1][x]:
|
||||
cwalk(y + 1, x, d | 2)
|
||||
|
||||
vis[y][x] = vis[h - y][w - x] = 0
|
||||
|
||||
def count_only(x, y):
|
||||
global vis, count, w, h
|
||||
count = 0
|
||||
w = x
|
||||
h = y
|
||||
|
||||
if (h * w) & 1:
|
||||
return count
|
||||
if h & 1:
|
||||
w, h = h, w
|
||||
|
||||
vis = [[0] * (w + 1) for _ in xrange(h + 1)]
|
||||
vis[h // 2][w // 2] = 1
|
||||
|
||||
if w & 1:
|
||||
vis[h // 2][w // 2 + 1] = 1
|
||||
|
||||
res = 0
|
||||
if w > 1:
|
||||
cwalk(h // 2, w // 2 - 1, 1)
|
||||
res = 2 * count - 1
|
||||
count = 0
|
||||
if w != h:
|
||||
cwalk(h // 2 + 1, w // 2, 3 if (w & 1) else 2)
|
||||
|
||||
res += 2 * count - (not (w & 1))
|
||||
else:
|
||||
res = 1
|
||||
|
||||
if w == h:
|
||||
res = 2 * res + 2
|
||||
return res
|
||||
|
||||
def main():
|
||||
for y in xrange(1, 10):
|
||||
for x in xrange(1, y + 1):
|
||||
if not (x & 1) or not (y & 1):
|
||||
print "%d x %d: %d" % (y, x, count_only(x, y))
|
||||
|
||||
main()
|
||||
45
Task/Cut-a-rectangle/REXX/cut-a-rectangle.rexx
Normal file
45
Task/Cut-a-rectangle/REXX/cut-a-rectangle.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 big integers.*/
|
||||
parse arg N .; if N=='' then N=10 /*Not specified? Use the 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.*/
|
||||
/*──────────────────────────────────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 call walk y+dir.j.0, x+dir.j.1
|
||||
end /*j*/
|
||||
|
||||
@.t=@.t-1; _=len-t; @._=@._-1
|
||||
return
|
||||
/*──────────────────────────────────S subroutine────────────────────────*/
|
||||
s: if arg(1)=1 then return arg(3); return word(arg(2) 's',1)
|
||||
/*──────────────────────────────────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 ½. */
|
||||
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 /*compute direction dist*/
|
||||
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 #
|
||||
82
Task/Cut-a-rectangle/Tcl/cut-a-rectangle.tcl
Normal file
82
Task/Cut-a-rectangle/Tcl/cut-a-rectangle.tcl
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
proc walk {y x} {
|
||||
global w ww h cnt grid len
|
||||
if {!$y || $y==$h || !$x || $x==$w} {
|
||||
incr cnt 2
|
||||
return
|
||||
}
|
||||
set t [expr {$y*$ww + $x}]
|
||||
set m [expr {$len - $t}]
|
||||
lset grid $t [expr {[lindex $grid $t] + 1}]
|
||||
lset grid $m [expr {[lindex $grid $m] + 1}]
|
||||
if {![lindex $grid [expr {$y*$ww + $x-1}]]} {
|
||||
walk $y [expr {$x-1}]
|
||||
}
|
||||
if {![lindex $grid [expr {($y-1)*$ww + $x}]]} {
|
||||
walk [expr {$y-1}] $x
|
||||
}
|
||||
if {![lindex $grid [expr {$y*$ww + $x+1}]]} {
|
||||
walk $y [expr {$x+1}]
|
||||
}
|
||||
if {![lindex $grid [expr {($y+1)*$ww + $x}]]} {
|
||||
walk [expr {$y+1}] $x
|
||||
}
|
||||
lset grid $t [expr {[lindex $grid $t] - 1}]
|
||||
lset grid $m [expr {[lindex $grid $m] - 1}]
|
||||
}
|
||||
|
||||
# Factored out core of [solve]
|
||||
proc SolveCore {} {
|
||||
global w ww h cnt grid len
|
||||
set ww [expr {$w+1}]
|
||||
set cy [expr {$h / 2}]
|
||||
set cx [expr {$w / 2}]
|
||||
|
||||
set len [expr {($h+1) * $ww}]
|
||||
set grid [lrepeat $len 0]
|
||||
incr len -1
|
||||
|
||||
for {set x $cx;incr x} {$x < $w} {incr x} {
|
||||
set t [expr {$cy*$ww+$x}]
|
||||
lset grid $t 1
|
||||
lset grid [expr {$len - $t}] 1
|
||||
walk [expr {$cy - 1}] $x
|
||||
}
|
||||
incr cnt
|
||||
}
|
||||
proc solve {H W} {
|
||||
global w h cnt
|
||||
set h $H
|
||||
set w $W
|
||||
if {$h & 1} {
|
||||
set h $W
|
||||
set w $H
|
||||
}
|
||||
if {$h & 1} {
|
||||
return 0
|
||||
}
|
||||
if {$w==1} {return 1}
|
||||
if {$w==2} {return $h}
|
||||
if {$h==2} {return $w}
|
||||
|
||||
set cnt 0
|
||||
SolveCore
|
||||
if {$h==$w} {
|
||||
incr cnt $cnt
|
||||
} elseif {!($w & 1)} {
|
||||
lassign [list $w $h] h w
|
||||
SolveCore
|
||||
}
|
||||
return $cnt
|
||||
}
|
||||
|
||||
apply {{limit} {
|
||||
for {set yy 1} {$yy <= $limit} {incr yy} {
|
||||
for {set xx 1} {$xx <= $yy} {incr xx} {
|
||||
if {!($xx&1 && $yy&1)} {
|
||||
puts [format "%d x %d: %ld" $yy $xx [solve $yy $xx]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}} 10
|
||||
Loading…
Add table
Add a link
Reference in a new issue