6 votes

Day 23: Unstable Diffusion

Today's problem description: https://adventofcode.com/2022/day/23

Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python with any of the "short names" listed in this page of supported languages):

<details>
<summary>Part 1</summary>

```python
Your code here.
```

</details>

1 comment

  1. bhrgunatha
    (edited )
    Link
    Data elves are a set of points. I keep meaning to switch co-ordinates to complex numbers but maybe some other time. (define (point+ a b) (map + a b)) (match-define (list N E S W) '((0 -1) (1 0) (0...
    Data

    elves are a set of points. I keep meaning to switch co-ordinates to complex numbers but maybe some other time.

    (define (point+ a b) (map + a b))
    (match-define (list N E S W) '((0 -1) (1 0) (0 1) (-1 0)))
    (match-define (list NE NW SE SW)
      (list (point+ N E) (point+ N W) (point+ S E) (point+ S W)))
    
    (define CARDINALS (list N S E W NE NW SE SW))
    (define MOVE-CHECKS
      (hash N (list N NE NW)
            S (list S SE SW)
            W (list W NW SW)
            E (list E NE SE)))
            
    (define (read-elves input)
      (for*/set ([(row y) (in-indexed (in-list input))]
                 [(c x) (in-indexed (in-string row))]
                 #:when (char=? c #\#))
        (list x y)))
    
    (define (show-grove elves)
      (define-values (xmin xmax ymin ymax) (bounds elves))
      (for ([y (in-inclusive-range ymin ymax)])
        (for ([x (in-inclusive-range xmin xmax)])
          (printf "~a" (if (set-member? elves (list x y)) "▓" ".")))
        (newline))
      (newline))
    
    (define (bounds elves)
      (match-define (list x y) (set-first elves))
      (for/fold ([xmin x] [xmax x] [ymin y] [ymax y])
                ([e (in-set elves)])
        (match-define (list ex ey) e)
        (values (min ex xmin) (max ex xmax) (min ey ymin) (max ey ymax))))
    
    Part 1

    Feels hugely verbose. I really shouldn't read /r/adventofcode after I finish, feels bad man. The only mildly interesting thing here is refactoring elf-garden for part 2 that takes a sequence - similar to generators or streams - (in-range 10) for part 1 and (in-naturals 1) for part 2.

    (define (part-01 input)
      (define-values (elves rounds) (elf-garden input (in-range 10)))
      (garden-space elves))
    
    (define (elf-garden input seq)
      (define elves (read-elves input))
      (define priorities (list N S W E))
      (for/fold ([elves elves] [settled? #f])
                ([i seq] #:break settled?)
        (define proposed (proposals elves priorities))
        (set! priorities (append (rest priorities) (list (first priorities))))
        (if (zero? (hash-count proposed))
            (values elves i)
            (values (move elves proposed) #f))))
    
    (define (proposals elves priorities)
      (for/hash ([e (in-set elves)]
                 #:when (has-neighbour? elves e)
                 #:do [(define dir (direction-choice elves e priorities))]
                 #:when dir)
        (values e (point+ e dir))))
    
    (define (direction-choice elves e priorities)
      (for/or ([dir (in-list priorities)])
        (for/and ([m (in-list (hash-ref MOVE-CHECKS dir))])
          (define to (point+ e m))
          (and (not (set-member? elves to)) dir))))
    
    (define (has-neighbour? elves e)
      (for/or ([d (in-list CARDINALS)])
        (set-member? elves (point+ e d))))
    
    (define (move elves proposed)
      (define counts (count-moved elves proposed))
      (for/fold ([elves elves])
                ([e (in-set elves)])
        (define to (hash-ref proposed e e))
        (if (= (hash-ref counts to 0) 1)
            (set-add (set-remove elves e) to)
            elves)))
    
    (define (garden-space elves)
      (define-values (xmin xmax ymin ymax) (bounds elves))
      (- (* (- xmax xmin -1) (- ymax ymin -1))
         (set-count elves)))
    
    Part 2

    The refactoring pays off hugely for part 2, but obviously I wrote 2 different versions of almost the same code while solving the problem.

    (define (part-02 input)
      (define-values (elves rounds) (elf-garden input (in-naturals 1)))
      rounds)
    
    2 votes