1 hour
Day 1 - Solutions
https://github.com/Lambdaphile/aoc/blob/main/2024/clojure/src/aoc/days/01/core.clj
(def all (slurp "input.txt"))
(def small (slurp "small.txt"))
(let [data (-> all
(split-lines)
(->>
(map #(split % #" "))))
col-a (sort (mapv #(Integer/parseInt %) (map first data)))
col-b (sort (mapv #(Integer/parseInt % ) (mapv second data)))
diff (map #(abs (- %1 %2)) col-a col-b )
total (reduce + diff)
]
total)Could have compressed even more, but no need. Awesome that we have a frequencies method. Part 1
(defn row-prep [rowstr]
(let [x (s/split rowstr #"[ ]+")
y (map #(Integer/parseInt %) x)]
;; Just return Y.
y))
(def c (map row-prep (s/split-lines in)))
(def left (sort (map first c)))
(def right (sort (map last c)))
(reduce + (map #(abs (- %1 %2)) left right))
Part 2
(def right-freqs (frequencies right))
(reduce + (map #(* % (get right-freqs % 0)) left))https://github.com/RyanFleck/aoc24/blob/master/src/aoc24/day1.clj
My day 1 solutions In YAMLScript: https://github.com/ingydotnet/advent-of-code/blob/main/2024/01/part1.ys
always seems like the parsing is the tough bit!
(defn parse-input [source]
(let [lines (str/split-lines source)]
(reduce (fn [[left right] line]
(let [[x y] (map parse-long
(str/split line #"\s+"))]
[(conj left x) (conj right y)]))
[[] []]
lines)))
(def day-1-input
(-> "resources/aoc2024/day1.txt"
slurp
parse-input))
(defn total-distance [[list1 list2]]
(reduce + 0 (map difference (sort list1) (sort list2))))
(defn task1 []
(total-distance day-1-input))
(defn similarity-score [[list1 list2]]
(let [l2-frequencies (frequencies list2)]
(transduce (map #(* % (get l2-frequencies % 0))) + 0 list1)))
(defn task2 []
(similarity-score day-1-input))https://github.com/bhauman/adv2024/blob/main/src/adv2024/day01/sol.clj
Refactored the overall AOC/YS repo layout. ReadMe has section to show code as Clojure. https://github.com/ingydotnet/advent-of-code/blob/main/ReadMe.md
I'm committing to not obsessively staying up every night this year to finish them when they drop, but at least for the easy days I will... ๐ https://gitlab.com/maximoburrito/advent2024/-/blob/main/src/day01/main.clj?ref_type=heads
Good to see a thread! Btw, Is it okay to post code to a public repo?
;; ## Day 1
(def pairs
(-> ( 1)
(
#"\n"
#"\s+"
parse-long)))
;; ### Part 1
(let [left-list (sort (map first pairs))
right-list (sort (map second pairs))
distance (fn [a b] (abs (- a b)))]
(reduce + (map distance left-list right-list)))
;; ### Part 2
(let [left (map first pairs)
right (map second pairs)
similarity (frequencies right)
similarity-score (fn [x] (* x (similarity x 0)))]
(reduce + (map similarity-score left))) Day 1 is up. It's fun to be writing Clojure again! โข Blog post: https://github.com/abyala/advent-2024-clojure/blob/main/docs/day01.md โข Source code: https://github.com/abyala/advent-2024-clojure/blob/main/src/advent_2024_clojure/day01.clj
@abyala Iโve been trying to wrap by head around juxt and this line really helps: > Whenever we take one thing and return a vector of things from different functions, we call on juxt Thanks for sharing ๐
As usual, day 1 is a breeze : https://github.com/Maravedis/advent_code/blob/master/src/advent_of_code/2024/01.clj . I wish those dropped at a friendlier time in Europe ๐
@kjw0323 Public repo is ok for your own solution, but they ask you do not commit any input or puzzle text. Source : https://adventofcode.com/2024/about > Can I copy/redistribute part of Advent of Code? Please don't. Advent of Code is free to use, not free to copy. If you're posting a code repository somewhere, please don't include parts of Advent of Code like the puzzle text or your inputs. If you're making a website, please don't make it look like Advent of Code or name it something similar.
(def real-input (slurp "src/2024/day01"))
(defn parse-input [input]
(->> (str "[" input "]")
edn/read-string
(partition 2)))
; 1
(let [input-data (parse-input real-input)
first-list (sort (map first input-data))
second-list (sort (map second input-data))
distances (map (fn [a b] (abs (- b a))) first-list second-list)]
(reduce + distances))
; 2
(let [input-data (parse-input real-input)
first-list (map first input-data)
second-list (map second input-data)
_ (prn (frequencies second-list)) ;; didn't think about that one
diff-scores (map (fn [a]
(* a (count (filter #{a} second-list))))
first-list)]
(reduce + diff-scores))The edn/read-string with the [] concat is really funny to me for some reason.
Love read-string for this ๐ Saw it first from Bruce Hauman in last yearโs (correction: was 2022) advent of code threads: https://clojurians.slack.com/archives/C0GLTDB2T/p1670259468872829
(defn total-distance-between-lists
"Given two sorted lists, return the sum of the absolute difference between each pair of numbers"
[list-1 list-2]
(reduce + (map #(Math/abs (- %1 %2)) list-1 list-2)))
(defn similarity-score
"Given a frequency map and a number, return the similarity score"
[frequency-map number]
(* number (frequency-map number 0)))
(defn total-similarity-score
"Given a sequence of numbers and a frequency map, return the total similarity score"
[numbers frequency-map]
(reduce (fn [total number]
(+ total (similarity-score frequency-map number)))
0
numbers))
(defn- pairs->vectors
"Given a sequence of pairs, return a pair of
vectors containing the first and second elements of each pair"
[pairs]
(reduce (fn [[list-1 list-2] [a b]]
[(conj list-1 a) (conj list-2 b)])
[[] []]
pairs))
(defn part-1
[input]
(let [pairs (utils/parse-long-pairs input)
[list-1 list-2] (pairs->vectors pairs)
sorted-list-1 (sort list-1)
sorted-list-2 (sort list-2)]
(total-distance-between-lists sorted-list-1 sorted-list-2)))
(defn part-2
[input]
(let [pairs (utils/parse-long-pairs input)
[list-1 list-2] (pairs->vectors pairs)
frequency-map (frequencies list-2)]
(total-similarity-score list-1 frequency-map)))(ns aoc2024.aoc01)
(def input (->> (slurp "/Users//aoc/aoc24/aoc1.txt")
(re-seq #"\d+")
(map parse-long)
(partition 2)
(apply map vector)))
(defn p1 [[l1 l2]]
(reduce + (mapv (comp abs -) (sort l1) (sort l2))))
(defn p2 [[l1 l2]]
(let [s (frequencies l2)]
(transduce (map #(abs (* % (s % 0)))) + l1)))That's the second use of transduce I've seen. I really need to look into how that works.
Itโs map + reduce (in this case)
Generally transduce is used when you have a reduce operation, but first you map/filter etc the input sequence. Granted you can just do that inside the reducing function in reduce but itโs generally cleaner to use transduce . Also using transducers can be much faster.
Okay, I will play around with using that for my solution.
Thanks for the explanation!
@roklenarcic you define input and then two functions, but how do you connect the two?
I'm trying to port your solution to the squint playground... I guess just call p1 and p2 on input?
yes, just (p1 input)
usually I have input and test-input etcโฆ so most of the time I have p1 and p2 functions that take an input so I can test with various inputs
ok cool, here's @roklenarcicโs solution on the squint playground: https://squint-cljs.github.io/squint/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2Fa6e9992b079e20e21d753e8c75a7353c5908b225%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4Cgo7OyBSZW1lbWJlciB0byB1cGRhdGUgdGhlIHllYXIgYW5kIGRheSBpbiB0aGUgZmV0Y2gtaW5wdXQgY2FsbC4KKGRlZiBpbnB1dCAoLT4%2BIChqcy1hd2FpdCAoZmV0Y2gtaW5wdXQgMjAyNCAxKSkKICAgICAgICAgICAgIChyZS1zZXEgIyJcZCsiKQogICAgICAgICAgICAgKG1hcCBwYXJzZS1sb25nKQogICAgICAgICAgICAgKHBhcnRpdGlvbiAyKQogICAgICAgICAgICAgKGFwcGx5IG1hcCB2ZWN0b3IpKSkKCihkZWZuIHAxIFtbbDEgbDJdXQogIChyZWR1Y2UgKyAobWFwdiAoY29tcCBhYnMgLSkgKHNvcnQgbDEpIChzb3J0IGwyKSkpKQoKKGRlZm4gcDIgW1tsMSBsMl1dCiAgKGxldCBbcyAoZnJlcXVlbmNpZXMgbDIpXQogICAgKHRyYW5zZHVjZSAobWFwICMoYWJzICgqICUgKGdldCBzICUgMCkpKSkgKyBsMSkpKQoKI18odGltZSAocDEgaW5wdXQpKQojXyh0aW1lIChwMiBpbnB1dCkp
Using read-string trick I can make it shorter: https://gist.github.com/RokLenarcic/18a9a9cd134ca7f53c8897396208149e
https://github.com/jramosg/advent-of-code/blob/master/src/advent_of_code/year_2024/day_01/main.clj
@roklenarcic read-string isn't available in squint (yet) :)
Today was a fun Day1 puzzle, I enjoyed it. [Here](https://github.com/alexalemi/advent/blob/main/2024/clojure/p01.clj) is my clojure solution. I would have liked to make the whole thing a transduce but I couldn't figure out how to turn (apply map list) into a transducer immediately.
https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2024/day01.clj
Fun warmup! https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2024/d1.clj
https://clojurians.slack.com/archives/C0GLTDB2T/p1733037898227799?thread_ts=1733029934.345259&cid=C0GLTDB2T Oops, I thought publishing my specific puzzle inputs was fine, as they're generated. Maybe it used to be fine, but they changed the policy? In any case, off to tweak my repo... ๐
https://github.com/ghaskins/adventofcode/blob/main/src/aoc/2024/day1.clj
I realized after that my use of zipmap was probably the wrong choice as it wouldnt have worked if there were repeating items in the lhs, but I got lucky. In any case, I didnt place on the leaderboard. This was my first AOC and it was fun
I tend to take advantage of day 1 being easy to explore a different language. just finished a Haskell book, so decided to put it to practice. https://github.com/FelipeCortez/advent-of-code/blob/master/2024/01.hs will switch to Clojure tomorrow!
I corrected my improper use of zipmap and simplfied
(ns aoc.2024.day1
(:require [clojure.string :as string]))
(defn parse []
(->> (slurp "inputs/day1.txt")
(string/split-lines)
(map #(map parse-long (string/split % #"\s+")))
(reduce (fn [acc items] (mapv conj acc items)) [[] []])
(map sort)))
(defn part1 []
(let [[left right] (parse)]
(->> (map (comp abs -) left right)
(reduce + 0))))
(defn part2 []
(let [[left right] (parse)
f (frequencies right)]
(->> (map #(* % (get f % 0)) left)
(reduce + 0))))@dingelsz3 - I'm glad you found it helpful!
@carnunmp it's from the very beginning. https://www.reddit.com/r/adventofcode/comments/7lesj5/comment/drlt9am/
I have a feeling that the last time I used frequencies was in AOC23 :-)
(def input [...])
(def lists
[(take-nth 2 input)
(take-nth 2 (rest input))])
(defn part1 []
(let [l1 (sort (first lists))
l2 (sort (second lists))]
(reduce + (map #(abs (- %1 %2)) l1 l2))))
(defn part2 []
(let [l1 (first lists)
l2f (frequencies (second lists))]
(reduce #(+ %1 (* (get l2f %2 0) %2)) 0 l1)))https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2024/day1.clj
take-nth I just learned about this
similar to others https://github.com/tschady/advent-of-code/blob/main/src/aoc/2024/d01.clj
People say Clojure isn't a language where you have one obvious way to do something, but looking at all the solutions they're all almost identical. Great minds think alike ๐ Here's mine https://codeberg.org/aciep/advent-of-code-2024-clojure/src/branch/master/src/aoc/d1.clj
(require '[ :as io]
'[net.cgrand.xforms :as x])
(def xf (comp (mapcat (fn [ln] (re-seq #"\d+" ln)))
(map parse-long)
(x/multiplex {:xs (take-nth 2) :ys (comp (drop 1) (take-nth 2))})
(x/by-key (comp (x/sort) (x/into [])))))
(let [{:keys [xs ys]} (into {} xf (io/lines-in *in*))]
(println "Part A:" (reduce + (map (comp abs -) xs ys)))
(println "Part B:" (let [frqs (frequencies ys)]
(transduce (map (fn [x] (* (get frqs x 0) x))) + xs))))
Trying to wrap my head around cgrand's xforms library a little, I'm sure theres more room for improvement hereOh! And not that I'll be playing for it this year, but is there a Clojure-specifichttps://adventofcode.com/2024/leaderboard/private? EDIT: Found it! Same as last year(s): https://adventofcode.com/2024/leaderboard/private/view/217019
We could maybe make a new one? Lots of people are obviously not participating.
Good idea! Let's make 2024 edition
(preparing one, stay tuned)
current status: failed... I've created new github account for that purposes but: You are marked as spam, and therefore cannot authorize a third party application...
no worries - alternative solution works
Ok! Here is the new code for this year: 4534281-b9354839
what is the channel name?
nm
Is the code something that can be shared?
what is the join code?
In the topic of the channel 217019-4a55b8eb
it says that private leaderboard is full. ๐ข
I got a "that private leaderboard is full" as well....bummer!
set the channel topic: Happy Advent 2024! Please put answers in the pinned threads or create one if it does not exist yet. | https://github.com/adventofcode-clojurians/adventofcode-clojurians | Join the private leaderboard with code 217019-4a55b8eb
We are not allowed to share the puzzle input on github (or other public site or repo) but since it's convenient to keep an archive of them I want to share my solution: keep it in the encrypted kv store file. I use H2 for that, feeding new input and examples every day (which I use in tests, and which are also under restriction).
Here is the code for that: https://github.com/genmeblog/advent-of-code/blob/master/src/common.clj#L4-L36
And the following to update the store from data/inputs and data/examples folders
(do
(add-all-data)
(add-all-data "examples"))Don't forget to purge github content with the history of input commits: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository
Could you review my solution of day1? Is there room for improvements? https://github.com/reflechant/aoc2024-clj/tree/main/src/reflechant/aoc2024/day01
Part 1 looks ok for me. One comment for part 2: you can get rid of map -> filter -> map chain by setting a default value in get
Thanks! Missed that ๐
Also (get freq % _default_) can be called as (freq % _default_)
yeah, maps are functions of their keys. I tried to do it but my lsp was complaining for some reason
A very useful tool when parsing numbers, or anything that just repeats, is re-seq , instead of having to split:
(re-seq #"\d+" input) ; => ["1" "2" "3" "14" "12"])
The advantage is that it also parses things like
Rudolf flies at 14km/h, for 10 seconds, before having to rest for 133 seconds.
and gives you back only the numbers.Oh, that's neat. Thanks!
Does anyone understand the ranking in the private leaderboard? For instance, the #1 slot has โ398โ but I understand you can only get a maximum of 200 points per puzzle. Does the global leaderboard rank differently?
On a private leaderboard page, you can click [Ordering] to have this snippet appear:
Ty!
Global and private rank differently.
The global leader on Day 1 finished Part 1 in 4 seconds and part 2 5 seconds later for a 9 second total. Wild stuff
It's someone who used an LLM. They actually apologized and deleted the link toward their repo. They were unaware it was discouraged to use AI as a solver and not just a crutch.
How do you see the stats of other leaderboard rows? I can see mine but not others
i.e. how did you see that #1 took 4 seconds @chase-lambert?
If you go to the global leaderboard there are links to the individual days at the top
@chase-lambert ty!
and thats crazy
slowest person was 1:24
I've never done it for time but I check out the times out of curiosity every now and then
i think i finished #1 in 14m, heh. Not even close