Permalink
Cannot retrieve contributors at this time
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?
AdventOfCode2020/AdventOfCode/AOCMemoryGame.class.st
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
57 lines (53 sloc)
1.95 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | |
] |