Fork me on GitHub
#adventofcode
<
2021-12-01
>
norman05:12:46

Hooray - I actually remembered advent of code on the first day.

💯 4
R.A. Porter05:12:18

Day 1 Solutions 🧵

R.A. Porter05:12:40

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.

Chase05:12:20

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

Chase05:12:06

and already seeing some great clojure solutions on the reddit solution thread

R.A. Porter05:12:09

Guess I should post mine. Elided the boilerplate of reading/parsing input.

👏 3
1
mchampine06:12:35

;; 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

👍 5
1
peterc06:12:50

(defn part1 [data]
  (->> (map - (rest data) data)
       (filter pos?)
       count))

(defn part2 [data]
  (->> (map - (rest (drop 2 data)) data)
       (filter pos?)
       count))

👍 2
2
nbardiuk06:12:50

Happy to use clojure alpha with parse-long in core https://github.com/nbardiuk/adventofcode/blob/master/2021/src/day01.clj

👍 3
🙌 5
Antonio Bibiano08:12:15

very similar to the others.. avoided some repetition

Antonio Bibiano08:12:27

(defn part1 [input]
  (->> input
       (partition 2 1)
       (filter #(apply < %))
       count))
(defn part2 [input]
  (->> input
       (partition 3 1)
       (map #(apply + %))
       part1))

👍 3
❤️ 1
Adam Haber08:12:45

(->> l 
     (#(map < % (rest %)))
     (filter identity)
     count)

Adam Haber08:12:57

(->> l
     (#(map + % (rest %) (rest (rest %))))
     (#(map < % (rest %)))
     (filter identity)
     count)

👍 1
Stuart09:12:32

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 😆

👍 1
1
tschady10:12:06

(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))))

👍 3
karlis11:12:06

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))))

👍 3
Felipe13:12:05

exact same solution as @U01HY37QQUA, 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)))

👍 3
ianjones16:12:54

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))

cyppan16:12:57

Tried to go lazy using transducers (using this lib https://github.com/cgrand/xforms for the missing partition transducer from the core)

pithyless17:12:43

@U0CL38MU1 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

cyppan17:12:57

oh thanks ! 😄

pithyless17:12:06

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 😜

cyppan17:12:12

you’re absolutely right

Andrew Byala18:12:18

My Clojure solution, including my https://github.com/abyala/advent-2021-clojure/blob/main/docs/day01.md about how I got there.

👍 1
nooga19:12:18

(def input [ .. ])
(def solve #(->> (map < %1 (next %1)) (filter true?) count))
(println (solve input))
(println (->> input (partition 3 1) (map #(apply + %1)) solve))

kj08:12:57

(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)

Tero Matinlassi21:12:19

(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
  )

Filip Strajnar20:12:03

(defn
  by-indicies-2
  [numbers]
  (->> numbers count dec range (filter #(< (nth numbers %) (nth numbers (inc %)))) count))

Filip Strajnar20:12:20

this is the 1st part, I'm looking for suggestions how to make it shorter

Vincent Cantin06:12:24

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.

😁 2
🙌 7
1
roelof06:12:47

morning , where can I find the stream and can I look to it when you have solved the challenges ?

Vincent Cantin06:12:01

I will start the stream in about 15 min

roelof11:12:15

@U8MJBRSR5 thanks for the stream but I wonder for adding the three numbers . why not use reduce for it ?

Vincent Cantin11:12:38

We could, but I tried to be accessible to a wider audience

Vincent Cantin11:12:42

I will mention it in tomorrow's stream. Thanks for mentioning it.

roelof11:12:14

np, just wondering

roelof14:12:28

he, no coding from @U8MJBRSR5?

Vincent Cantin18:12:23

I did it on Twitch, but late because of the reClojure conference

roelof18:12:20

oke I will look it later

roelof18:12:40

and hopefully learn from it

roelof18:12:26

@U8MJBRSR5 are you french and live in Europe ?

Vincent Cantin20:12:08

I live in Taiwan :flag-tw:

roelof20:12:31

oke, I asked because I think I heard a french acccent , I apolize

Vincent Cantin21:12:34

French people in Taiwan do not lose their French accent 😁

roelof08:12:00

coulod be, was just curious @U8MJBRSR5

Vincent Cantin09:12:18

Yes, I am French

misha06:12:01

👋 opieop

👋 4
nooga12:12:53

👋 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:

metal 2
👍 1
👏 2
nooga19:12:07

spoiler! not bad for a barebones interpreter huh?

👍 1
nooga20:12:49

and since AoC is about collecting stars, I wouldn’t mind some github stars 😁

Stuart13:12:28

either will work. I can't think of any reason why you would need clojure cli tools over lein

2
Andrew Byala18:12:20

🧵 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.

Andrew Byala18:12:37

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?

pithyless18:12:45

> Threading to avoid partial spoilers. Pun intended!

😂 9
1
nooga18:12:35

@U01HHBJ56J1 I think they’re roughly the same for small colls

☝️ 1
pithyless18:12:20

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.

tschady18:12:51

I remember reduce had significantly better benchmarks on larger colls.

Andrew Byala19:12:37

@U05476190 - your first comment was terrible, and you just made a friend today.

❤️ 1
Andrew Byala19:12:02

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?

Antonio Bibiano19:12:50

Looking at the source looks like reduce is optimized for different types of collections while apply is just a lot of calls to cons

Antonio Bibiano19:12:36

so I would imagine when you know that the collection is going to be quite small

Antonio Bibiano19:12:33

or if you have to do it a lot of times! according to my not so advanced benchmarking skills

Antonio Bibiano19:12:45

(time
 (loop [n 0]
   (when (< n 1000000)
     (apply + '(1 2 3))
     (recur (inc n)))))

Antonio Bibiano19:12:57

takes ~200 ms on my machine

Antonio Bibiano19:12:05

switching to reduce takes 45 ms

Chase21:12:54

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.

Chase21:12:27

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

Chase21:12:08

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.

pithyless21:12:19

@U01HY37QQUA 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))
    ))

🙌 1
pithyless21:12:42

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 ns

pithyless21:12:54

But 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 ;)

✔️ 2
Chase22:12:43

Someone created and posted a great resource to explore the solution threads by computer language: https://aocweb.yulrizka.com/

🙏 1
😍 2
Chase22:12:43

APL is such a wild language

Stuart23:12:16

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 ?

nooga23:12:04

The ones I’ve seen used only notepad 😛

Stuart00:12:49

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 😄

Phil Shapiro14:12:29

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.