Last active
December 23, 2019 00:29
-
-
Save invasionofsmallcubes/623e5b816f6a040ffeaf855375ea3501 to your computer and use it in GitHub Desktop.
Advent of Code Day 3 #adventOfCode2019
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; https://adventofcode.com/2019/day/3 | |
;; EXERCISES | |
(ns cljbrave.core) | |
(defrecord Movement [direction length]) | |
(defrecord Coordinate [x y]) | |
(def origin (->Coordinate 0 0)) | |
(defn movements | |
"R6 becomes (:R 6)" | |
[string-coordinates] | |
(->Movement (keyword (str (first string-coordinates))) | |
(Integer. (apply str (rest string-coordinates))))) | |
(defn get-movements | |
"R6,U7 becomes [(:R, 6),(:U, 7)]" | |
[string-of-coordinates] | |
(map movements (.split string-of-coordinates ","))) | |
(defn moveUp [p] (+ p 1)) | |
(defn moveDown [p] (- p 1)) | |
(def directionsFn { | |
:R {:x moveUp :y identity} | |
:U {:x identity :y moveUp} | |
:L {:x moveDown :y identity} | |
:D {:x identity :y moveDown} | |
}) | |
(defn moves1 | |
[movement length directionFn] | |
(if (= length 0) | |
[] | |
(let [next (->Coordinate ((:x directionFn) (:x movement)) | |
((:y directionFn) (:y movement)))] | |
(cons next (moves1 next (- length 1) directionFn))))) | |
(defn moves | |
"(0,0) and (:R, 2) will give ((1,0), (2,0))" | |
[start movement] | |
(moves1 start (:length movement) ((:direction movement) directionsFn))) | |
(defn path-accumulator | |
[result current] | |
(let [current-path (moves (:start result) current)] | |
{:start (last current-path) :acc (into (:acc result) current-path)})) | |
(defn generate-coordinates | |
"R1,D1 becomes [(1,0),(1,-1)]" | |
[raw-instructions] | |
(:acc (reduce path-accumulator {:start origin :acc []} (get-movements raw-instructions)))) | |
(defn read-lists | |
[path] | |
(map generate-coordinates (.split (slurp path) "\n"))) | |
(defn common-coordinates | |
[list-of-paths] | |
(let [a-list (first list-of-paths) | |
b-list (last list-of-paths)] | |
(clojure.set/intersection (set a-list) (set b-list)))) | |
(defn min-distance | |
[coordinates] | |
(apply min (map #(+ (Math/abs (:x %)) (Math/abs (:y %))) coordinates))) | |
(defn sum-while | |
[f, coll] | |
(+ 1 (count (take-while #(not= % f) coll)))) | |
(defn min-steps | |
[path] | |
(let [list-of-coordinates (read-lists path) | |
a-list (first list-of-coordinates) | |
b-list (last list-of-coordinates) | |
intersections (common-coordinates list-of-coordinates)] | |
(apply min (map #(+ (sum-while % a-list) (sum-while % b-list)) intersections)))) | |
;; TESTS | |
(ns cljbrave.core-test | |
(:require [clojure.test :refer :all] | |
[cljbrave.core :refer :all])) | |
(deftest can-move-string-to-list | |
(testing "R6 become (R, 6)" | |
(is (= (movements "R6") (->Movement :R 6)))) | |
(testing "U6 become (U, 16)" | |
(is (= (movements "U16") (->Movement :U 16))))) | |
(deftest can-get-list-and-transform-couple | |
(testing "R6,U7 becomes [(:R, 6),(:U, 7)]" | |
(is (= (get-movements "R6,U7") [(->Movement :R 6), (->Movement :U 7)])))) | |
(deftest can-get-moves | |
(testing "(0,0) and (:R, 2) will give [(1,0), (2,0)]" | |
(is (= (moves origin (->Movement :R 2)) | |
[(->Coordinate 1 0), (->Coordinate 2 0)]))) | |
(testing "(0,0) and (:U, 2) will give [(0,1), (0,2)]" | |
(is (= (moves origin (->Movement :U 2)) | |
[(->Coordinate 0 1), (->Coordinate 0 2)]))) | |
(testing "(0,0) and (:L, 2) will give [(-1,0), (-2,0)]" | |
(is (= (moves origin (->Movement :L 2)) | |
[(->Coordinate -1 0), (->Coordinate -2 0)]))) | |
(testing "(0,0) and (:D, 2) will give [(0,-1), (0,-2)]" | |
(is (= (moves origin (->Movement :D 2)) | |
[(->Coordinate 0 -1), (->Coordinate 0 -2)]))) | |
(testing "(0,0) and (:R, 0) will give []" | |
(is (= (moves origin (->Movement :R 0)) | |
[])))) | |
(deftest can-generate-a-list-of-coordinates | |
(testing "R2,D1 becomes [(1,0),(2,0),(2,-1)]" | |
(is (= (generate-coordinates "R2,D1") [(->Coordinate 1 0), (->Coordinate 2 0), (->Coordinate 2 -1)])))) | |
(deftest can-slurp | |
(testing "can read file" | |
(is (= (slurp "test/cljbrave/test1.txt") "R1,U1,L1,D1\nU1,R1,D1,L1")))) | |
(deftest can-get-list-from-file | |
(testing "can get list from files" | |
(is (= (first (read-lists "test/cljbrave/test1.txt")) [(->Coordinate 1 0), (->Coordinate 1 1), (->Coordinate 0 1), (->Coordinate 0 0)]))) | |
(testing "can get list from files" | |
(is (= (last (read-lists "test/cljbrave/test1.txt")) [(->Coordinate 0 1), (->Coordinate 1 1), (->Coordinate 1 0), (->Coordinate 0 0)])))) | |
(deftest calculate-interserctions | |
(testing "get-intersection" | |
(is (= (common-coordinates (read-lists "test/cljbrave/test1.txt")) (set [(->Coordinate 0 0), (->Coordinate 0 1), (->Coordinate 1 0), (->Coordinate 1 1)]))))) | |
(deftest calculate-minimum-distance | |
(testing "minimum distance" | |
(is (= (min-distance (common-coordinates (read-lists "test/cljbrave/test2.txt"))) 6)))) | |
(deftest calculate-minimum-distance2 | |
(testing "minimum distance" | |
(is (= (min-distance (common-coordinates (read-lists "test/cljbrave/test3.txt"))) 159)))) | |
(deftest calculate-minimum-distance3 | |
(testing "minimum distance" | |
(is (= (min-distance (common-coordinates (read-lists "test/cljbrave/test4.txt"))) 135)))) | |
(deftest calculate-minimum-distance3 | |
(testing "minimum distance" | |
(is (= (min-distance (common-coordinates (read-lists "test/cljbrave/real.txt"))) 225)))) | |
(deftest sumwhile | |
(testing "sumwhile" | |
(is (= (sum-while (->Coordinate 1 1) | |
[(->Coordinate 0 0), (->Coordinate 0 1), (->Coordinate 1 0), (->Coordinate 1 1)]) 4)))) | |
(deftest calculate-minimum-steps | |
(testing "minimum steps" | |
(is (= (min-steps "test/cljbrave/test2.txt") 30))) | |
(testing "minimum steps" | |
(is (= (min-steps "test/cljbrave/test3.txt") 610))) | |
(testing "minimum steps" | |
(is (= (min-steps "test/cljbrave/test4.txt") 410))) | |
(testing "minimum steps" | |
(is (= (min-steps "test/cljbrave/real.txt") 35194)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment