From 6029164067a0d7338e3c2347d13e5ce5d2121ef8 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 6 Dec 2022 23:02:10 -0800 Subject: [PATCH] Add day 7 solutions --- day7.chpl | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ day7.cr | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 day7.chpl create mode 100644 day7.cr diff --git a/day7.chpl b/day7.chpl new file mode 100644 index 0000000..e02a08f --- /dev/null +++ b/day7.chpl @@ -0,0 +1,74 @@ +use IO, Map, List; + +class TreeNode { + var name: string; + var parent: borrowed TreeNode?; + + var files = new map(string, int); + var dirs = new list(owned TreeNode); + + var size = -1; + + proc init(name: string, parent: borrowed TreeNode?) { + this.name = name; + this.parent = parent; + } + + /* + + ```Chapel + iter these(param tag: iterKind): (string, int) where tag == iterKind.standalone { + var size = + reduce files.values(); + coforall dir in dirs with (+ reduce size) { + // Yield directory sizes from the dir. + forall subSize in dir do yield subSize; + // Count its size for our size. + size += dir.size; + } + yield (name, size); + this.size = size; + } + ``` + + */ + + iter these(): (string, int) { + var size = + reduce files.values(); + for dir in dirs { + // Yield directory sizes from the dir. + for subSize in dir.these() do yield subSize; + // Count its size for our size. + size += dir.size; + } + yield (name, size); + this.size = size; + } +} + +var rootFolder: owned TreeNode = new owned TreeNode("", nil); +var currentFolder: borrowed TreeNode = rootFolder.borrow(); + +for line in stdin.lines() { + const strippedLine = line.strip(); + if strippedLine == "$ cd .." { + if const parent = currentFolder.parent then + currentFolder = parent; + } else if strippedLine.startsWith("$ cd ") { + const dirName = strippedLine["$ cd ".size..]; + var newFolder = new owned TreeNode(dirName, currentFolder); + currentFolder.dirs.append(newFolder); + currentFolder = currentFolder.dirs.last().borrow(); + } else if !strippedLine.startsWith("$ ls") { + const (sizeOrDir, _, name) = strippedLine.partition(" "); + if sizeOrDir == "dir" { + // Ignore directories, we'll CD into them. + } else { + currentFolder.files[name] = sizeOrDir : int; + } + } +} + +writeln(+ reduce [(_, size) in rootFolder] if size < 100000 then size); + +const toDelete = rootFolder.size - 40000000; +writeln(min reduce [(_, size) in rootFolder] if size >= toDelete then size); diff --git a/day7.cr b/day7.cr new file mode 100644 index 0000000..a250f99 --- /dev/null +++ b/day7.cr @@ -0,0 +1,64 @@ +require "advent" +INPUT = input(2022, 7).lines[1..] + +class DirTree + property name : String + property files : Hash(String, Int64) + property subDirs : Array(DirTree) + property parent : DirTree? + + def initialize(@name, @parent) + @files = {} of String => Int64 + @subDirs= [] of DirTree + @parent.try &.subDirs.<<(self) + end + + def sum_yielding(&block : Int32 ->): Int32 + size = 0 + size += @subDirs.sum do |x| + x.sum_yielding(&block) + end + size += @files.sum { |k,v| v } + yield size + return size + end +end + +dir = DirTree.new("", nil) + +INPUT.each do |line| + if line =~ /\$ cd (.+)$/ + if $1 == ".." + dir = dir.parent.not_nil! + else + dir = DirTree.new($1, dir) + end + elsif line == "$ ls" + else + x, y = line.split(" ") + if x == "dir" + else + dir.files[y] = x.to_i64 + end + end +end + +while par = dir.parent + dir = par +end + +total = 0 +outer_size = dir.sum_yielding do |i| + total += i if i <= 100000 +end +puts total + +puts "Used: #{outer_size}" +puts "Unused: #{70000000 - outer_size}" +to_delete = 30000000 - (70000000 - outer_size) +puts "To delete: #{to_delete}" +big_enough = [] of Int32 +outer_size = dir.sum_yielding do |i| + big_enough << i if i >= to_delete +end +puts big_enough.min