fork download
  1. Object subclass: DoubleLinkedNode [
  2.  
  3. | value nextNode previousNode |
  4.  
  5. DoubleLinkedNode class >> new [
  6. <category: 'Instance Creation'>
  7. | o |
  8. o := super new.
  9. o init.
  10. ^o.
  11. ]
  12.  
  13. DoubleLinkedNode class >> new: newValue [
  14. | o |
  15. o := self new.
  16. o value: newValue.
  17. ^o.
  18. ]
  19.  
  20. init [
  21. value := nil.
  22. nextNode := nil.
  23. previousNode := nil.
  24. ]
  25.  
  26. value [
  27. ^value.
  28. ]
  29.  
  30. value: newValue [
  31. value := newValue.
  32. ]
  33.  
  34. nextNode [
  35. ^nextNode.
  36. ]
  37.  
  38. nextNode: newValue [
  39. (nextNode == newValue) | (newValue == nil) ifFalse: [
  40. nextNode := newValue.
  41. nextNode previousNode: self.
  42. ]
  43. ]
  44.  
  45. previousNode [
  46. ^previousNode.
  47. ]
  48.  
  49. previousNode: newValue [
  50. (previousNode == newValue) | (newValue == nil) ifFalse: [
  51. previousNode := newValue.
  52. previousNode nextNode: self.
  53. ]
  54. ]
  55.  
  56. printOn: stream [
  57. super printOn: stream.
  58. stream nextPutAll: ' with value: '.
  59. value printOn: stream.
  60. ]
  61.  
  62. ]
  63.  
  64. SequenceableCollection subclass: CircularDoublyLinkedList [
  65.  
  66. | firstNode size |
  67.  
  68. CircularDoublyLinkedList class >> new [
  69. <category: 'Instance creation'>
  70. | o |
  71. o := super new.
  72. o init.
  73. ^o.
  74. ]
  75.  
  76. init [
  77. firstNode := nil.
  78. ]
  79.  
  80. at: index [
  81. ^(self nodeAt: index) value.
  82. ]
  83.  
  84. nodeAt: index [
  85. | currentNode i |
  86. i := 0.
  87. currentNode := firstNode.
  88. [ index > i ] whileTrue: [
  89. currentNode := currentNode nextNode.
  90. i := i + 1.
  91. ].
  92. ^currentNode.
  93. ]
  94.  
  95. addAtEnd: value [
  96. | node |
  97. node := DoubleLinkedNode new: value.
  98. (firstNode == nil) ifTrue: [
  99. firstNode := node.
  100. node nextNode: node.
  101. ] ifFalse: [
  102. firstNode previousNode nextNode: node.
  103. node nextNode: firstNode.
  104. ]
  105. ]
  106.  
  107. addAtStart: value [
  108. | node |
  109. node := DoubleLinkedNode new: value.
  110. (firstNode == nil) ifTrue: [
  111. firstNode := node.
  112. node nextNode: node.
  113. ] ifFalse: [
  114. firstNode previousNode nextNode: node.
  115. node nextNode: firstNode.
  116. firstNode := node.
  117. ]
  118. ]
  119.  
  120. size [
  121. "This is a really poor implementation because it purposefully walks the entire node graph"
  122. | calculatedSize currentNode |
  123. calculatedSize := 1.
  124. currentNode := firstNode nextNode.
  125. [ firstNode == currentNode ] whileFalse: [
  126. currentNode := currentNode nextNode.
  127. calculatedSize := calculatedSize + 1.
  128. ].
  129. ^ calculatedSize.
  130. ]
  131.  
  132. ]
  133.  
  134. Object subclass: Lock [
  135.  
  136. | rotationIncrements currentNode dial totalDigits |
  137.  
  138. Lock class >> new: size [
  139. <category: 'Instance Creation'>
  140. | o |
  141. o := super new.
  142. o init.
  143. o totalDigits: size.
  144. o currentNode: (o dial nodeAt: 0).
  145. ^o.
  146. ]
  147.  
  148. init [
  149. rotationIncrements := 0.
  150. currentNode := nil.
  151. dial := CircularDoublyLinkedList new.
  152. ]
  153.  
  154. dial [
  155. ^dial.
  156. ]
  157.  
  158. currentNode [
  159. ^currentNode.
  160. ]
  161.  
  162. currentNode: value [
  163. <category: 'Private'>
  164. ^currentNode := value.
  165. ]
  166.  
  167. rotationIncrements [
  168. ^rotationIncrements
  169. ]
  170.  
  171. totalDigits [
  172. ^totalDigits.
  173. ]
  174.  
  175. totalDigits: value [
  176. <category: 'Private'>
  177. (totalDigits == 0) ifFalse: [
  178. 0 to: (value - 1) do: [ :x |
  179. dial addAtEnd: x.
  180. ].
  181. totalDigits := value.
  182. ]
  183. ]
  184.  
  185. rotateRight [
  186. currentNode := currentNode nextNode.
  187. rotationIncrements := rotationIncrements + 1.
  188. ]
  189.  
  190. rotateRight: steps [
  191. 1 to: steps do: [ :x |
  192. self rotateRight.
  193. ]
  194. ]
  195.  
  196. rotateRightUntil: value [
  197. [ currentNode value == value] whileFalse: [
  198. self rotateRight.
  199. ]
  200. ]
  201.  
  202. rotateLeft [
  203. currentNode := currentNode previousNode.
  204. rotationIncrements := rotationIncrements + 1.
  205. ]
  206.  
  207. rotateLeft: steps [
  208. 1 to: steps do: [ :x |
  209. self rotateLeft.
  210. ]
  211. ]
  212.  
  213. rotateLeftUntil: value [
  214. [ currentNode value == value ] whileFalse: [
  215. self rotateLeft.
  216. ]
  217. ]
  218.  
  219. resetLock [
  220. self rotateLeft: 2 * totalDigits.
  221. ]
  222.  
  223. ]
  224.  
  225. line := FileStream stdin nextLine.
  226. parts := line subStrings: ' '.
  227. lock := Lock new: ((parts removeAtIndex: 1) asInteger).
  228. clockwise := true.
  229. firstRotation := true.
  230. lock resetLock.
  231. [ parts size == 0 ] whileFalse: [
  232. | next |
  233. next := parts removeFirst asInteger.
  234. clockwise ifTrue: [
  235. clockwise := clockwise not.
  236. lock rotateRightUntil: next.
  237. ] ifFalse: [
  238. clockwise := clockwise not.
  239. lock rotateLeftUntil: next.
  240. ].
  241. firstRotation ifTrue: [
  242. firstRotation := firstRotation not.
  243. lock rotateRight: (lock dial size).
  244. ].
  245. ].
  246. lock rotationIncrements printNl.
Success #stdin #stdout 0.02s 74240KB
stdin
5 1 2 3
stdout
10