advent2022

Advent of Code 2022 Solutions
git clone git://bsandro.tech/advent2022
Log | Files | Refs | README | LICENSE

main.go (1905B)


      1 package main
      2 
      3 import (
      4 	"bufio"
      5 	"fmt"
      6 	"log"
      7 	"math"
      8 	"os"
      9 	"strconv"
     10 	"strings"
     11 )
     12 
     13 type Dir struct {
     14 	Name   string
     15 	Size   int
     16 	Parent *Dir
     17 }
     18 
     19 type Dirs []*Dir
     20 
     21 func main() {
     22 	if len(os.Args) > 1 {
     23 		day07(os.Args[1])
     24 	} else if len(os.Args) == 1 {
     25 		fmt.Printf("usage: %s inputfile.txt\n", os.Args[0])
     26 	} else {
     27 		fmt.Println("No input data")
     28 	}
     29 }
     30 
     31 func day07(input_file string) {
     32 	fmt.Printf("day 07 input filename: %s\n", input_file)
     33 	var dirs Dirs
     34 	dirs.loadFile(input_file)
     35 
     36 	const sizeLimit = 100000
     37 	const fsSize = 70000000
     38 	const updSize = 30000000
     39 
     40 	totalSize := 0
     41 	delSize := math.MaxInt
     42 	clearSpace := updSize - fsSize + dirs.getRootSize()
     43 	for _, d := range dirs {
     44 		if d.Size < sizeLimit {
     45 			totalSize += d.Size
     46 		}
     47 		if d.Size >= clearSpace && d.Size < delSize {
     48 			delSize = d.Size
     49 		}
     50 	}
     51 	fmt.Printf("Part 1: %d\n", totalSize)
     52 	fmt.Printf("Part 2: %d\n", delSize)
     53 }
     54 
     55 func (dirs Dirs) getRootSize() int {
     56 	for _, dir := range dirs {
     57 		if dir.Name == "/" {
     58 			return dir.Size
     59 		}
     60 	}
     61 	return 0
     62 }
     63 func (dirs *Dirs) loadFile(input_file string) {
     64 	input, err := os.Open(input_file)
     65 	if err != nil {
     66 		log.Fatal(err)
     67 	}
     68 	defer input.Close()
     69 
     70 	var cur *Dir = nil
     71 	scanner := bufio.NewScanner(input)
     72 	for scanner.Scan() {
     73 		in := scanner.Text()
     74 		// commands (cd, ls)
     75 		if in[0] == '$' {
     76 			cmd := strings.Split(in, " ")
     77 			if cmd[1] == "cd" {
     78 				if cmd[2] == ".." {
     79 					// won't work if we do "cd .." from /
     80 					cur = cur.Parent
     81 				} else {
     82 					dir := &Dir{
     83 						Name:   cmd[2],
     84 						Size:   0,
     85 						Parent: cur,
     86 					}
     87 					*dirs = append(*dirs, dir)
     88 					cur = dir
     89 				}
     90 			}
     91 		} else { // file listing
     92 			sizeStr, _, _ := strings.Cut(in, " ")
     93 			// we care only about files
     94 			if sizeStr != "dir" {
     95 				size, _ := strconv.Atoi(sizeStr)
     96 				for d := cur; d != nil; {
     97 					d.Size += size
     98 					d = d.Parent
     99 				}
    100 			}
    101 		}
    102 	}
    103 	if err = scanner.Err(); err != nil {
    104 		log.Fatal(err)
    105 	}
    106 }