Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pietソースコード精読

1,537 views

Published on

2015年5月24日. 京大マイコンクラブ部室.
第11回KMC学習発表会.

http://www.slideshare.net/KMC_JP/piet-46068527 を読め

Published in: Engineering
  • Be the first to comment

Pietソースコード精読

  1. 1. Pietソースコード精読 ID: hnagamin(長嶺英朗) 2015/05/24 第11回KMC学習発表会
  2. 2. おまえだれ ● ID: hnagamin(長嶺英朗) – KMC-2回生 – KMC38第会計 ● 京都大学工学部電気電子工学科2回 ● Piet歴2ヶ月 Twitter: @hnagamin GitHub: 1995hnagamin
  3. 3. 今日話すこと ● Pietの概要 ● プログラミングするときに考えること ● ソースコードの解説(逆ポーランド記法電卓の実装)
  4. 4. Pietの概要 http://www.slideshare.net/KMC_JP/piet-46068527 を読め(終了)
  5. 5. プログラミングするときに考えること ● 最初からゴルフをしない ● 解くべき問題の難易度を下げる – 超重要 – そもそも(人間が)Pietでできることはあまり多くない – 徐々に難易度を上げていくと士気が落ちない ● スタックの上での再帰 ● 黒ドットが少ないと良いプログラムみたいなとこある
  6. 6. 逆ポーランド記法電卓の実装
  7. 7. 背景 ● Pietでそれなりに(大きな|実用的な)プログラムを 書きたかった ● Pietはスタックの操作と相性が良いので、逆ポーラ ンド記法数式計算を実装することは完成度の割に 難易度が小さそうだと思った
  8. 8. 課題設定 ● とりあえず実装できることを確かめる – キャンバスが余っても気にしない ● 1桁の数字の入力だけ受け付ける – 複数桁の処理はつらい ● 四則演算くらいは実装する ● 知らない文字が出てきたらエラー処理 ● 終了記号を使おう – PietはEOFを受け取れない
  9. 9. 課題 逆ポーランド記法の数式を入力として受け取り、 その計算結果を出力する
  10. 10. 課題 受け付ける入力は以下とする <stmt> := <expr> <DOT> <expr> := <NUM> | <expr> <expr> <operator> <operator> := <PLUS> <MINUS> <MULT> <DIV> <NUM> [0­9] <DOT> . <PLUS> + <MINUS> ­ <MULT> * <DIV> /
  11. 11. 方針 ● 入力ストリームから1文字ずつ受け取る ● 受け取った文字が – '.'ならスタックの先頭要素を出力 – 数字なら対応する数をスタックにpush – 演算子ならスタックから2要素popして計算結果をpush – どれにも当てはまらなければエラーとして終了(“E”と出力)
  12. 12. イメージ stack<int> s; while (true) { char c = getchar(); if (c == '.') { int ans = s.top(); cout << ans; break; } else if (isdigit(c)) { s.push(c­48); } else if (c == '+') { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a + b); } else if (c == '­') { ...
  13. 13. イメージ stack<int> s; while (true) { char c = getchar(); if (c ­ 46 == 0) { int ans = s.top(); cout << ans; break; } else if (c > 47 && 58 > c) { s.push(c­48); } else if (c ­ 43 == 0) { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a + b); } else if (c ­ 43 == 0) { ...
  14. 14. 文字コード * 42 + 43 ­ 45 . 46 / 47 0 48
  15. 15. 実装
  16. 16. // ここでデモを行う
  17. 17. さらなる高みへ ● ソースコードのサイズを小さくしよう – エラー処理は省こう ● 複数桁の入力を受け付けよう
  18. 18. 課題 受け付ける入力は以下とする <stmt> := <expr> <DOT> <expr> := <NUM> | <expr> <expr> <operator> <operator> := <PLUS> <MINUS> <MULT> <DIV> <NUM> [0­9]+ <DOT> . <PLUS> + <MINUS> ­ <MULT> * <DIV> / (デリミタ) #Space
  19. 19. 複数桁の入力 ● 再帰する ● 保存している数を10倍しながら入力された数を 足しあわせていく
  20. 20. 動作例 入力: “2014+” スタック: [0]
  21. 21. 動作例 入力: “014+” スタック: [0,2] 入力を受け取る
  22. 22. 動作例 入力: “014+” スタック: [0,2] 保存している数を10倍する 0×10 = 0
  23. 23. 動作例 入力: “014+” スタック: [2] 足す
  24. 24. 動作例 入力: “14+” スタック: [2,0] 入力を受け取る
  25. 25. 動作例 入力: “14+” スタック: [20,0] 保存している数を10倍する
  26. 26. 動作例 入力: “14+” スタック: [20] 足す
  27. 27. 動作例 入力: “4+” スタック: [20,1] 入力を受け取る
  28. 28. 動作例 入力: “4+” スタック: [200,1] 保存している数を10倍する
  29. 29. 動作例 入力: “4+” スタック: [201] 足す
  30. 30. 動作例 入力: “+” スタック: [201,4] 入力を受け取る
  31. 31. 動作例 入力: “+” スタック: [2010,4] 保存している数を10倍する
  32. 32. 動作例 入力: “+” スタック: [2014] 足す
  33. 33. 動作例 入力: “” スタック: [2014,43(+)] 入力を受け取る
  34. 34. 動作例 入力: “” スタック: [2014,43(+)] 数字じゃないので終了
  35. 35. 実装
  36. 36. さらなる高みへ ● ゴルフをする ● ロジックは変えない ● コードの進む向きをうねらせる
  37. 37. 実装
  38. 38. もう話すことがない ● Pietは楽しい ● スタックで再帰するのは意外と簡単、意外と楽しい – 2変数くらいまでだったらなんとなくいける – 3変数以上でも多分何とかなる ● 書こう

×