Created
March 15, 2009 04:49
-
-
Save maraigue/79310 to your computer and use it in GitHub Desktop.
円周率の中から、日付とみなせる10桁の部分文字列を発見する
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| # 円周率の中から、日付とみなせる10桁の部分文字列を発見する | |
| # (http://d.hatena.ne.jp/hyuki/20090314#pi) | |
| # PI_STRは、円周率の小数第1位~500位を文字列で表したもの | |
| # from ftp://pi.super-computing.org/pub/pi10m/pi10m.ascii.01of10 | |
| PI_STR = ( | |
| "14159265358979323846264338327950288419716939937510"+ | |
| "58209749445923078164062862089986280348253421170679"+ | |
| "82148086513282306647093844609550582231725359408128"+ | |
| "48111745028410270193852110555964462294895493038196"+ | |
| "44288109756659334461284756482337867831652712019091"+ | |
| "45648566923460348610454326648213393607260249141273"+ | |
| "72458700660631558817488152092096282925409171536436"+ | |
| "78925903600113305305488204665213841469519415116094"+ | |
| "33057270365759591953092186117381932611793105118548"+ | |
| "07446237996274956735188575272489122793818301194912") | |
| # TRANS_TABLEは、日付のみを受理する有限オートマトン(FA)の遷移図 | |
| def rule_accept_all(dest) # どんな数字でもdestへ遷移する場合 | |
| ret = {} | |
| (0..9).each{ |i| ret[i] = dest } | |
| ret | |
| end | |
| def rule_accept_nonzero(dest) # 0以外だったらdestへ遷移する場合 | |
| ret = {} | |
| (1..9).each{ |i| ret[i] = dest } | |
| ret | |
| end | |
| def rule_accept_under5(dest) # 5以下だったらdestへ遷移する場合 | |
| ret = {} | |
| (0..5).each{ |i| ret[i] = dest } | |
| ret | |
| end | |
| TRANS_TABLE = { | |
| :A => {0=>:B, 1=>:C}, | |
| :B => {2=>:D, 1=>:E, 3=>:E, 5=>:E, 7=>:E, 8=>:E, | |
| 4=>:F, 6=>:F, 9=>:F}, | |
| :C => {0=>:E, 2=>:E, 1=>:F}, | |
| :D => {0=>:G, 1=>:H, 2=>:H}, | |
| :E => {0=>:G, 1=>:H, 2=>:H, 3=>:I}, | |
| :F => {0=>:G, 1=>:H, 2=>:H, 3=>:J}, | |
| :G => rule_accept_nonzero(:K), | |
| :H => rule_accept_all(:K), | |
| :I => {0=>:K, 1=>:K}, | |
| :J => {0=>:K}, | |
| :K => {0=>:L, 1=>:L, 2=>:M}, | |
| :L => rule_accept_all(:N), | |
| :M => {0=>:N, 1=>:N, 2=>:N, 3=>:N}, | |
| :N => rule_accept_under5(:O), | |
| :O => rule_accept_all(:P), | |
| :P => rule_accept_under5(:Q), | |
| :Q => rule_accept_all(:R)} | |
| INIT_STATE = :A # FAの開始状態 | |
| END_STATE = :R # FAの終了状態 | |
| # メイン部 | |
| class String | |
| def digit_at(pos) | |
| # 文字列のpos文字目が数字ならその数(Integer)を、 | |
| # そうでなければnilを返す | |
| tmp = self[pos] | |
| if (?0..?9).include?(tmp) | |
| tmp - ?0 | |
| else | |
| nil | |
| end | |
| end | |
| end | |
| def main | |
| for i in 0...(PI_STR.length-10) | |
| state = INIT_STATE | |
| for j in 0...10 | |
| state = TRANS_TABLE[state][PI_STR.digit_at(i+j)] | |
| case state | |
| when END_STATE | |
| puts "from digit #{i+1}: #{PI_STR[i,j+1]}" | |
| return | |
| when nil # nilになる=FAに拒否される(日付になっていない) | |
| break | |
| end | |
| end | |
| end | |
| end | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment