Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- "*
- * A subclass of IdentityDictionary that can store and validate passport fields
- *"
- IdentityDictionary subclass: Passport [
- <shape: #pointer>
- " Initializer for the Passport Validator class variable "
- Passport class >> initialize [
- Validator := IdentityDictionary new.
- Validator at: #byr put: [:v | v asInteger between: 1920 and: 2002 ];
- at: #iyr put: [:v | v asInteger between: 2010 and: 2020 ];
- at: #eyr put: [:v | v asInteger between: 2020 and: 2030 ];
- at: #hcl put: [:v | (v =~ '^#[[:xdigit:]]{6}$') matched ];
- at: #ecl put: [:v | (v =~ '^(amb|blu|brn|gry|grn|hzl|oth)$') matched ];
- at: #pid put: [:v | (v =~ '^[[:digit:]]{9}$') matched ];
- at: #hgt put: [ :v |
- (v =~ '^([[:digit:]]+)(cm|in)$') ifMatched: [ :res |
- | h |
- h := (res at: 1) asInteger.
- ((res at: 2) = 'cm') ifTrue: [
- h between: 150 and: 193
- ] ifFalse: [
- h between: 59 and: 76
- ]
- ] ifNotMatched: [
- false
- ]
- ];
- at: #cid put: [:v | true ].
- ]
- " Check if all the needed fields are in this ID "
- hasAllFields [
- #(#byr #iyr #eyr #hcl #ecl #pid #hgt) do: [ :key |
- self at: key ifAbsent: [
- ^false
- ]
- ].
- ^true
- ]
- " Check if all the fields we have in this ID are valid "
- fieldsValid [
- (Validator isNil) ifTrue: [ Passport initialize ].
- (self keys) do: [ :key |
- ((Validator at: key) value: (self at: key)) ifFalse: [
- ^false
- ]
- ].
- ^true
- ]
- ]
- "*
- * A class for parsing stdin, returning Passports (nil if done)
- *"
- Object subclass: IDParser [
- | inStream |
- IDParser class >> new [
- ^(super new) init
- ]
- init [
- "*
- * stdin has a bug in Gnu Smalltalk where it resets back to the beginning,
- * so I'm just snarfing all the contents and putting my own ReadStream on that.
- *"
- inStream := stdin lines contents readStream.
- ^self
- ]
- " parse lines until we have a full Passport, then return it (nil if done) "
- nextPassport [
- | line id key_value |
- id := Passport new.
- [ (line := inStream next) notNil and: [(line =~ '^$') matched not] ] whileTrue: [
- (line subStrings: ' ') do: [ :field |
- key_value := (field subStrings: ':').
- id at: (key_value at: 1) asSymbol put: (key_value at: 2).
- ]
- ].
- (id size == 0) ifTrue: [ ^nil ]. " Should only happen at end "
- ^id
- ]
- ]
- "*
- * Mainline
- *"
- part1 := 0.
- part2 := 0.
- parse := IDParser new.
- [ (id := parse nextPassport) notNil ] whileTrue: [
- (id hasAllFields) ifTrue: [
- part1 := part1 + 1.
- (id fieldsValid) ifTrue: [
- part2 := part2 + 1
- ]
- ]
- ].
- stdout nextPutAll: 'Part 1: ', part1 asString; nl.
- stdout nextPutAll: 'Part 2: ', part2 asString; nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement