Last active
December 26, 2018 21:36
-
-
Save ygrenzinger/82f4012fead2d3a192fe85da7f863d8b to your computer and use it in GitHub Desktop.
Advent of Code
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
(def inputs-for-the-day (clojure.string/split-lines (slurp "src/advent_of_code/day6/input.txt"))) | |
(def sample ["1, 1" | |
"1, 6" | |
"8, 3" | |
"3, 4" | |
"5, 5" | |
"8, 9"]) | |
(defn parse-line [line] | |
(let [[_ x y] (re-matches #"(\d+), (\d+)" line)] | |
[(read-string x) (read-string y)])) | |
;; assign an ID (starting from 1) to each points | |
(defn parse-points [input] | |
(->> input | |
(map parse-line) | |
(map #(zipmap [:label :coord] [%1 %2]) (range 1 (inc (count input)))))) | |
(defn manhattan-distance [a b] | |
(let [xa (first a) | |
xb (first b) | |
ya (second a) | |
yb (second b)] | |
(+ (if (< xa xb) (- xb xa) (- xa xb)) | |
(if (< ya yb) (- yb ya) (- ya yb))))) | |
(defn grouped-by-dist [coord points] | |
(group-by #(manhattan-distance coord (:coord %)) points)) | |
(defn closests-point [coord points] | |
(->> points | |
(grouped-by-dist coord) | |
(sort-by key) | |
first | |
second)) | |
(def distance-equality 0) | |
(defn closest-point [coord points] | |
(let [closests (closests-point coord points)] | |
(if (= 1 (count closests)) | |
(:label (first closests)) ;; return the ID of the point | |
distance-equality))) ;; return distance equality if more closest dist equality | |
(defn line-of-closest-points [y range-x points] | |
(map #(closest-point (vector % y) points) range-x)) | |
(defn areas-with-closest-distances [points] | |
(let [max-x (apply max (map first (map :coord points))) | |
range-x (range (inc (inc max-x))) | |
max-y (apply max (map second (map :coord points))) | |
range-y (range (inc (inc max-y)))] | |
(map #(line-of-closest-points % range-x points) range-y))) | |
;; list of distance equality coord and points which are on the border (so infinite areas) | |
(defn areas-to-filter [areas] | |
(let [s1 (into #{distance-equality} (first areas)) | |
s2 (into s1 (last areas)) | |
s3 (into s2 (map first areas)) | |
s4 (into s3 (map last areas))] | |
s4)) | |
(defn filter-areas [areas] | |
(let [areas-to-filter (areas-to-filter areas)] | |
(filter #(not (contains? areas-to-filter %)) (apply concat areas)))) | |
(defn part1 [input] | |
(->> (parse-points input) | |
areas-with-closest-distances | |
filter-areas | |
frequencies | |
vals | |
(apply max))) | |
(defn display-line [line] | |
(apply str (interpose " " line))) | |
(defn display-areas [input] | |
(let [points (parse-points input) | |
areas (areas-with-closest-distances points)] | |
(map #(println (display-line %)) areas))) |
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
import java.io.File | |
import java.util.* | |
import java.util.concurrent.atomic.AtomicInteger | |
data class Coordinate(val x: Int, val y: Int) | |
data class Point(val label: Int, val coordinate: Coordinate) | |
data class area(val associatedToPoint: Point, val size: Int = 0) | |
var seqId = AtomicInteger(1) | |
fun parseLine(line: String): Point { | |
val s = line.split(",") | |
val coord = Coordinate(s[0].trim().toInt(), s[1].trim().toInt()) | |
return Point(seqId.getAndIncrement(), coord) | |
} | |
fun parseFile(filename: String): List<Point> { | |
return File(filename).readLines().map { parseLine(it) } | |
} | |
fun manhattanDistance(a: Coordinate, b: Coordinate): Int { | |
val x = if (a.x < b.x) b.x - a.x else a.x - b.x | |
val y = if (a.y < b.y) b.y - a.y else a.y - b.y | |
return x + y | |
} | |
fun findClosestPoint(coordinate: Coordinate, points: List<Point>): Int { | |
val sorted = points.groupBy { manhattanDistance(coordinate, it.coordinate) }.toSortedMap() | |
val closest: List<Point> = sorted[sorted.firstKey()] ?: emptyList() | |
if (closest.size == 1) { | |
return closest.first().label | |
} else { | |
return 0 | |
} | |
} | |
fun buildAreasOfClosestPoints(points: List<Point>): List<List<Int>> { | |
val maxX = points.map { it.coordinate.x }.max()!! + 1 | |
val maxY = points.map { it.coordinate.x }.max()!! + 1 | |
return (0..maxY).map { y -> | |
(0..maxX).map { x -> | |
findClosestPoint(Coordinate(x, y), points) | |
} | |
} | |
} | |
fun areaToFilter(areas: List<List<Int>>) : Set<Int> { | |
return setOf(0) | |
.plus(areas.first()) | |
.plus(areas.last()) | |
.plus(areas.map { it.first() }) | |
.plus(areas.map { it.last() }) | |
} | |
fun biggestArea(points: List<Point>) : Int { | |
val areas = buildAreasOfClosestPoints(points) | |
val areasToFilter = areaToFilter(areas) | |
return areas | |
.flatten() | |
.filter { !areasToFilter.contains(it) } | |
.groupBy { it } | |
.values | |
.map { it.size } | |
.max()!! | |
} | |
fun main(args: Array<String>) { | |
//parseFile("day6.txt").forEach { println(it) } | |
val points = parseFile("day6.txt") | |
println("Biggest area : " + biggestArea(points)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment