blob: d1eac37f0283b0502235c53bd2df0dd71c36d404 (
plain)
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
|
;;; solver.el --- Day 09 -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 Óscar Nájera
;;
;; Author: Óscar Nájera <hi@oscarnajera.com>
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
;; Created: December 09, 2022
;; Modified: December 09, 2022
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Day 09
;;
;;; Code:
(defsubst solver-diff (head tail)
(cons (- (car head) (car tail)) (- (cdr head) (cdr tail))))
(defsubst solver-distance-1 (vec)
"Norm 1 distance."
(+ (abs (car vec)) (abs (cdr vec))))
(defsubst solver-diagonal (vec)
(and (= 1 (abs (car vec))) (= 1 (abs (cdr vec)))))
(defun solver-move (direction)
(cl-ecase direction
('R (lambda (x) (cl-incf (car x))))
('L (lambda (x) (cl-decf (car x))))
('U (lambda (x) (cl-incf (cdr x))))
('D (lambda (x) (cl-decf (cdr x))))))
;; WARN This need to be bytecompiled otherwise the lambda is not capturing diff-v in the closure
(defun solver-puller (diff-v)
(let ((distance (solver-distance-1 diff-v)))
(cond
((or (<= distance 1)
(solver-diagonal diff-v)) #'identity)
((= distance 2)
(pcase diff-v
(`(0 . ,d) (solver-move (if (= d 2) 'U 'D)))
(`(,d . 0) (solver-move (if (= d 2) 'R 'L)))))
((= distance 3)
(lambda (x)
(funcall (solver-move (if (< 0 (car diff-v)) 'R 'L)) x)
(funcall (solver-move (if (< 0 (cdr diff-v)) 'U 'D)) x)))
(t (error "Head moved too far")))))
(with-temp-buffer
(insert-file-contents "input")
;; (insert "R 4
;; U 4
;; L 3
;; D 1
;; R 4
;; D 1
;; L 5
;; R 2")
(let (path
(head (cons 0 0))
(tail (cons 0 0))
(moves
(thread-last
(split-string (buffer-string) "\n" t)
(mapcar (lambda (inst) (let ((move (split-string inst)))
(cons (intern (car move))
(string-to-number (cadr move))))))
)))
(dolist (move moves)
(dotimes (_ (cdr move))
(funcall (solver-move (car move)) head)
(funcall (solver-puller (solver-diff head tail)) tail)
(push (cons (car tail) (cdr tail)) path)))
(= 6384 (length (cl-remove-duplicates path :test #'equal))))
|