Skip to content

Instantly share code, notes, and snippets.

@seltzer1717
Last active December 10, 2023 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seltzer1717/2cecf8401e17634b3955e7c532a9833a to your computer and use it in GitHub Desktop.
Save seltzer1717/2cecf8401e17634b3955e7c532a9833a to your computer and use it in GitHub Desktop.
AOC Day 3b Solution
(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