Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,12 +1,4 @@
import core.stdc.stdio, core.stdc.stdlib,
core.stdc.string, std.typetuple;
template Range(uint stop) { // For loop unwinding.
static if (stop <= 0)
alias TypeTuple!() Range;
else
alias TypeTuple!(Range!(stop - 1), stop - 1) Range;
}
import core.stdc.stdio, core.stdc.stdlib, core.stdc.string, std.typecons;
enum int[2][4] dir = [[0, -1], [-1, 0], [0, 1], [1, 0]];
@ -15,7 +7,7 @@ __gshared uint w, h, len;
__gshared ulong cnt;
__gshared uint[4] next;
void walk(in uint y, in uint x) nothrow {
void walk(in uint y, in uint x) nothrow @nogc {
if (!y || y == h || !x || x == w) {
cnt += 2;
return;
@ -25,7 +17,7 @@ void walk(in uint y, in uint x) nothrow {
grid[t]++;
grid[len - t]++;
foreach (i; Range!4) // Manual loop unwinding.
foreach (immutable i; staticIota!(0, 4))
if (!grid[t + next[i]])
walk(y + dir[i][0], x + dir[i][1]);
@ -33,7 +25,7 @@ void walk(in uint y, in uint x) nothrow {
grid[len - t]--;
}
ulong solve(in uint hh, in uint ww, in bool recur) nothrow {
ulong solve(in uint hh, in uint ww, in bool recur) nothrow @nogc {
h = (hh & 1) ? ww : hh;
w = (hh & 1) ? hh : ww;

View file

@ -0,0 +1,82 @@
package main
import "fmt"
var grid []byte
var w, h, last int
var cnt int
var next [4]int
var dir = [4][2]int{{0, -1}, {-1, 0}, {0, 1}, {1, 0}}
func walk(y, x int) {
if y == 0 || y == h || x == 0 || x == w {
cnt += 2
return
}
t := y*(w+1) + x
grid[t]++
grid[last-t]++
for i, d := range dir {
if grid[t+next[i]] == 0 {
walk(y+d[0], x+d[1])
}
}
grid[t]--
grid[last-t]--
}
func solve(hh, ww, recur int) int {
h = hh
w = ww
if h&1 != 0 {
h, w = w, h
}
switch {
case h&1 == 1:
return 0
case w == 1:
return 1
case w == 2:
return h
case h == 2:
return w
}
cy := h / 2
cx := w / 2
grid = make([]byte, (h+1)*(w+1))
last = len(grid) - 1
next[0] = -1
next[1] = -w - 1
next[2] = 1
next[3] = w + 1
if recur != 0 {
cnt = 0
}
for x := cx + 1; x < w; x++ {
t := cy*(w+1) + x
grid[t] = 1
grid[last-t] = 1
walk(cy-1, x)
}
cnt++
if h == w {
cnt *= 2
} else if w&1 == 0 && recur != 0 {
solve(w, h, 0)
}
return cnt
}
func main() {
for y := 1; y <= 10; y++ {
for x := 1; x <= y; x++ {
if x&1 == 0 || y&1 == 0 {
fmt.Printf("%d x %d: %d\n", y, x, solve(y, x, 1))
}
}
}
}

View file

@ -0,0 +1,75 @@
subset Byte of Int where ^256;
my @grid of Byte = 0;
my Int ($w, $h, $len);
my Int $cnt = 0;
my @next;
my @dir = [0, -1], [-1, 0], [0, 1], [1, 0];
sub walk(Int $y, Int $x) {
my ($i, $t);
if !$y || $y == $h || !$x || $x == $w {
$cnt += 2;
return;
}
$t = $y * ($w + 1) + $x;
@grid[$t]++, @grid[$len - $t]++;
loop ($i = 0; $i < 4; $i++) {
if !@grid[$t + @next[$i]] {
walk($y + @dir[$i][0], $x + @dir[$i][1]);
}
}
@grid[$t]--, @grid[$len - $t]--;
}
sub solve(Int $hh, Int $ww, Int $recur) returns Int {
my ($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 div 2, $cx = $w div 2;
$len = ($h + 1) * ($w + 1);
@grid = ();
@grid[$len--] = 0;
@next[0] = -1;
@next[1] = -$w - 1;
@next[2] = 1;
@next[3] = $w + 1;
if $recur { $cnt = 0; }
loop ($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;
} elsif !($w +& 1) && $recur {
solve($w, $h, 0);
}
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));
}
}
}
}

View file

@ -0,0 +1,82 @@
use strict;
use warnings;
my @grid = 0;
my ($w, $h, $len);
my $cnt = 0;
my @next;
my @dir = ([0, -1], [-1, 0], [0, 1], [1, 0]);
sub walk {
my ($y, $x) = @_;
if (!$y || $y == $h || !$x || $x == $w) {
$cnt += 2;
return;
}
my $t = $y * ($w + 1) + $x;
$grid[$_]++ for $t, $len - $t;
for my $i (0 .. 3) {
if (!$grid[$t + $next[$i]]) {
walk($y + $dir[$i]->[0], $x + $dir[$i]->[1]);
}
}
$grid[$_]-- for $t, $len - $t;
}
sub solve {
my ($hh, $ww, $recur) = @_;
my ($t, $cx, $cy, $x);
($h, $w) = ($hh, $ww);
if ($h & 1) { ($t, $w, $h) = ($w, $h, $w); }
if ($h & 1) { return 0; }
if ($w == 1) { return 1; }
if ($w == 2) { return $h; }
if ($h == 2) { return $w; }
{
use integer;
($cy, $cx) = ($h / 2, $w / 2);
}
$len = ($h + 1) * ($w + 1);
@grid = ();
$grid[$len--] = 0;
@next = (-1, -$w - 1, 1, $w + 1);
if ($recur) { $cnt = 0; }
for ($x = $cx + 1; $x < $w; $x++) {
$t = $cy * ($w + 1) + $x;
@grid[$t, $len - $t] = (1, 1);
walk($cy - 1, $x);
}
$cnt++;
if ($h == $w) {
$cnt *= 2;
} elsif (!($w & 1) && $recur) {
solve($w, $h);
}
return $cnt;
}
sub MAIN {
print "ok\n";
my ($y, $x);
for my $y (1 .. 10) {
for my $x (1 .. $y) {
if (!($x & 1) || !($y & 1)) {
printf("%d x %d: %d\n", $y, $x, solve($y, $x, 1));
}
}
}
}
MAIN();

View file

@ -1,7 +1,7 @@
/*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?*/
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.*/
@ -11,31 +11,22 @@ dir.=0; dir.0.1=-1; dir.1.0=-1; dir.2.1=1; dir.3.0=1 /*directions.*/
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)
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 ½. */
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
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*/
@ -43,3 +34,17 @@ if recur then #=0
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

View file

@ -0,0 +1,40 @@
def cut_it(h, w)
if h.odd?
return 0 if w.odd?
h, w = w, h
end
return 1 if w == 1
nxt = [[w+1, 1, 0], [-w-1, -1, 0], [-1, 0, -1], [1, 0, 1]] # [next,dy,dx]
blen = (h + 1) * (w + 1) - 1
grid = [false] * (blen + 1)
walk = lambda do |y, x, count=0|
return count+1 if y==0 or y==h or x==0 or x==w
t = y * (w + 1) + x
grid[t] = grid[blen - t] = true
nxt.each do |nt, dy, dx|
count += walk[y + dy, x + dx] unless grid[t + nt]
end
grid[t] = grid[blen - t] = false
count
end
t = h / 2 * (w + 1) + w / 2
if w.odd?
grid[t] = grid[t + 1] = true
count = walk[h / 2, w / 2 - 1]
count + walk[h / 2 - 1, w / 2] * 2
else
grid[t] = true
count = walk[h / 2, w / 2 - 1]
return count * 2 if h == w
count + walk[h / 2 - 1, w / 2]
end
end
for w in 1..9
for h in 1..w
puts "%d x %d: %d" % [w, h, cut_it(w, h)] if (w * h).even?
end
end

View file

@ -0,0 +1,74 @@
class Rectangle
DIRS = [[1, 0], [-1, 0], [0, -1], [0, 1]]
def initialize(h, w)
raise ArgumentError if (h.odd? and w.odd?) or h<=0 or w<=0
@h, @w = h, w
@limit = h * w / 2
end
def cut(disp=true)
@cut = {}
@select = []
@result = []
@grid = make_grid
walk(0,0)
display if disp
@result
end
def make_grid
Array.new(@h+1) {|i| Array.new(@w+1) {|j| true if i<@h and j<@w }}
end
def walk(y, x)
@grid[y][x] = @grid[@h-y-1][@w-x-1] = false
@select.push([y,x])
select = @select.sort
unless @cut[select]
@cut[select] = true
if @select.size == @limit
@result << select
else
search_next.each {|yy,xx| walk(yy,xx)}
end
end
@select.pop
@grid[y][x] = @grid[@h-y-1][@w-x-1] = true
end
def search_next
nxt = {}
@select.each do |y,x|
DIRS.each do |dy, dx|
nxt[[y+dy, x+dx]] = true if @grid[y+dy][x+dx]
end
end
nxt.keys
end
def display
@result.each do |select|
@grid = make_grid
select.each {|y,x| @grid[y][x] = false}
puts to_s
end
end
def to_s
text = Array.new(@h*2+1) {" " * (@w*4+1)}
for i in 0..@h
for j in 0..@w
text[i*2][j*4+1,3] = "---" if @grid[i][j] != @grid[i-1][j]
text[i*2+1][j*4] = "|" if @grid[i][j] != @grid[i][j-1]
text[i*2][j*4] = "+"
end
end
text.join("\n")
end
end
rec = Rectangle.new(2,2)
puts rec.cut.size
rec = Rectangle.new(3,4)
puts rec.cut.size