one day later, day 5

oh, so much hashtables, this is urgh
This commit is contained in:
efim 2022-12-06 13:07:06 +00:00
parent a0f3c07e06
commit 25709d2a43
3 changed files with 715 additions and 0 deletions

501
day5-input.txt Normal file
View File

@ -0,0 +1,501 @@
move 4 from 9 to 6
move 7 from 2 to 5
move 3 from 5 to 2
move 2 from 2 to 1
move 2 from 8 to 4
move 1 from 6 to 9
move 1 from 9 to 4
move 7 from 1 to 2
move 5 from 2 to 3
move 5 from 7 to 4
move 5 from 6 to 3
move 1 from 7 to 6
move 2 from 6 to 9
move 3 from 2 to 4
move 4 from 5 to 6
move 2 from 7 to 3
move 2 from 9 to 3
move 1 from 5 to 2
move 11 from 4 to 3
move 1 from 2 to 9
move 1 from 9 to 3
move 2 from 1 to 6
move 5 from 8 to 5
move 7 from 5 to 4
move 2 from 5 to 6
move 6 from 6 to 4
move 17 from 3 to 4
move 1 from 8 to 3
move 11 from 4 to 7
move 1 from 6 to 4
move 3 from 4 to 2
move 2 from 2 to 6
move 8 from 3 to 1
move 8 from 3 to 9
move 3 from 9 to 6
move 3 from 1 to 3
move 11 from 7 to 5
move 1 from 6 to 4
move 4 from 9 to 6
move 3 from 1 to 4
move 1 from 2 to 3
move 1 from 6 to 9
move 24 from 4 to 9
move 2 from 6 to 5
move 1 from 1 to 2
move 1 from 1 to 3
move 12 from 9 to 6
move 5 from 4 to 2
move 4 from 2 to 3
move 5 from 6 to 3
move 13 from 6 to 7
move 1 from 5 to 6
move 9 from 5 to 3
move 4 from 7 to 5
move 1 from 6 to 1
move 3 from 5 to 1
move 14 from 9 to 4
move 2 from 7 to 9
move 13 from 4 to 9
move 1 from 4 to 7
move 4 from 7 to 9
move 3 from 5 to 1
move 8 from 3 to 9
move 4 from 1 to 4
move 8 from 3 to 7
move 3 from 7 to 6
move 4 from 4 to 2
move 3 from 1 to 9
move 6 from 2 to 6
move 3 from 3 to 1
move 7 from 9 to 7
move 2 from 6 to 5
move 1 from 5 to 3
move 3 from 7 to 5
move 5 from 7 to 4
move 2 from 1 to 4
move 5 from 5 to 9
move 6 from 4 to 1
move 6 from 7 to 8
move 22 from 9 to 3
move 7 from 1 to 8
move 4 from 9 to 6
move 1 from 4 to 5
move 8 from 6 to 4
move 7 from 8 to 1
move 1 from 6 to 4
move 1 from 9 to 4
move 1 from 1 to 2
move 1 from 2 to 5
move 1 from 9 to 8
move 11 from 3 to 7
move 1 from 6 to 2
move 2 from 1 to 5
move 1 from 8 to 2
move 1 from 7 to 8
move 4 from 5 to 7
move 1 from 6 to 9
move 6 from 3 to 1
move 6 from 3 to 1
move 15 from 7 to 5
move 1 from 3 to 1
move 1 from 3 to 6
move 1 from 6 to 8
move 14 from 5 to 1
move 16 from 1 to 3
move 2 from 8 to 9
move 1 from 7 to 4
move 3 from 9 to 8
move 3 from 8 to 7
move 2 from 3 to 5
move 1 from 7 to 1
move 6 from 8 to 5
move 2 from 2 to 9
move 1 from 7 to 2
move 2 from 9 to 2
move 5 from 4 to 7
move 3 from 2 to 7
move 14 from 1 to 5
move 2 from 4 to 7
move 8 from 7 to 6
move 1 from 1 to 5
move 1 from 7 to 4
move 1 from 7 to 5
move 1 from 1 to 8
move 12 from 3 to 4
move 1 from 8 to 7
move 3 from 4 to 1
move 1 from 6 to 2
move 8 from 5 to 2
move 1 from 7 to 6
move 1 from 1 to 7
move 6 from 6 to 2
move 1 from 1 to 2
move 14 from 5 to 7
move 1 from 6 to 4
move 4 from 4 to 7
move 1 from 1 to 6
move 1 from 5 to 6
move 2 from 3 to 1
move 14 from 7 to 5
move 10 from 4 to 7
move 1 from 1 to 9
move 1 from 5 to 9
move 11 from 5 to 1
move 6 from 7 to 6
move 1 from 4 to 6
move 1 from 3 to 7
move 2 from 1 to 5
move 13 from 2 to 1
move 10 from 6 to 7
move 4 from 5 to 2
move 1 from 9 to 1
move 1 from 3 to 6
move 2 from 5 to 2
move 1 from 9 to 3
move 1 from 3 to 1
move 21 from 7 to 5
move 1 from 6 to 4
move 4 from 5 to 1
move 1 from 4 to 1
move 6 from 2 to 3
move 1 from 3 to 6
move 1 from 3 to 8
move 1 from 8 to 7
move 1 from 7 to 3
move 9 from 5 to 3
move 24 from 1 to 4
move 1 from 3 to 7
move 11 from 3 to 8
move 1 from 7 to 3
move 1 from 2 to 4
move 2 from 2 to 1
move 2 from 3 to 5
move 1 from 6 to 5
move 10 from 4 to 6
move 2 from 6 to 4
move 5 from 1 to 2
move 1 from 6 to 7
move 8 from 8 to 6
move 4 from 2 to 7
move 8 from 6 to 7
move 1 from 2 to 8
move 1 from 8 to 3
move 1 from 7 to 4
move 3 from 4 to 1
move 2 from 6 to 7
move 4 from 1 to 9
move 3 from 6 to 7
move 10 from 7 to 4
move 2 from 3 to 9
move 2 from 6 to 9
move 2 from 1 to 8
move 2 from 9 to 5
move 4 from 5 to 6
move 3 from 8 to 1
move 4 from 4 to 8
move 5 from 8 to 4
move 1 from 8 to 2
move 5 from 5 to 9
move 1 from 6 to 1
move 2 from 1 to 7
move 22 from 4 to 8
move 4 from 8 to 7
move 2 from 6 to 7
move 1 from 2 to 6
move 16 from 8 to 9
move 3 from 7 to 4
move 1 from 5 to 9
move 2 from 6 to 7
move 1 from 8 to 2
move 1 from 2 to 3
move 24 from 9 to 3
move 1 from 1 to 7
move 3 from 5 to 1
move 4 from 4 to 6
move 15 from 3 to 6
move 18 from 6 to 2
move 3 from 3 to 2
move 4 from 1 to 6
move 4 from 7 to 3
move 1 from 3 to 9
move 4 from 2 to 1
move 1 from 8 to 7
move 3 from 9 to 6
move 1 from 9 to 3
move 4 from 7 to 3
move 2 from 4 to 2
move 1 from 1 to 2
move 7 from 3 to 5
move 8 from 6 to 1
move 1 from 9 to 2
move 3 from 7 to 5
move 1 from 4 to 8
move 3 from 1 to 7
move 5 from 7 to 6
move 3 from 5 to 2
move 3 from 7 to 3
move 5 from 5 to 9
move 5 from 3 to 6
move 1 from 8 to 3
move 5 from 9 to 7
move 7 from 2 to 4
move 11 from 2 to 7
move 7 from 1 to 6
move 1 from 1 to 9
move 5 from 3 to 6
move 5 from 2 to 1
move 1 from 3 to 9
move 1 from 3 to 7
move 6 from 6 to 2
move 10 from 6 to 7
move 5 from 6 to 7
move 28 from 7 to 8
move 2 from 9 to 1
move 1 from 6 to 3
move 4 from 7 to 5
move 1 from 3 to 6
move 7 from 2 to 7
move 6 from 7 to 3
move 1 from 5 to 9
move 1 from 6 to 2
move 1 from 7 to 3
move 1 from 9 to 1
move 4 from 5 to 2
move 5 from 3 to 5
move 2 from 2 to 8
move 4 from 4 to 7
move 1 from 4 to 7
move 2 from 3 to 6
move 5 from 7 to 1
move 2 from 5 to 8
move 2 from 5 to 8
move 2 from 5 to 3
move 2 from 3 to 1
move 2 from 6 to 7
move 31 from 8 to 3
move 2 from 8 to 5
move 2 from 7 to 4
move 7 from 1 to 4
move 2 from 5 to 1
move 3 from 2 to 8
move 2 from 4 to 6
move 3 from 1 to 2
move 6 from 4 to 8
move 1 from 1 to 8
move 1 from 6 to 5
move 11 from 8 to 9
move 1 from 6 to 8
move 1 from 4 to 1
move 1 from 8 to 7
move 1 from 5 to 8
move 3 from 2 to 1
move 2 from 4 to 3
move 1 from 8 to 1
move 7 from 3 to 6
move 12 from 3 to 2
move 1 from 7 to 9
move 4 from 6 to 1
move 1 from 6 to 3
move 12 from 9 to 3
move 1 from 6 to 4
move 1 from 1 to 7
move 1 from 4 to 1
move 1 from 7 to 2
move 1 from 6 to 5
move 1 from 5 to 6
move 5 from 3 to 1
move 1 from 6 to 4
move 7 from 2 to 1
move 3 from 2 to 6
move 1 from 4 to 5
move 3 from 3 to 2
move 4 from 2 to 8
move 1 from 6 to 4
move 1 from 4 to 9
move 1 from 5 to 1
move 11 from 1 to 5
move 10 from 1 to 8
move 2 from 6 to 4
move 1 from 2 to 9
move 1 from 2 to 4
move 18 from 3 to 5
move 4 from 1 to 4
move 3 from 1 to 2
move 14 from 8 to 5
move 2 from 2 to 6
move 1 from 3 to 2
move 2 from 2 to 7
move 3 from 4 to 1
move 2 from 4 to 3
move 2 from 3 to 4
move 2 from 6 to 9
move 1 from 7 to 1
move 3 from 1 to 4
move 4 from 9 to 7
move 31 from 5 to 2
move 25 from 2 to 4
move 13 from 4 to 2
move 10 from 2 to 3
move 2 from 5 to 7
move 5 from 2 to 9
move 7 from 5 to 7
move 5 from 7 to 4
move 1 from 5 to 8
move 2 from 7 to 3
move 11 from 4 to 8
move 1 from 7 to 3
move 1 from 1 to 4
move 2 from 5 to 3
move 3 from 2 to 9
move 8 from 9 to 6
move 10 from 8 to 2
move 5 from 3 to 2
move 1 from 7 to 3
move 3 from 7 to 3
move 15 from 2 to 1
move 11 from 1 to 3
move 1 from 8 to 2
move 8 from 6 to 5
move 1 from 2 to 6
move 1 from 6 to 1
move 12 from 3 to 7
move 1 from 2 to 9
move 2 from 4 to 1
move 3 from 1 to 8
move 1 from 8 to 7
move 3 from 3 to 4
move 1 from 4 to 7
move 15 from 7 to 9
move 1 from 7 to 5
move 4 from 1 to 8
move 6 from 8 to 6
move 1 from 6 to 2
move 5 from 5 to 1
move 2 from 6 to 8
move 1 from 2 to 7
move 1 from 8 to 2
move 1 from 7 to 1
move 1 from 5 to 8
move 6 from 3 to 1
move 4 from 3 to 8
move 7 from 8 to 5
move 1 from 2 to 4
move 2 from 4 to 2
move 3 from 6 to 4
move 5 from 9 to 3
move 4 from 1 to 4
move 10 from 5 to 9
move 8 from 1 to 7
move 1 from 2 to 1
move 1 from 1 to 9
move 20 from 9 to 2
move 12 from 2 to 3
move 17 from 4 to 3
move 6 from 7 to 2
move 5 from 3 to 8
move 20 from 3 to 5
move 2 from 9 to 4
move 3 from 3 to 1
move 1 from 7 to 1
move 6 from 3 to 6
move 4 from 2 to 3
move 4 from 5 to 3
move 1 from 1 to 9
move 6 from 6 to 1
move 3 from 8 to 4
move 1 from 9 to 8
move 2 from 2 to 1
move 3 from 3 to 2
move 1 from 3 to 6
move 1 from 7 to 4
move 3 from 3 to 6
move 6 from 1 to 5
move 9 from 2 to 4
move 3 from 2 to 5
move 2 from 6 to 5
move 16 from 4 to 8
move 18 from 8 to 6
move 1 from 4 to 5
move 2 from 6 to 7
move 4 from 1 to 7
move 22 from 5 to 6
move 1 from 4 to 9
move 4 from 7 to 6
move 11 from 6 to 5
move 9 from 5 to 2
move 2 from 2 to 3
move 2 from 7 to 2
move 1 from 1 to 7
move 9 from 6 to 2
move 1 from 5 to 1
move 1 from 8 to 9
move 18 from 6 to 8
move 1 from 7 to 4
move 4 from 5 to 1
move 2 from 5 to 2
move 2 from 2 to 5
move 1 from 9 to 5
move 1 from 5 to 9
move 1 from 9 to 1
move 1 from 9 to 2
move 1 from 4 to 8
move 4 from 1 to 4
move 2 from 6 to 5
move 1 from 1 to 9
move 3 from 6 to 7
move 1 from 6 to 9
move 1 from 9 to 8
move 2 from 5 to 9
move 3 from 3 to 5
move 7 from 2 to 3
move 1 from 1 to 3
move 2 from 5 to 9
move 1 from 5 to 7
move 10 from 8 to 3
move 10 from 8 to 9
move 3 from 4 to 3
move 9 from 2 to 1
move 4 from 9 to 6
move 5 from 1 to 9
move 2 from 5 to 9
move 1 from 6 to 4
move 4 from 7 to 2
move 7 from 2 to 9
move 3 from 6 to 8
move 1 from 1 to 3
move 2 from 8 to 5
move 1 from 8 to 1
move 18 from 3 to 6
move 15 from 9 to 2
move 8 from 9 to 1
move 2 from 9 to 2
move 2 from 4 to 9
move 2 from 9 to 7
move 12 from 6 to 3
move 7 from 1 to 7
move 12 from 2 to 5
move 7 from 3 to 2
move 4 from 3 to 4
move 2 from 7 to 6
move 7 from 7 to 8
move 1 from 4 to 2
move 4 from 1 to 8
move 5 from 3 to 1
move 9 from 8 to 3
move 1 from 8 to 7
move 2 from 1 to 2
move 4 from 6 to 7
move 11 from 2 to 5
move 2 from 4 to 6
move 1 from 8 to 2
move 7 from 3 to 2
move 1 from 2 to 4
move 4 from 6 to 1
move 7 from 5 to 8
move 2 from 3 to 1
move 7 from 2 to 3
move 6 from 5 to 1
move 1 from 4 to 2
move 8 from 1 to 6
move 3 from 2 to 9

4
day5-test-input.txt Normal file
View File

@ -0,0 +1,4 @@
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

210
day5.lisp Normal file
View File

@ -0,0 +1,210 @@
;;; wow, now this is complicated.
;; first read in until the empty line
;; and somehow construct internal representation
;; i want Stack data structure. cool. where is that?
;; use list with PUSH and REMOVE ?
(defparameter *some-stack* (list 1 2 3))
(push 1 *some-stack*)
(pop *some-stack*)
*some-stack*
;; well, yea. list is a stack. ok
;; so I need to have addressable from 1 to n
;; lists
;; and after i read them - reverse
;; i guess i could read in the string. and calculate index of the list
(defparameter *test-string-0* " [D]")
(defparameter *test-string* "[Z] [M] [P]")
;; [Z] [M] [P]
;; 1 2 3
;; 01234567890
;; so. first letter is at 1 (after 0) and next letter is at i+4
;; let's write function that translates that string into '((1 Z) (2 M) (3 P))
;; and would translate *test-string* into '((2 D))
;; i guess i could just iterate by i+4 from i=1 until the end of the string, and that's it
(defun parse-crate-string (str)
(do
((str-index 1 (+ 4 str-index))
(index 1 (1+ index))
(accum (list)))
((> str-index (1- (length str))) accum)
(let ((box-label (aref str str-index)))
(if (not (eq box-label #\ ))
(setq accum (push (list index (aref str str-index)) accum))))))
(defparameter *test-line-parsed* (parse-crate-string *test-string*))
(do
( (index 1 (+ 4 index)))
((> index 15) "hello")
(format t "lala ~D~%" index)
)
(do ((temp-one 1 (1+ temp-one))
(temp-two 0 (1- temp-two)))
((> (- temp-one temp-two) 5) temp-one))
(aref "hello-world" 1)
(aref " hello-world" 0)
(aref "hello-world" 11)
(length "hello-world")
;;; now. for each string I want to take index, take list on that index and put the label on top
;; now, i want "common lisp MAP", and ideally with default
(defparameter *test-table* (make-hash-table))
(gethash 1 *test-table*)
(setf (gethash 2 *test-table*) "hello")
(gethash 2 *test-table*)
(gethash 3 *test-table* (list)) ; so anyway by default it returns NIL
*test-line-parsed*
(mapcar (lambda (box-descr)
(let* ((index (first box-descr))
(label (second box-descr))
(cur-list (gethash index *test-table*)))
(setf (gethash index *test-table*) (push label cur-list))))
*test-line-parsed*)
*test-table*
(defun apply-parsed-line-to-lists (parsed-line table)
(mapcar (lambda (box-descr)
(let* ((index (first box-descr))
(label (second box-descr))
(cur-list (gethash index table)))
(setf (gethash index table) (push label cur-list))))
parsed-line))
(apply-parsed-line-to-lists *test-line-parsed* *test-table*)
(defparameter *full-test-boxes* " [D]
[N] [C]
[Z] [M] [P] ")
(require 'cl-ppcre)
(cl-ppcre:split (cl-ppcre:create-scanner :end-anchor) *full-test-boxes*)
(cl-ppcre:split (cl-ppcre:create-scanner "\n") *full-test-boxes*)
;; all of this didn't fucking work. can't split the line by the newline, what a joke
;;; god. i'm ready to create these lists manually.
;;; ugh.
(defparameter *all-test-boxes-lines* (list
" [D]"
"[N] [C]"
"[Z] [M] [P]"))
(defparameter *all-input-boxes-lines* (list
" [C] [N] [R]"
"[J] [T] [H] [P] [L]"
"[F] [S] [T] [B] [M] [D]"
"[C] [L] [J] [Z] [S] [L] [B]"
"[N] [Q] [G] [J] [J] [F] [F] [R]"
"[D] [V] [B] [L] [B] [Q] [D] [M] [T]"
"[B] [Z] [Z] [T] [V] [S] [V] [S] [D]"
"[W] [P] [P] [D] [G] [P] [B] [P] [V]"))
(defun get-boxes-lists-hashtable (boxes-lines)
(let ((hash-table (make-hash-table))
(parsed-lines (mapcar #'parse-crate-string boxes-lines)))
(mapcar (lambda (parsed-line) (apply-parsed-line-to-lists parsed-line hash-table)) parsed-lines)
(maphash (lambda (key list) (setf (gethash key hash-table) (reverse list))) hash-table)
hash-table))
(defparameter *test-boxes* (get-boxes-lists-hashtable *all-test-boxes-lines*))
(gethash 2 (get-boxes-lists-hashtable *all-test-boxes-lines*))
;; yay. ok. good enough.
;; now i need a function that would modify that hash table for each line
;; "move 1 from 2 to 1"
;; if i just to intern, would i get numbers?
(cddr (mapcar #'intern (cl-ppcre:split " " "move 1 from 2 to 1")))
;; nope that would be a symbol
;; allright, let's just emit list of numbers
(let ((string "move 1 from 2 to 3"))
(do*
((words (cl-ppcre:split " " string) (cddr words))
(number (parse-integer (second words)) (parse-integer (second words)))
(nums (list number) (push number nums)))
((not (cddr words)) (reverse nums))))
(defun command-string-to-indices (str)
(do*
((words (cl-ppcre:split " " str) (cddr words))
(number (parse-integer (second words)) (parse-integer (second words)))
(nums (list number) (push number nums)))
((not (cddr words)) (reverse nums))))
(command-string-to-indices "move 1 from 2 to 1")
(defun run-command (hashtable amount from to)
(loop
for i from 1 to amount
do (push (pop (gethash from hashtable)) (gethash to hashtable))))
(run-command *test-boxes* 3 2 1)
(gethash 2 *test-boxes*)
(gethash 1 *test-boxes*)
(with-open-file (in "day5-test-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (apply #'run-command (cons *test-boxes* (command-string-to-indices line)))))
;; https://riptutorial.com/common-lisp/example/4463/looping-over-hash-tables
(print (coerce (loop
for v from 1 to 3
collect (first (gethash v *test-boxes*))) 'string))
(defparameter *day-5-boxes* (get-boxes-lists-hashtable *all-input-boxes-lines*))
(gethash 1 *day-5-boxes*)
(with-open-file (in "day5-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (apply #'run-command (cons *day-5-boxes* (command-string-to-indices line)))))
;; printing things as a string
(print (coerce (loop
for v from 1 to (hash-table-count *day-5-boxes*)
collect (first (gethash v *day-5-boxes*))) 'string))
(getf :count *day-5-boxes*)
(hash-table-count *day-5-boxes*)
;; oh, wow. now i need to implement moving "with retaining order".
;; cool
(defun run-command-9001 (hashtable amount from to)
(let ((moving-part (subseq (gethash from hashtable) 0 amount))
(remaining-part (subseq (gethash from hashtable) amount)))
(setf (gethash from hashtable) remaining-part)
(setf (gethash to hashtable) (concatenate 'list moving-part (gethash to hashtable)))))
;; so, taking is subseq, but wound need to drop these elements
;; but how to prepend list to another list? concat?
(concatenate 'list (list 1 2 3) (list 5 6 7))
(subseq (list 1 2 3 4 5) 0 2) ; so "until end"
(subseq (list 1 2 3 4 5) 2)
;; nullify hash with boxes before running
(with-open-file (in "day5-test-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (apply #'run-command-9001 (cons *test-boxes* (command-string-to-indices line)))))
(with-open-file (in "day5-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (apply #'run-command-9001 (cons *day-5-boxes* (command-string-to-indices line)))))