(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))
    ))