73번 문제는 틱택토 판을 읽어 승자를 판별하는 함수를 작성하는 문제다.
(= :x (__ [[:x :e :o]
[:x :e :e]
[:x :e :o]]))
우선 마구잡이 풀이, 우선 :x가 이겼나 보고, 아니면 :o 가 이겼나 보고, 아니면 nil!
이겼는지는 row/col/diagonal이 모두 해당 플레이어인지 확인.
;; 294
(fn [board]
(let [b2 (apply mapv vector board)
d1 (map #(%1 %2) board [0 1 2])
d2 (map #(%1 %2) board [2 1 0])
win? (fn [p]
(or (every? #(= p %) (board 0))
(every? #(= p %) (board 1))
(every? #(= p %) (board 2))
(every? #(= p %) (b2 0))
(every? #(= p %) (b2 1))
(every? #(= p %) (b2 2))
(every? #(= p %) d1)
(every? #(= p %) d2)))]
(cond (win? :x) :x
(win? :o) :o
:else nil)))
Thinking Functionally with Haskell의 5장 Sudoku Solver와 비슷한 부분이 보인다. 결국은 3 rows, 3 cols, 2 diags 를 모두 구할 수 있으면 여기서 [:x :x :x]와 같은 것이 있는지 보면 되는거다.
collection에 요소가 있는지 확인하는 방법은 말그대로 set을 사용하면 된다. (set은 T => Bool 함수이기 때문)
;; 146
(fn [b]
(let [c (apply mapv vector b)
d (mapv #(%1 %2) b [0 1 2])
e (mapv #(%1 %2) b [2 1 0])
win? (fn [p]
(some #{[p p p]} (concat b c [d e])))]
(cond (win? :x) :x
(win? :o) :o
:else nil)))
가만 보면 원래 collection을 집합으로 보는 것이 낫겠다. 그리고 :else nil은 사족이다.
;; 136
(fn [b]
(let [c (apply mapv vector b)
d (mapv #(%1 %2) b [0 1 2])
e (mapv #(%1 %2) b [2 1 0])
win? (fn [p]
((set (concat b c [d e])) [p p p]))]
(cond (win? :x) :x
(win? :o) :o)))
그러고 보면 win?이란 함수는 set으로 처리가능하다.
;; 131
(fn [b]
(let [c (apply map vector b)
d (map #(%1 %2) b [0 1 2])
e (map #(%1 %2) b [2 1 0])
win? (set (concat b c [d e]))]
(cond (win? [:x :x :x]) :x
(win? [:o :o :o]) :o)))
일단 여기까지 하고 인라인, 인자 전달 등의 골프 기법 동원하여..
;; 110
(fn [a m b]
(let [w (set (concat b
(apply m vector b)
[(m a b [0 1 2])
(m a b [2 1 0])]))]
(cond (w [:x :x :x]) :x
(w [:o :o :o]) :o))) #(%1 %2) map
(= :x (__ [[:x :e :o]
[:x :e :e]
[:x :e :o]]))
우선 마구잡이 풀이, 우선 :x가 이겼나 보고, 아니면 :o 가 이겼나 보고, 아니면 nil!
이겼는지는 row/col/diagonal이 모두 해당 플레이어인지 확인.
;; 294
(fn [board]
(let [b2 (apply mapv vector board)
d1 (map #(%1 %2) board [0 1 2])
d2 (map #(%1 %2) board [2 1 0])
win? (fn [p]
(or (every? #(= p %) (board 0))
(every? #(= p %) (board 1))
(every? #(= p %) (board 2))
(every? #(= p %) (b2 0))
(every? #(= p %) (b2 1))
(every? #(= p %) (b2 2))
(every? #(= p %) d1)
(every? #(= p %) d2)))]
(cond (win? :x) :x
(win? :o) :o
:else nil)))
Thinking Functionally with Haskell의 5장 Sudoku Solver와 비슷한 부분이 보인다. 결국은 3 rows, 3 cols, 2 diags 를 모두 구할 수 있으면 여기서 [:x :x :x]와 같은 것이 있는지 보면 되는거다.
collection에 요소가 있는지 확인하는 방법은 말그대로 set을 사용하면 된다. (set은 T => Bool 함수이기 때문)
;; 146
(fn [b]
(let [c (apply mapv vector b)
d (mapv #(%1 %2) b [0 1 2])
e (mapv #(%1 %2) b [2 1 0])
win? (fn [p]
(some #{[p p p]} (concat b c [d e])))]
(cond (win? :x) :x
(win? :o) :o
:else nil)))
가만 보면 원래 collection을 집합으로 보는 것이 낫겠다. 그리고 :else nil은 사족이다.
;; 136
(fn [b]
(let [c (apply mapv vector b)
d (mapv #(%1 %2) b [0 1 2])
e (mapv #(%1 %2) b [2 1 0])
win? (fn [p]
((set (concat b c [d e])) [p p p]))]
(cond (win? :x) :x
(win? :o) :o)))
그러고 보면 win?이란 함수는 set으로 처리가능하다.
;; 131
(fn [b]
(let [c (apply map vector b)
d (map #(%1 %2) b [0 1 2])
e (map #(%1 %2) b [2 1 0])
win? (set (concat b c [d e]))]
(cond (win? [:x :x :x]) :x
(win? [:o :o :o]) :o)))
일단 여기까지 하고 인라인, 인자 전달 등의 골프 기법 동원하여..
;; 110
(fn [a m b]
(let [w (set (concat b
(apply m vector b)
[(m a b [0 1 2])
(m a b [2 1 0])]))]
(cond (w [:x :x :x]) :x
(w [:o :o :o]) :o))) #(%1 %2) map
댓글 없음:
댓글 쓰기