aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/12/solver.el
blob: 1c68d04f50db94a4d2fb015ca1cecf8bc5736ad7 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
;;; 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 (< -1 y (1- height)) (+ pos width)) ;; down move
           (when (<  0 x width) (1- pos))            ;; left 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-next-steps (path land)
  (let* ((pos (car path))
         (elevation (aref land pos)))
    (if (= 27 elevation) ;; reached destination
        (list (vconcat (reverse path)))
      (mapcan (lambda (option)
                (when (and (not (memq option path))
                           (>= (1+ elevation) (aref land option))) ;; allowed move
                  (list (cons option path))))
              (solver-directions pos width height)))))


(defun solver-search (queue land)

  (let* ((next (mapcan (lambda (path) (solver-next-steps path land)) queue))
        (finish (seq-filter #'vectorp next)))
    (cond
     ((null next) "No solution")
     ((null finish) (solver-search next land))
     (finish))
      ))

(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)))
    ;; (solver-search
    ;;  land)
    (let ((res (solver-search (list (list start)) land)))
      (list
       (length res)
       (mapcar #'length res))
      )
    ))

(thread-first
  (cl-sort
   #'<
   :key #'length)
  (car)
  (length)
  (1-))