ํผ๋ผ๋ฏธ๋ ์ค๋ฅด๊ธฐ ¶
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()










