Dear Advent of Coders!
The babashka-advent-of-code-template now lets you download input automatically when you set your AOC_SESSION environment variable:
https://github.com/borkdude/advent-of-babashka-template#downloading-input
Also you can run the code on Github Codespaces now (if you just want to try it out)!
https://github.com/borkdude/advent-of-babashka-template#github-codespaces
Nice idea, this automatic download of the input. I also applied it to my AoC project.
FYI I am doing the challenges using scittle
I'm improving the visuals as I go along and ideas are welcome
Why not use Joyride for Advent of Code this year around? A first version of a Use #joyride for Advent of Code repository. It's full of typos and things I haven't thought about. I will improve on it! joyride https://github.com/PEZ/joyride-aoc-2022
Why is map-invert in the set namespace ? π€
Couple of answers follow. https://clojurians.slack.com/archives/C053AK3F9/p1639157027128700
I'll put it in let-go's core I think
Also, fun fact: (set/map-invert who-beats-who) = (comp who-beats-who who-beats-who)
@alexalemi good one! didn't occur to me
it's basically shifting the table
@qmstuart because maps can be regarded as sets of key-value pairs? it beats me :)
All these beautiful, explicit solutions and I'm just playing code golf π
please share π
(def pt-one-points [4 8 3 1 5 9 7 2 6])
(def pt-two-points [3 4 8 1 5 9 2 6 7])
(def outcomes [["A" "X"] ["A" "Y"] ["A" "Z"]
["B" "X"] ["B" "Y"] ["B" "Z"]
["C" "X"] ["C" "Y"] ["C" "Z"]])
(def pt-one-scores (zipmap outcomes pt-one-points))
(def pt-two-scores (zipmap outcomes pt-two-points))
(with-open [rdr (-> "public/puzzle_inputs/day_two.txt"
io/resource
io/reader)]
(->> (line-seq rdr)
(transduce (map (comp #(get pt-one-scores %)
#(string/split % #"\s"))) + 0)))nice
;; 202202
(let [rule1 {["A" "Z"] (+ 0 3), ["A" "X"] (+ 3 1), ["A" "Y"] (+ 6 2)
["B" "X"] (+ 0 1), ["B" "Y"] (+ 3 2), ["B" "Z"] (+ 6 3)
["C" "Y"] (+ 0 2), ["C" "Z"] (+ 3 3), ["C" "X"] (+ 6 1)}
rule2 {["A" "X"] (+ 0 3), ["A" "Y"] (+ 3 1), ["A" "Z"] (+ 6 2)
["B" "X"] (+ 0 1), ["B" "Y"] (+ 3 2), ["B" "Z"] (+ 6 3)
["C" "X"] (+ 0 2), ["C" "Y"] (+ 3 3), ["C" "Z"] (+ 6 1)}
d (->> (slurp "src/y2022/input202202")
(re-seq #"\w")
(partition 2))]
(map #(->> d (transduce (map %) +)) [rule1 rule2]))
;; (12772 11618)(Still learning, so probably my solution is not super idiomatic?)
(def rules
[[2 0 1] ;; R = 0 [who-loses who-draws who-wins]
[0 1 2] ;; P = 1
[1 2 0]]) ;; S = 2
(defn parse [line]
(let [[a b] (re-seq #"\w" line)]
[(index-of "ABC" a) (index-of "XYZ" b)]))
(defn result [[a b] part]
(if (= part 1)
(+ (inc b) (* 3 (.indexOf (rules a) b)))
(+ (inc ((rules a) b)) (* 3 b))))
(defn -main [day]
(let [input (map parse (file->lines day))
game (fn [p] (apply + (map #(result % p) input)))]
{:part1 (game 1) :part2 (game 2)}))@piotr.kaznowski that looks good to me. One minor improvement, you can use destructuring to grab the chars from the line and avoid re-seq:
(defn parse [[a _ b]]
[(index-of "ABC" a) (index-of "XYZ" b)])Of course! Thanks for the hint, @pshapiro.
modest improvements to the UI
Hey everybody. I'm a CS teacher by day and Clojure hobbyist off hours. I wrote up a piece on days 1 and 2 wearing my teacher hat. The post isn't clojure specific but the embedded videos is a Clojure walkthrough of both days. No claims of being great solutions but wanted to share. Days 1 and 2 of #AdventOfCode from a teacher's persepctive: https://cestlaz.github.io/post/advent-2022-day01-01/
I actually stumbled on your video on YouTube before I saw this post. Really liked the way you talked through your thought process when finding the solution. Great work!
Thanks - wish I had time to make more.
We recorded a demo of solving day 1 using Joyride at the office today. Itβs in post processing. I think it will be pretty nice content when weβre done with it. Extra bonus is that my colleague made an βanswerβ using Rust and an application he has written, that can run Rust code. I think Iβll attach that as an appendix. Weβll see.
The rust version as an appendix would be cool! π€ but I just thinking about AoC and Joyride on my walk so looking forward either way!
awesome :)
man, I like it when I paste a giant fn from clojure.core and it just works
I'm sure there's a blog explaining this (I've had a look but couldn't find anything quite on point) but is there a 'best way' to reset the environment of an nREPL session? I'm trying Neovim with Conjure to solve AOC problems this year and found that the solution I built up for Day 1 was relying on some bindings that I'd renamed in my source file but which I didn't notice were gone until I later on tried to load the file again. What I have found online is more directed at larger scale systems, I just have two files (the source file for the day's solution and a utilities file with some helper functions).
You can remove a certain binding with https://clojuredocs.org/clojure.core/ns-unmap So, if you want to just remove all the bindings in the current namespace, you could eval something like:
(do-seq [sym (keys (ns-interns *ns*))]
(ns-unmap *ns* sym))
Note: that's usually good enough for re-evaluating a single namespace, but it won't eg. clean up other namespaces that have referred to previous bindings. If you need something that tracks dependencies, etc. you may need to use something more heavy-handed like clojure.tools.namespace.replThanks. Yeah, I kind of want something that will just blow away everything (without requiring the REPL to be restarted) and so maybe clojure.tools.namespace.repl is the place to look. Thanks for the above code, though. If the utilities library remains stable, maybe that is all I need π
I think the trick is to learn to eval things often as you make small changes. It should be rare to end up with so much change that you need to blow away everything to get back to a known steady-state.
Yeah, in this particular case, it was two instances where I'd renamed a binding but forgotten to update the references to it.
Perhaps the better solution is something that assists in refactorings like this (although that might be overkill for something like an AOC puzzle).
Day 2 - looks like we need a solutions thread
https://github.com/rap1ds/advent-of-code-2022/blob/main/src/day2.clj
(ns day2)
(def syms {"A" 1 "B" 2 "C" 3 "X" 1 "Y" 2 "Z" 3})
(def domi {1 2 2 3 3 1})
(def losi {2 1 3 2 1 3})
(defn parse [l]
(map syms (split l " ")))
(def data (->> "input/day2.txt" slurp lines (map parse)))
(defn score [[a b]]
(+ (cond
(= a (domi b)) 0
(= a b) 3
:else 6)
b))
(defn strat [[a b]]
[a (case b
1 (losi a)
3 (domi a)
a)])
(println "1:" (->> data (map score) (reduce +)))
(println "2:" (->> data (map (comp score strat)) (reduce +)))https://github.com/benjamin-asdf/advent-of-code-2021/blob/master/src/Y2022/day2.clj
https://github.com/ValentinMouret/advent-2022/blob/main/src/day_02.clj's longer, but might be more readable. Feedback is welcome. π
I just condensed the information into two lookup tables:
(def data (str "input-" day ".txt"))
(def get-score-1 {'(:A :X) 4
'(:B :Y) 5
'(:C :Z) 6
'(:A :Y) 8
'(:A :Z) 3
'(:B :X) 1
'(:B :Z) 9
'(:C :X) 7
'(:C :Y) 2})
(def get-score-2 {'(:A :X) 3
'(:A :Y) 4
'(:A :Z) 8
'(:B :X) 1
'(:B :Y) 5
'(:B :Z) 9
'(:C :X) 2
'(:C :Y) 6
'(:C :Z) 7})
(defn parse [lines]
(->> lines
(map #(str/split % #" "))
(map #(map keyword %))))
(parse (utils/read-lines data))
(defn part-1 [input]
(->> input
(map #(get-score-1 %))
(apply +)))
(defn part-2 [input]
(->> input
(map #(get-score-2 %))
(apply +)))
(part-1 (parse (utils/read-lines data)))
;; => 10404
(part-2 (parse (utils/read-lines data)))
;; => 10334
(ns aoc2022.day-2
(:require [aoc2022.misc :as misc]))
(defmulti score identity)
(defmacro score-methods [points]
`(do
~@(for [they ["A" "B" "C"]
I ["X" "Y" "Z"]]
`(defmethod score ~(format "%s %s" they I) [_#]
~(+ (get-in points [I I])
(get-in points [I they]))))))
(defn solve-1 []
(score-methods {"X" {"X" 1
"A" 3
"B" 0
"C" 6}
"Y" {"Y" 2
"A" 6
"B" 3
"C" 0}
"Z" {"Z" 3
"A" 0
"B" 6
"C" 3}})
(binding [misc/*day* 2]
(misc/read-lines
(fn [rounds]
(transduce
(map score)
+ 0
rounds)))))
(defn solve-2 []
(score-methods {"X" {"X" 0
"A" 3
"B" 1
"C" 2}
"Y" {"Y" 3
"A" 1
"B" 2
"C" 3}
"Z" {"Z" 6
"A" 2
"B" 3
"C" 1}})
(binding [misc/*day* 2]
(misc/read-lines
(fn [rounds]
(transduce
(map score)
+ 0
rounds)))))
(time
(dotimes [_ 1000]
(solve-1)))
;; 334ms
(time
(dotimes [_ 1000]
(solve-2)))
;; 291ms
with dynamic multimethods and macro πhttps://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2022/d2.clj π
my code today is very verbose https://github.com/nbardiuk/adventofcode/blob/master/2022/src/day02.clj
Mine looks pretty-ugly:
(let [to-int
(let [A (int \A) X (int \X)]
(fn [a x]
(+ (* 3 (- (int a) A))
(- (int x) X))))
p1 (int-array [4 8 3 1 5 9 7 2 6])
p2 (int-array [3 4 8 1 5 9 2 6 7])]
(defn day2 [^String fs]
(let [n (count fs)]
(loop [i 0 x 0 y 0]
(if (>= i n)
[x y]
(let [z (to-int (.charAt fs i) (.charAt fs (+ i 2)))]
(recur (+ i 4)
(+ x (aget p1 z))
(+ y (aget p2 z)))))))))
Runs decently-quickly:
(let [s (slurp "02.txt")]
(criterium.core/quick-bench (day2 s)))
; Evaluation count : 9996 in 6 samples of 1666 calls.
; Execution time mean : 60.479461 Β΅s
; Execution time std-deviation : 302.265610 ns
; Execution time lower quantile : 60.114543 Β΅s ( 2.5%)
; Execution time upper quantile : 60.909793 Β΅s (97.5%)https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d02.clj
Mostly static lookups... https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2022/day02.clj
Dictionary for the lookup of what beats what, invert it to get the hand to play for part 2 https://github.com/stuartstein777/clj-advent-of-code/blob/master/src/stuartstein777/2022/day2.clj
I parsed the file into "rock" "paper" "scissors" because "A", "B", "C", "X", "Y", "Z" was confusing me.
Isn't this a link to a private repository?
it's 404 for us
yeah, shit was private. I had no idea. SHould be public now π
https://github.com/v-garcia/aoc_2022/blob/main/day2.clj
with rock paper scissors encoded as 0 1 2
https://github.com/luissantos/aoc/blob/main/src/luissantos/aoc_2022.clj
(defn round-score [round]
(case round
[:rock :paper] (+ 0 1)
[:rock :scissors] (+ 6 1)
[:paper :rock] (+ 6 2)
[:paper :scissors] (+ 0 2)
[:scissors :rock] (+ 0 3)
[:scissors :paper] (+ 6 3)
[:rock :rock] (+ 3 1)
[:paper :paper] (+ 3 2)
[:scissors :scissors] (+ 3 3)))
(defn pick-correct-hand [round]
(case round
[:x :paper] [:rock :paper]
[:x :rock] [:scissors :rock]
[:x :scissors] [:paper :scissors]
[:y :paper] [:paper :paper]
[:y :rock] [:rock :rock]
[:y :scissors] [:scissors :scissors]
[:z :paper] [:scissors :paper]
[:z :rock] [:paper :rock]
[:z :scissors] [:rock :scissors]))
(defn day2-part2 []
(let [hands {\A :rock \B :paper \C :scissors \X :x \Y :y \Z :z}]
(->> (string/split-lines (slurp "input/day-2-input-1.txt"))
(map #(string/replace % " " ""))
(map #(map hands %))
(map reverse)
(map pick-correct-hand)
(map round-score)
(reduce +))))Day 2 https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day2/sol.clj
I did an alternative approach for day 2 using core.logic, which was pretty fun: https://github.com/formsandlines/aoc2022-clojure/blob/main/src/advent_of_clerk/day_02_logic.cljc Unfortunately, Babashka doesnβt seem to work with core.logic, so I couldnβt get my tests to run with it.
Day 2: https://github.com/dogenpunk/advent-of-code/blob/main/src/aoc22/day02.cljc
(ns day-02)
;;A-rock, B-paper, C-scissors, X-rock, Y-paper, Z-scissors
(def score-1 {\A {\X 4 \Y 8 \Z 3}
\B {\X 1 \Y 5 \Z 9}
\C {\X 7 \Y 2 \Z 6}})
;;X-loss, Y-draw, Z-win
(def score-2 {\A {\X 3 \Y 4 \Z 8}
\B {\X 1 \Y 5 \Z 9}
\C {\X 2 \Y 6 \Z 7}})
(defn input [score]
(for [[a _ b] (re-seq #".+" (slurp "../day_02.data"))]
((score a) b)))
(defn solution-1 []
(reduce + (input score-1)))
(defn solution-2 []
(reduce + (input score-2)))A bit late to the game : / day job intervened, let's see if I can catch up
https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day02/main.clj
https://coyotesqrl.github.io/advent-of-code/2022/src/coyotesqrl/2022/day02.html
https://gist.github.com/iwrotesomecode/ea0a28a1e0ad5ac55123805d45d8f35e
I suspect I'll be one of the few to take the particular strategy I used. I'm frankly just too tired to have done it more elegantly tonight.
https://github.com/alexalemi/advent/blob/main/2022/clojure/p02.clj
3 lines of code + data: https://github.com/pwojnowski/advent-of-code/blob/master/src/aoc/aoc2022.clj
(ns aoc2022.day02
(:require [clojure.string :as s])
(:gen-class))
(def data
(->> (s/split-lines (slurp "resources/input02.txt"))
(map #(s/split % #" "))))
(defn round-result [s1 s2]
([3 6 0 3 6]
(+ ({"A" 0 "B" 2 "C" 1} s1)
({"X" 0 "Y" 1 "Z" 2} s2))))
(defn points-for-round [[s1 s2]]
(+ ({"X" 1 "Y" 2 "Z" 3} s2)
(round-result s1 s2)))
(defn my-shape-for-situation [s1 s2]
(["X" "Y" "Z" "X" "Y"]
(+ ({"A" 2 "B" 0 "C" 1} s1)
({"X" 0 "Y" 1 "Z" 2} s2))))
(defn part1 [data]
(transduce (map points-for-round) + data))
(defn part2 [data]
(transduce
(map (fn [[s1 s2]]
(->> (my-shape-for-situation s1 s2)
(vector s1)
points-for-round)))
+ data))