use strict;
use warnings;
use Test::More;
use POSIX;
my @TESTS
= (
[(0, 0) => undef],
[(0, 1) => undef],
[(1, 0) => undef],
[(1, 1) => 'AB'],
[(2, 1) => 'ABA'],
[(3, 1) => { map {$_=>1} qw(ABAA AABA)}],
[(4, 1) => { map {$_=>1} qw(ABAAA AABAA AAABA)}],
[(1, 2) => { map {$_=>1} qw(ABB BBA BAB)}],
[(2, 2) => 'ABBA'],
[(7, 6) => 'ABABABABABABA'],
[(3, 3) => { map {$_=>1} qw(ABBABA ABABBA)}],
[(4, 14) => { map {$_=>1} qw(
ABBBBABBBBBABBBBBA
ABBBBBABBBBABBBBBA
ABBBBBABBBBBABBBBA
)}],
);
plan tests => scalar @TESTS;
for my $test (@TESTS) {
my $skewer;
my ($n_a, $n_b, $expected) = @$test;
eval {
$skewer = interleave( $n_a, $n_b );
};
if ($@) {
ok(
!defined( $expected ),
"($n_a, $n_b) => undef"
);
next;
}
if (ref $expected) {
ok(
exists $expected->{ $skewer },
"($n_a, $n_b) => $skewer"
);
}
else {
ok(
$expected eq $skewer,
"($n_a, $n_b) => $skewer"
);
}
}
exit( 0 );
##-------------------------------------------------------------------+
sub interleave {
my ($n_a, $n_b) = @_;
if ($n_a < 1 or $n_b < 1) {
die "Bad args to interleave: ($n_a, $n_b)";
}
if ($n_a == 1) {
return 'A' . 'B' x $n_b;
}
my $min_b = floor( $n_b / ($n_a - 1) );
my $leftover_b = $n_b - $min_b * ($n_a - 1);
##warn "($n_a, $n_b) => min_b:$min_b, lefto:$leftover_b";
my $skewer = 'A';
for (1..$leftover_b) {
$skewer .= 'B' x ($min_b + 1);
$skewer .= 'A';
}
for ($leftover_b + 1 .. $n_a - 1) {
$skewer .= 'B' x $min_b;
$skewer .= 'A';
}
##warn "returning ($n_a, $n_b) => $skewer";
return $skewer;
}
prints:
1..12
ok 1 - (0, 0) => undef
ok 2 - (0, 1) => undef
ok 3 - (1, 0) => undef
ok 4 - (1, 1) => AB
ok 5 - (2, 1) => ABA
ok 6 - (3, 1) => ABAA
ok 7 - (4, 1) => ABAAA
ok 8 - (1, 2) => ABB
ok 9 - (2, 2) => ABBA
ok 10 - (7, 6) => ABABABABABABA
ok 11 - (3, 3) => ABBABA
ok 12 - (4, 14) => ABBBBBABBBBBABBBBA