If someone would like the horrible experience of using JavaScript instead of Clojure... ๐ At least it supports reloading of JavaScripts code. Any ideas of how to integrate ChatGPT in a cool way would be awesome. Please ๐งต . I asked ChatGPT about integrating with its API and it seems pretty straight forward, especially since it gave me the code for it.
Sup Clojurians. Here are my 2022 Advent of Code solutions in Clojure: https://github.com/theronic/advent-of-code/tree/main/src/advent_of_code/year2022
PSA for those new to some of the core functions people use in these solutions: Study the https://clojure.org/api/cheatsheet . e.g. Have a sequence, and want to get some things from the front? go to โSeq In, Seq Outโ -> โHead Itemsโ and checkout the list: take take-while butlast drop-last for.
I totally forgot about distinct? and really miss basic factory function for queue (sth like (def queue [coll]... (clojure.lang.PersistentQueue ...)
me too! distinct? and keep-indexed this time (`re-seq` yesterday)
every day something new ๐
Kind of a meta-point: over time I've come up with a bit of https://github.com/scottbale/advent-of-code/blob/main/clojure/resources/template.clj.txt to tackle each day's puzzle, and I like it so much that this year I wrote a little https://github.com/scottbale/advent-of-code/blob/main/clojure/src/user.clj to generate each day's new one. It's not much boilerplate, but it takes care of the little bit of file I/O fiddliness and my experience becomes, I just hop into the REPL and start hacking first using the puzzle's hardcoded sample data, and then more often than not it works on the first try with my personalized input (which I have to copy into the resource file). So for example day 5 looks like this at the start:
(ns aoc-2022.day5
"docstring"
(:require
[ :as io]))
(defn runner
"runner docstring"
[input]
)
(comment
(runner [" [D]"
"[N] [C]"
"[Z] [M] [P]"
" 1 2 3"
""
"move 1 from 2 to 1"
"move 3 from 1 to 3"
"move 2 from 2 to 1"
"move 1 from 1 to 2"])
(with-open [r (io/reader (io/resource "aoc-2022/day5.txt"))]
(runner (line-seq r)))
) I have a bb script to create a new day from a template with all my clerk boilerplate
https://github.com/elken/aoc/blob/master/resources/template.clj
Neat! I started building something that parses the html to markdown and pastes that into clerk, but I might just steal your idea of using hickory and using the clerk/html viewer. The downside is that the prose is not visible in the editor, but the upside is that the prose is not visible in the editor. ๐ค
Yeah I did it manually at first but it's tedious to do and wastes space. You can have the notebook in an xwidgets browser frame of Emacs is compiled with it (which is how I work)
I'm old-fashioned and still use an external browser for my Portal and Clerk. :) I managed to automate the markdown parsing with this: https://github.com/simon-brooke/html-to-md But it's just a hacky POC at the moment and I'm not aware of what the sharp edges are (OTOH the AOC html is relatively straightforward so shouldn't be too many issues going forward). I will play with both approaches when I find some time in the coming days and report back. Thanks for sharing @elken!
bb has Selmer built-in, might want to check that out. (ns aoc.{{year}}.d{{day}} is convenient.
Iโve seen someone using clojure.lang.PersistentQueue in todays puzzle, so I wondered if this data structure is something that you use frequently in Clojure and if there are any caveats to be aware of (other than from the general properties of queues).
I already explored how it behaves with conj, peek and pop, which is as expected from a queue (first-in-first-out). I also see that seq works on queues and so they can be mapped, filtered, etc. and you can use (into clojure.lang.PersistentQueue/EMPTY โฆ) to get a queue from a seq or vector. They also seem to work with Babashka.
Funny you should mention it: earlier this very day, I was mentioning to someone that, although I've been programming Clojure since 2011, until I very recently read chapter 2 of Clojure Applied I did not even know of the existence of clojure.lang.PersistentQueue. ๐คท
<sample-of-one>I looked through my past AoC solutions and Iโve used it about once a year on average. In a full stack production app Iโve been working on, havenโt used it at all.</sample-of-one>
anecdotally (looking through my AoC history), I have used it a couple times for path-finding puzzles but it looks like I switched to clojure.data.priority-map at some point. Iโm not a clojure expert in any way, so I canโt say whether either was the right way to go. (other than they did do the job asked of them)
If you all havenโt seen this, itโs really worth looking at. It demonstrates the interaction with chatGPT to solve advent problems. https://note89.github.io/the-advent-of-code-ai-edition/ via @cfleming
Thanks for sharing! The day 4 prompt is revelatory: > Write instructions for the following challenge in such a way that a large language model like yourself can take those instructions and produce a program that creates the right output when run. The program needs to read from a file called input.txt Reminds me of starting to code straight from a business request vs. doing a planning session first and getting requirements straight.
Day 6 - Solutions
(ns aoc2022.day6
(:require [ :refer [resource]]
[clojure.string :as str]
[clojure.set :refer [intersection]]))
(defn data []
(->> (resource "inputs/day6.txt")
(slurp)))
(defn solution [s len]
(let [start-3 (into [] (take len s))
except-start-3 (into [] (drop len s))]
(+ len
(reduce (fn [[l idx] e]
(tap> [l idx])
(if (apply distinct? (conj l e))
(reduced idx)
[(conj (subvec l 1) e) (inc idx)]))
[(into [] start-3) 1]
except-start-3))))
(def part1 #(solution % 3))
(def part2 #(solution % 13)) (defn solve [input nb]
(reduce (fn [acc item]
(if (= (count item) nb)
(reduced (+ acc nb))
(inc acc)))
0
(map set (partition nb 1 input))))
(defn part1 [input]
(solve input 4))
(defn part2 [input]
(solve input 14))(defn marker-id
[data marker-length]
(->> (partition marker-length 1 data)
(map (comp count set))
(map-indexed vector)
(sort-by second >)
(first)
(reduce +)))Todays was a LOT easier than yesterday ๐ https://github.com/stuartstein777/clj-advent-of-code/blob/master/src/stuartstein777/2022/day6.clj
https://github.com/jramosg/advent-of-code/blob/master/src/advent_of_code/year_2022/day_06/main.clj
(defn solve [it len]
(let [f (fn [ii] ((juxt #(take len %) #(drop 1 %)) ii))]
(loop [[a b] (f it), pos len]
(if (= len (count (set a))) pos
(recur (f b) (inc pos))))))
(defn -main [day]
(let [input (file->str day)
result (partial solve input)]
(zipmap [:part1 :part2] (map result [4 14]))))Itโs so nice to learn about all these functions from your examples (`distinct?`, take-while, keep-indexedโฆ).
In https://github.com/ValentinMouret/advent-2022/blob/main/src/day_06.clj, I used reduce and reduced and I donโt think I have seen it so far.
https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2022/day6.clj
Variations on above. This was the first day I used my bb submit to send in the answers. Next up, submit direct from emacs cider
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d06.clj
I am happy that today my solution is almost the same as @tws
Maybe I missed something, but why in Clojure there's no queue function to create a queue?
Mine: > (defn day-06 [input n] > (loop [seen (apply conj (clojure.lang.PersistentQueue/EMPTY) (take n input)) i n] > (if (= (count (set seen)) n) > i > (recur (conj (pop seen) (get input i)) (inc i))))) > > (defn day-06-1 [input] > (day-06 input 4)) > > (defn day-06-2 [input] > (day-06 input 14))
You have PersistentQueue
but I guess you can mimic simple queues with vectors
I couldn't resist not using juxt ๐:
(defn day6 [fs]
((juxt #(% 4) #(% 14))
(fn [k]
(->> (partition k 1 fs)
(keep-indexed
#(when (apply distinct? %2)
(+ % k)))
first))))I've been using AoC as an opportunity to finally learn how to use transducers. For example https://github.com/lassemaatta/clj-aoc-2022/blob/master/src/lassemaatta/aoc_2022/day06.clj my solution for day 6.
https://github.com/zamansky/advent2022/blob/main/src/day06.clj
https://github.com/mducharm/advent_of_code_2022/blob/main/src/advent_of_code/day_06.clj
(->> (slurp "day6.txt")
(partition 14 1)
(map (comp count set))
(#(.indexOf % 14))
(+ 14))https://github.com/nooga/aoc2022/blob/master/day6.lg
(ns day6)
(def data (slurp "input/day6.txt"))
(defn solve [n]
(->> data (partition n 1) (map (comp #{n} count set)) (take-while not) count (+ n)))
(println "1:" (solve 4))
(println "2:" (solve 14))
helped me to fix my comp implementation ๐Day 6 https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day6/sol.clj
https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2022/d6.clj, eh? the essence of it:
(defn find-marker [n input]
(->> (partition n 1 input)
(keep-indexed #(when (apply distinct? %2) %1))
first
(+ n)))I think this just means tomorrow will be brutal :)
indeed... has felt like the calm before the storm for a while now
first week is always kinda like this and then it turns into a full time job
What I spent 5 minutes debugging last night... Zipmap maps aren't ordered.
day06.main> (for [[n] (zipmap (range) "abcdedghijklmn")] n)
(0 7 1 4 13 6 3 12 2 11 9 5 10 8)
day06.main> (for [[n] (map-indexed vector "abcdefghijklmn")] n)
(0 1 2 3 4 5 6 7 8 9 10 11 12 13)
keep-indexed wasn't really in my vocabulary, but now that I see those solutions, I will definitely start using it ore@xnooga yeah the perf of let-go is going to definitely get tested for sure
bring it on I say
Day 6: https://github.com/dogenpunk/advent-of-code/blob/main/src/aoc22/day06.cljc
Danggit! I always forget partition can take a size argumentโฆ
(defn sliding-window [seq length]
(loop [result ()
remaining seq]
(let [chunk (take length remaining)]
(if (< (count chunk) length)
(reverse result)
(recur (cons chunk result) (rest remaining))))))
(->> (sliding-window (slurp "input/day-6-input.txt") 14)
(reduce (fn [acc n]
(if (= (count (set n)) 14)
(reduced (+ acc (count n)))
(inc acc )))
0))
I wont forget that partition trick. ๐I was looking for an equivalent of rust's windows function, and learned that partition could do that. Very handy!
I went with a queue for this one but loving the succinct partition answer!
(defn find-marker [stream marker-len]
(reduce-kv (fn [acc k v]
(cond
(< (count acc) marker-len) (conj acc v)
(= marker-len (count (into #{} acc))) (reduced k)
:else (conj (pop acc) v)))
(clojure.lang.PersistentQueue/EMPTY)
(into [] stream)))(defn partition-till-detected [n s]
(take-while (complement (partial apply distinct?))
(partition n 1 s)))
(defn count-to-marker [n s]
(+ n (count (partition-till-detected n s))))
(count-to-marker 4 input) ;; part 1
(count-to-marker 14 input) ;; part 2And my day 6 solution: https://github.com/LouDnl/advent-of-code-2022/blob/master/src/clj/advent_of_code_2022/days/day_six.clj
;; 202206
(let [d (slurp "resources/202206")
f #(->> (partition % 1 d)
(keep-indexed (fn [i x]
(if (= % (count (set x)))
(+ % i))))
first)]
(map f [4 14]))
;; (1850 2823)https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day06/main.clj worst performance yet
https://github.com/zelark/AoC-2022/blob/master/src/zelark/aoc_2022/day_06.clj
https://coyotesqrl.github.io/advent-of-code/2022/src/coyotesqrl/2022/day06.html
;; Part 1
(defn sop [n s]
(let [cs (partition-all n 1 s)
mk (apply str (first (filter #(= % (distinct %)) cs)))]
(+ n (str/index-of s mk))))
(sop 4 input) ;; 1343
;; Part 2
(sop 14 input) ;; 2193https://github.com/rap1ds/advent-of-code-2022/blob/main/src/day6.clj And happy independence day Finland ๐ซ๐ฎ!
TIL distinct? https://github.com/nbardiuk/adventofcode/blob/master/2022/src/day06.clj
https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2022/day_06_packets.clj
https://github.com/tylerw/advent-of-code-2022/blob/master/src/aoc2022/day06.cljc
Keeping with the advent-of-transducers theme
this regrettably only got me the first part but gonna keep working with it
(def input (-> "public/puzzle_inputs/day_six.txt" io/resource slurp))
(defn process-data [n s]
(let [packets (map #(apply str %) (partition n 1 s))
unique-packets (map (comp #(apply str %) distinct) packets)
nums (filter some? (map #(if (= %1 %2) %3 nil)
packets unique-packets (range)))]
(first (drop n nums))))
I think changing your last line to (+ (first nums) n) should do it
Seems like I missed out on the take-while train ๐
https://github.com/motform/advent-of-clojure/blob/master/src/advent_of_clojure/2022/06.clj