Subscribed unsubscribe Subscribe Subscribe

ハノイの塔ワンライナー

「とべとべ」で拝見しました、ハノイの塔。
http://tobe-tobe.kwappa.net/wiki/?event%2F2009-06-03%20vol.4
Perlで書くとどんなカンジに?と調べてみると以下のものを発見。
Hanoi: Perl
じゃあとりあえずコレをワンライナーにしてみよう、と少々の改造を加えて作ったのが、これ。

perl -le'sub h{my($n,$f,$t,$u)=@_;h($n-1,$f,$u,$t),print("$f->$t"),h($n-1,$u,$t,$f)if$n}h(pop,A,C,B)'

実行例:

$ perl -le'sub h{my($n,$f,$t,$u)=@_;h($n-1,$f,$u,$t),print("$f->$t"),h($n-1,$u,$t,$f)if$n}h(pop,A,C,B)' 4
A->B
A->C
B->C
A->B
C->A
C->B
A->B
A->C
B->C
B->A
C->A
B->C
A->B
A->C
B->C

Aに積まれているものをCに移すのに、どこからどこへ移すか、という解答を順番に表示する。


しかし変数が4つ出てきたりするのはなんかなぁ。と考えてたところ、配列のスライスを使えばもう少しきれいになりそう、と思いついて、書き直してみた。

perl -le'sub h{my$n=pop;h(@_[0,2,1],$n),print("$_[0]=>$_[2]"),h(@_[1,0,2],$n)if$n--}h(A..C,pop)'
$ perl -le'sub h{my$n=pop;h(@_[0,2,1],$n),print("$_[0]=>$_[2]"),h(@_[1,0,2],$n)if$n--}h(A..C,pop)' 4
A=>B
A=>C
B=>C
A=>B
C=>A
C=>B
A=>B
A=>C
B=>C
B=>A
C=>A
B=>C
A=>B
A=>C
B=>C

"->"が矢印演算子として展開しようとしてしまうので、"=>"に変更。5バイトくらいしか短くなってないけど自分なりに色々工夫したつもり。
他に良い方法はあるかなぁ。