(ns day-2.core
(:require [clojure.java.io :as io])
(:require [clojure.string :as str])
(:use [clojure.test :only [is]])
(:use [clojure.pprint :only [pprint]])
(:gen-class))
(def test-set "7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9")
(defn str-subtract [a b] (- (Integer/parseInt a) (Integer/parseInt b)))
(defn satisfy-restriction [pred el]
(and (pred el 0) (<= (abs el) 3)))
(defn every-satisfies-restriction [pred elements]
(every? (partial satisfy-restriction pred) elements))
(defn every-satisfies-either-restriction [xs]
(or (every-satisfies-restriction > xs) (every-satisfies-restriction < xs)))
(defn solve-first [data]
(let [lines (map #(str/split (str/triml %) #" ") (str/split-lines data))
differences (map #(map str-subtract (drop 1 %) %) lines)]
(->> differences
(map every-satisfies-either-restriction)
(filter true?)
(count))))
(defn test-all-combinations [xs]
(or (not-every? false? (->> (range 0 (count xs))
(map #(let [n %
n2 (+ n 2)
end (if (> n2 (count xs)) n n2)
start (if (> n2 (count xs)) (dec n) n)]
(concat (take start xs) [(->> (drop start (take end xs)) (reduce +))] (drop n2 xs))))
(map #(every-satisfies-either-restriction (into '() %)))
))
(every-satisfies-either-restriction (drop 1 xs))))
(defn take-if-true [elements mask]
(->> (map vector elements mask)
(filter (fn [[_ condition]] condition))
(map first)))
(defn solve-second [data]
(let [lines (map #(str/split (str/triml %) #" ") (str/split-lines data))
differences (map #(map str-subtract (drop 1 %) %) lines)]
(count (filter true? (map test-all-combinations differences)))
))
(defn -main
[& args]
(let [data-set (slurp "data/day2.txt")]
(println "(1) Test set...")
(println (solve-first test-set))
(println "(1) Large set...")
(println (solve-first data-set))
(println "(2) Test set...")
(println (solve-second test-set))
(println "(2) Large set...")
(println (solve-second data-set))
))