Last active
December 10, 2023 16:57
-
-
Save seltzer1717/2cecf8401e17634b3955e7c532a9833a to your computer and use it in GitHub Desktop.
AOC Day 3b Solution
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
(ns cloud.seltzer1717.aoc.day3b | |
(:require [clojure.set :as set] | |
[clojure.pprint :as pretty]) | |
(:import (java.io BufferedReader FileReader) | |
(java.nio.file Files Paths))) | |
(defn gearProduct | |
"Reducing function, product of gear pairs." | |
[[partNumber1 partNumber2]] | |
(* partNumber1 partNumber2)) | |
(defn gearPairs | |
"Mapping function, returns gear number pairs." | |
[[_ parts]] | |
(->> parts | |
(map :number) | |
(mapv #(Integer/parseInt %)))) | |
(defn gearPart? | |
"Filter function for gear parts." | |
[[_ parts]] | |
(= 2 (count parts))) | |
(defn getPartAdjacents | |
"Takes part and returns set of part adjacent locations." | |
[[lineIndex startPosition endPosition]] | |
(as-> #{} $ | |
(reduce conj $(for [col (range (dec startPosition) (+ 2 endPosition))] [(dec lineIndex) col])) ;; above | |
(reduce conj $ (for [col (range (dec startPosition) (+ 2 endPosition))] [(inc lineIndex) col])) ;; below | |
(reduce conj $ #{[lineIndex (dec startPosition)] [lineIndex (inc endPosition)]}))) ;; sides | |
(defn partAdjacentReducer | |
"Reducing function, part adjacent locations to part adjacent map." | |
[part partAdjacentMap adjacentLocation] | |
(update partAdjacentMap adjacentLocation | |
(fnil conj #{}) part)) | |
(defn partsAdjacentReducer | |
"Reducing function, parts -> map of adjacent locations to parts set." | |
[partAdjacentMap {:keys [location] :as part}] | |
(reduce (partial partAdjacentReducer part) | |
partAdjacentMap | |
(getPartAdjacents location))) | |
(defn star? | |
"Filters for stars." | |
[symbol] | |
(= "*" (:symbol symbol))) | |
(defn partReducer | |
"Partial reducing function, line to parts." | |
[lineIndex parts matchResult] | |
(->> {:number (.group matchResult) | |
:location [lineIndex (.start matchResult) (dec (.end matchResult))]} | |
(conj parts))) | |
(defn partLineReducer | |
"Reducing kv function, schematic lines to parts." | |
[parts lineIndex line] | |
(->> line | |
(.matcher #"\d+") | |
(.results) | |
(.toList) | |
(reduce (partial partReducer lineIndex) #{}) | |
(concat parts) | |
(set))) | |
(defn symbolReducer | |
"Partial reducing function, line to symbols." | |
[lineIndex symbols matchResult] | |
(->> {:symbol (.group matchResult) | |
:location [lineIndex (.start matchResult)]} | |
(conj symbols))) | |
(defn symbolLineReducer | |
"Reducing kv function, schematic lines to symbols." | |
[symbols lineIndex line] | |
(->> line | |
(.matcher #"[^\.\d]") | |
(.results) | |
(.toList) | |
(reduce (partial symbolReducer lineIndex) #{}) | |
(concat symbols) | |
(set))) | |
(defn reduceToGearSum | |
"Takes schematic returns sum of gear products." | |
[schematicPath] | |
(let [schemaLines (Files/readAllLines (Paths/get schematicPath (into-array String []))) | |
symbols (reduce-kv symbolLineReducer #{} (vec schemaLines)) | |
parts (reduce-kv partLineReducer #{} (vec schemaLines)) | |
stars (filter star? symbols) | |
starLocations (set (map :location stars)) | |
partAdjacentMap (reduce partsAdjacentReducer {} parts) | |
partAdjacentKeys (set (keys partAdjacentMap)) | |
starPartKeys (set/intersection starLocations partAdjacentKeys) | |
starPartAdjMap (select-keys partAdjacentMap starPartKeys) | |
gearPartAdjList (filter gearPart? starPartAdjMap) | |
gearPartPairs (map gearPairs gearPartAdjList) | |
gearProducts (map gearProduct gearPartPairs)] | |
(reduce + gearProducts))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment