Advertisement
musifter

AoC 2022, day 13 (smalltalk)

Dec 13th, 2022 (edited)
2,246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 4.24 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Collection extend [
  4.     apply: method  [ ^self collect: [:x | x perform: method] ]
  5. ]
  6.  
  7. "
  8. |  Definition of a tree node in out Packet structure
  9. "
  10. Object subclass: PacketNode [
  11.     | value children |
  12.     " Constructors "
  13.     PacketNode class >> new: aStream [
  14.         ^super new init: aStream
  15.     ]
  16.  
  17.     init: aStream [
  18.         value    := nil.
  19.         children := OrderedCollection new.
  20.         ^self parseNode: aStream.
  21.     ]
  22.  
  23.     " Construct a leaf (Integer) node "
  24.     PacketNode class >> leaf: val [
  25.         ^super new initLeaf: val
  26.     ]
  27.  
  28.     initLeaf: val [
  29.         value    := val.
  30.         children := OrderedCollection with: self. " for promotion to list "
  31.         ^self
  32.     ]
  33.  
  34.     " Access methods "
  35.     isInteger [ ^value notNil ]
  36.     value     [ ^value        ]
  37.  
  38.     isList    [ ^value isNil      ]
  39.     listSize  [ ^children size    ]
  40.     at: idx   [ ^children at: idx ]
  41.  
  42.     " Tree parser and builder "
  43.     parseNode: aStream [
  44.         | chr val |
  45.         val := nil.
  46.         [ aStream atEnd not ] whileTrue: [
  47.             chr := aStream next.
  48.  
  49.             (chr = $[) ifTrue: [
  50.                 children add: (PacketNode new: aStream)
  51.             ].
  52.  
  53.             (chr isDigit) ifTrue: [
  54.                 " Can't assume single digits this time! "
  55.                 val isNil ifTrue:  [ val := chr digitValue ]
  56.                           ifFalse: [ val := 10 * val + chr digitValue ]
  57.             ].
  58.  
  59.             ((chr = $,) or: [chr = $]]) ifTrue: [
  60.                 val ifNotNil: [
  61.                     children add: (PacketNode leaf: val).
  62.                     val := nil.
  63.                 ].
  64.                 (chr = $]) ifTrue: [^self]
  65.             ]
  66.         ].
  67.         ^self
  68.     ]
  69.  
  70.     " Test: true on less-than, false on greater than, nil on equal "
  71.     < other [
  72.         (self isInteger & other isInteger) ifTrue: [
  73.             " Test integer values (nil on equal) "
  74.             (self value = other value) ifTrue: [ ^nil ].
  75.             ^(self value < other value)
  76.  
  77.         ] ifFalse: [
  78.             | minLen ret |
  79.             " First try the elements up to the size of the smaller list: "
  80.             minLen := self listSize min: other listSize.
  81.             (1 to: minLen) do: [ :i |
  82.                 (ret := (self at: i) < (other at: i)) ifNotNil: [ ^ret ]
  83.             ].
  84.  
  85.             " Tests for when we run out of elements in a list: "
  86.             (self listSize = other listSize) ifTrue: [ ^nil ].
  87.             ^self listSize < other listSize
  88.         ]
  89.     ]
  90.  
  91.     " For display "
  92.     printOn: aStream [
  93.         (self isInteger) ifTrue: [
  94.             aStream nextPutAll: value asString.
  95.         ] ifFalse: [
  96.             aStream nextPutAll: '['.
  97.             (children size > 0) ifTrue: [
  98.                 (children allButLast) do: [ :kid |
  99.                     kid printOn: aStream.
  100.                     aStream nextPutAll: ','.
  101.                 ].
  102.                 children last printOn: aStream.
  103.             ].
  104.             aStream nextPutAll: ']'.
  105.         ]
  106.     ]
  107. ]
  108.  
  109. "
  110. | Definition of a packet
  111. "
  112. Object subclass: Packet [
  113.     | root |
  114.     Packet class >> new: aString [
  115.         ^super new init: (PacketNode new: (ReadStream on: aString)).
  116.     ]
  117.  
  118.     init: node [
  119.         root := node.
  120.         ^self
  121.     ]
  122.  
  123.     root  [ ^root ]
  124.  
  125.     " For part 1 (NOTE: returns nil on equal!) "
  126.     < right [ ^self root < right root ]
  127.  
  128.     " Needed for smalltalk sort, used in part 2 "
  129.     <= right [
  130.         ((self root < right root) = false) ifTrue: [ ^false ].
  131.         ^true
  132.     ]
  133.  
  134.     printOn: aStream [
  135.         root printOn: aStream.
  136.     ]
  137. ]
  138.  
  139. "
  140. | Mainline
  141. "
  142. pairs := (stdin contents tokenize: '\n\n') apply: #lines.
  143.  
  144. allPackets := SortedCollection new.
  145.  
  146. " Part 1 "
  147. part1 := 0.
  148.  
  149. pairs keysAndValuesDo: [ :idx :p |
  150.     left  := allPackets add: (Packet new: p first).
  151.     right := allPackets add: (Packet new: p second).
  152.  
  153.     (left < right) ifTrue: [ part1 := part1 + idx ].
  154. ].
  155.  
  156. ('Part 1: %1' % {part1}) displayNl.
  157.  
  158. " Part 2 "
  159. part2 := 0.
  160.  
  161. " Add marker items: "
  162. packet2 := allPackets add: (Packet new: '[[2]]').
  163. packet6 := allPackets add: (Packet new: '[[6]]').
  164.  
  165. part2 := (allPackets indexOf: packet2) * (allPackets indexOf: packet6).
  166. ('Part 2: %1' % {part2}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement