From 56918007dd196be5cb58d5530ace0109fd4aced4 Mon Sep 17 00:00:00 2001 From: cow Date: Thu, 22 Dec 2022 01:45:26 -0500 Subject: [PATCH] day 7 progress in common lisp --- common-lisp/day-7/example.txt | 1 + common-lisp/day-7/solution.lisp | 115 ++++++++++++++++++++++++++++++++ input/day-7-example.txt | 23 +++++++ 3 files changed, 139 insertions(+) create mode 120000 common-lisp/day-7/example.txt create mode 100755 common-lisp/day-7/solution.lisp create mode 100644 input/day-7-example.txt diff --git a/common-lisp/day-7/example.txt b/common-lisp/day-7/example.txt new file mode 120000 index 0000000..87c7c28 --- /dev/null +++ b/common-lisp/day-7/example.txt @@ -0,0 +1 @@ +../../input/day-7-example.txt \ No newline at end of file diff --git a/common-lisp/day-7/solution.lisp b/common-lisp/day-7/solution.lisp new file mode 100755 index 0000000..d7ef614 --- /dev/null +++ b/common-lisp/day-7/solution.lisp @@ -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))))) diff --git a/input/day-7-example.txt b/input/day-7-example.txt new file mode 100644 index 0000000..bcbb513 --- /dev/null +++ b/input/day-7-example.txt @@ -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 \ No newline at end of file