Other replies mentioned the "prefer ones" algorithm. If you think, instead, of it as a "prefer last" algorithm, it appears to work for your stated problem. Start with T of the first character. Then try to add the last character to the answer, moving from last character to second last character to third last character, etc., as long as a repetition exists.
#!/usr/bin/perl -l # http://perlmonks.org/?node_id=1188292 use strict; use warnings; my $n = shift // 3; # alphabet size my $t = shift // $n; # size of tuples my @alphabet = ('A'..'Z', '0'..'9', 'a'..'z'); my %previous; @previous{@alphabet[1..$#alphabet]} = @alphabet; # last to 2nd last, e +tc. my $need = $n ** $t + $t - 1; # length of the answer $_ = $alphabet[0] x $t; # start string with first chars printf "%77s\n", $_ while s/^ (?=(.{$t})) (?=.+\1) . /$previous{$&}/x # prev char if repeat or $need > length && s/^/$alphabet[$n - 1]/; # or add last char print; # the answer my $chars = join '', @alphabet[0..$n-1]; # test if valid /^[$chars]+$/ or die "invalid character"; my %all; $all{$1}++ while /(?=(.{$t}))/g; print "\nwant @{[ $n ** $t ]} unique tuples, have @{[ scalar keys %all + ]}"; print "solution passes tests";
I haven't found a case yet where backtracking is required.
In reply to Re: Generic De Bruijn Sequence
by tybalt89
in thread Generic De Bruijn Sequence
by QM
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |