Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Object subclass: Parser [
- | rule_table patt_table |
- Parser class >> withRules: rules [
- ^(super new) init: rules
- ]
- init: str [
- | section break num rules |
- rule_table := LookupTable new.
- patt_table := LookupTable new.
- (str tokenize: '\n') do: [ :r |
- break := r subStrings: ':'.
- num := break first.
- rules := ((break second) subStrings: ' ') collect: [ :tok |
- ((tok at: 1) = $") ifTrue: [
- patt_table at: num put: (tok at: 2) asString.
- nil
- ] ifFalse: [
- tok
- ]
- ].
- rule_table at: num put: rules.
- ].
- " Build pattern table: "
- self recurse_rules: '0'.
- ]
- recurse_rules: rule_num [
- | regex |
- patt_table at: rule_num ifAbsent: [
- regex := (rule_table at: rule_num) gather: [ :tok |
- (tok = '|') ifTrue: [ '|' ] ifFalse: [ self recurse_rules: tok ].
- ].
- regex := ('(', regex, ')').
- patt_table at: rule_num put: regex.
- ].
- ^patt_table at: rule_num
- ]
- getPattern: num [
- ^patt_table at: num asString.
- ]
- ]
- "
- | Mainline
- "
- section := stdin contents tokenize: '\n\n'.
- " First section: rules: "
- parser := Parser withRules: (section first).
- " Second section signals: "
- signals := (section second) tokenize: '\n'.
- "
- | Unfortunately, gst cannot handle Regex past a particular length. Patterns 0 and 11 are
- | too long. So we'll make do with just 42 and 31.
- |
- | Part 1: 0: 8 11, 8: 42, 11: 42 31 => 0: 42 42 31
- | Part 2: 0: 8 11, 8: 42 | 42 8, 11: 42 31 | 42 11 32 => 0: 42{n} 31{<n}
- |
- | XXX: Not robust... could take a long match of 42s, when a shorter one is what matched 31s.
- |
- "
- part2 := 0.
- (2 to: 10) do: [ :i |
- patt42_re := ('^', (parser getPattern: 42), '{', i asString, '}') asRegex.
- patt31_re := ('^', (parser getPattern: 31), '{1,', (i - 1) asString, '}$') asRegex.
- mats := signals select: [ :sig |
- (sig =~ patt42_re) ifMatched: [ :res |
- | rest |
- rest := sig readStream copyFrom: (res matchInterval last) to: (sig size - 1).
- (rest =~ patt31_re) matched.
- ] ifNotMatched: [
- false
- ]
- ].
- part2 := part2 + (mats size).
- (i = 2) ifTrue: [ stdout nextPutAll: ('Part 1: ', part2 asString); nl; flush ]
- ].
- stdout nextPutAll: ('Part 2: ', part2 asString); nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement