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; }