🎄⌨️ Advent of Code 2018

Check-in [440bf0]
Overview
Comment:Day 15 first steps
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | day15
Files: files | file ages | folders
SHA3-256: 440bf0f7f5cfc23b89d897c6ae5d0a41dad4615b9b9665cb75a3e4817a39f818
User & Date: joel on 2019-11-25 13:27:54
Other Links: branch diff | manifest | tags
Context
2019-11-26
23:01
Refine what we got check-in: e94fa4 user: joel tags: day15
2019-11-25
13:27
Day 15 first steps check-in: 440bf0 user: joel tags: day15
2018-12-24
13:29
Add Day 14 solutions Leaf check-in: 80485b user: joel tags: trunk
Changes

Added day15.rkt version [89a4f7].













































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#lang debug racket/base

(require racket/match
         racket/function
         racket/list
         racket/vector
         threading)

(struct fighter (x y hp) #:transparent)
(struct posn (x y) #:transparent)
(struct grid (vec rows cols) #:transparent)

(define (make-grid line-strs)
  (define row-count (length line-strs))
  (define col-count (string-length (first line-strs)))
  (grid
   (apply vector-append
          (map list->vector
               (map string->list line-strs)))
   row-count
   col-count))

(define test-map
  (make-grid
   '("#######"
     "#E..G.#"
     "#...#.#"
     "#.G.#G#"
     "#######")))

(module+ test
  (require rackunit))

(define (grid-ref g x y)
  (vector-ref (grid-vec g) (+ (* (grid-cols g) y) x)))

(define (grid-clear-at? g p #:goal [goal #f])
  (match-define (posn x y) p)
  (or #R (equal? #R goal #R p)
      (equal? (grid-ref g x y) #\.)))

(define (copy-blank-grid g)
  (match-define (grid _ rows cols) g)
  (grid (make-vector (* rows cols) #f) rows cols))

(define (display-grid g)
  (display
   (apply string-append
          (for/fold ([lst '()]
                     #:result (reverse (cons "\n" lst)))
                    ([val (in-vector (grid-vec g))]
                     [i (in-naturals 1)])
            (define ch
              (cond [(number? val) (number->string (modulo val 10))]
                    [(boolean? val) "-"]
                    [(string? val) val]
                    [else (format "~a" val)]))
            (cond [(equal? 0 (modulo i (grid-cols g)))
                   (cons "\n" (cons ch lst))]
                  [else (cons ch lst)])))))

(define (posn-outside-grid? p g)
  (match-define (posn px py) p)
  (or (< px 0)
      (< py 0)
      (> px (- (grid-rows g) 1))
      (> py (- (grid-cols g) 1))))

(define (grid-mark! g pos v)
  (match-define (posn x y) pos)
  (vector-set! (grid-vec g) (+ (* (grid-cols g) y) x) v))

(define (neighbor-coords pos)
  (match-define (posn x y) pos)
  (map (lambda (lst) (apply posn lst))
       `((,(- x 1) ,y)
         (,x ,(+ y 1))
         (,(+ x 1) ,y)
         (,x ,(- y 1)))))

(define (free-neighbors-at world pos #:goal [goal #f])
  (filter (curry grid-clear-at? world #:goal goal) (neighbor-coords pos)))

(define (not-yet-checked? pmap iter-num pos)
  (match-define (posn x y) pos)
  (let ([val (grid-ref pmap x y)])
    (or (boolean? val)
        (and (number? val)
             (> val iter-num)))))

(define (path-grid world f end-pos)
  (define f-pos (posn (fighter-x f) (fighter-y f)))
  (define result-grid (copy-blank-grid world))
  
  (grid-mark! result-grid end-pos 0)
  (display-grid result-grid)
  
  (let loop ([to-check (list end-pos)]
             [i 1])
    (define new-1 (map (curry free-neighbors-at world #:goal f-pos) #R to-check))
    (define new-2 (remove-duplicates (flatten #R new-1)))
    (define new-coords (filter (curry not-yet-checked? result-grid i) #R new-2))
    (for-each (lambda (p) (grid-mark! result-grid p i)) new-coords)
    (display-grid result-grid)
    (cond
      [(member f-pos new-coords) result-grid]
      [(empty? new-coords) #f]
      [else (loop new-coords (+ 1 i))])))