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 }