blob: 44fe5256fc0a270394b280b105181e5837fa2a48 (
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
|
;;; solver.el --- Day 12 -*- 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 12, 2022
;; Modified: December 12, 2022
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Day 12
;;
;;; Code:
(require 'ert)
(defun solver-directions (pos width height)
;; point on grid is p=x+y*width
(let ((x (mod pos width))
(y (/ pos width)))
(delq nil
(list
(when (< -1 x (1- width)) (1+ pos)) ;; right move
(when (< 0 x width) (1- pos)) ;; left move
(when (< -1 y (1- height)) (+ pos width)) ;; down move
(when (< 0 y height) (- pos width)))))) ;; up move
(should (equal (solver-directions 6 5 5) '(7 5 11 1)))
(should (equal (solver-directions 0 5 5) '(1 5)))
(defun solver-land (data)
(vconcat (mapconcat (lambda (row)
(cl-map 'string (lambda (chr)
(cl-case chr
(?S 0)
(?E 27)
(t (- chr 96))))
row))
data "")))
(defun solver-search (path land)
(let* ((pos (car path))
(elevation (aref land pos))
(next-cells (solver-directions pos width height)))
(if (= 27 elevation) ;; reached destination
(list (reverse path))
(mapcan (lambda (option)
(when (and (not (memq option path))
(>= (1+ elevation) (aref land option))) ;; allowed move
(solver-search (cons option path) land)))
next-cells))))
(with-temp-buffer
(insert "Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi")
(let* ((data (split-string (buffer-string) "\n"))
(height (length data))
(width (length (car data)))
(land (solver-land data))
(start (seq-position land 0 #'eq)))
(thread-first
(cl-sort
(solver-search (list start) land)
#'<
:key #'length)
(car)
(length)
(1-))
))
|