-
Notifications
You must be signed in to change notification settings - Fork 0
/
day6.el
76 lines (64 loc) · 2.38 KB
/
day6.el
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
;;; -*- lexical-binding: t -*-
;; create an orbit map
;; count number of orbits / tree depth from COM
(setq raw-map "COM)B B)C C)D D)E E)F B)G G)H D)I E)J J)K K)L K)YOU I)SAN")
;; map format is cons of
;; - hashmap of object -> list of things orbiting it
;; - hashmap of object -> thing it's orbiting
(defun make-map (raw-map)
(let ((map-list (mapcar #'(lambda (elt) (split-string elt ")")) (split-string raw-map " ")))
(forward-links (make-hash-table :test 'equal))
(back-links (make-hash-table :test 'equal)))
(dolist (element map-list)
(let* ((center (car element))
(orbit (cadr element))
(val (gethash center forward-links)))
(puthash orbit center back-links)
(if val
(puthash center (cons orbit val) forward-links)
(puthash center (list orbit) forward-links))))
(cons forward-links back-links)))
(defun count-orbits (map)
(defun inner-count (object depth)
(let ((orbits (gethash object (car map)))
(count depth))
(dolist (orbit orbits count)
(setq count (+ count (inner-count orbit (1+ depth)))))))
(inner-count "COM" 0))
(count-orbits (make-map raw-map))
;; => 42
;;(setq map (make-map raw-map))
;;(get-neighbors "J")
(setq raw-map1
(with-temp-buffer
(insert-file-contents "day6-input.txt")
(replace-regexp-in-string "\n" " " (buffer-string))))
(count-orbits (make-map raw-map1))
;; => 314247
(defun filter-list (list f)
(let ((filtered '()))
(dolist (elt list filtered)
(if (apply f (list elt))
(setq filtered (cons elt filtered))))))
(defun get-distance (map start end)
(let ((real-start (gethash start (cdr map)))
(real-end (gethash end (cdr map)))
(visited (make-hash-table :test 'equal)))
(defun get-neighbors (object)
(filter-list
(cons (gethash object (cdr map))
(gethash object (car map)))
#'(lambda (object) (not (gethash object visited)))))
(defun inner-distance (object distance)
(puthash object object visited)
(if (equal real-end object)
distance
(loop
for neighbor in (get-neighbors object)
for inner = (inner-distance neighbor (1+ distance))
if inner return inner)))
(inner-distance real-start 0)))
(get-distance (make-map raw-map) "YOU" "SAN")
;; => 4
(get-distance (make-map raw-map1) "YOU" "SAN")
;; => 514