いろんな言語でハノイの塔
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
いろんな言語でハノイの塔 [2019/06/27 23:32] – [awk] araki | いろんな言語でハノイの塔 [2021/04/30 12:38] (現在) – [Rust] araki | ||
---|---|---|---|
行 31: | 行 31: | ||
^bash |4.3.42 |Celeron N3150 (1.60GHz) |Vine Linux 6.5 |122 | | ^bash |4.3.42 |Celeron N3150 (1.60GHz) |Vine Linux 6.5 |122 | | ||
^awk (gawk) |3.1.8 |Celeron N3150 (1.60GHz) |Vine Linux 6.5 |8 | | ^awk (gawk) |3.1.8 |Celeron N3150 (1.60GHz) |Vine Linux 6.5 |8 | | ||
+ | ^go|1.16.0|Core i3 5010U (2.1GHz) |Ubuntu 20.4 LTS|0.004 | | ||
+ | ^Rust|1.47.0|Core i3 5010U (2.1GHz) |Ubuntu 20.4 LTS|0.004 | | ||
===== プログラム ===== | ===== プログラム ===== | ||
==== PowerShell ==== | ==== PowerShell ==== | ||
行 46: | 行 48: | ||
なお、デジタル署名するのが面倒くさかったので、実行にあたっては、実行ポリシーを'' | なお、デジタル署名するのが面倒くさかったので、実行にあたっては、実行ポリシーを'' | ||
((管理者権限でPowerShellを起動して'' | ((管理者権限でPowerShellを起動して'' | ||
+ | 管理者権限を使ってシステム全体のポリシーを変更するのがコワイ場合は、 | ||
+ | < | ||
+ | PS C: | ||
+ | </ | ||
+ | のようにして、実行中のプロセス内でのみ許可することも出来る。 | ||
+ | この方法には管理者権限は不要なので、気軽にスクリプトを試すことが出来る。 | ||
+ | |||
一般的な関数型言語が採用している、関数呼び出しと違い、引数を括弧でくくってカンマで区切ってはいけない。 | 一般的な関数型言語が採用している、関数呼び出しと違い、引数を括弧でくくってカンマで区切ってはいけない。 | ||
括弧でくくってカンマで区切るとそれは配列として、関数の第一引数に全て渡されてしまう。 | 括弧でくくってカンマで区切るとそれは配列として、関数の第一引数に全て渡されてしまう。 | ||
行 1077: | 行 1086: | ||
0.003u 0.005s 0:00.00 0.0% 0+0k 0+0io 0pf+0w | 0.003u 0.005s 0:00.00 0.0% 0+0k 0+0io 0pf+0w | ||
araki@chive[158]% | araki@chive[158]% | ||
+ | </ | ||
+ | ==== Go ==== | ||
+ | === 能書き === | ||
+ | Goは比較的新しいコンパイラ言語である。 | ||
+ | 静的型付けを基本とする言語であるが、メモリ管理は言語側が行い、ガベージコレクションなどの機能も内包している。 | ||
+ | |||
+ | 関数型言語であり、構造体を使った、オブジェクト指向っぽい記述もできる。 | ||
+ | |||
+ | === コード === | ||
+ | |||
+ | コマンドラインの引数をとるために flagを、表示の加工用に fmtモジュールを利用している以外は、コード内で完結している。 | ||
+ | |||
+ | < | ||
+ | package main | ||
+ | |||
+ | import ( | ||
+ | " | ||
+ | " | ||
+ | ) | ||
+ | |||
+ | type Discs int | ||
+ | |||
+ | type Hanoi struct { | ||
+ | N Discs | ||
+ | a int | ||
+ | b int | ||
+ | c int | ||
+ | } | ||
+ | |||
+ | func NewTower(n int) *Hanoi { | ||
+ | h := new(Hanoi) | ||
+ | h.N = Discs(n) | ||
+ | h.a = 1 | ||
+ | h.b = 2 | ||
+ | h.c = 3 | ||
+ | return h | ||
+ | } | ||
+ | |||
+ | func (n Discs) doit(a int, b int, c int) { | ||
+ | if n > 0 { | ||
+ | (n - 1).doit(a, c, b) | ||
+ | fmt.Printf(" | ||
+ | (n - 1).doit(c, b, a) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | func (h Hanoi) run() { | ||
+ | h.N.doit(h.a, | ||
+ | } | ||
+ | |||
+ | func main() { | ||
+ | n := flag.Int(" | ||
+ | flag.Parse() | ||
+ | hanoi := NewTower(*n) | ||
+ | hanoi.run() | ||
+ | } | ||
+ | </ | ||
+ | === 実行結果 === | ||
+ | |||
+ | < | ||
+ | araki@cherry: | ||
+ | Disc 1 moved from 1 to 3. | ||
+ | Disc 2 moved from 1 to 2. | ||
+ | Disc 1 moved from 3 to 2. | ||
+ | Disc 3 moved from 1 to 3. | ||
+ | Disc 1 moved from 2 to 1. | ||
+ | Disc 2 moved from 2 to 3. | ||
+ | Disc 1 moved from 1 to 3. | ||
+ | Disc 4 moved from 1 to 2. | ||
+ | Disc 1 moved from 3 to 2. | ||
+ | Disc 2 moved from 3 to 1. | ||
+ | Disc 1 moved from 2 to 1. | ||
+ | Disc 3 moved from 3 to 2. | ||
+ | Disc 1 moved from 1 to 3. | ||
+ | Disc 2 moved from 1 to 2. | ||
+ | Disc 1 moved from 3 to 2. | ||
+ | |||
+ | real 0m0.004s | ||
+ | user 0m0.005s | ||
+ | sys | ||
+ | araki@cherry: | ||
+ | </ | ||
+ | |||
+ | ==== Rust ==== | ||
+ | === 能書き === | ||
+ | システム記述言語として注目を集めているRust。 | ||
+ | メモリの管理が静的に行われており、予期せぬメモリリークなどによるセキュリティホールなどを言語レベルで防止できる。 | ||
+ | |||
+ | cargoを使用してひな型を作り、getoptsによるオプション処理を加えた。 | ||
+ | ハノイの塔本体部分より、オプションの処理部分のほうが大きい。 | ||
+ | なお、ハノイの塔部分に関しては特にオブジェクト指向的なつくりにはしていない。 | ||
+ | === コード === | ||
+ | コードは、RubyやPythonなどのスクリプト型言語と似た感じになっているが、静的な片付けが行われているところが、これらの言語とは違っている。 | ||
+ | また、ガベージコレクションによる動的なメモリ管理ではなく、静的な管理が中心となる。 | ||
+ | |||
+ | < | ||
+ | use getopts:: | ||
+ | use std:: | ||
+ | use std::env; | ||
+ | |||
+ | fn print_usage(prog_name: | ||
+ | { | ||
+ | let brief = format!(" | ||
+ | print!(" | ||
+ | process:: | ||
+ | } | ||
+ | |||
+ | fn hanoi(n: i32, a: i32, b: i32, c: i32) | ||
+ | { | ||
+ | if n > 0 | ||
+ | { | ||
+ | hanoi(n - 1, a, c, b); | ||
+ | println!(" | ||
+ | hanoi(n - 1, c, b, a); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | fn main() | ||
+ | { | ||
+ | let args: Vec< | ||
+ | let program = args[0].clone(); | ||
+ | |||
+ | let mut opts = Options:: | ||
+ | opts.optopt(" | ||
+ | opts.optflag(" | ||
+ | let matches = match opts.parse(& | ||
+ | { | ||
+ | Ok(m) => { m } | ||
+ | Err(f) => { panic!(f.to_string()) } | ||
+ | }; | ||
+ | if matches.opt_present(" | ||
+ | { | ||
+ | print_usage(& | ||
+ | return; | ||
+ | } | ||
+ | let n = match matches.opt_get_default::< | ||
+ | { | ||
+ | Ok(t) => { t } | ||
+ | Err(f) => { panic!(f.to_string()) } | ||
+ | }; | ||
+ | hanoi(n, 1, 2, 3); | ||
+ | } | ||
+ | </ | ||
+ | === 実行結果 === | ||
+ | < | ||
+ | araki@cherry: | ||
+ | Disc 1 moved from 1 to 3 | ||
+ | Disc 2 moved from 1 to 2 | ||
+ | Disc 1 moved from 3 to 2 | ||
+ | Disc 3 moved from 1 to 3 | ||
+ | Disc 1 moved from 2 to 1 | ||
+ | Disc 2 moved from 2 to 3 | ||
+ | Disc 1 moved from 1 to 3 | ||
+ | Disc 4 moved from 1 to 2 | ||
+ | Disc 1 moved from 3 to 2 | ||
+ | Disc 2 moved from 3 to 1 | ||
+ | Disc 1 moved from 2 to 1 | ||
+ | Disc 3 moved from 3 to 2 | ||
+ | Disc 1 moved from 1 to 3 | ||
+ | Disc 2 moved from 1 to 2 | ||
+ | Disc 1 moved from 3 to 2 | ||
+ | |||
+ | real 0m0.004s | ||
+ | user 0m0.003s | ||
+ | sys | ||
+ | araki@cherry: | ||
</ | </ | ||
いろんな言語でハノイの塔.1561678365.txt.gz · 最終更新: 2019/06/27 23:32 by araki