Common Lispでリスト内包表記
リストを生成するとき、リスト内包表記(List comprehensions)で書けると可読性がよくなる。ロゼッタコードの当該部分を参考にしながらHaskell、Python、Clojure、そしてCommon Lispで内包表記を使ってみる。
Haskellでリスト内包表記:
[(a,b,c) | a <- [1..19], b <- [a..19], c <- [b..19], a^2 + b^2 == c^2] -- 結果 [(3,4,5),(5,12,13),(6,8,10),(8,15,17),(9,12,15)]
Pythonでリスト内包表記:
[(a,b,c) for a in range(1,20) for b in range(a,20) for c in range(b,20) if a**2 + b**2 == c**2] # 結果 [(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15)]
Clojureでリスト内包表記:
(for [a (range 1 20) b (range a 20) c (range b 20) :when (= (+ (* a a) (* b b)) (* c c))] [a b c]) ;; 結果 ([3 4 5] [5 12 13] [6 8 10] [8 15 17] [9 12 15])
Common Lispで...:
(loop for a from 1 to 19 append (loop for b from a to 19 append (loop for c from b to 19 when (= (+ (* a a) (* b b)) (* c c)) collect (list a b c)))) ;; 結果 ((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15))
最後のは読みにくい。素のCommon Lispではリスト内包表記が使えないみたいなので、残念だ。でもincf-clを使えば大丈夫、Common Lispでも内包表記っぽいものが使えて、万事解決。
Common Lispでリスト内包表記:
;; 準備 (ql:quickload :incf-cl) (use-package :incf-cl) (lc (list a b c) (<- a (range 1 19)) (<- b (range a 19)) (<- c (range b 19)) (= (+ (* a a) (* b b)) (* c c))) ;; 結果 ((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15))