fork(1) download
  1. (ns challenge-0155.core
  2. (:require [clojure.string :refer [split]]
  3. [clojure.java.io :refer [reader]]))
  4.  
  5. (def initial-positions {:a {:1 :rook, :2 :pawn, :7 :pawn :8 :rook}
  6. :b {:1 :knight, :2 :pawn, :7 :pawn :8 :knight}
  7. :c {:1 :bishop, :2 :pawn, :7 :pawn :8 :bishop}
  8. :d {:1 :queen, :2 :pawn, :7 :pawn :8 :queen}
  9. :e {:1 :king, :2 :pawn, :7 :pawn :8 :king}
  10. :f {:1 :bishop, :2 :pawn, :7 :pawn :8 :bishop}
  11. :g {:1 :knight, :2 :pawn, :7 :pawn :8 :knight}
  12. :h {:1 :rook, :2 :pawn, :7 :pawn :8 :rook}})
  13.  
  14. (def initial-score 39)
  15.  
  16. (def piece-values {:pawn 1, :knight 3, :bishop 3, :rook 5, :queen 9})
  17.  
  18. (def piece-name {"K" :king, "N" :knight, "Q" :queen, "R" :rook, "B" :bishop, "" :pawn})
  19.  
  20. (defn other-player [player]
  21. (case player
  22. :white :black
  23. :black :white))
  24.  
  25. (defn board-position
  26. "Translates a move (e.g. e5) to a board position (e.g. [:e :5])"
  27. [move]
  28. (map #(-> % str keyword) move))
  29.  
  30. (defn score-capture [player move board scores]
  31. (update-in scores [(other-player player)] - (piece-values (get-in board move))))
  32.  
  33. (defn score-en-passant [player scores]
  34. (update-in scores [(other-player player)] - 1))
  35.  
  36. (defn analyze-move [player move board scores]
  37. (let [[_ piece capture move promotion en-passant]
  38. (re-find #"([KNQRB]?)[a-h1-8]?(x?)([a-h][1-8])([KNQRB]?)((?:e.p.)?)" move)
  39. position (board-position move)
  40. piece (if (and (= "" piece) (not= "" promotion)) promotion piece)
  41. new-scores (or (when-not (= "" en-passant)
  42. (score-en-passant player scores))
  43. (when-not (= "" capture)
  44. (score-capture player position board scores))
  45. scores)]
  46. {:board (assoc-in board position (piece-name piece))
  47. :scores new-scores}))
  48.  
  49. (defn process-move [player move board scores]
  50. (cond
  51. (= move "O-O") (let [rank (if (= player :white) :1 :8)]
  52. {:board (assoc-in (assoc-in board [:g rank] :king) [:f rank] :rook)
  53. :scores scores})
  54. (= move "O-O-O") (let [rank (if (= player :white) :1 :8)]
  55. {:board (assoc-in (assoc-in board [:c rank] :king) [:d rank] :rook)
  56. :scores scores})
  57. :else (analyze-move player move board scores)))
  58.  
  59. (defn process-round [round board scores]
  60. (let [[_ wmove bmove] (split round #" ")
  61. {:keys [board scores]} (process-move :white wmove board scores)]
  62. (process-move :black bmove board scores)))
  63.  
  64. (defn process-input [lines]
  65. (loop [line (first lines)
  66. xs (next lines)
  67. board initial-positions
  68. scores {:white initial-score :black initial-score}]
  69. (let [{:keys [scores board]} (process-round line board scores)]
  70. (if xs
  71. (recur (first xs) (next xs) board scores)
  72. {:board board :scores scores}))))
  73.  
  74. (let [{:keys [scores]} (process-input (line-seq (reader *in*)))]
  75. (println (format "%d-%d" (:white scores) (:black scores))))
Success #stdin #stdout 1.45s 389120KB
stdin
1. e4 e5
2. Nf3 Nc6
3. Bb5 Nf6
4. d3 Bc5
5. Bxc6 dxc6
6. h3 Nd7
7. Be3 Bd6
8. Nbd2 O-O
9. O-O Re8
10. Nc4 Nf8
11. d4 exd4
12. Qxd4 c5
13. Qd3 b6
14. Nxd6 Qxd6
15. Qxd6 cxd6
16. Rfd1 Bb7
17. Rxd6 Bxe4
18. Ne1 Rad8
19. Rad1 Ne6
20. Rxd8 Rxd8
21. Rxd8+ Nxd8
22. f3 Bd5
23. a3 Nc6
24. Kf2 f6
25. Nd3 Kf8
26. Ke2 Ke7
27. Kd2 Kd7
28. Nf4 Bf7
29. b3 Ne7
30. h4 Nd5
stdout
12-12