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 }