Unfortunately, it doesn't produce the correct results:#!/usr/bin/perl use strict; print_interleave(1,1); print_interleave(2,1); print_interleave(1,2); print_interleave(2,2); print_interleave(3,3); print_interleave(4,14); print_interleave(7,4); sub print_interleave { my ($total_a, $total_b) = @_; print '(', $total_a, ', ', $total_b, ")\t"; print interleave($total_a, $total_b), "\n"; } sub interleave { my ($remaining_a, $remaining_b) = @_; if ($remaining_a > 1) { return 'A' . interleave($remaining_a - 2, $remaining_b) . 'A'; } elsif ($remaining_b > 1) { return 'B' . interleave($remaining_a, $remaining_b - 2) . 'B'; } elsif ($remaining_a == 1) { return 'A'; } elsif ($remaining_b == 1) { return 'B'; } else { return ''; # Just for completeness } }
As for how to terminate it, every time interleave() calls itself, it reduces either $remaining_a or $remaining_b. One of them will eventually reach 0 and terminate that branch of the recursion. Since nothing in interleave() ever increases them, all branches will terminate.(1, 1) A (2, 1) ABA (1, 2) BAB (2, 2) ABBA (3, 3) ABABA (4, 14) AABBBBBBBBBBBBBBAA (7, 4) AAABBABBAAA
UPDATE: Replacing the above interleave() with this interleave2()
appears to produce correct results:sub interleave2 { my ($remaining_a, $remaining_b) = @_; if ($remaining_a > 1 && $remaining_b) { my $b_range = int($remaining_b/($remaining_a - 1)); return 'A' . 'B' x $b_range . interleave2($remaining_a - 1, $remai +ning_b - $b_range); } elsif ($remaining_a) { return 'A' . interleave2($remaining_a - 1, $remaining_b); } elsif ($remaining_b) { return 'B' . interleave2($remaining_a, $remaining_b - 1); } else { return ''; # Just for completeness } }
(1, 1) AB (2, 1) ABA (1, 2) ABB (2, 2) ABBA (3, 3) ABABBA (4, 14) ABBBBABBBBBABBBBBA (7, 4) AAABABABABA
In reply to Re^3: Spreading out the elements
by dsheroh
in thread Spreading out the elements
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |