Automat:
Automat można „zwinąć” w ten sposób:
Na pierwszym grafie usunąłem ścieżki prowadzące do „martwych” stanów. Na drugim „zwinąłem” rogi – usunąłem je (te wierzchołki) jednocześnie wstawiając do grafu krawędzie, które zachowują równoważność z grafem z rogami. Na trzecim grafie zrobiłem osobny stan początkowy i osobny stan końcowy. Na czwartym usunąłem kolejny wierzchołek. Po czym stwierdziłem, że tyle kroków wystarczy by zobaczyć sens algorytmu, a efekt końcowy będzie równie nieczytelny co skrypt perlowy dude'a, więc pozostawię usunięcie reszty zbędnych wierzchołków czytelnikowi (ew. komuś przy tablicy).
\left(a(dc+cd)^*b+b(dc+cd)^*a+c(ab+ba)^*d+d(ab+ba)^*c + adbc + bdac + acbd + bcad + cadb + dacb + cbda + dbca\right)^*
Nie przechodzi adbacb
Wygenerowane programem w perlu, lol http://dude.bshellz.net/zad13.pl
#!/usr/bin/perl -w
use strict;
my $start;
my $finish;
my %trans;
while (<>) {
chomp;
next if !$_;
if (/^S:\s*(\(.*\))/) {
$start = $1;
} elsif (/^F:\s*(\(.*\))/) {
$finish = $1;
} elsif (/(\(.*?\))\s*-(.*?)>\s*(\(.*?\))/) {
if ($trans{$1}->{$3}) {
$trans{$1}->{$3} .= " + $2";
} else {
$trans{$1}->{$3} = "$2";
}
}
}
while (keys %trans > 1) {
for my $toremove (keys %{$trans{$start}}) {
next if $toremove eq $start;
my $loop = "";
if ($trans{$toremove}->{$toremove}) {
$loop = "($trans{$toremove}->{$toremove})*";
}
for my $neigh (keys %trans) {
next if $neigh eq $toremove;
next unless ($trans{$neigh}->{$toremove});
my $via = $trans{$neigh}->{$toremove};
$via = "($via)" if ($via =~ /(\+\s)/);
for my $dist (keys %{$trans{$toremove}}) {
next if $dist eq $toremove;
my $via2 = $trans{$toremove}->{$dist};
$via2 = "($via2)" if ($via2 =~ /(\+\s)/);
my $path = "$via$loop$via2";
if ($trans{$neigh}->{$dist}) {
$trans{$neigh}->{$dist} .= " + $path";
} else {
$trans{$neigh}->{$dist} = "$path";
}
}
delete $trans{$neigh}->{$toremove};
}
delete $trans{$toremove};
}
}
my $loop = "";
if ($trans{$start}->{$start}) {
$loop = "($trans{$start}->{$start})*";
}
my $path = "";
if ($trans{$start}->{$finish}) {
$path = $trans{$start}->{$finish};
}
$path = "$loop$path";
$path =~ s/e([a-df-z]+)/$1/g;
$path =~ s/([a-df-z]+)e/$1/g;
print "$path\n";
S: ( 0, 0) F: (A) ( 0, 0) -a> ( 1, 0) ( 0, 0) -b> (-1, 0) ( 0, 0) -c> ( 0, 1) ( 0, 0) -d> ( 0,-1) ( 0, 0) -e> (A) ( 1, 0) -a> (F) ( 1, 0) -b> ( 0, 0) ( 1, 0) -c> ( 1, 1) ( 1, 0) -d> ( 1,-1) (-1, 0) -a> ( 0, 0) (-1, 0) -b> (F) (-1, 0) -c> (-1, 1) (-1, 0) -d> (-1,-1) ( 0, 1) -a> ( 1, 1) ( 0, 1) -b> (-1, 1) ( 0, 1) -c> (F) ( 0, 1) -d> ( 0, 0) ( 0,-1) -a> ( 1,-1) ( 0,-1) -b> (-1,-1) ( 0,-1) -c> ( 0, 0) ( 0,-1) -d> (F) ( 1, 1) -a> (F) ( 1, 1) -b> ( 0, 1) ( 1, 1) -c> (F) ( 1, 1) -d> ( 1, 0) ( 1,-1) -a> (F) ( 1,-1) -b> ( 0,-1) ( 1,-1) -c> ( 1, 0) ( 1,-1) -d> (F) (-1, 1) -a> ( 0, 1) (-1, 1) -b> (F) (-1, 1) -c> (F) (-1, 1) -d> (-1, 0) (-1,-1) -a> ( 0,-1) (-1,-1) -b> (F) (-1,-1) -c> (-1, 0) (-1,-1) -d> (F)