🎄⌨️ Advent of Code 2018

Check-in [2228f0]
Overview
Comment:Add Day 6 solutions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2228f026d361e9cd964387073c928c4d4fb87835d541f78a6a5e393d1c4ae9ca
User & Date: joel on 2018-12-07 17:09:17
Other Links: manifest | tags
Context
2018-12-07
19:09
Add Day 7 input file check-in: d152a4 user: joel tags: trunk
17:09
Add Day 6 solutions check-in: 2228f0 user: joel tags: trunk
17:09
Add Day 6 input check-in: b4b3f5 user: joel tags: trunk
Changes

Added day06.rkt version [3ae9d4].











































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#lang racket

(require rackunit)

(define (inputline->pair str)
  (map string->number (string-split str ", ")))

(define input (map inputline->pair (file->lines "day06-input.txt")))

;; Get the biggest coordinate and use that as the grid size in both directions
(define grid-size (apply max (first (sort input > #:key (curry apply max)))))

;; Manhattan distance is just the sum of the diff between two x and y coordinates
(define (distance-between pt1 pt2)
  (+ (abs (- (first pt1) (first pt2)))
     (abs (- (second pt1) (second pt2)))))

;; Return the index of "input" that is the closest point to the point given,
;; or -1 if there is a tie
(define (closest-input-pt p)
  (define distances (map (curry distance-between p) input))
  (define closest-idxs (indexes-of distances (apply min distances)))
  (cond
    [(> (length closest-idxs) 1) -1]
    [else (first closest-idxs)]))

;; Create a list of all x,y points in the grid, together with a third element:
;; the index of the closest point in `inputs` (-1 if a tie)
(define grid
  (for*/list ([x (in-range grid-size)]
              [y (in-range grid-size)])
             (list x y (closest-input-pt (list x y)))))

; An edge point is one where either coordinate is 0 or equal to `grid-size`
(define (is-edge? pt)
  (let ([coords (take pt 2)])
    (or (member 0 coords) (member (sub1 grid-size) coords))))

;; Identify the indexes of the points in `input` whose areas are infinite
;; I assume the "infinite" areas are those which touch the grid edges
(define infinite-area-pt-idxs
  (let ([edges (filter is-edge? grid)])
    ; don't include -1 in result
    (remove-duplicates (filter positive? (map third edges)))))

;; A list of same length as `input`, where each element is the size of the area
;; of the corresponding point in `input`
(define point-areas
  (for/list ([idx (in-range (length input))])
            (count (curry = idx) (map third grid))))

(define (day06-part1)
  (define filtered-pt-areas
    (filter positive?
            (for/list ([idx (in-range (length input))])
                      (if (member idx infinite-area-pt-idxs) 0 (list-ref point-areas idx)))))
  (apply max filtered-pt-areas))

(module+ test
  (check-equal? (time (day06-part1)) 5626)) ; Correct answer for part 1

(define (sum-of-distances grid-pt)
  (apply + (map (curry distance-between (take grid-pt 2)) input)))

(define (day06-part2)
  (count (curryr < 10000) (map sum-of-distances grid)))

(module+ test
  (check-equal? (time (day06-part2)) 46554)) ; Correct answer for part 2