Skip to content

Instantly share code, notes, and snippets.

@alexander-yakushev
Created December 5, 2023 14:04
Show Gist options
  • Save alexander-yakushev/7f10ec2b18b504533447af0438179507 to your computer and use it in GitHub Desktop.
Save alexander-yakushev/7f10ec2b18b504533447af0438179507 to your computer and use it in GitHub Desktop.
Advent of Code 2023, day 5
(ns day5
(:require [clojure.java.io :as io]))
(def lines (vec (line-seq (io/reader "2023/day5.txt"))))
(defn parse [task]
(let [seeds (mapv parse-long (re-seq #"\d+" (first lines)))
seeds (case task
1 seeds
2 (->> (partition 2 seeds)
(mapv (fn [[a b]] [a (+ a b)]))))
maps (->> (partition-by empty? (rest lines))
(keep (fn [lines]
(->> lines
(keep #(when-let [[dst src n] (re-seq #"\d+" %)]
(let [src (parse-long src)]
[src
(+ src (parse-long n))
(- (parse-long dst) src)])))
(sort-by first)
seq))))]
[seeds maps]))
(defn convert [seed maps]
(reduce (fn [seed m]
(or (some (fn [[from to delta]]
(when (and (>= seed from) (< seed to))
(+ seed delta)))
m)
seed))
seed maps))
(defn task1 []
(let [[seeds maps] (parse 1)]
(apply min (map #(convert % maps) seeds))))
;;;;
(defn transform-range [[from to] amap]
(loop [start from, amap amap, res []]
(if (>= start to)
res ;; exit
(let [amap (drop-while #(>= start (second %)) amap)
[mfrom mto delta] (first amap)]
(cond (or (nil? mfrom) (<= to mfrom))
(recur to amap (conj res [start to]))
(< start mfrom)
(recur mfrom amap (conj res [start mfrom]))
:else
(let [to (min to mto)]
(recur to amap (conj res [(+ start delta) (+ to delta)]))))))))
(defn task2 []
(let [[seeds maps] (parse 2)]
(ffirst
(reduce (fn [ranges amap]
(->> (mapcat #(transform-range % amap) ranges)
(sort-by first)))
seeds
maps))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment