Skip to content
Permalink
7c929a2833
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
57 lines (53 sloc) 1.95 KB
Class {
#name : #AOCMemoryGame,
#superclass : #Object,
#instVars : [
'numberDict',
'lastSpoken',
'turnNumber'
],
#category : #AdventOfCode
}
{ #category : #'as yet unclassified' }
AOCMemoryGame class >> seedWith: aSequence [
"Records the seed turns"
|ans|
ans := self new.
aSequence do: [ :x | ans recordTurn: x ].
^ ans.
]
{ #category : #initialization }
AOCMemoryGame >> initialize [
turnNumber := 0.
"a dictionary from number to sequence of numbers is used to find out when was the last time a number was spoken. The key is the spoken number (not the turn number) and the values are turn numbers (not spoken numbers). Everything is 1 indexed. The sequence is actually an array truncated to length 2."
"IdentityDictionary is roughly an order of magnitude faster than Dictionary. Pharo dicts are still really slow though and part 2 takes ~5-7min on a Pixelbook mobile processor."
numberDict := IdentityDictionary new.
]
{ #category : #'as yet unclassified' }
AOCMemoryGame >> recordTurn: anInteger [
"updates object state with the new value"
|record |
turnNumber := turnNumber + 1.
lastSpoken := anInteger.
record := numberDict at: anInteger ifAbsent: [ nil ].
record := record ifNil: [ { turnNumber } ] ifNotNil: [ { record last . turnNumber } ].
numberDict at: anInteger put: record.
]
{ #category : #'as yet unclassified' }
AOCMemoryGame >> turn [
"play a turn. answer the number that was spoken."
| turnsForNumber spoken |
turnsForNumber := numberDict at: lastSpoken.
"
self assert: (turnsForNumber size > 0).
self assert: (turnsForNumber size <= 2)."
spoken := (turnsForNumber size = 1) ifTrue: [
"If that was the first time the number has been spoken, the current player says 0"
0
] ifFalse: [
"Otherwise, the number had been spoken before; the current player announces how many turns apart the number is from when it was previously spoken"
(turnsForNumber last) - (turnsForNumber first)
].
self recordTurn: spoken.
^ spoken.
]