νΌλΌλ―Έλ μ€λ₯΄κΈ° ¶
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()