Object subclass: #PaintedNumber instanceVariableNames: 'value possibilities position holder ' classVariableNames: '' poolDictionaries: '' category: 'Practice-NumberPaintedBrick2'! !PaintedNumber commentStamp: 'sumim 5/21/2003 16:58' prior: 0! I am an object in order to solve the "number painted brick problem". In this story, two numbers will be painted on a brick. When one number is odd, another should be even, vice versa. Three bricks on a row and all numbers painted on them should be unique, i.e., there should be no same number on the same row. Six rows were piled up and each of them was putting alternately. All column of painted number has the same rule of rows. You can find already painted numbers as below. How should you paint other blank spaces (*s)? ------------------------------- 6 ][ * 5 ][ * * ][ * =============================== [ * 6 ][ * * ][ * * ] =============================== 4 ][ * * ][ * * ][ * =============================== [ * * ][ * 4 ][ * 1 ] =============================== * ][ * * ][ * 1 ][ * =============================== [ * * ][ * 5 ][ * * ] =============================== I know who is my holder (an Array2D as brick wall) and who is my neighbor that shares the same brick. I also know my possibility of numbers and when the possibilities narrow down to one, I will reveal it as my value. When my value is decided, that should be omitted from possibilities of other's on the same row or column chain-reactively. " | brickWall | brickWall _ Array2D extent: 6@6. 1 to: 6 do: [ :x | 1 to: 6 do: [ :y | brickWall at: x at: y put: (PaintedNumber position: x@y in: brickWall)]]. World findATranscript: nil. #( (1 1) 6 (3 1) 5 (2 2) 6 (1 3) 4 (4 4) 4 (6 4) 1 (5 5) 1 (4 6) 5) pairsDo: [ :pos :val | (brickWall at: pos first at: pos last) value: val. Transcript cr. 1 to: brickWall height do: [ :n | Transcript cr; show: (brickWall atRow: n) printString]]. "! !PaintedNumber methodsFor: 'private' stamp: 'sumim 5/21/2003 16:53'! setPosition: aPoint holder: anArray2D position _ aPoint. holder _ anArray2D. holder at: position x at: position y put: self. possibilities _ (1 to: anArray2D width) asOrderedCollection! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 17:33'! exclude: anInteger | oddIntegersSize | possibilities remove: anInteger ifAbsent: []. value ifNil: [possibilities size = 1 ifTrue: [self value: possibilities first]]. oddIntegersSize _ (possibilities select: [ :each | each odd]) size. oddIntegersSize = 0 ifTrue: [self neighbor excludeEvens]. oddIntegersSize = possibilities size ifTrue: [self neighbor excludeOdds]! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 17:21'! excludeEvens | odds | odds _ possibilities select: [ :each | each odd]. odds size = possibilities size ifTrue: [^ self]. self possibilities: (possibilities select: [ :each | each odd])! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 17:21'! excludeOdds | evens | evens _ possibilities select: [ :each | each even]. evens size = possibilities size ifTrue: [^ self]. self possibilities: evens! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 14:20'! holder ^ holder! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 14:39'! neighbor ^ (holder atRow: position y) atWrap: position x + ( (position x + (position y \\ 2)) odd ifTrue: [1] ifFalse: [-1])! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 14:19'! position ^ position! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 14:19'! possibilities ^ possibilities! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 16:49'! possibilities: aCollection | oddNumbersSize | possibilities _ aCollection. aCollection size = 1 ifTrue: [self value: aCollection first]. oddNumbersSize _ (aCollection select: [ :each | each odd]) size. oddNumbersSize = 0 ifTrue: [self neighbor excludeEvens]. oddNumbersSize = aCollection size ifTrue: [self neighbor excludeOdds]! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 16:08'! value ^ value! ! !PaintedNumber methodsFor: 'accessing' stamp: 'sumim 5/21/2003 17:27'! value: anInteger value _ anInteger. possibilities _ {anInteger} asOrderedCollection. self rowCheck. self columnCheck. anInteger odd ifTrue: [self neighbor excludeOdds] ifFalse: [self neighbor excludeEvens]! ! !PaintedNumber methodsFor: 'checking' stamp: 'sumim 5/21/2003 17:30'! columnCheck (holder atCol: position x) do: [ :each | each ~~ self ifTrue: [each exclude: value]]! ! !PaintedNumber methodsFor: 'checking' stamp: 'sumim 5/21/2003 17:29'! rowCheck (holder atRow: position y) do: [ :each | each ~~ self ifTrue: [each exclude: value]]! ! !PaintedNumber methodsFor: 'printing' stamp: 'sumim 5/21/2003 16:57'! printOn: aStream value ifNotNil: [value printOn: aStream] ifNil: [possibilities asArray printOn: aStream]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! PaintedNumber class instanceVariableNames: ''! !PaintedNumber class methodsFor: 'instance creation' stamp: 'sumim 5/21/2003 16:32'! position: aPoint in: anArray2D ^ self new setPosition: aPoint holder: anArray2D; yourself! !