This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-04
Channels
- # adventofcode (154)
- # announcements (1)
- # babashka (8)
- # beginners (28)
- # bristol-clojurians (3)
- # calva (131)
- # cider (43)
- # clj-kondo (14)
- # clojure (135)
- # clojure-europe (1)
- # clojure-italy (7)
- # clojure-madison (1)
- # clojure-nl (6)
- # clojure-spec (8)
- # clojure-uk (90)
- # clojurescript (47)
- # core-async (9)
- # cryogen (4)
- # cursive (12)
- # datomic (9)
- # emacs (7)
- # fulcro (5)
- # graalvm (56)
- # joker (4)
- # juxt (1)
- # leiningen (6)
- # off-topic (62)
- # pathom (4)
- # pedestal (2)
- # reagent (2)
- # reitit (5)
- # ring (2)
- # schema (4)
- # shadow-cljs (133)
- # sql (38)
- # tools-deps (10)
- # vim (28)
Wasted a lot of time on silly misplaced parens error on this one. 😉 https://github.com/jreighley/aoc2019/blob/master/src/aoc/aoc3.clj
Have you tried parinfer or parindent?
I use cursive and parinfer. It was my distance function that added the absolute values of the two vectors. Since it was all on the same line, it didn’t help
(+ (abs x)) (abs y)
instead of
(+ (abs x) (abs y))
The function was returning the correct number on the y deltas but 0 on the x deltas…@erwinrooijakkers nice tip, using peek instead of last shaved 500ms of the 7s.
Only made it through part 1 of day 3 while slacking at work towards the end of the day… no one noticed the Clojure instead of Python on my screen 🤷 https://github.com/KennyMonster/aoc_2019/blob/c2dfdfffdc4447c34aa6a7c90b0a763d10da8713/src/day_3.clj
There's some days when I've needed a break to do some real programming and get my brain moving again before going back to 'real work'. So long as it hasn't cut into the hours I'm contracted to bill, anyway. 🙂
Puzzle 4 was way easier than the last two. I count 8 lines of code for Part 1, with a single line altered to adapt the part 1 solution to part 2.
Actually, just a single character change for part 2. I have a test for repeated digits that looks like this:
(some #(<= 2 (count %)) (partition-by identity (str n))
For part 2, just changing the “<=” to “=” was sufficient.
i used frequency on the list of digits
Still find it awesome how lisps allow you to do things like #((case part 1 <= 2 =) 2 (count %))
@mpcjanssen ?? You mean frequencies? But that doesn’t care about order, so I don’t see how it would detect sequential duplicates differently than non-sequential ones..
@mchampine you are right. it did give the right answer though
no because the digits are increasing
so any same digits are consecutive
rationalisation after the fact 🙂
did not completely think this through before
why do you divide by 10000 though I don't get it why not something like (<= 100000 x 999999)
Wow, using spec. Neat. Btw, you can do a quick and dirty digits conversion with (map read-string (map str (str 123456)))
http://quil.info/sketches/show/4350261fceb6f0e6f385e23fcd9a8ca91623ffd813912ca79c47bfa51ad1a6f1
also nice literal coding with org-babel
Yes, tried org-babel a while back. Pretty great stuff you can do. I was mixing bash, python, clojure, and LaTeX as I recall.
Todays one went pretty smooth https://gitlab.com/dmarjenburgh/adventofcode/blob/master/src/adventofcode/year_2019.clj#L65-78
apart from the somewhat vague description for puzzle #2, today was quick & easy: https://github.com/skazhy/advent/blob/master/src/advent/2019/day4.clj
here’s mine https://gist.github.com/roman01la/c607849e71e6de11549976428cd3d6a6
Smart regex for increasing
regex turned out to be much faster than parsing and comparing digits
@karlis indeed, it took me a while to decypher description of the 2nd part
Try a first time with "filter wrong values", but my predicates were pretty bad, so my evaluation "never" finishes. I re-write it in a dirty (but successful) way. https://github.com/Charlynux/advent-of-code-2019/blob/master/day04/day04.clj
I think each year there are a few problems like day 4 pt. 2 that seem almost intentionally vague… https://github.com/taylorwood/advent-of-code/blob/master/src/advent_of_code/2019/4.clj
Mine is ugly, but it works: https://github.com/rhinoman/aoc2019/blob/master/src/aoc2019/day4.clj
It doesn't like it when the first digit is 0
@taylor nice digits
func to convert an int to a seq of digits without string manipulations. I would have never thought to do it that way
@jrwdunham my solution initially used string manipulation, I got about 10x speedup when I cut out all of the type conversions 🙂
(time
(let [MIN 382345
MAX 843167
int-vec (fn [n] (->> n str (map str) (mapv #(Integer/parseInt % 10))))
low (int-vec MIN)
high (int-vec MAX)
too-low #(neg? (compare % low))
in-range #(neg? (compare % high))
pwds (for [a (range 0 10)
b (range a 10)
c (range b 10)
d (range c 10)
e (range d 10)
f (range e 10)
:let [n [a b c d e f]]
:when (->> n frequencies vals (some #{2}))]
n)]
(->> pwds
(drop-while too-low)
(take-while in-range)
(count))))
"Elapsed time: 13.145288 msecs"
=> 290
James'es times on my input and laptop are: "Elapsed time: 159.510294 msecs" "Elapsed time: 324.308817 msecs"
btw, I understood part 2 immediately by looking at examples, don't know why so many were confused. (however, there were few similar requirements in previous years' puzzles, so I might have just recognized it)
I had a solution that worked for all the examples but not for my test input; took me like 6 submissions to get it right
same here. although I tend to jam the examples into my tests before I think too much over the problem description
also this is why I did not use frequencies initially, because I recalled "2 but not 3+ in a row", and thought of letters, and did not figure out that there can only be 1 streak per digit, and can't be e.g. 11xx1x
.
(partition-by identity coll)
gives you groups
:
(partition-by identity "123444")
=> ((\1) (\2) (\3) (\4 \4 \4))
Thats not how I understood it. Which was my complaint since it was left up to interpretation
group of 2
is two of the same digits in a row.
larger group
is tree or more of the same digit in a row
the two adjacent matching digits are not part of a larger group of matching digits.I understood this as: As long the repeating digit is not part of the largest group of all groups then it is valid.
yes. here, 33____ and 33__ are two adjacent matching digits
but both are part of a larger group of matching digits
333___
222333
has two groups. Each of size 3 meaning there is no larger group. Since they are both the same
122333 is valid, because there is only 2 2
in a row,
222333 in invalid, because there is 3 2
in a row
. (map count (partition-by identity "122333")) => (1 2 3) ;; has group of exactly 2 numbers (map count (partition-by identity "222333")) => (3 3) ;; does not have group of exactly 2 numbers
this is why people here bragged about "part 2 was just 1 char diff commit!": (->> ... (some #(<= 2 %))) for part 1 and (->> ... (some #(= 2 %))) for part 2
Not for me. I kept thinking "Oh I get it now." Type the answer in and getting "Sorry wrong answer. Plz wait 10 mins before submitting again."
happened a lot to me in other puzzles. It is not in the aoc interests to make it obvious to you what needs to be done, hence lots of text, indirection in terminology, random bold font highlights, "by the ways", ambiguous examples
I wrote a crazy regex to get dec4/pt2 which i'm sharing for laughs. (Liking the concise and sane strategies I'm seeing here):
(def pattern
(re-pattern
(str
"("
"(^|[^1])11($|[^1])"
"|"
"(^|[^2])22($|[^2])"
"|"
"(^|[^3])33($|[^3])"
"|"
"(^|[^4])44($|[^4])"
"|"
"(^|[^5])55($|[^5])"
"|"
"(^|[^6])66($|[^6])"
"|"
"(^|[^7])77($|[^7])"
"|"
"(^|[^8])88($|[^8])"
"|"
"(^|[^9])99($|[^9])"
"|"
"(^|[^0])00($|[^0])"
")")))
I always feel like I am cheating when I use regex. That never stops me from being tempted. (Including today)
adventofcode-clj-2019.day04> (time (part-1))
"Elapsed time: 19.688852 msecs"
1605
adventofcode-clj-2019.day04> (time (part-2))
"Elapsed time: 23.650609 msecs"
1102
Yep, i didn't thought about using for. But my solution is more general (not only for six digit length numbers)
And is only slightly slower
@misha I did a similar optimization to only iterate through non-decreasing digit-vectors 🙂
(defn incr [ds]
(let [d (peek ds)]
(if (= 9 d) ;; recursive
(let [ds* (incr (pop ds))]
(conj ds* (peek ds*))) ;; roll over using prev digit
(conj (pop ds) (inc d)))))
(iterate incr [1 4 6 8])
;; => ([1 4 6 8]
;; [1 4 6 9]
;; [1 4 7 7]
;; [1 4 7 8]
;; [1 4 7 9]
;; [1 4 8 8]
;; [1 4 8 9]
;; [1 4 9 9]
;; [1 5 5 5]
;; [1 5 5 6]
;; ...)
adventofcode-clj-2019.day04> (time (part-1))
"Elapsed time: 19.688852 msecs"
1605
adventofcode-clj-2019.day04> (time (part-2))
"Elapsed time: 23.650609 msecs"
1102
I replaced the nested for
clauses in your solution with (for [n (iterate incr [0 0 0 0 0 0]])
and got a 13.5 msec => 9.0 msec speed up
is it consistent speed up? do you consistently get 13ms on my snippet? for me it fluctuates +-2ms
@misha my un-aptly named monotonically-increasing?
filter seems to be correctly filtering out the 0
s
i see. See any way to make the regex more concise, with backreferences and lookahead/behind fanciness?
Yes, also not fast: part 1: Elapsed time: 485.806268 msecs
; part 2: Elapsed time: 578.42914 msecs
.
For speed AND idiomatic code it's probably better to do it in Rust
(defn day4
[start end part]
(let [dv (fn [n] (mapv #(Character/getNumericValue %) (str n)))
dv< (fn [a b] (= -1 (compare a b)))
startv (dv start)
endv (dv end)
incr (fn [ds] ;; increase digit vector until it satisfies non-decreasing condition
(let [d (peek ds)]
(if (= d 9) ;; recursive
(let [ds* (incr (pop ds))]
(conj ds* (peek ds*))) ;; roll over using prev digit
(conj (pop ds) (inc d)))))
pw? (fn [xs]
(some #((case part 1 <=, 2 =) 2 (count %))
(partition-by identity xs)))]
(transduce
(comp
(drop-while #(dv< % startv))
(take-while #(dv< % endv))
(filter pw?))
(completing (fn [n _] (inc n)))
0
(iterate incr (vec (repeat (count startv) (first startv)))))))
(day4 124075 580769 1) ;; => 2150
(day4 124075 580769 2) ;; => 1462
Nice @qythium, about 1msec faster than @dmarjenburgh’s solution in my timing.
Doing AOC last year was so much easier when I was on vacation for almost the entire month. I have a feeling I'm going to be playing catch up all month...
But I feel better about it knowing that I'm not aiming for leaderboard points. I'll learn what I'm aiming to, just more slowly.
Simple enough: https://github.com/jreighley/aoc2019/blob/master/src/aoc/aoc4.clj It’s not too often that I use ns without a :require. The separated-pairs? fn seems a bit hacky, but effective.