day 7 progress in common lisp
This commit is contained in:
parent
8d2dc71ece
commit
dab8d182ee
1
common-lisp/day-7/example.txt
Symbolic link
1
common-lisp/day-7/example.txt
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../input/day-7-example.txt
|
115
common-lisp/day-7/solution.lisp
Executable file
115
common-lisp/day-7/solution.lisp
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
#!/usr/bin/env -S sbcl --script
|
||||||
|
|
||||||
|
(require 'asdf)
|
||||||
|
(require 'cl-ppcre)
|
||||||
|
(require 'str)
|
||||||
|
(require 'iterate)
|
||||||
|
(require 'uiop)
|
||||||
|
|
||||||
|
(defpackage :solution
|
||||||
|
(:use :cl)
|
||||||
|
(:import-from :iterate :iter)
|
||||||
|
(:import-from :uiop :if-let)
|
||||||
|
(:shadow :directory))
|
||||||
|
|
||||||
|
(in-package :solution)
|
||||||
|
|
||||||
|
(defclass dir ()
|
||||||
|
((name
|
||||||
|
:initarg :name
|
||||||
|
:reader name)
|
||||||
|
(parent
|
||||||
|
:initarg :parent
|
||||||
|
:reader parent)
|
||||||
|
(files
|
||||||
|
:initform nil
|
||||||
|
:accessor files)
|
||||||
|
(subdirs
|
||||||
|
:initform nil
|
||||||
|
:accessor subdirs)))
|
||||||
|
|
||||||
|
(defun mkdir (dir dirname)
|
||||||
|
(push (cons dirname (make-instance 'dir :name dirname :parent dir)) (subdirs dir)))
|
||||||
|
|
||||||
|
(defun touch (dir filename filesize)
|
||||||
|
(push (cons filename filesize) (files dir)))
|
||||||
|
|
||||||
|
(defun find-dir (dir dirname)
|
||||||
|
(if-let ((d (assoc dirname (subdirs dir) :test 'string=)))
|
||||||
|
(cdr d)
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defun depth (dir &optional (depth 0))
|
||||||
|
(if-let ((p (parent dir)))
|
||||||
|
(depth p (incf depth))
|
||||||
|
depth))
|
||||||
|
|
||||||
|
(defmethod print-object ((obj dir) stream)
|
||||||
|
(format stream
|
||||||
|
"~&name: ~a~%parent: ~a~%depth: ~a~%subdirs: ~a~%files: ~a ~&"
|
||||||
|
(name obj)
|
||||||
|
(if (> (depth obj) 0)
|
||||||
|
(name (parent obj)))
|
||||||
|
(depth obj)
|
||||||
|
(files obj)
|
||||||
|
(subdirs obj)))
|
||||||
|
|
||||||
|
(defclass fs ()
|
||||||
|
((root
|
||||||
|
:initform (make-instance 'dir :name "root" :parent nil)
|
||||||
|
:reader root)
|
||||||
|
(cwd
|
||||||
|
:initform nil
|
||||||
|
:accessor cwd)))
|
||||||
|
|
||||||
|
(defvar fs-indent-factor 4)
|
||||||
|
|
||||||
|
(defun cd (fs dirname)
|
||||||
|
(with-accessors ((cwd cwd)
|
||||||
|
(root root))
|
||||||
|
fs
|
||||||
|
(cond ((string= dirname "/")
|
||||||
|
(setf cwd root))
|
||||||
|
((string= dirname "..")
|
||||||
|
(setf cwd (parent cwd)))
|
||||||
|
(t
|
||||||
|
(setf cwd (find-dir cwd dirname))))))
|
||||||
|
|
||||||
|
(defun fs-print-tree (dir stream)
|
||||||
|
(let ((indent (* (depth dir) fs-indent-factor)))
|
||||||
|
(iter (iter:for (filename . filesize) in (files dir))
|
||||||
|
(format stream "~vt - ~a size=~a~%" indent filename filesize))
|
||||||
|
(iter (iter:for (subdirname . subdir) in (subdirs dir))
|
||||||
|
(format stream "~vt / ~a~%" indent subdirname)
|
||||||
|
(fs-print-tree subdir stream))))
|
||||||
|
|
||||||
|
(defmethod print-object ((obj fs) stream)
|
||||||
|
(format stream "/ root~%")
|
||||||
|
(fs-print-tree (root obj) stream))
|
||||||
|
|
||||||
|
(defun parse-input (lines)
|
||||||
|
(iter (iter:for line in lines)
|
||||||
|
(iter:for parts = (str:split " " line))
|
||||||
|
(cond ((string= (nth 1 parts) "cd")
|
||||||
|
(iter:collect (list 'cd (nth 2 parts))))
|
||||||
|
((string= (nth 0 parts) "dir")
|
||||||
|
(iter:collect (list 'dir (nth 1 parts))))
|
||||||
|
((str:digit? (nth 0 parts))
|
||||||
|
(iter:collect (list 'file (nth 1 parts) (parse-integer (nth 0 parts))))))))
|
||||||
|
|
||||||
|
(defun solution-part-1 (events)
|
||||||
|
(iter (iter:with fs = (make-instance 'fs))
|
||||||
|
(iter:for event in events)
|
||||||
|
(let* ((type (car event))
|
||||||
|
(dir-or-file-name (cadr event))
|
||||||
|
(size (if (equal type 'file) (car (last event)) nil)))
|
||||||
|
(with-accessors ((root root)
|
||||||
|
(cwd cwd))
|
||||||
|
fs
|
||||||
|
(cond ((equal type 'cd)
|
||||||
|
(cd fs dir-or-file-name))
|
||||||
|
((equal type 'dir)
|
||||||
|
(mkdir cwd dir-or-file-name))
|
||||||
|
((equal type 'file)
|
||||||
|
(touch cwd dir-or-file-name size))))
|
||||||
|
(iter:finally (return fs)))))
|
23
input/day-7-example.txt
Normal file
23
input/day-7-example.txt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
$ cd /
|
||||||
|
$ ls
|
||||||
|
dir a
|
||||||
|
14848514 b.txt
|
||||||
|
8504156 c.dat
|
||||||
|
dir d
|
||||||
|
$ cd a
|
||||||
|
$ ls
|
||||||
|
dir e
|
||||||
|
29116 f
|
||||||
|
2557 g
|
||||||
|
62596 h.lst
|
||||||
|
$ cd e
|
||||||
|
$ ls
|
||||||
|
584 i
|
||||||
|
$ cd ..
|
||||||
|
$ cd ..
|
||||||
|
$ cd d
|
||||||
|
$ ls
|
||||||
|
4060174 j
|
||||||
|
8033020 d.log
|
||||||
|
5626152 d.ext
|
||||||
|
7214296 k
|
Loading…
Reference in a new issue