νΌλΌλ―Έλ μ€λ₯΄κΈ° ¶
2h 20m 28s
μμ΄λμ΄λ JuNe μ λ°°κ° λ§νλ κ²μ΄λ€.(μ λ² μλ° μ»¨νΌλ°μ€μμ μλκ°..) ν λ² λμ νμΌλ‘ μ§νλλ κ²μ κ°μ μΈ΅μΌλ‘ λ³Έλ€. κ·Έλ¬λ©΄ κ°μ₯ λ°κΉ₯μͺ½μ 1μΈ΅, λ€μ μμͺ½μ 2μΈ΅ μ΄λ° μμΌλ‘ μμͺ½μΌλ‘ κ°μλ‘ λμ΄κ° λμμ§λ€. ν μ¬λμ΄ νΌλΌλ―Έλλ₯Ό ν λ°ν΄ λκ³ λ€μ μΈ΅μΌλ‘ μ¬λΌκ°λ©΄μ μμ μ΄ λ€λ λ κ³³μ΄ λͺ λ²μ§ΈμΈμ§, μ’νλ 무μμΈμ§ κΈ°μ΅νλ€. ν μΈ΅μ λ€ λλ©΄ μμνλ μλ¦¬λ‘ λμμ€κΈ° λλ¬Έμ μ€λ³΅ν΄μ κΈ°μ΅ν μ’νλ μ§μ°κ³ λ€μ μΈ΅μΌλ‘ μ΄λνλ€.
~cpp
import unittest
ROW = 0
COL = 1
class Direction:
def move(self, coordinate, board):
if ( board.isWall( self.next(coordinate) ) ):
return coordinate
return self.next(coordinate)
class Down(Direction):
def next(self, coordinate):
return (coordinate[ROW] + 1, coordinate[COL])
class Up( Direction ):
def next(self, coordinate):
return (coordinate[ROW] - 1, coordinate[COL])
class Right(Direction):
def next(self, coordinate):
return (coordinate[ROW], coordinate[COL] + 1 )
class Left(Direction):
def next(self, coordinate):
return (coordinate[ROW], coordinate[COL] - 1 )
class Board:
def __init__(self):
self.size = 0
def setBoundary( self, start, end ):
self.start = start
self.end = end
def isWall( self, coordinate ):
if ( coordinate[ROW] < self.start ):
return True
elif ( coordinate[ROW] >= self.end ):
return True
elif ( coordinate[COL] < self.start ):
return True
elif ( coordinate[COL] >= self.end ):
return True
return False
def decreaseBoundary(self, amount):
self.setBoundary( self.start+amount, self.end-amount )
class Mover:
def __init__(self):
self.coordinate = (0,0)
self.moveCount = 0
self.history = []
def position(self):
return self.coordinate
def goStraight(self, direction, board):
while ( not self.coordinate == direction.move(self.coordinate, board) ):
self.history.append( Point( self.coordinate, self.moveCount+1 ) )
self.moveCount += 1
self.coordinate = direction.move( self.coordinate, board )
self.history.append( Point( self.coordinate, self.moveCount+1 ) )
def mark(self, point, value):
point.value = value
def _setMoveCount(self, count):
self.moveCount = count
def _setPosition(self, coordinate):
self.coordinate = coordinate
def getHistory(self):
return self.history
def turnRound(self, board):
self.goStraight( Right(), board )
self.goStraight( Down(), board )
self.goStraight( Left(), board )
self.goStraight( Up(), board )
board.decreaseBoundary(1)
self.eraseLastMovement()
self._setPosition( self.nextFloor() )
def nextFloor(self):
return (self.coordinate[ROW]+1, self.coordinate[COL]+1 )
def eraseLastMovement(self):
self._setMoveCount( self.history.pop().value - 1 )
class Point:
def __init__(self, coordinate, value):
self.coordinate = coordinate
self.value = value
class Array:
def __init__(self, size):
self.matrix = []
for i in range(size):
self.matrix.append( [Point((-1,-1),-1)] * size )
def isAllFilled(self):
for row in self.matrix:
for point in row:
if ( point.value < 0 ):
return False
return True
def _fillAll(self):
for row in self.matrix:
for point in row:
point.value = 1
def get(self, row, col):
return self.matrix[row][col]
def construct(self, pointList):
for p in pointList:
self.matrix[p.coordinate[ROW]][p.coordinate[COL]] = p
def printValues(self):
for row in self.matrix:
for point in row:
print point.value,
print "\t",
print
class SpiralArrayTest(unittest.TestCase):
def setUp(self):
self.board = Board()
self.size = 10
self.board.setBoundary(start=0, end=self.size)
self.mover = Mover()
self.array = Array( self.size )
def testMoveDown(self):
self.assertEquals( (1,0), Down().move( (0,0), self.board ) )
self.assertEquals( (self.size-1,0), Down().move( (self.size-1,0), self.board ) )
def testMoveUp(self):
self.assertEquals( (0,0), Up().move( (0,0), self.board ) )
self.assertEquals( (self.size-1,0), Up().move( (self.size,0), self.board ) )
def testIsWall(self):
self.assertEquals( False, self.board.isWall( (0,0) ) )
self.assertEquals( True, self.board.isWall( (-1,0) ) )
self.assertEquals( True, self.board.isWall( (0,-1) ) )
self.assertEquals( True, self.board.isWall( (0,self.size) ) )
self.assertEquals( True, self.board.isWall( (self.size,0) ) )
def testGoStraightRight(self):
self.mover.goStraight(Right(), self.board)
self.assertEquals( (0,self.size-1), self.mover.position() )
def testMark(self):
point = Point((0,0),0)
self.mover._setMoveCount(1)
self.mover.mark( point, self.mover.moveCount )
self.assertEquals( 1, point.value )
def testStorePointCoordinate(self):
self.mover.goStraight( Down(), self.board )
points = self.mover.getHistory()
self.assertEquals( (self.size-1,0), points.pop().coordinate )
self.assertEquals( (self.size-2,0), points.pop().coordinate )
def testStoreMoveCount(self):
self.mover._setPosition((self.size-1, self.size-1))
self.mover.goStraight( Left(), self.board )
points = self.mover.getHistory()
self.assertEquals( self.size, points.pop().value )
self.assertEquals( self.size-1, points.pop().value )
def testTurnRound(self):
self.mover._setPosition( (0,0) )
self.mover.turnRound(self.board)
self.assertEquals( (1,0), self.mover.getHistory().pop().coordinate )
def testIsFinished(self):
self.assertEquals( False, self.array.isAllFilled() )
self.array._fillAll()
self.assertEquals( True, self.array.isAllFilled() )
def testConstructArray(self):
self.mover._setPosition( (0,0) )
self.mover.turnRound(self.board)
self.array.construct( self.mover.getHistory() )
self.assertEquals( (0,0), self.array.get(0,0).coordinate )
self.assertEquals( (self.size-1, self.size-1),
self.array.get(self.size-1, self.size-1).coordinate )
if __name__ == "__main__":
## unittest.main()
inputSize = input()
board = Board()
board.setBoundary(0, inputSize )
array = Array(inputSize)
mover = Mover()
mover._setPosition((0,0))
while not ( array.isAllFilled() ):
mover.turnRound(board)
array.construct(mover.getHistory())
array.printValues()
νΌλΌλ―Έλ μ€λ₯΄κΈ° Refacotring ¶
1h 58m 26s
μ§λ λ² λ¦¬ν©ν λ§ λμμ΄μλ Moverν΄λμ€, Arrayν΄λμ€μ μ’
λ£κ²μ¬, ν
μ€νΈ μΌμ΄μ€λ₯Ό 리ν©ν λ§ νλ€. ν
μ€νΈ μΌμ΄μ€μ Arrayν΄λμ€λ μ½κ² 리ν©ν λ§ ν μ μμλ€. νμ§λ§ Moverν΄λμ€λ₯Ό μλλλ° μ€λ κ±Έλ Έλ€.
goStraight μ λ²μ μ Directionν΄λμ€λ₯Ό μ΄μ©ν΄μ μ΄λν(λ²½μ λ§λλ©΄ μ΄λνμ§ μμ) μμΉλ₯Ό μ»μ΄λ΄κ³ , μ΄λν κΈ°λ‘μ μ μ₯νλ νμμ΄μλ€. λ²½μ λν κ²μ¬κ° κ²ΉμΉλ κ² κ°μ moverμμ λ°λ‘ λ²½μ κ²μ¬νκ³ λ²½μ λ€μ΄μλ©΄ μ’
λ£νλ κ²μΌλ‘ λ§λ€μλ€. κ·Έλ¬κ³ 보λ λ°λ‘ μΉ΄μ΄νΈ ν νμκ° μμ΄ moveCountλ³μλ₯Ό μμ΄λ€. moverκ° μ’
λ£ μ‘°κ±΄λ κ²μ¬νλλ° board λμ΄λ§νΌ μ΄λνμΌλ©΄ λλλ κ²μ΄κΈ° λλ¬Έμ΄λ€.
κ·Έλ°λ° λ²½μ λ€μ΄μμΌ μ’
λ£νλ€ λ³΄λκΉ moverλ₯Ό λ²½μ λ€μ΄κ°κΈ° μ μ μμΉλ‘ λλλ €λμμΌ νλ€. κ·Έλμ directionμ λͺ¨λ previous λ©μλκ° μκ²Όλ€. νλ° λ€μ λ² goStraightλ₯Ό ν λλ μ΄λ―Έ μ΄λνλ κΈ°λ‘μ΄ λ¨μμκ² λμλ€. κ·Έλμ λ§€λ² goStraightλ₯Ό ν λλ§λ€ λ§μ§λ§ μ΄λ κΈ°λ‘μ μμ νλ€. κ·Έλ¬λ€λ³΄λ boardν¬κΈ°κ° 1μΌ κ²½μ°λ μ΄λν κΈ°λ‘μ΄ λͺ¨λ μ§μμ Έλ²λ¦¬λ κ²μ΄ μλκ°. μ‘°μ‘νμ§λ§ μμΈ μ²λ¦¬λ₯Ό ν΄μ£Όμλ€.
κ²½κ³μ‘°κ±΄μ΄ μ°Έ λ―Έλ¬νλ€λ κ²μ λκΌλ€. μμκ³Ό λμ μ΄λ»κ² ν κ²μΈκ°? νμ°Έμ ν€λ§€λ€λ³΄λ λ λμ λ°©λ²μ΄ μλλ°λ μ°Ύμ§ λͺ»νλ κ² κ°λ€.
μ½λ μμμ ν€λ§€κΈ° 보λ€λ μ νν μκ°μ μ 리ν΄μ ꡬνν΄μΌ νλ€. μ΄κ² ν΄λ³΄κ³ μ κ² ν΄λ³΄λ μ¬μ΄μ μκ°μ΄ λ무 λ§μ΄ νλ¬κ°λ€. κ²°κ΅μ λ΅μ λμμ§λ§, μ΄λ³΄λ€ 빨리 ν μ μμ κ²μ΄λ€.
~cpp
import unittest
ROW = 0
COL = 1
class Direction:
pass
class Down(Direction):
def next(self, coordinate):
return (coordinate[ROW] + 1, coordinate[COL])
def previous(self, coordinate):
return Up().next( coordinate )
class Up( Direction ):
def next(self, coordinate):
return (coordinate[ROW] - 1, coordinate[COL])
def previous(self, coordinate):
return Down().next( coordinate )
class Right(Direction):
def next(self, coordinate):
return (coordinate[ROW], coordinate[COL] + 1 )
def previous(self, coordinate):
return Left().next( coordinate )
class Left(Direction):
def next(self, coordinate):
return (coordinate[ROW], coordinate[COL] - 1 )
def previous(self, coordinate):
return Right().next( coordinate )
class Board:
def __init__(self, initialSize):
self.size = initialSize
self.setBoundary( 0, self.size )
def setBoundary( self, start, end ):
self.start = start
self.end = end
def isWall( self, coordinate ):
if ( coordinate[ROW] < self.start ):
return True
elif ( coordinate[ROW] >= self.end ):
return True
elif ( coordinate[COL] < self.start ):
return True
elif ( coordinate[COL] >= self.end ):
return True
return False
def decreaseBoundary(self, amount):
self.setBoundary( self.start+amount, self.end-amount )
class Mover:
def __init__(self):
self.coordinate = (0,0)
self.history = []
def position(self):
return self.coordinate
def goStraight(self, direction, board):
while ( not board.isWall( self.coordinate ) ):
self.history.append( Point( self.coordinate, self.moveCount() ) )
self.coordinate = direction.next( self.coordinate )
self.coordinate = direction.previous( self.coordinate )
def mark(self, point, value):
point.value = value
def moveCount(self):
return len( self.history ) + 1
def setPosition(self, coordinate):
self.coordinate = coordinate
def getHistory(self):
return self.history
def turnRound(self, board):
for direction in [Right(), Down(), Left()]:
self.goStraight( direction, board )
self.eraseLastMovement()
self.goStraight( Up(), board )
if ( board.end - board.start != 1 ):
self.eraseLastMovement()
self.setPosition( self.nextFloor() )
def nextFloor(self):
return (self.coordinate[ROW]+1, self.coordinate[COL]+1 )
def eraseLastMovement(self):
self.history.pop()
def isFinished( self, board ):
return board.size * board.size < self.moveCount()
def lastHistory( self ):
return self.history[-1]
class Point:
def __init__(self, coordinate, value):
self.coordinate = coordinate
self.value = value
class Array:
def __init__(self, size):
self.matrix = []
for i in range(size):
self.matrix.append( [Point((-1,-1),-1)] * size )
def get(self, row, col):
return self.matrix[row][col]
def construct(self, pointList):
for p in pointList:
self.matrix[p.coordinate[ROW]][p.coordinate[COL]] = p
def printValues(self):
for row in self.matrix:
for point in row:
print point.value,
print "\t",
print
class SpiralArrayTest(unittest.TestCase):
def setUp(self):
self.size = 10
self.board = Board(self.size)
self.board.setBoundary(start=0, end=self.size)
self.mover = Mover()
self.array = Array( self.size )
class DirectionTest(SpiralArrayTest):
def testNext(self):
self.assertEquals( (1,0), Down().next( (0,0) ) )
def testPrevious(self):
self.assertEquals( (0,0), Down().previous( (1,0) ) )
class BoardTest(SpiralArrayTest):
def testIsWall(self):
self.assertEquals( False, self.board.isWall( (0,0) ) )
self.assertEquals( True, self.board.isWall( (-1,0) ) )
self.assertEquals( True, self.board.isWall( (0,-1) ) )
self.assertEquals( True, self.board.isWall( (0,self.size) ) )
self.assertEquals( True, self.board.isWall( (self.size,0) ) )
class MoverTest(SpiralArrayTest):
def testGoStraightRight(self):
self.mover.goStraight(Right(), self.board)
self.assertEquals( (0,self.size-1), self.mover.position() )
def testStorePointCoordinate(self):
self.mover.goStraight( Down(), self.board )
points = self.mover.getHistory()
self.assertEquals( (self.size-1,0), points.pop().coordinate )
self.assertEquals( (self.size-2,0), points.pop().coordinate )
def testStoreMoveCount(self):
self.mover.setPosition((self.size-1, self.size-1))
self.mover.goStraight( Left(), self.board )
points = self.mover.getHistory()
self.assertEquals( self.size, points.pop().value )
self.assertEquals( self.size-1, points.pop().value )
def testStoreMovementWhenTurnRoundAndBoudaryNotOne(self):
self.mover.setPosition( (0,0) )
self.mover.turnRound(self.board)
points = self.mover.getHistory()
self.assertEquals( (self.size-1) * 4 , len( points ) )
def testStoreMovementWhenTurnRoundAndBoudaryOne(self):
self.board = Board( initialSize = 1 )
self.mover.setPosition( (0,0) )
self.mover.turnRound(self.board)
points = self.mover.getHistory()
self.assertEquals( 1 , len( points ) )
def testTurnRoundWithBoundary0(self):
self.mover.setPosition( (0,0) )
self.mover.turnRound(self.board)
self.assertEquals( (1,0), self.mover.lastHistory().coordinate )
def testIsFinished(self):
self.board = Board( initialSize = 1 )
self.assertEquals( False, self.mover.isFinished( self.board ) )
self.mover.turnRound( self.board )
self.assertEquals( True, self.mover.isFinished( self.board ) )
def testRun(self):
self.board = Board( initialSize = 3 )
self.mover.setPosition( (0,0) )
self.mover.turnRound(self.board)
self.assertEquals( (1,0), self.mover.lastHistory().coordinate )
self.assertEquals( (1,1), self.mover.position() )
self.board.decreaseBoundary(1)
self.mover.turnRound(self.board)
self.assertEquals( (1,1), self.mover.lastHistory().coordinate )
class ArrayTest(SpiralArrayTest):
def testConstructArray(self):
self.mover.setPosition( (0,0) )
self.mover.turnRound(self.board)
self.array.construct( self.mover.getHistory() )
self.assertEquals( (0,0), self.array.get(0,0).coordinate )
self.assertEquals( (self.size-1, self.size-1),
self.array.get(self.size-1, self.size-1).coordinate )
if __name__ == "__main__":
unittest.main()
inputSize = input()
board = Board(inputSize)
mover = Mover()
mover.setPosition((0,0))
while ( not mover.isFinished( board ) ):
mover.turnRound(board)
board.decreaseBoundary(1)
array = Array(inputSize)
array.construct(mover.getHistory())
array.printValues()










