Skip to content

Instantly share code, notes, and snippets.

@ygrenzinger
Last active December 26, 2018 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ygrenzinger/82f4012fead2d3a192fe85da7f863d8b to your computer and use it in GitHub Desktop.
Save ygrenzinger/82f4012fead2d3a192fe85da7f863d8b to your computer and use it in GitHub Desktop.
Advent of Code
(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)))
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