package common import ( "bufio" "strconv" "strings" ) 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 subfolders []*Folder files []File parent *Folder } func (folder Folder) GetSize() int { sum := 0 for _, folder := range folder.subfolders { sum += folder.GetSize() } for _, file := range folder.files { sum += file.GetSize() } return sum } func (folder Folder) GetSubfoldersUnderSize(size int) []*Folder { folders := []*Folder{} for _, subfolder := range folder.subfolders { 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.subfolders { if subfolder.GetSize() >= size { folders = append(folders, subfolder) } folders = append(folders, subfolder.GetSubfoldersOverSize(size)...) } return folders } func (folder Folder) GetName() string { return folder.name } func (folder Folder) GetSubfolders() []*Folder { return folder.subfolders } func (folder Folder) GetFilers() []File { return folder.files } func (folder *Folder) GetOrCreateFolder(name string) *Folder { for _, subfolder := range folder.subfolders { if subfolder.GetName() == name { return subfolder } } newFolder := Folder{name, []*Folder{}, []File{}, folder} folder.subfolders = append(folder.subfolders, &newFolder) return &newFolder } func (folder *Folder) GetOrCreateFile(name string, size int) File { for _, file := range folder.files { if file.GetName() == name { return file } } newFile := File{name, size} folder.files = append(folder.files, newFile) return newFile } func Parse(scanner bufio.Scanner) Folder { rootFolder := Folder{"/", []*Folder{}, []File{}, 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 }