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