thorondir's recent activity
-
Comment on Day 7: No Space Left On Device in ~comp.advent_of_code
-
Comment on Day 6: Tuning Trouble in ~comp.advent_of_code
thorondir Oh, right. O(n) in a place I didn't expect. Thanks for the pointers! :)Oh, right. O(n) in a place I didn't expect.
Thanks for the pointers! :)
-
Comment on Day 6: Tuning Trouble in ~comp.advent_of_code
thorondir Reading your solutions [and the docs, to figure out what you did xD] is always super helpful. :D I went about it a bit differently, by manually keeping track of the index. Which also meant part...Reading your solutions [and the docs, to figure out what you did xD] is always super helpful. :D
I went about it a bit differently, by manually keeping track of the index. Which also meant part two was a change of adding a single character. xD
Both Parts
(define (unique? lst) (= (length lst) (set-count (list->set lst)))) (define (process-slice slice idx slice-length) (cond [(< (length slice) slice-length) (displayln "slice too small") (values empty -1)] [(>= (length slice) slice-length) (define new-slice (take slice slice-length)) (cond [(unique? new-slice) (values empty (+ idx slice-length))] [else (process-slice (rest slice) (add1 idx) slice-length)])] [else (values 'never-supposed-to-get-here -1)])) (define (part-1 input) (define-values (m i) (process-slice input 0 4)) i) (define (part-2 input) (define-values (m i) (process-slice input 0 14)) i)
-
Comment on Day 4: Camp Cleanup in ~comp.advent_of_code
-
Comment on Day 5: Supply Stacks in ~comp.advent_of_code
thorondir Still doesn't feel idiomatic, because I use a bunch of mutation, but it's getting easier to write down what I want to do, so that's a win. Now I just have to not do the unidiomatic thing. xD...Still doesn't feel idiomatic, because I use a bunch of mutation, but it's getting easier to write down what I want to do, so that's a win. Now I just have to not do the unidiomatic thing. xD
Racket:
Part 1
(struct move (amount src dst) #:transparent) (define (parse-stacks stack-lines) (define stacks# (length (string-split (last stack-lines)))) (define stacks (make-vector stacks# '())) (for ([stack-line (rest (reverse stack-lines))]) (define matches (regexp-match* #rx"(...) ?" stack-line)) (for ([m matches] [i (in-range stacks#)]) (when (not (char=? (string-ref m 1) #\ )) ; only add something if the slot is not empty (vector-set! stacks i (cons (string-ref m 1) (vector-ref stacks i)))))) stacks) (define (parse-moves move-lines) (for/list ([line move-lines]) (define matches (regexp-match #px"move (\\d+) from (\\d+) to (\\d+)" line)) (move (string->number (second matches)) ; amount (sub1 (string->number (third matches))) ; src (sub1 (string->number (fourth matches)))))) ; dst ;; function to make input usable (define (sanitize-input input) (define split (string-split input "\n\n")) (define stack-def-raw (string-split (first split) "\n")) (define proc-def-raw (string-split (second split) "\n")) (define stacks (parse-stacks stack-def-raw)) (define moves (parse-moves proc-def-raw)) (values stacks moves)) (define (proc-moves! stacks moves) (for ([m moves]) (for ([i (in-range (move-amount m))]) (move-container! stacks (move-src m) (move-dst m))))) (define (move-container! stack src dst) (define container (first (vector-ref stack src))) (vector-set! stack src (rest (vector-ref stack src))) (vector-set! stack dst (cons container (vector-ref stack dst)))) ;; take the small input from the text (define raw-small-input (file->string "small-input_05")) (define small-answer-1 "CMZ") ;; workhorse, part 1 (define (part-1 raw-input) (define-values (stacks moves) (sanitize-input raw-input)) (proc-moves! stacks moves) (list->string (vector->list (vector-map first stacks)))) ;; test that "workhorse, part 1" does as it should (check-equal? (part-1 raw-small-input) small-answer-1) (displayln (~a "part 1: " (part-1 raw-aoc-input)))
And Part 2:
Part 2
(define (move-multiple-containers! stacks move) (define containers (take (vector-ref stacks (move-src move)) (move-amount move))) (vector-set! stacks (move-src move) (drop (vector-ref stacks (move-src move)) (move-amount move))) (vector-set! stacks (move-dst move) (append containers (vector-ref stacks (move-dst move))))) (define (proc-moves-2! stacks moves) (for ([m moves]) (move-multiple-containers! stacks m))) ;; part 2 (define small-answer-2 "MCD") (define (part-2 raw-input) (define-values (stacks moves) (sanitize-input raw-input)) (proc-moves-2! stacks moves) (list->string (vector->list (vector-map first stacks)))) (check-equal? (part-2 raw-small-input) small-answer-2) (displayln (~a "part 2: " (part-2 raw-aoc-input)))
-
Comment on Day 4: Camp Cleanup in ~comp.advent_of_code
thorondir This, I feel, went much better than day 03. Part 1 ;; function to make input usable (define (sanitize-input input) (for/list ([l (string-split input "\n")]) (parse-values l))) ;; take the small...This, I feel, went much better than day 03.
Part 1
;; function to make input usable (define (sanitize-input input) (for/list ([l (string-split input "\n")]) (parse-values l))) ;; take the small input from the text (define raw-small-input (file->string "small-input_04")) (define small-answer-1 2) (define small-input (sanitize-input raw-small-input)) (define (process-line line) (define l (first line)) (define r (second line)) (if (or (and (<= (first l) (first r)) (>= (second l) (second r))) (and (>= (first l) (first r)) (<= (second l) (second r)))) #t #f)) ;; workhorse, part 1 (define (part-1 input) (for/fold ([acc 0] #:result acc) ([l input]) (if (process-line l) (add1 acc) acc)))
And I'm quite proud of the overlap function. xD
Part 2
(define (overlap? line) (define l (first line)) (define r (second line)) (if (or (< (second l) (first r)) (> (first l) (second r))) #f #t)) ;; part 2 (define small-answer-2 4) (define (part-2 input) (for/fold ([acc 0] #:result acc) ([l input]) (if (overlap? l) (add1 acc) acc)))
I know the destructuring in
process-line
andoverlap?
aren't necessary, but it was easier to think about, this way. :D -
Comment on Day 3: Rucksack Reorganization in ~comp.advent_of_code
thorondir Ah, sets make a lot of sense, didn't think of them. I went about it in a rather... procedural way, which felt dirty, but worked. xD Part 1 ;; sanitize-input gets called before part-1 (define...Ah, sets make a lot of sense, didn't think of them.
I went about it in a rather... procedural way, which felt dirty, but worked. xD
Part 1
;; sanitize-input gets called before part-1 (define (sanitize-input raw-input) (for/list ([l (string-split raw-input "\n")]) (define strlen (string-length l)) (list ; return halves independently (string->list (substring l 0 (/ strlen 2))) (string->list (substring l (/ strlen 2)))))) (define (char-mapper c) (if (char-lower-case? c) (- (char->integer c) (sub1 (char->integer #\a))) (+ 26 (- (char->integer c) (sub1 (char->integer #\A)) )))) (define (calculate-priority priorities) (for/fold ([acc 0]) ([c priorities]) (+ acc (char-mapper c)))) (define (part-1 input) (define duplicates (for/list ([backpack input]) (define h (make-hash)) (for ([c (first backpack)]) (hash-set! h c 1)) (for/last ([c (second backpack)] #:when (hash-has-key? h c)) c))) (calculate-priority duplicates))
And part 2 also makes use of hash-maps a lot.
Part 2
; each backpack gets a hash where the characters are mapped to 1 (define (map-backpack backpack) (define h (make-hash)) (map (lambda (c) (hash-set! h c 1)) (append (first backpack) (second backpack))) h) ; calculate the union of the hashes by combining the values with + ; which means that the key that has a value of 3 is the badge we're looking for (define (compare-backpack-maps backpack-maps) (apply hash-union! backpack-maps #:combine +) (define combined (first backpack-maps)) (for/last ([k (in-hash-keys combined)] #:when (= (hash-ref combined k) 3)) k)) ; split the backpacks into groups of three ; calculate the badge for the current group ; recursively calculate the badge for the next group (define (process-backpacks backpacks) (cond [(< (length backpacks) 3) empty] [else (define-values (current-group other-groups) (split-at backpacks 3)) (cons (compare-backpack-maps (for/list ([b current-group]) (map-backpack b))) (process-backpacks other-groups))])) ;; part 2 (define small-answer-2 70) (define (part-2 input) (define badges (process-backpacks input)) (calculate-priority badges))
-
Comment on Day 1: Calorie Counting in ~comp.advent_of_code
thorondir Oh, nice! That does make it much more readable. xD Thank you so much!Oh, nice! That does make it much more readable. xD
Thank you so much!
-
Comment on Day 1: Calorie Counting in ~comp.advent_of_code
thorondir That's... much more elegant than what I did. From how the story went, I was sure there was going to be something more difficult for part two, so I set it up in a broader way, which then turned out...That's... much more elegant than what I did.
From how the story went, I was sure there was going to be something more difficult for part two, so I set it up in a broader way, which then turned out to be unnecessary...
Input parsing
;; function to make input usable (define (sanitize-input input) (define elf-strings (string-split input "\n\n")) (for/list ([e elf-strings]) (define inventory (map string->number (string-split e "\n"))) (elf (apply + inventory) inventory) )) ; returns a list of elves, each with their own inventory and the sum of calories as its own thing, for easy access
Given that, parts one was actually a simple one-liner.
Part 1
(define (part-1 input) (elf-calories (argmax elf-calories input)))
Part two was a bit more complicated, because I have to tell it how to sort the elves, but it's not rocket science.
Part 2
(define (part-2 input) (apply + (map elf-calories (take (sort input (lambda (a b) (> (elf-calories a) (elf-calories b)))) 3))))
For starting with racket not all that long ago, I'm quite happy about how it turned out.
-
Comment on Timasomo 2022: Final Update Thread in ~creative.timasomo
thorondir I've also not gotten very far, turns out the difference between "things that are Arduino-compatible" and an RP2040 is... huge, when it comes to usability. I've come to appreciate what Arduino has...I've also not gotten very far, turns out the difference between "things that are Arduino-compatible" and an RP2040 is... huge, when it comes to usability. I've come to appreciate what Arduino has done for entering a field that seems so incredibly opaque (to someone who's done sysadmin and "above the kernel" programming work).
I didn't manage to get my RP2040 to do what I thought it should do. Readouts of pins make no sense and don't correlate with what happens on those pins electrically, and I'm very confused.
-
Comment on Timasomo 2022: Week 1 Update Thread in ~creative.timasomo
thorondir Got a bit stuck with trying to figure out why the capacitative sensor doesn't work correctly, but the gold-plated one does, so... :shrug: I'll go with that. I did manage to track a complete drying...Got a bit stuck with trying to figure out why the capacitative sensor doesn't work correctly, but the gold-plated one does, so... :shrug: I'll go with that.
I did manage to track a complete drying cycle in one of the pots, turns out "dry" does not equal "dry", so I'll probably have to customize thresholds for when to water per plant. Which will take a while, so I don't think I'll manage all of that in the next two weeks.
-
Comment on Timasomo 2022: Roll Call in ~creative.timasomo
-
Comment on Timasomo 2022: Roll Call in ~creative.timasomo
thorondir Off-the-shelf, I'm using one of the following, depending on what works better: https://learn.sparkfun.com/tutorials/soil-moisture-sensor-hookup-guide...Off-the-shelf, I'm using one of the following, depending on what works better:
- https://learn.sparkfun.com/tutorials/soil-moisture-sensor-hookup-guide
- https://blog.zerokol.com/2021/01/hw-390-capacitive-soil-moisture-sensor.html
I'm actually not sure where exactly I got them from, but probably something like Pimoroni?
-
Comment on Timasomo 2022: Roll Call in ~creative.timasomo
thorondir (edited )LinkI'll build an automatic plant-watering system for indoor plants: a humidity sensor that checks soil humidity a microcontroller that decides whether what has been sensed is enough a pump, which the...I'll build an automatic plant-watering system for indoor plants:
- a humidity sensor that checks soil humidity
- a microcontroller that decides whether what has been sensed is enough
- a pump, which the microcontroller can trigger, that waters the plant
Ideally, it's all battery-powered [I've got some small LiPos lying around], but if I have to run some wires, so be it.
If everything turns out great, I'll give myself bonus points for setting up a 433MHz sender on the thing, with a Rasberry Pi receiver, that centrally monitors N potential watering stations throughout the house.
-
Comment on Announcing Tildes' Make Something Month (Timasomo) for 2022! in ~creative.timasomo
thorondir The past two years I've watched people do amazing things, on here, but never had the time. This time around, I just got laid off, have two months of free time, which fits perfectly, so I'll do...The past two years I've watched people do amazing things, on here, but never had the time.
This time around, I just got laid off, have two months of free time, which fits perfectly, so I'll do something I've been putting off for... way too long:
I'll build an automatic plant-watering system for indoor plants:
- a humidity sensor that checks soil humidity
- a microcontroller that decides whether whether what has been sensed is enough
- a pump, which the microcontroller can trigger, that waters the plant
Ideally, it's all battery-powered [I've got some small LiPos lying around], but if I have to run some wires, so be it.
If everything turns out great, I'll give myself bonus points for setting up a 433MHz sender on the thing, with a Rasberry Pi receiver, that centrally monitors N potential watering stations throughout the house.
-
Comment on Where/how should I acquire a .com domain for three years in advance? in ~tech
thorondir I think Namecheap allows for that. They also host Wordpress, if you're looking for that. I've been with them for a year, no complaints so far.I think Namecheap allows for that.
They also host Wordpress, if you're looking for that.I've been with them for a year, no complaints so far.
-
Comment on Self hosting email at home? in ~comp
thorondir That's pretty much exactly how it went for me, though I had the luxury of being a student with entirely too much free time, to figure stuff out. The initial setup is not all that complicated,...That's pretty much exactly how it went for me, though I had the luxury of being a student with entirely too much free time, to figure stuff out.
The initial setup is not all that complicated, actually, as the Arch Wiki tells you pretty much exactly what to do ( for those interested: https://wiki.archlinux.org/index.php/Virtual_user_mail_system ).
The difficult bit was in figuring out afterwards what I actually did, and whether what I did conformed to what I wanted to do.There are indeed a lot of moving parts, but after about a week of tinkering with it basically around the clock, back in 2015, I think, and some maintenance every now and again (and recently adding DMARC), it's been amazing.
To be fair, I'm a nerd that likes that sort of thing, so YMMV.
-
Comment on Everyone is beautiful and no one is horny in ~movies
thorondir As someone who doesn't know anything about buddhism, I'm genuinely curious: Why despise it?As someone who doesn't know anything about buddhism, I'm genuinely curious: Why despise it?
-
Comment on What programming/technical projects have you been working on? in ~comp
thorondir That's very fair. If you do decide to publish it somewhere, do post it here on Tildes, I'd be curious. :)That's very fair.
If you do decide to publish it somewhere, do post it here on Tildes, I'd be curious. :)
-
Comment on What programming/technical projects have you been working on? in ~comp
thorondir Have you considered writing a blog post about it, or something along those line, to make the things you figured out public? Make it easier for the next person?Have you considered writing a blog post about it, or something along those line, to make the things you figured out public? Make it easier for the next person?
Today felt... hacky, again. Lots of mutation of state going on, to set everything up for the calculations at the end.
After solving, I realized how to better reuse the solver from part 1 for part 2, so I rewrote the bits I had.
Input-"sanitizer"
I figured I'd just build a tree of inodes while parsing.
With that done, I calculated all the sizes, recursively:
size-calculations
The "solver" can then go through the tree and find all the directories that match some criterion:
Solver
At this point, parts one and two are just a few lines of code:
Both Parts