Hooray - I actually remembered advent of code on the first day.
Day 1 Solutions π§΅
https://github.com/benjamin-asdf/advent-of-code-2021/blob/master/src/increases.clj
(def input ...)
(defn count-increases
[coll n]
(->> (map < coll (drop n coll))
(filter true?)
count))
;; Part 1
(count-increases input 1)
;; Part 2
(count-increases input 3)solution to day1: https://github.com/euccastro/advent-of-code-2021/blob/main/day1.clj
https://gist.github.com/corasaurus-hex/389968ca616083ba0feb630330ba1739
Took me twice as long as it could have because I forgot the pad for partition was a collection. But otherwise...just partitions and filters on comparisons.
https://github.com/Chase-Lambert/aoc-clojure/blob/main/src/aoc/2021/day_01.clj
That was exciting to be there at the start. I wasted a few minutes doing something dumb and ended up at like 4000th place which is probably the best spot I'll get. lol
and already seeing some great clojure solutions on the reddit solution thread
https://github.com/kwpav/advent-of-code-2021/blob/master/src/advent_of_code_2021/day01.clj
Guess I should post mine. Elided the boilerplate of reading/parsing input.
;; part1
(defn count-incs [nn]
(count (filter pos? (map - (rest nn) nn))))
(count-incs input) ;; => 1681
;; part2
;; sliding window size 3
(-> (map #(apply + %) (partition 3 1 input))
count-incs) ;; => 1704
(defn part1 [data]
(->> (map - (rest data) data)
(filter pos?)
count))
(defn part2 [data]
(->> (map - (rest (drop 2 data)) data)
(filter pos?)
count))Happy to use clojure alpha with parse-long in core
https://github.com/nbardiuk/adventofcode/blob/master/2021/src/day01.clj
@pez Only 20 days later π https://www.youtube.com/watch?v=q_I3r0JGhR8
(defn
by-indicies-2
[numbers]
(->> numbers count dec range (filter #(< (nth numbers %) (nth numbers (inc %)))) count))this is the 1st part, I'm looking for suggestions how to make it shorter
(ns day1
(:require [clojure.string]))
(comment
; part 1
(->> "input"
slurp
clojure.string/split-lines
(map #(Integer/parseInt %))
(reduce (fn [[c a] b]
(if (> b a)
[(inc c) b]
[c b]))
[0 0])
first
dec)
;=> 1752
)
(defn sliding-window [s]
(partition 3 (interleave s (rest s) (rest (rest s)))))
(comment
; part 2
(->> "input"
slurp
clojure.string/split-lines
(map #(Integer/parseInt %))
sliding-window
(map #(reduce + %))
(reduce (fn [[c a] b]
(if (> b a)
[(inc c) b]
[c b]))
[0 0])
first
dec)
;=> 1781
)very similar to the others.. avoided some repetition
(defn part1 [input]
(->> input
(partition 2 1)
(filter #(apply < %))
count))
(defn part2 [input]
(->> input
(partition 3 1)
(map #(apply + %))
part1))(->> l
(#(map < % (rest %)))
(filter identity)
count)(->> l
(#(map + % (rest %) (rest (rest %))))
(#(map < % (rest %)))
(filter identity)
count)Using my utility function that reads a file, splits it line by line and applies a parser function to each line.
(def puzzle-input "puzzle-inputs/2021/day1")
(defn calculate-increasing [xs]
(->> (map < xs (rest xs))
(filter true?)
(count)))
(defn parser [n]
(Integer/parseInt n))
;; Part 1
(->> (f/read-all-lines-and-parse puzzle-input parser)
calculate-increasing)
;; Part 2
(->> (f/read-all-lines-and-parse puzzle-input parser)
(partition 3 1)
(map #(reduce + %))
calculate-increasing)
Easy day 1. Don't know if that's a good sign or not π(def input (file-util/read-ints "2021/d01.txt"))
(defn part-1 [input]
(count (filter pos? (map - (rest input) input))))
(defn part-2 [input]
(count (filter pos? (map - (drop 3 input) input))))Starting off easy π
(defn increase-count [i] (count (filter true? (map < i (drop 1 i)))))
(def puzzle1 increase-count)
(defn puzzle2 [input]
(increase-count (map + input (drop 1 input) (drop 2 input))))exact same solution as @antbbn, minus the thread macros
(def input (map read-string (clojure.string/split-lines (slurp ""))))
(defn increases [coll] (count (filter #(apply < %) (partition 2 1 coll))))
;; part 1
(increases input)
;; part 2
(increases (map #(apply + %) (partition 3 1 input))) heh, some of yβalls solutions are so simple. Im new so I didnt know about partition facepalm
(defn add-not-nil [& col]
(when (not (some nil? col)) (reduce + col)))
(defn optimized [col]
(reduce-kv (fn [count index value]
(let [value2 (nth col (inc index) nil)
value3 (nth col (inc (inc index)) nil)
value4 (nth col (inc (inc (inc index))) nil)
window1 (add-not-nil value value2 value3)
window2 (add-not-nil value2 value3 value4)]
(if (and (not (nil? window1)) (not (nil? window2)))
(if (< window1 window2)
(inc count)
count)
count))) 0 col))Tried to go lazy using transducers (using this lib https://github.com/cgrand/xforms for the missing partition transducer from the core)
@cyppan xforms has an x/count and x/lines-in - ie. (x/count (comp ,,,) (xio/lines-in resource))
That way, you wouldn't need the with-open, and returning and adding up the 1 's from keep
oh thanks ! π
I'd also argue that this is a little misleading: > Tried to go lazy using transducers I think more appropriate would be > Tried to go super-eager using transducers π
youβre absolutely right
My HTML solution π: https://samadams.dev/2021/12/01/advent-of-code-day-1.html
My Clojure solution, including my https://github.com/abyala/advent-2021-clojure/blob/main/docs/day01.md about how I got there.
https://github.com/raicotop/advent-of-code-2021/blob/main/src/advent_of_code_2021/day-01.clj
(def input [ .. ])
(def solve #(->> (map < %1 (next %1)) (filter true?) count))
(println (solve input))
(println (->> input (partition 3 1) (map #(apply + %1)) solve))Good morning everyone, and happy new AoC ! I won't compete on the clock this year, I chose to stream while slowly solving the problems in the hope of making more people discover Clojure.
coulod be, was just curious @vincent.cantin
Yes, I am French
Morning!
morning , where can I find the stream and can I look to it when you have solved the challenges ?
Vincent streams on twitch https://www.twitch.tv/greencoder
I will start the stream in about 15 min
I wait
he, no coding from @vincent.cantin?
I did it on Twitch, but late because of the reClojure conference
oke I will look it later
and hopefully learn from it
@vincent.cantin are you french and live in Europe ?
I live in Taiwan πΉπΌ
My repo for AoC 2021 is at https://github.com/green-coder/advent-of-code/tree/master/src/aoc_2021
oke, I asked because I think I heard a french acccent , I apolize
French people in Taiwan do not lose their French accent π
@vincent.cantin thanks for the stream but I wonder for adding the three numbers . why not use reduce for it ?
We could, but I tried to be accessible to a wider audience
I will mention it in tomorrow's stream. Thanks for mentioning it.
np, just wondering
π opieop
π Happy AoC everyone! This year Iβm solving using my own Clojure(-like-language) implementation: https://github.com/nooga/let-go Hoping to extend the core lib and weed out some bugs as I go through AoC problems π Funnily enough, let-go seems to outperform other implementations on simple programs since it has very minimal startup time:
spoiler! not bad for a barebones interpreter huh?
nice!
and since AoC is about collecting stars, I wouldnβt mind some github stars β π
wonders if you need the clojure-tools or that advent-of-code can be solved by using leiningen
either will work. I can't think of any reason why you would need clojure cli tools over lein
π§΅ I had a simple question about something I've seen in a few solutions for Day 1 Part 2 today. Threading to avoid partial spoilers.
In my solution, when I created the sum of each three-tuple, I used
(map (partial apply +) triples),
but I've seen some folks use
(map (partial reduce +) triples). Both give the same answer, so how would you choose one over the other?
> Threading to avoid partial spoilers. Pun intended!
From just an aesthetics perspective, apply X will work for any variadic function, but reduce X will work any monoid. I originally wrote apply + and then converted it to reduce + for exactly that reason: I figured there are more monoids than variadic functions, so maybe that should be the default.
I remember reduce had significantly better benchmarks on larger colls.
@pithyless - your first comment was terrible, and you just made a friend today.
Ok, so in instances when both would work, reduce is the preferred operation, even if the performance doesn't matter for smaller collection sizes. So when would you ever choose apply then?
Looking at the source looks like reduce is optimized for different types of collections while apply is just a lot of calls to cons
so I would imagine when you know that the collection is going to be quite small
or if you have to do it a lot of times! according to my not so advanced benchmarking skills
(time
(loop [n 0]
(when (< n 1000000)
(apply + '(1 2 3))
(recur (inc n)))))takes ~200 ms on my machine
switching to reduce takes 45 ms
I've always liked apply + because I think it highlights a great benefit of the lisp notation where you can have variadic args to the + function, etc.
In my head, that's what I want to use because that is how I mentally solve that particular use case but then in the back of my mind I know it is less performant than reduce and I hate that. I don't why this bothers me so much. hahaha
That's one thing I appreciate in Rust. I think it allows me to write code the way I want to without punishing me on performance.
@antbbn it's good to reach for criterium when you need to do some quick micro-benchmarking:
(require '[criterium.core :as criterium])
(criterium/with-progress-reporting
(criterium/bench
(reduce + '(1 2 3))
;; (apply + '(1 2 3))
))On my machine, it looks like this:
;; reduce
;; Execution time mean : 25.832360 ns
;; Execution time std-deviation : 0.751152 ns
;;
;; apply
;; Execution time mean : 169.971152 ns
;; Execution time std-deviation : 9.294313 nsBut really, this is a microbenchmark that doesn't really mean anything unless we're in some performance critical code; and then you probably want to worry more about boxing and unchecked math ;)
Someone created and posted a great resource to explore the solution threads by computer language: https://aocweb.yulrizka.com/
APL is such a wild language
Yes, there's an APL IDE, https://www.dyalog.com/. The UI has a palette that contains all (most?) symbols, and each symbol has a two key shortcut.
I take it APL needs you to be really familiar with keyboard shortcuts to input those weird characters into your IDE (do APL people use an IDE?) Or a keyboard with custom keycaps ?
The ones Iβve seen used only notepad π
I have a lot of text substitutions setup in my IDE (vs code), but I still type in regular clojure, its just displayed more concisely, I have no idea how I would even type in most of those APL characaters π