2014年3月9日

スーパーなどで自分の並んだレジがいつも遅く感じる件に関して

レジの進み具合を決定する要因としては、レジ担当者の能力、顧客の購入商品数、支払方法など不確定な要素が多すぎて、どのレジに並ぶか決定をせまられた時に瞬時に判断することが不可能という前提で話をすすめると、どのレジも遅れる、あるいは早く進むことは等しく起こると考えることになると思います
等しく起こるとは、すなわちサイコロを振ってどの目がでるかを事前に予測することは事実上不可能と考えることと、スーパーのレジでどの列が早く進むかは同じ問題だと考えることになります
なので、どのレジが遅れるか、処理が早いかは確率の問題で考えることになると思います
例えばスーパーのレジが10ある場合、自分の並んだレジが一番早く進むことは1/10の確率で起こります
逆に9/10は自分の並んだレジ以外のレジが早く進みます
平均から考えると他のレジ5つより早くすすめば自分の並んでいるレジが平均より早くすすんでいるはずなのに、人間は自分の並んだレジではなく、他のレジが一つでも早くすすむと遅いと感じると思うので9/10は遅いと感じることになると考えられます
レジで会計するという行為は必要と感じてもレジに並ぶという行為自体不要と考えるのが普通だと思うので、早く進んだ印象より遅れる印象が残りやすいので、レジに並ぶこと自体の印象が悪くなる循環にあると考えます

この文章を読んだ方へ
これからは自分の並んだレジが一番最初に進むことは稀と考え対処していくことをオススメします
あるいは、レジで並んでいる最中に前後の方がイライラしている場合は、並んでいる間にこのことを伝えてあげてはいかがでしょうか.

2014年3月3日

アナフォリックマクロ

アナフォリックマクロって偉大だな
アナフォリックマクロ使えるだけでもCommon Lisp使う意味あるかと思えてくるくらい偉大だ
やっぱりマクロは偉大だ
アナフォリックマクロの存在を知ってしまうと、ifで調べた式の戻り値をとっておくとかいちいち書くことがいやでいやで仕方がなくなるよな

2014年2月25日

codejamの過去問でcommon lispの練習2

問題は2013のqualification round B

結果用の高さ100の芝生を用意して、入力される刈り込みたい候補案を高さ100のものに適用する
適用は、入力縦横一行取り出して、その一行の一番高いものを結果用に当てはめる
当てはめる際に入力より高い場合は入力値に合わせる
すでに入力より低い場合はそのまま
縦横当てはめて結果用と入力が同じかどうか判定


(defmacro form1(x) `(format t "~A~%" ,x))

(defun repeat(x n)
  (labels ((rec(i acc)
    (if (= i n)
      acc
      (rec (1+ i) (cons x acc)))))
 (rec 0 nil)))

(defun range(n)
  (labels ((rec(i acc)
    (if (= i n)
      (reverse acc)
      (rec (1+ i) (cons i acc)))))
 (rec 0 nil)))

(defun readstream(callback)
  (labels ((rec(n)
    (let ((line (read-line *standard-input* nil)))
      (when line
     (funcall callback line n)
     (rec (1+ n))))))
 (rec 0)))

(defun parseNM(line)
  (read-from-string (format nil "(~A)" line)))

(defun maxval(lst)
  (reduce #'max (cdr lst) :initial-value (car lst)))

(defun toverticalvals(lst)
  (mapcar (lambda(i)
   (reduce (lambda(r x) (max r (nth i x))) (cdr lst) :initial-value (nth i (car lst))))
 (range (length (car lst)))))

(defun applyverticalvals(lst vlst)
  (mapcar (lambda(r) (mapcar #'min r vlst)) lst))

(defun compute(in)
  (labels ((rec(in acc)
    (if (null in)
      (reverse acc)
      (rec (cdr in) (cons (repeat (maxval (car in)) (length (car in))) acc)))))
 (equal in (applyverticalvals (rec in nil) (toverticalvals in))))
  )

(defun test()
  ;(form1 (toverticalvals '((2 1 2) (1 8 1) (2 1 3))))
  ;(form1 (range 10))
  ;(form1 (maxval '(8 7 6 5 4 3 2)))
  )
(test)

(let ((in nil)
   (no_of_problem 0)
   (problemindex 0)
   (size '(1 0))
   (nextsizeindex 1)
   (messagelut '((t . "YES") (nil . "NO"))))
  (readstream (lambda(line n)
    ;(format t "~A ~A ~A~%" n nextsizeindex line)
    (cond ((zerop n) (setf no_of_problem (read-from-string line)))
       ((= n nextsizeindex) (incf problemindex) (setf size (parseNM line)) (setf nextsizeindex (+ nextsizeindex (car size) 1)) (setf in nil))
       (t (setf in (cons (parseNM line) in)) (when (= n (1- nextsizeindex))
                 (format t "Case #~A: ~A~%" problemindex (cdr (assoc (compute (reverse in)) messagelut)))))
       )
    )
     )
  )

2014年2月18日

codejamの過去問でcommon lispの練習

codejamの季節が近づいてきたのでcommon lispの練習をしました
問題は2013のqualification round

まずA
入力をアトムへ置き換えて横向きのリストで格納して、さらに縦向きのリストと斜めのリストを作ってX,Oどちらかが勝っている状態があるか検索
とりあえず横向きで検索、見つからなかったら縦向きで検索、さらに見つからなかったら斜めで検索
X,Oどちらの勝利状態も見つからない場合引き分けかどうか判定
マクロの練習として、縦向きのリストの作成をマクロで展開してみました
例えば将棋やオセロなんかのプログラムだとリストを走査する際にループじゃなくていちいち展開しているっぽいなと思ったので、一度マクロで試してみたかったので無理やりマクロ使いましたが結果はいいのか悪いのか不明
プログラムが分かりにくくなったのはとりあえず分かる


(defun readstream(callback)
  (labels ((rec(n)
    (let ((line (read-line *standard-input* nil)))
      (when line
     (funcall callback line n)
     (rec (1+ n))))))
 (rec 0)))

(let ((a '(0 1 2 3)))
  (defun tosymb(line)
 (mapcar (lambda(n) (read-from-string (substitute #\B #\. line) nil nil :start n :end (1+ n))) a))
  (defmacro tocross(lst)
 `(list
    (list ,@(mapcar (lambda(n) `(nth ,n (nth ,n ,lst))) a))
    (list ,@(mapcar (lambda(n) `(nth (- 3 ,n) (nth ,n ,lst))) a))
    ))
  (defmacro tovertical(lst)
 `(list
    ,@(mapcar (lambda(m)
     (cons 'list (mapcar (lambda(n) `(nth ,m (nth ,n ,lst))) a))
     ) a)
    )
 )
  (defun makelst(b n)
 (mapcar (lambda(m) (if (= n m) 't b)) a))

  (defmacro searcher(lst v)
 `(let ((target ',(mapcar (lambda(n) (makelst v n)) a)))
    (labels ((rec(ta)
      (cond ((null ta) nil)
      ((equal (car ta) ,lst) ',v)
      (t (rec (cdr ta))))))
   (rec (cons (list ',v ',v ',v ',v) target))
    )
 ))
  )

(defun hanbetsu(inlst)
  (labels ((rec(lst)
    (cond ((null lst) nil)
       ((searcher (car lst) x) 'x)
       ((searcher (car lst) o) 'o)
       (t (rec (cdr lst))))))
 (rec inlst)))

(defun drawp(lst)
  (labels ((rec(lst)
    (cond ((null lst) 'd)
       ((find 'b (car lst)) 'n)
       (t (rec (cdr lst))))))
 (rec lst)))

(defmacro ifelse(pred else)
  `(let ((r ,pred))
  (if r
    r
    (progn ,else))))

(defun test()
  (let ((lst '((a b c d) (e f g h) (i j k l) (m n o p))))
 (format t "~A~%" (macroexpand-1 '(ifelse (hanbetsu (tocross in)) (lambda()))))
 ;(format t "~A~%" (drawp '((a z c d e))))
 ;(format t "~A~%" (mapcar (lambda(n) (makelst 'x n)) '(0 1 2 3)))
 ;(format t "~A~%" (macroexpand-1 '(searcher (car lst) x)))
 ;(format t "~A~%" (hanbetsu '((x x t x))))
 ;(format t "~A~%" (macroexpand-1 '(tocross lst)))
 ;(format t "~A~%" (tocross lst))
 ;(format t "~A~%" (macroexpand-1 '(tovertical lst)))
 ;(format t "~A~%" (tovertical lst))
 (format t "~%~%")
 ))
;(test)

(defun compute(in)
  (ifelse (hanbetsu (tocross in))
    (ifelse (hanbetsu (tovertical in))
      (ifelse (hanbetsu in)
        (drawp in)))))

(let ((in nil)
   (index 0)
   (messagelut '((x . "X won") (o . "O won") (d . "Draw") (n . "Game has not completed"))))
  (readstream (lambda(line n)
    (cond ((zerop (rem n 5)) (setf in nil) (incf index))
    ((= (rem n 5) 4)
     (progn
    (setf in (cons (tosymb line) in))
    (format t "Case #~A: ~A~%" index (cdr (assoc (compute (reverse in)) messagelut)))
    ))
    (t (setf in (cons (tosymb line) in)))))
  )
  )

2014年2月16日

Lispの割り算まとめ

mod rem
floor truncate ceiling round

mod:floorの余り
rem:truncateの余り

floor:商-∞
truncate:商0
ceiling:商+∞
round:商を近い整数

x < 0の場合
(truncate x)と(ceiling x)は同じ
x > 0の場合
(floor x)と(truncate x)は同じ




'FLOOR     (/   3  2) is   1   1/2
'TRUNCATE  (/   3  2) is   1   1/2
'CEILING   (/   3  2) is   2  -1/2
'ROUND     (/   3  2) is   2  -1/2
'FLOOR     (/  -3  2) is  -2   1/2
'TRUNCATE  (/  -3  2) is  -1  -1/2
'CEILING   (/  -3  2) is  -1  -1/2
'ROUND     (/  -3  2) is  -2   1/2
'FLOOR     (/   4  2) is   2     0
'TRUNCATE  (/   4  2) is   2     0
'CEILING   (/   4  2) is   2     0
'ROUND     (/   4  2) is   2     0

2014年2月14日

clispはスクリプトとして実行できる

こりゃ便利だな
ファイルの先頭に

#!/usr/local/bin/clisp

とか追加してファイルに実行権限つけるとそのまま実行できるって便利だな

まだまだ未熟者のみにはいちいちコンパイルして実行してってやらなくてすむのは大変ありがたいですね

2014年2月13日

Erlangの文法は難しい

セミコロン、カンマ、ピリオドの使い分けが難しい
なかなか慣れない馴染まない
関数節がセミコロン区切り

と思っていたら「;」はor、「,」はand、「.」は終了とすると覚えやすいのだってね

2014年1月22日

wandboxでのErlang実行方法について

-module( testhalt ).
-export( [ main/1 ] ).

f(N) -> N*2.
f("+", [N1|[N2]]) -> N1 + N2;
f("*", [N1|[N2]]) -> N1 * N2.
 
main(_) -> io:format("~w~n", [f("+", [5, 6])]).

2014年1月12日

Erlangリンク

すごいサイト見つけた
早速読もう
Learn you some Erlang for great good!¶

Erlang公式


Erlangメモ

2進数
2#1010(10)

16進数
-16#EA(-234)

ASCII
$a(97)
$A(65)
$\n(改行 10)

浮動小数点
17.368 -56.654 1.234E-10


表記 説明 データ型
+ 単項+ 整数|浮動小数点
- 単項- 整数|浮動小数点
* 乗算 整数|浮動小数点
/ 浮動小数点除算 整数|浮動小数点
div 整数除算 整数
rem 整数剰余 整数
+ 加算 整数|浮動小数点
- 減算 整数|浮動小数点

アトム
比較のみ、英小文字で始める[a-z]([a-z][0-9]@._)*
または単一引用符で囲む

ブール
true
false

演算子 説明
and 両方の引数がtrueの場合に限りtrueを返す
andalso andのショートカット評価
or いずれか一方の引数がtrueの場合にtrueを返す
orelse orのショートカット評価
xor 排他的論理和
not 単項否定演算子

組(タプル)
波カッコ{...}で囲み、コンマで区切る
組のサイズを返す
tuple_size(組)
要素を取り出す
element(1からのインデックス,組)
要素を設定する
setelement(1からのインデックス,組,値)

リスト
角カッコ[...]で囲み、コンマで区切る
コンス
[Head|Tail]
連結
++
引き算
--

リスト内包
NewList = [Expression || GeneratorExp1, GeneratorExp2, ..., GeneratorExpN, Condition1, Condition2,... ConditionN]


比較演算子
演算子 説明
== 等しい
/= 等しくない
=:= 完全に等しい
=/= 完全に等しくない
=< 等しいかまたは小さい
< 小さい
>= 等しいか大きい
> 大きい

変数
[A-Z][a-zA-Z0-9_]

パターンマッチング
ワイルドカード
_


関数
関数名(引数) ->
文;
関数名(_) ->
文.

ガード
f(N) when N > 100 -> true;
f(_) -> false.


関数呼び出し
モジュール名:関数名

無名関数
fun(args) ->
state;
end


レコード
-record(レコード名, {名前=(初期値),...}).


シェルについて

起動
erl

ドット、終止符をつける

help().

コンパイル
c(ファイル名).

終了
q().


その他
ファイルの先頭に書くこと
-module(modulename).
-compile(export_all).


BIF(Built-in function)

2013年10月11日

Common Lispリンク

Lisp Works
http://www.lispworks.com/documentation/common-lisp.html

http://ancient.s6.xrea.com/lisp/cookbook.html

http://lisperati.com/logo.html

2013年10月10日

Common Lisp関連書籍

Land of Lisp
オライリーだけど表紙が地球上の生物じゃないと言うことで話題の本

Let Over Lambda
最高に脳みそが刺激される本

実践Common Lisp
内容はcommon lispだけど「実践」と謳ってあるだけあって非常に実践的
common lispで実践したい人向け

実用Common Lisp
「実用」と言っていますが実用とは思えなかった内容でしたが

On Lisp
とにかくマクロ
マクロを使うためにはどうすればいいか
あとは良いプログラムを書くための心得のようなものも
ポールグレアムの暑苦しさが伝わってきます
スタートアップ企業で成功するような人はこんな感じの人が多いんでしょうね
こんな感じの人じゃないとスタートアップ企業で成功できないんだろうな

ANSI Common Lisp
ポールグレアム著と言うことで買いました
たったそれだけ、多分hyperspecで事足りる

COMMON LISP第二版
個人的にはhyperspecでいいんじゃないかなと思っていますが
所有しているとご利益がありそうなので購入しました

初めての人のためのLISP
実用と言うよりは啓蒙
非常にlispらしい、c言語とかjavaから入ってきた人にはなんじゃこりゃ的な内容で素晴らしい
良くも悪くもlispらしい本だと思います
他の言語ではこういう話の本は書きにくいだろうな


schemeだけどほぼ共通ととらえていいと思う
計算機プログラムの構造と解釈

2013年9月26日

あなたの人生の物語感想

テッド・チャン

あなたの人生の物語

とにかく聖書、キリスト系の話といった印象
全体的に面白みにかけている、マジメな人だなって印象かな
個人的にはもっとふざけててもいいのにと思う
ディックみたいにノリノリでワルノリで書いてもそっちの方が面白いと思う人には少し退屈ではないでしょうか

バビロンの塔
途中の塔を登っていく過程は面白かったですね
太陽を下に見下ろしてさらに登っていく様、星がぶつかりそうなところもよかった
ただ、結局地上に戻ってくる終わらせ方なんだなとすこしがっかりしました

ゼロで割る

あなたの人生の物語
これ結局なんだったんだろうか
地球人、人類は逐次的解釈で他に逐次的に解釈しない生命がいると言いたいんだなと
まあそんな生命がいてもいいんじゃないかという点すごくなっとくいく
強烈に特異な発想かと言われるとどうも

七十二文字
理解できなかったです

人類科学の進化
同上

地獄とは神の不在なり

顔の美醜について


2013年9月3日

Goまとめ

http://tour.golang.org/
一通り見た感想

1.import "fmt"が汎用言語を強く意識させてます

7.引数の型、戻り値の型を後ろに書くパターンの良さが?

8.7.は引数の型がまとめられる利点なのかな

9.複数戻り値ね、タプル的なものは用意しないのね

10.Named resultsの良さがわからない

11.12.変数宣言はこんなものか、色々用意されていますね

15.Constantsは好みじゃないのよ、C#のプロパティがいいね

18.Forか、これだと自分でeachとか定義しないといけないのね

22.if内でのみ利用可能な変数はいいね

33.なぜかNilが登場、Nilに反応するあたり

34.Rangeか

43.closureはいいね

後半よくわからないし、並列辺りもほとんど読み飛ばしました

全体的な印象としては糖衣構文満載、ただし抑えるべき基本はしっかり抑えている印象ですね
Cの後継としては非常によくできていると思います
使ってみたいですね

2013年5月15日

妄想について

HaskellかCommon Lispを使う仕事ってないのかな
なんかざっくりしたイメージだけで言ってますが楽しそうなんだけどな
とか言って期待しすぎちゃって実際就いてみたらつまらなくてHaskellやCommon Lispのことが嫌いになったりしてね
データベースとかSQLとかサーバーの設定とかインストールとか実行環境の互換性とかそういった煩わしいものがなくてHaskellやCommon Lispでかっこいいプログラムを作ることに集中できるような仕事ってないもんかね
って言うか要はとにかく粋なプログラムを書きたい、書けるようになりたいのだけど
粋なプログラムの定義ができてなくてイマイチですが

2013年4月17日

Haskellでcode jamに挑戦 2013予選C

予選C
実際調べてみたら、1e14までなら対象の数が数十個なので一旦数十個見つけ出してあとは入力範囲内にその数十個からあるだけ数えるでLarge input 1は解けました

が、Large input 2は対象の数が多すぎて1e100ってどうやって調べるかまったく見当もつかない状態でギブアップです



これも本番時はどうしてもIntとIntegerとFloatingの変換でうまく動かず
と言うか、動く以前にコンパイルすら通すことができず断念


予選Bといい、予選CといいHaskellってまったくいいところなしのクソクズ言語だなって思ってしまいましたが、翌日落ち着いて改めて取り組んでみたらサクサク進んだと言うかやっぱりいい言語なんじゃないかなと言ったところが最終的な結論でしょうか

1e100の入力はどうやってやるか不明のままです
--digitcp c = any (\i -> i == c) ['0'..'9']

pow base n = foldl (*) 1 (take n $ repeat base)

--rInt s = read (takeWhile digitcp s) :: Integer
rInt s = read s :: Integer

check lower upper = let lowersqrt = (ceiling . sqrt)
   uppersqrt = (truncate . sqrt)
   rr = [(lowersqrt (lower::Double))..(uppersqrt (upper::Double))]
   tostr = map show
   z arr = zip (tostr arr) ((map reverse . tostr) arr)
   filterpalindrome arr = (map (rInt . fst) . filter (\(a, b) -> a == b) . z) arr
   in
   (map (rInt . fst) . filter (\(a, b) -> a == b) . z) (map (\x -> x * x) $ filterpalindrome rr)
   --(length . filter (\(a, b) -> a == b) . z) (map (\x -> x * x) $ filterpalindrome rr)

start = check (pow 10 14) (pow 10 15)
st n = check (pow 10 n) (pow 10 (n + 1))
format n m = "Case #" ++ show n ++ ": " ++ show m

parserec _ [] = []
parserec n lines = let lower = (rInt . head . words . head) lines
         upper = (rInt . last . words . head) lines
         in
         (format (n + 1) (check (fromIntegral lower) (fromIntegral upper))) : (parserec (n + 1) . tail) lines

parserec_large1 _ _ [] = []
parserec_large1 n res lines = let lower = (rInt . head . words . head) lines
      upper = (rInt . last . words . head) lines
      in
      ((format (n + 1) . length . filter (\i -> and [(i >= lower), (i <= upper)])) res) : (parserec_large1 (n + 1) res . tail) lines

parse lines = let t = (rInt . head) lines
    in
    (parserec 0 . tail) lines

parse_large1 lines = let t = (rInt . head) lines
    res = check 1 (pow 10 14)
    in
    (parserec_large1 0 res . tail) lines

main = do cs <- getContents
   (putStr . unlines . parse_large1 . lines) cs

Haskellでcode jamに挑戦 2013予選B

予選B
とりあえず入力に近づくように刈れるだけ刈ってみる
縦横m*n回できるかぎり入力のように刈ってみて入力と比較して結局一緒になっているかどうかで可能かどうか判定

特に困るところはなくsmallもlargeも解けた




と言いたいところなんですけど、どっか間違えていてなぜかincorrect判定
で直せない、直す気力がなかったです
アルゴリズム的には絶対合っている自信があったので次の日再度プログラム組んでみたらやっぱり正解でした
と言うことで公式記録としては点数として残りませんでした

やっぱり本番だろうと動揺せずに冷静に取り組めるようになるためにも練習とか大事だなと思いましたね
って言うかこの時点では本当に入力データのパースに参っていて何やってるかさっぱり訳わかんない状態だったからね
自分で考えてHaskellのプログラムしたのは去年のcode jam以来だと思うので
って言うか去年も数問解けたのあるのですけど本当、自分でやっておいてまったく信じられないからね
よくHaskellで問題が解けたな去年の俺って感じですから

あと次の日落ち着いて練習のつもりで気楽にやってみたら入力文字のパースも簡単な方法がわかってなんか拍子抜けな感じ
takeとdropと再帰とwordsでこんなにも簡単にパースできるなんて昨日の苦労はなんだったんだろうかと感じております
org n = take n $ repeat 100

f rows cols ans = let size = rows * cols
        inrow n i = and [i >= n * cols, i < ((n + 1) * cols)]
        incol n i = (i `mod` cols) == n
        setrowval nth n = map (\i -> if inrow nth i then n else 0) [0..(size - 1)]
        setcolval nth n = map (\i -> if incol nth i then n else 0) [0..(size - 1)]
        mergeifnotzero = zipWith (\a  b -> if b /= 0 then (min a b) else a)
        rowvals nth = zipWith (\a b -> if inrow nth a then b else 0) [0..]
        colvals nth = zipWith (\a b -> if incol nth a then b else 0) [0..]
        computerow ans input nth = mergeifnotzero input $ setrowval nth ((maximum . rowvals nth) ans)
        computerows ans input = foldl (computerow ans) input [0..rows-1]
        computecol ans input nth = mergeifnotzero input $ setcolval nth ((maximum . colvals nth) ans)
        computecols ans input = foldl (computecol ans) input [0..cols-1]
        compute ans = (computerows ans . computecols ans . org) (rows * cols)
        in
        compute ans

rInt s = read s :: Int
resformat n b
  | b = "Case #" ++ show n ++ ": YES"
  | otherwise = "Case #" ++ show n ++ ": NO"

parseItem _ [] = []
parseItem n lines = let rows = (rInt . head . words . head) lines
   cols = (rInt . last . words . head) lines
   ls = (take rows . drop 1) lines
   ans = (map rInt . words . unlines) ls
   res = f rows cols ans
   in
   ((resformat (n + 1) . and) $ zipWith (==) ans res) : (parseItem (n + 1) . drop (rows + 1)) lines

parse lines = let t = (rInt . head) lines
    in
    (parseItem 0 . tail) lines

main = do cs <- getContents
   (putStr . unlines . parse . lines) cs

Haskellでcode jamに挑戦 2013予選A

2013年のcode jamに懲りずにまたまたHaskellで挑戦しました

Land of Lisp読んだばっかりだからやっぱりCommon Lispでやりたかったけど結局code jamみたいな数値計算系はHaskellの方が有利かなと思ってHaskellで挑戦しました
結局、入力のパースで散々な目にあいましたが

予選A
Xを+1、Oを-1、Tを2倍にするとして+3を上回るか-3を下回るものがあるか検索
+3を上回るか-3を下回るものが見つかったら終了
見つからなかったら「.」を検索してあったら途中、なかったら引き分けとして決着
注意点はTの2倍を最後に回すように気をつけてsmall、largeともにクリアできました

HaskellらしくX,O,Tの処理を関数の部分適応で対応したところがHaskellらしいのではないかなと思っております

しかし本題に取り組むよりも入力のパースで手間取りました
Haskellで入力をパースしてどうこうするってことをあまりやったことがないからテキストから整数に変換する方法やら入力を成形するところで大幅につまづきました
正直、途中で心が折れるところでした
import Data.List

x = (+1)
t = (*2)
o = (subtract 1)
d = (+0)

input = "xxxt....oo......"
predp 't' _ = GT
predp _ _ = LT

mapf = map f
     where f 'x' = x
    f 't' = t
    f 'o' = o
           f 'X' = x
    f 'T' = t
    f 'O' = o
    f '.' = d
    f _ = d

so = sortBy predp

r n = take 4 . drop (4 * n)
c n xs = foldr (\nn a -> (head $ drop (4 * nn + n) xs) : a) [] [0..3]
lurb xs = foldr f [] [0..3]
     where f 0 a = (head xs) : a
    f 1 a = (head $ drop 5 xs) : a
    f 2 a = (head $ drop 10 xs) : a
    f 3 a = (head $ drop 15 xs) : a
rulb xs = foldr f [] [0..3]
     where f 0 a = (head $ drop 3 xs) : a
    f 1 a = (head $ drop 6 xs) : a
    f 2 a = (head $ drop 9 xs) : a
    f 3 a = (head $ drop 12 xs) : a
app = foldl (\n x -> x n) 0

inputs = map (app . mapf . so) $ (map (\n -> r n input) [0..3]) ++ (map (\n -> c n input) [0..3]) ++ [(lurb input)] ++ [(rulb input)]
inlist i = map (app . mapf .so ) $ (map (\n -> r n i) [0..3]) ++ (map (\n -> c n i) [0..3]) ++ [(lurb i)] ++ [(rulb i)]

rInt s = read s :: Int

res [] s n
  | any (=='.') s = "Case #" ++ show n ++ ": Game has not completed"
  | otherwise = "Case #" ++ show n ++ ": Draw"
res (x:xs) s n
  | x > 3 = "Case #" ++ show n ++ ": X won"
  | x < -3 = "Case #" ++ show n ++ ": O won"
  | otherwise = res xs s n

main = do cs <- getContents
   putStr $ unlines $ map (\(s, m) -> res (inlist s) s (m + 1)) $ map (\n -> (foldl (++) "" $ take 4 $ drop ((n * 5) + 1) $ lines cs, n)) [0..((rInt $ head $ lines cs) - 1)]

2013年4月4日

ナチス式敬礼をしたサッカー選手

ナチス式敬礼をしたサッカー選手が騒ぎになっていましたけど、この人の写真見たときに富永一郎のマネしてるかと思いましたね

お笑いマンガ道場のエンディングで富永一郎がいつもやってるポーズと同じだなと

2013年4月2日

虚数の情緒

たまに趣味なんですかとか休みの日なにやってるんですかって聞かれるんですけど数学って答えるとびっくりされて鬱陶しいんですけどね
こんな本を休みに好んで読んでるってことはちょっとおかしいかもしれないなと思えるような本
今の時代らしいとにかく金を稼げと
とにかくお金で換算してどうこうって本とは全然違ってとにかく勉強しろと言う熱い本
時間がかかってもいいからとにかくやれと
資本主義の概念だとお金払って数学得意な人を雇えといわれそうなんですけどこの本では自分で身に付けろといってい