Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
82
Task/Cut-a-rectangle/Go/cut-a-rectangle.go
Normal file
82
Task/Cut-a-rectangle/Go/cut-a-rectangle.go
Normal 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Task/Cut-a-rectangle/Perl-6/cut-a-rectangle.pl6
Normal file
75
Task/Cut-a-rectangle/Perl-6/cut-a-rectangle.pl6
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Task/Cut-a-rectangle/Perl/cut-a-rectangle.pl
Normal file
82
Task/Cut-a-rectangle/Perl/cut-a-rectangle.pl
Normal 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();
|
||||
|
|
@ -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
|
||||
|
|
|
|||
40
Task/Cut-a-rectangle/Ruby/cut-a-rectangle-1.rb
Normal file
40
Task/Cut-a-rectangle/Ruby/cut-a-rectangle-1.rb
Normal 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
|
||||
74
Task/Cut-a-rectangle/Ruby/cut-a-rectangle-2.rb
Normal file
74
Task/Cut-a-rectangle/Ruby/cut-a-rectangle-2.rb
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue