PROGRAMMING IN HASKELL

Slides:



Advertisements
Similar presentations
プログラミング言語論 第3回 BNF 記法について(演習付き) 篠埜 功. 構文の記述 プログラミング言語の構文はどのように定式化できるか? 例1 : for ループの中に for ループが書ける。 for (i=0; i
Advertisements

模擬国内予選2013 Problem F テトラ姫のパズル 原案:須藤 解答:大友、須藤 解説:須藤.
0章 数学基礎.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
到着時刻と燃料消費量を同時に最適化する船速・航路計画
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
プログラムのパタン演習 解説.
Problem J Tile Puzzle 原案:野田 担当:平野,吉田,泉,松本.
プログラミング言語としてのR 情報知能学科 白井 英俊.
Ex7. Search for Vacuum Problem
Ex8. Search for Vacuum Problem(2)
最適化ソルバーのための Python言語入門
はじめに 教科書 プログラミングHaskell Graham Hutton (著), 山本 和彦 (翻訳) オーム社、全 232 ページ
型宣言 (Type Declarations)
遺伝アルゴリズムによる NQueen解法 ~遺伝補修飾を用いた解探索の性能評価~
型宣言(Type Declarations)
論理式の表現を数学的に取り扱いやすくするために代数学の助けを借りる.
香川大学工学部 富永浩之 情報数学1 第5-2章 命題論理式の 同値変形とカルノー表 香川大学工学部 富永浩之
整数計画法を用いた ペグソリティアの解法 ver. 2.1
情報処理Ⅱ 2005年12月9日(金).
条件式 (Conditional Expressions)
模擬国内予選2014 Problem C 壊れた暗号生成器
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
データ構造とアルゴリズム論 第2章 配列(構造)を使った処理
2007/1/11 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
10.通信路符号化手法2 (誤り検出と誤り訂正符号)
メソッド名とその周辺の識別子の 相関ルールに基づくメソッド名変更支援手法
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
table 'results' SELECT name, teacher FROM results;
第5回 統計処理(2) 塩浦 昭義 東北大学全学教育科目 情報基礎 A 1セメスター 木曜1,3講時 経済学部・法学部
データ構造と アルゴリズム 第十一回 理工学部 情報システム工学科 新田直也.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
プログラミング言語論 第3回 BNF記法について(演習付き)
第25章 単一始点最短路 3節 Bellman-Fordのアルゴリズム
PROGRAMMING IN HASKELL
第10回関数 Ⅱ (ローカル変数とスコープ).
PROGRAMMING IN HASKELL
6. リスト処理関数の設計(発展版) プログラミング論 I.
お仕事にまったく役にたたない内容のコードレビューやりたいと思います。
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
Where is Wumpus Propositional logic (cont…) Reasoning where is wumpus
国立情報学研究所 ソフトウェア研究系 助教授/
クイズやゲーム形式で紹介した実例です。いずれも過去のインターン作です。
Cプログラムの理解を 支援するナビゲーション機能
知能情報システム特論 Introduction
Ex7. Search for Vacuum Problem
フロントエンドとバックエンドのインターフェース
第6章:リストとデータフレーム 10月23日発表 藤井 丈明
統計ソフトウエアRの基礎.
アルゴリズムとプログラミング (Algorithms and Programming)
Type Systems and Programming Languages
プログラミング 3 2 次元配列.
計算の理論 I -数学的概念と記法- 火曜 12:50~14:20 大月 美佳 2004年4月20日.
PROGRAMMING IN HASKELL
計算の理論 I -数学的概念と記法- 月曜3校時 大月 美佳.
発表者: 稲葉 一浩 複雑ネットワーク・地図グラフ セミナー 2017/1/19
PROGRAMMING IN HASKELL
Eijiro Sumii and Naoki Kobayashi University of Tokyo
~sumii/class/proenb2010/ml5/
香川大学工学部 富永浩之 情報数学1 第5-2章 命題論理式の 同値変形とカルノー表 香川大学工学部 富永浩之
PROGRAMMING IN HASKELL
参考:大きい要素の処理.
Haskell Programming Language
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
第3章 関係データベースの基礎 3.1 関係とは 3.2 関係代数.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
情報処理Ⅱ 第8回:2003年12月9日(火).
Presentation transcript:

PROGRAMMING IN HASKELL Chapter 11 - The Countdown Problem 切符番号遊び 愛知県立大学 情報科学部 計算機言語論(山本晋一郎・大久保弘崇、2013年)講義資料 オリジナルは http://www.cs.nott.ac.uk/~gmh/book.html を参照のこと

切符番号遊び (Countdown) とは 英国のテレビで 1982 年から放送されている人気のクイズ番組 フランス版の "Des Chiffres et Des Lettres" がオリジナル そのクイズ番組に切符番号遊びと呼ばれる 数を用いたゲームがあった

Example 以下の数 と算術演算子 を使って値が 765 になる式を作れるか? 1 3 7 10 25 50 括弧も使って良い + -   を使って値が 765 になる式を作れるか? 765

ゲームのルール 計算の途中結果を含む全ての数は、正の自然数(1, 2, 3, ...) であること 与えられた自然数を 2 回以上使ってはいけない テレビ番組では他のルールもあったが省略する

先ほどの例では、以下の式は正解の一つ = 注意: 780 個の正解が存在する 値を 831 に変えると、正解は無い (25-10)  (50+1) 765 = 注意: 780 個の正解が存在する 値を 831 に変えると、正解は無い 831

式を評価する 演算子を表すデータ型 Op: 演算子を引数に適用する apply: data Op = Add | Sub | Mul | Div 演算子を引数に適用する apply: apply :: Op  Int  Int  Int apply Add x y = x + y apply Sub x y = x - y apply Mul x y = x * y apply Div x y = x `div` y

演算子を 2 つの自然数に適用した結果が、 自然数か否かを判定する述語 valid: valid :: Op  Int  Int  Bool valid Add _ _ = True valid Sub x y = x > y valid Mul _ _ = True valid Div x y = x `mod` y == 0 式を表すデータ型 Expr: 式は、自然数そのものか、 2 つの式への演算子の適用 data Expr = Val Int | App Op Expr Expr

長さ 1 の自然数リストは成功、 空リストは失敗 式の値を求める eval ただし、値は自然数であること: eval :: Expr  [Int] eval (Val n) = [n | n > 0] eval (App o l r) = [apply o x y | x  eval l , y  eval r , valid o x y] 長さ 1 の自然数リストは成功、 空リストは失敗

進行 以下の順序で説明を行う 問題の定式化 わかりやすいが遅いプログラム 効率化の手法 正解か否かを判定する述語を定義する 全ての式 (解の候補) を順に生成し、正解か否か判定する 効率化の手法 無駄な解候補の生成を減らす

問題の形式化 リストから 0 個以上の要素を取り出す方法の順列をリストにする choices: For example: choices :: [a]  [[a]] For example: > choices [1,2] [[],[1],[2],[1,2],[2,1]]

式の中の全ての自然数をリストにする values: values :: Expr  [Int] values (Val n) = [n] values (App _ l r) = values l ++ values r 式 e が、自然数リスト ns と目標の自然数 n で与えられる切符番号遊びの正解か判定する述語 solution: solution :: Expr  [Int]  Int  Bool solution e ns n = elem (values e) (choices ns) && eval e == [n]

実行例

総当たりな解法 リストを 2 つの非空リストに分割する方法のすべてをリストにする関数 split: For example: split :: [a]  [([a],[a])] For example: > split [1,2,3,4] [([1],[2,3,4]),([1,2],[3,4]),([1,2,3],[4])]

与えられた自然数の全部を使ってできる、全ての式を リストにする exprs: exprs :: [Int]  [Expr] exprs [] = [] exprs [n] = [Val n] exprs ns = [e | (ls,rs)  split ns , l  exprs ls , r  exprs rs , e  combine l r] この章のキーとなる関数

2 つの式を、全ての演算子で繋ぐ combine: combine :: Expr  Expr  [Expr] combine l r = [App o l r | o  [Add,Sub,Mul,Div]] 切符番号遊びの全ての正解のリストを返す solutions: solutions :: [Int]  Int  [Expr] solutions ns n = [e | ns'  choices ns , e  exprs ns' , eval e == [n]]

どのくらいの速さか? System: Compiler: Example: One solution: All solutions: 1.2GHz Pentium M laptop GHC version 6.4.1 0.36 seconds 43.98 seconds solutions [1,3,7,10,25,50] 765

さらに良い方法は? 生成した多くの式の値が自然数ではないため無駄になる 例では、3300 万の式のうち 500 万だけが自然数 生成と評価を組み合わせれば、無駄な式を早期に除外できる

2 つの関数を融合する 正しい式とその値を組を表すデータ型 Result: 式の生成と評価を融合した関数 results: type Result = (Expr,Int) 式の生成と評価を融合した関数 results: results :: [Int]  [Result] results ns = [(e,n) | e  exprs ns , n  eval e]

This behaviour is achieved by defining results [] = [] results [n] = [(Val n,n) | n > 0] results ns = [res | (ls,rs)  split ns , lx  results ls , ry  results rs , res  combine' lx ry] where combine' :: Result  Result  [Result]

切符番号遊びを解く新しい関数 solutions’: 結果を結合する combine’: combine’ (l,x) (r,y) = [(App o l r, apply o x y) | o  [Add,Sub,Mul,Div] , valid o x y] 切符番号遊びを解く新しい関数 solutions’: solutions' :: [Int]  Int  [Expr] solutions' ns n = [e | ns'  choices ns , (e,m)  results ns' , m == n]

Around 10 times faster in both cases. 速くなったか? Example: One solution: All solutions: solutions' [1,3,7,10,25,50] 765 0.04 seconds 3.47 seconds Around 10 times faster in both cases.

さらなる高速化は? 多くの式は、算術式の性質により本質的に同じとみなせる、例えば: = x  y y  x x  1 x = この性質を用いると、探索すべき式と正解の数を減らすことができる

代数則の利用 交換律と単位元を考慮して、正しい式をより制限する valid: valid :: Op  Int  Int  Bool Add x y と Add y x はどちらか一方で十分 Mul x y と Mul y x も同様 さらに、Mul x 1 と Mul 1 y は、どちらも不要 Div x 1 も同様 代数則の利用 交換律と単位元を考慮して、正しい式をより制限する valid: valid :: Op  Int  Int  Bool valid Add x y = True valid Sub x y = x > y valid Mul x y = True valid Div x y = x `mod` y == 0 x  y x  y && x  1 x  y && x  1 && y  1 x  y && y  1

ふたたび、速くなったか? Example: Valid: Around 20 times less. Solutions: 250,000 expressions 49 expressions Around 16 times less.

Around 2 times faster. One solution: All solutions: 0.02 seconds 0.44 seconds Around 7 times faster. テレビ番組で出される問題の 1 つの正解なら、瞬く間に求めることができる。全ての正解でも、1 秒以下だろう。

Example 以下の数と 算術演算子を使って 値が 765 になる式を作れるか? 1 3 7 10 25 50 + -   765

Changing the target number to gives an example that has no solutions. 先ほどの例では、以下の式は正解の一つ (25-10)  (50+1) 765 = Notes: 780個の正解が存在する Changing the target number to gives an example that has no solutions. 831