Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Collection extend [
- apply: method [ ^self collect: [:x | x perform: method] ]
- sum [ ^self inject: 0 into: [:a :b | a + b] ]
- min [ ^self inject: SmallInteger largest into: [:a :b | a min: b] ]
- ]
- "
- | A Directory in our File System.
- |
- | Contains more than for the problem, mostly to pretty print the file structure
- | like in the problem description.
- "
- Object subclass: ElfDirectory [
- | name depth parent children files totalSize |
- ElfDirectory class >> name: str withParent: dir [
- ^(super new) init: str parent: dir
- ]
- init: str parent: dir [
- name := str.
- parent := dir.
- depth := parent ifNotNil: [parent depth + 1] ifNil: [0].
- children := Dictionary new.
- files := nil. " Set later during file system creation "
- totalSize := nil. " Set later after file system created and size called "
- ^self
- ]
- addChildren: kids [
- " Only add files the first time we ls this directory. "
- " Directories will be created later as we cd into them. "
- files ifNil: [
- files := Dictionary from: ((kids reject: [:k | k first = 'dir'])
- collect: [:f | f second -> f first asNumber]).
- ]
- ]
- goChild: name [
- ^children at: name ifAbsentPut: [ElfDirectory name: name withParent: self]
- ]
- size [
- " Return total size of files in this directory and all subdirectories. "
- totalSize ifNil: [
- totalSize := files values sum + (children apply: #size) sum
- ].
- ^totalSize
- ]
- diskUsage [
- | res |
- " Return a bag of the sizes of all subdirectories "
- res := Bag with: self size.
- children do: [ :child | res addAll: child diskUsage ].
- ^res
- ]
- parent [ ^parent ]
- depth [ ^depth ]
- " Output subtree on display: "
- printOn: aStream [
- depth timesRepeat: [aStream nextPutAll: ' '].
- aStream nextPutAll: ('- %1 (dir)' % {name}); nl.
- files keysAndValuesDo: [ :name :size |
- depth + 1 timesRepeat: [aStream nextPutAll: ' '].
- aStream nextPutAll: ('- %1 (file, size=%2)' % {name. size}); nl.
- ].
- children do: [ :child | child printOn: aStream ]
- ]
- ]
- "
- | Holder class for the File System
- |
- | Builds the file structure from the logs, then covers method calls to fileRoot.
- "
- Object subclass: ElfFileSystem [
- | fileRoot |
- ElfFileSystem class >> new: log [
- ^(super new) init: log
- ]
- init: log [
- | cwd |
- " Build file system from log "
- fileRoot := ElfDirectory name: '/' withParent: nil.
- cwd := fileRoot.
- log do: [ :in |
- | dest |
- (in first = 'ls') ifTrue: [
- cwd addChildren: (in allButFirst apply: #substrings)
- ] ifFalse: [ " cd command "
- dest := in first substrings second.
- (dest first isLetter) ifTrue: [
- cwd := cwd goChild: dest
- ] ifFalse: [
- cwd := (dest = '/') ifTrue: [fileRoot]
- "cd .." ifFalse: [cwd parent]
- ]
- ]
- ].
- ^self
- ]
- size [ ^fileRoot size ]
- diskUsage [ ^fileRoot diskUsage ]
- printOn: aStream [ fileRoot printOn: aStream ]
- ]
- "
- | Mainline
- "
- input := (stdin contents tokenize: '\$ ') allButFirst apply: #lines.
- fileSystem := ElfFileSystem new: input.
- fileSystem displayNl.
- dirSizes := fileSystem diskUsage.
- needed := 30_000_000 - (70_000_000 - fileSystem size).
- ('Part 1: %1' % {(dirSizes select: [:x | x <= 100000]) sum}) displayNl.
- ('Part 2: %1' % {(dirSizes select: [:x | x >= needed]) min}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement