Files
advent-of-code-2022/day07/common/filesystem.go
2022-12-15 14:56:28 +01:00

139 lines
2.9 KiB
Go

package common
import (
"bufio"
"strconv"
"strings"
)
type FileBase interface {
GetSize() int
GetName() string
}
type File struct {
name string
size int
}
func (file *File) GetSize() int {
return file.size
}
func (file *File) GetName() string {
return file.name
}
type Folder struct {
name string
content []FileBase
parent *Folder
}
func (folder *Folder) GetSize() int {
sum := 0
for _, file := range folder.content {
sum += file.GetSize()
}
return sum
}
func (folder *Folder) GetName() string {
return folder.name
}
func (folder Folder) GetSubfoldersUnderSize(size int) []*Folder {
folders := []*Folder{}
for _, subfolder := range folder.GetSubfolders() {
if subfolder.GetSize() <= size {
folders = append(folders, subfolder)
}
folders = append(folders, subfolder.GetSubfoldersUnderSize(size)...)
}
return folders
}
func (folder Folder) GetSubfoldersOverSize(size int) []*Folder {
folders := []*Folder{}
for _, subfolder := range folder.GetSubfolders() {
if subfolder.GetSize() >= size {
folders = append(folders, subfolder)
}
folders = append(folders, subfolder.GetSubfoldersOverSize(size)...)
}
return folders
}
func (folder *Folder) GetSubfolders() []*Folder {
subfolders := []*Folder{}
for _, file := range folder.content {
if folder, ok := file.(*Folder); ok {
subfolders = append(subfolders, folder)
}
}
return subfolders
}
func (folder *Folder) GetFiles() []*File {
files := []*File{}
for _, file := range folder.content {
if file, ok := file.(*File); ok {
files = append(files, file)
}
}
return files
}
func (folder *Folder) GetOrCreateFolder(name string) *Folder {
for _, subfolder := range folder.GetSubfolders() {
if subfolder.GetName() == name {
return subfolder
}
}
newFolder := Folder{name, []FileBase{}, folder}
folder.content = append(folder.content, &newFolder)
return &newFolder
}
func (folder *Folder) GetOrCreateFile(name string, size int) *File {
for _, file := range folder.GetFiles() {
if file.GetName() == name {
return file
}
}
newFile := File{name, size}
folder.content = append(folder.content, &newFile)
return &newFile
}
func Parse(scanner bufio.Scanner) Folder {
rootFolder := Folder{"/", []FileBase{}, nil}
var currentFolder *Folder
for scanner.Scan() {
line := scanner.Text()
switch line[0:4] {
case "$ cd":
if line[5:] == "/" {
currentFolder = &rootFolder
} else if line[5:] == ".." {
currentFolder = currentFolder.parent
} else {
currentFolder = currentFolder.GetOrCreateFolder(line[5:])
}
case "$ ls":
case "dir ":
currentFolder.GetOrCreateFolder(line[4:])
default:
splittedLine := strings.Split(line, " ")
size, _ := strconv.Atoi(splittedLine[0])
currentFolder.GetOrCreateFile(splittedLine[1], size)
}
}
return rootFolder
}