<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=SpiralArray%2FLeonardong</id>
	<title>SpiralArray/Leonardong - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.zeropage.org/index.php?action=history&amp;feed=atom&amp;title=SpiralArray%2FLeonardong"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;action=history"/>
	<updated>2026-05-14T14:33:55Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=87627&amp;oldid=prev</id>
		<title>Maintenance script: Repair MoniWiki formatting after migration</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=87627&amp;oldid=prev"/>
		<updated>2026-03-29T00:34:30Z</updated>

		<summary type="html">&lt;p&gt;Repair MoniWiki formatting after migration&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 00:34, 29 March 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l2&quot;&gt;Line 2:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 2:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  2h 20m 28s&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  2h 20m 28s&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;아이디어는 JuNe 선배가 말했던 것이다.(저번 자바 컨퍼런스에서 였던가..) 한 번 나선형으로 진행되는 것을 같은 층으로 본다. 그러면 가장 바깥쪽은 1층, 다음 안쪽은 2층 이런 식으로 안쪽으로 갈수록 높이가 높아진다. 한 사람이 피라미드를 한 바퀴 돌고 다음 층으로 올라가면서 자신이 들렀던 곳이 몇 번째인지, 좌표는 무엇인지 기억한다. 한 층을 다 돌면 시작했던 자리로 돌아오기 때문에 중복해서 기억한 좌표는 지우고 다음 층으로 이동한다.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;아이디어는 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[&lt;/ins&gt;JuNe&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]] &lt;/ins&gt;선배가 말했던 것이다.(저번 자바 컨퍼런스에서 였던가..) 한 번 나선형으로 진행되는 것을 같은 층으로 본다. 그러면 가장 바깥쪽은 1층, 다음 안쪽은 2층 이런 식으로 안쪽으로 갈수록 높이가 높아진다. 한 사람이 피라미드를 한 바퀴 돌고 다음 층으로 올라가면서 자신이 들렀던 곳이 몇 번째인지, 좌표는 무엇인지 기억한다. 한 층을 다 돌면 시작했던 자리로 돌아오기 때문에 중복해서 기억한 좌표는 지우고 다음 층으로 이동한다.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;하지만 여지껏 그러한 접근법을 알고서도 TDD로 풀지를 못했었다. 매번 나선형 &amp;quot;행렬&amp;quot;에 어떻게 숫자를 새길지만 생각했기 때문이다. 그러다 보니 2차원 배열의 인덱스를 조작하는 수준에서 생각이 벗어나질 못했다. 하지만 사실은 움직임(이전의 인덱스 조작), 움직인 점들, 행렬을 따로 생각할 수 있었다. 아! 이렇게 테스트 하면 되겠구나!&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;하지만 여지껏 그러한 접근법을 알고서도 TDD로 풀지를 못했었다. 매번 나선형 &amp;quot;행렬&amp;quot;에 어떻게 숫자를 새길지만 생각했기 때문이다. 그러다 보니 2차원 배열의 인덱스를 조작하는 수준에서 생각이 벗어나질 못했다. 하지만 사실은 움직임(이전의 인덱스 조작), 움직인 점들, 행렬을 따로 생각할 수 있었다. 아! 이렇게 테스트 하면 되겠구나!&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key mediawiki:diff::1.12:old-84985:rev-87627 --&gt;
&lt;/table&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=84985&amp;oldid=prev</id>
		<title>Maintenance script: Repair batch-0003 pages from live compare</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=84985&amp;oldid=prev"/>
		<updated>2026-03-27T00:29:11Z</updated>

		<summary type="html">&lt;p&gt;Repair batch-0003 pages from live compare&lt;/p&gt;
&lt;a href=&quot;https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;amp;diff=84985&amp;amp;oldid=39269&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Maintenance script</name></author>
	</entry>
	<entry>
		<id>https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=39269&amp;oldid=prev</id>
		<title>imported&gt;Unknown at 05:28, 7 February 2021</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.zeropage.org/index.php?title=SpiralArray/Leonardong&amp;diff=39269&amp;oldid=prev"/>
		<updated>2021-02-07T05:28:05Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 피라미드 오르기 ==&lt;br /&gt;
 2h 20m 28s&lt;br /&gt;
&lt;br /&gt;
아이디어는 JuNe 선배가 말했던 것이다.(저번 자바 컨퍼런스에서 였던가..) 한 번 나선형으로 진행되는 것을 같은 층으로 본다. 그러면 가장 바깥쪽은 1층, 다음 안쪽은 2층 이런 식으로 안쪽으로 갈수록 높이가 높아진다. 한 사람이 피라미드를 한 바퀴 돌고 다음 층으로 올라가면서 자신이 들렀던 곳이 몇 번째인지, 좌표는 무엇인지 기억한다. 한 층을 다 돌면 시작했던 자리로 돌아오기 때문에 중복해서 기억한 좌표는 지우고 다음 층으로 이동한다.&lt;br /&gt;
&lt;br /&gt;
하지만 여지껏 그러한 접근법을 알고서도 TDD로 풀지를 못했었다. 매번 나선형 &amp;quot;행렬&amp;quot;에 어떻게 숫자를 새길지만 생각했기 때문이다. 그러다 보니 2차원 배열의 인덱스를 조작하는 수준에서 생각이 벗어나질 못했다. 하지만 사실은 움직임(이전의 인덱스 조작), 움직인 점들, 행렬을 따로 생각할 수 있었다. 아! 이렇게 테스트 하면 되겠구나!&lt;br /&gt;
&lt;br /&gt;
TDD로 풀었다는 점이 기쁘다. 처음부터 너무 메서드를 어디에 속하게 할 지 고민하지 않고 시작한 것이 유용했다. 그 결과로 예전 같으면 생각하지 못했을 Direction클래스와 그 하위 클래스가 탄생했다. 또한 행렬은 최종 결과물을 저장하고 보여주는 일종의 뷰처럼 쓰였다.&lt;br /&gt;
&lt;br /&gt;
현재는 행렬 구성이 비효율적이다. 움직였던 기록을 가지고 행렬을 구성하기를 반복한다.이것을 수정할 때 좀더 효율적으로 작동하게 만들어야겠다. Mover클래스, Array클래스의 종료검사, 테스트 케이스는 확실히 Refactoring이 필요하다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 import unittest&lt;br /&gt;
 &lt;br /&gt;
 ROW = 0&lt;br /&gt;
 COL = 1&lt;br /&gt;
 &lt;br /&gt;
 class Direction:&lt;br /&gt;
     def move(self, coordinate, board):&lt;br /&gt;
         if ( board.isWall( self.next(coordinate) ) ):    &lt;br /&gt;
             return coordinate&lt;br /&gt;
         return self.next(coordinate)&lt;br /&gt;
 &lt;br /&gt;
 class Down(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW] + 1, coordinate[COL])&lt;br /&gt;
     &lt;br /&gt;
 class Up( Direction ):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW] - 1, coordinate[COL])&lt;br /&gt;
 &lt;br /&gt;
 class Right(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW], coordinate[COL] + 1 )&lt;br /&gt;
 &lt;br /&gt;
 class Left(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW], coordinate[COL] - 1 )&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class Board:&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.size = 0&lt;br /&gt;
     def setBoundary( self, start, end ):&lt;br /&gt;
         self.start = start&lt;br /&gt;
         self.end = end&lt;br /&gt;
     def isWall( self, coordinate ):&lt;br /&gt;
         if ( coordinate[ROW] &amp;amp;lt; self.start ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[ROW] &amp;amp;gt;= self.end ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[COL] &amp;amp;lt; self.start ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[COL] &amp;amp;gt;= self.end ):&lt;br /&gt;
             return True&lt;br /&gt;
         return False&lt;br /&gt;
     def decreaseBoundary(self, amount):&lt;br /&gt;
         self.setBoundary( self.start+amount, self.end-amount )&lt;br /&gt;
     &lt;br /&gt;
 &lt;br /&gt;
 class Mover:&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.coordinate = (0,0)&lt;br /&gt;
         self.moveCount = 0&lt;br /&gt;
         self.history = []&lt;br /&gt;
     def position(self):&lt;br /&gt;
         return self.coordinate&lt;br /&gt;
     def goStraight(self, direction, board):&lt;br /&gt;
         while ( not self.coordinate == direction.move(self.coordinate, board) ):&lt;br /&gt;
             self.history.append( Point( self.coordinate, self.moveCount+1 ) )&lt;br /&gt;
             self.moveCount += 1&lt;br /&gt;
             self.coordinate = direction.move( self.coordinate, board )&lt;br /&gt;
         self.history.append( Point( self.coordinate, self.moveCount+1 ) )&lt;br /&gt;
     def mark(self, point, value):&lt;br /&gt;
         point.value = value&lt;br /&gt;
     def _setMoveCount(self, count):&lt;br /&gt;
         self.moveCount = count&lt;br /&gt;
     def _setPosition(self, coordinate):&lt;br /&gt;
         self.coordinate = coordinate&lt;br /&gt;
     def getHistory(self):&lt;br /&gt;
         return self.history&lt;br /&gt;
     def turnRound(self, board):&lt;br /&gt;
         self.goStraight( Right(), board )&lt;br /&gt;
         self.goStraight( Down(), board )&lt;br /&gt;
         self.goStraight( Left(), board )&lt;br /&gt;
         self.goStraight( Up(), board )&lt;br /&gt;
         board.decreaseBoundary(1)&lt;br /&gt;
         self.eraseLastMovement()&lt;br /&gt;
         self._setPosition( self.nextFloor() )&lt;br /&gt;
     def nextFloor(self):&lt;br /&gt;
         return (self.coordinate[ROW]+1, self.coordinate[COL]+1 )&lt;br /&gt;
     def eraseLastMovement(self):&lt;br /&gt;
         self._setMoveCount( self.history.pop().value - 1 )&lt;br /&gt;
         &lt;br /&gt;
 class Point:&lt;br /&gt;
     def __init__(self, coordinate, value):&lt;br /&gt;
         self.coordinate = coordinate&lt;br /&gt;
         self.value = value&lt;br /&gt;
 &lt;br /&gt;
 class Array:&lt;br /&gt;
     def __init__(self, size):&lt;br /&gt;
         self.matrix = []&lt;br /&gt;
         for i in range(size):&lt;br /&gt;
             self.matrix.append( [Point((-1,-1),-1)] * size )&lt;br /&gt;
     def isAllFilled(self):&lt;br /&gt;
         for row in self.matrix:&lt;br /&gt;
             for point in row:&lt;br /&gt;
                 if ( point.value &amp;amp;lt; 0 ):&lt;br /&gt;
                     return False&lt;br /&gt;
         return True&lt;br /&gt;
     def _fillAll(self):&lt;br /&gt;
         for row in self.matrix:&lt;br /&gt;
             for point in row:&lt;br /&gt;
                 point.value = 1&lt;br /&gt;
     def get(self, row, col):&lt;br /&gt;
         return self.matrix[row][col]&lt;br /&gt;
     def construct(self, pointList):&lt;br /&gt;
         for p in pointList:&lt;br /&gt;
             self.matrix[p.coordinate[ROW]][p.coordinate[COL]] = p&lt;br /&gt;
     def printValues(self):&lt;br /&gt;
         for row in self.matrix:&lt;br /&gt;
             for point in row:&lt;br /&gt;
                 print point.value,&lt;br /&gt;
                 print &amp;quot;\t&amp;quot;,&lt;br /&gt;
             print&lt;br /&gt;
 &lt;br /&gt;
 class SpiralArrayTest(unittest.TestCase):&lt;br /&gt;
     def setUp(self):&lt;br /&gt;
         self.board = Board()&lt;br /&gt;
         self.size = 10&lt;br /&gt;
         self.board.setBoundary(start=0, end=self.size)&lt;br /&gt;
         self.mover = Mover()&lt;br /&gt;
         self.array = Array( self.size )&lt;br /&gt;
     def testMoveDown(self):&lt;br /&gt;
         self.assertEquals( (1,0), Down().move( (0,0), self.board ) )&lt;br /&gt;
         self.assertEquals( (self.size-1,0), Down().move( (self.size-1,0), self.board ) )&lt;br /&gt;
     def testMoveUp(self):&lt;br /&gt;
         self.assertEquals( (0,0), Up().move( (0,0), self.board ) )&lt;br /&gt;
         self.assertEquals( (self.size-1,0), Up().move( (self.size,0), self.board ) )&lt;br /&gt;
     def testIsWall(self):&lt;br /&gt;
         self.assertEquals( False, self.board.isWall( (0,0) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (-1,0) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (0,-1) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (0,self.size) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (self.size,0) ) )&lt;br /&gt;
     def testGoStraightRight(self):&lt;br /&gt;
         self.mover.goStraight(Right(), self.board)&lt;br /&gt;
         self.assertEquals( (0,self.size-1), self.mover.position() )        &lt;br /&gt;
     def testMark(self):&lt;br /&gt;
         point = Point((0,0),0)&lt;br /&gt;
         self.mover._setMoveCount(1)&lt;br /&gt;
         self.mover.mark( point, self.mover.moveCount )&lt;br /&gt;
         self.assertEquals( 1, point.value )&lt;br /&gt;
     def testStorePointCoordinate(self):&lt;br /&gt;
         self.mover.goStraight( Down(), self.board )&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( (self.size-1,0), points.pop().coordinate )&lt;br /&gt;
         self.assertEquals( (self.size-2,0), points.pop().coordinate )&lt;br /&gt;
     def testStoreMoveCount(self):&lt;br /&gt;
         self.mover._setPosition((self.size-1, self.size-1))&lt;br /&gt;
         self.mover.goStraight( Left(), self.board )&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( self.size, points.pop().value )&lt;br /&gt;
         self.assertEquals( self.size-1, points.pop().value )&lt;br /&gt;
     def testTurnRound(self):&lt;br /&gt;
         self.mover._setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.assertEquals( (1,0), self.mover.getHistory().pop().coordinate )&lt;br /&gt;
     def testIsFinished(self):&lt;br /&gt;
         self.assertEquals( False, self.array.isAllFilled() )&lt;br /&gt;
         self.array._fillAll()&lt;br /&gt;
         self.assertEquals( True, self.array.isAllFilled() )        &lt;br /&gt;
     def testConstructArray(self):&lt;br /&gt;
         self.mover._setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.array.construct( self.mover.getHistory() )&lt;br /&gt;
         self.assertEquals( (0,0), self.array.get(0,0).coordinate )&lt;br /&gt;
         self.assertEquals( (self.size-1, self.size-1),&lt;br /&gt;
                            self.array.get(self.size-1, self.size-1).coordinate )&lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
 ##    unittest.main()&lt;br /&gt;
     inputSize = input()&lt;br /&gt;
     board = Board()&lt;br /&gt;
     board.setBoundary(0, inputSize )&lt;br /&gt;
     array = Array(inputSize)&lt;br /&gt;
     mover = Mover()&lt;br /&gt;
     mover._setPosition((0,0))&lt;br /&gt;
     while not ( array.isAllFilled() ):&lt;br /&gt;
         mover.turnRound(board)&lt;br /&gt;
         array.construct(mover.getHistory())&lt;br /&gt;
     array.printValues()&lt;br /&gt;
&lt;br /&gt;
== 피라미드 오르기 Refacotring ==&lt;br /&gt;
1h 58m 26s&lt;br /&gt;
&lt;br /&gt;
지난 번 리팩토링 대상이었던 Mover클래스, Array클래스의 종료검사, 테스트 케이스를 리팩토링 했다. 테스트 케이스와 Array클래스는 쉽게 리팩토링 할 수 있었다. 하지만 Mover클래스를 손대는데 오래 걸렸다.&lt;br /&gt;
&lt;br /&gt;
goStraight 전 버전은 Direction클래스를 이용해서 이동한(벽을 만나면 이동하지 않음) 위치를 얻어내고, 이동한 기록을 저장하는 형식이었다. 벽에 대한 검사가 겹치는 것 같아 mover에서 바로 벽을 검사하고 벽에 들어서면 종료하는 것으로 만들었다. 그러고 보니 따로 카운트 할 필요가 없어 moveCount변수를 없앴다. mover가 종료 조건도 검사하는데 board 넓이만큼 이동했으면 끝나는 것이기 때문이다.&lt;br /&gt;
&lt;br /&gt;
그런데 벽에 들어서야 종료하다 보니까 mover를 벽에 들어가기 전에 위치로 되돌려놓아야 했다. 그래서 direction에 모두 previous 메서드가 생겼다. 한데 다음 번 goStraight를 할 때는 이미 이동했던 기록이 남아있게 되었다. 그래서 매번 goStraight를 할 때마다 마지막 이동 기록을 삭제했다. 그러다보니 board크기가 1일 경우는 이동한 기록이 모두 지워져버리는 것이 아닌가. 조잡하지만 예외 처리를 해주었다.&lt;br /&gt;
&lt;br /&gt;
경계조건이 참 미묘하다는 것을 느꼈다. 시작과 끝을 어떻게 할 것인가? 한참을 헤매다보니 더 나은 방법이 있는데도 찾질 못하는 것 같다.&lt;br /&gt;
&lt;br /&gt;
코드 안에서 헤매기 보다는 정확히 생각을 정리해서 구현해야 한다. 이것 해보고 저것 해보는 사이에 시간이 너무 많이 흘러갔다. 결국에 답은 나왔지만, 이보다 빨리 할 수 있을 것이다.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 import unittest&lt;br /&gt;
 &lt;br /&gt;
 ROW = 0&lt;br /&gt;
 COL = 1&lt;br /&gt;
 &lt;br /&gt;
 class Direction:&lt;br /&gt;
     pass&lt;br /&gt;
 class Down(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW] + 1, coordinate[COL])&lt;br /&gt;
     def previous(self, coordinate):&lt;br /&gt;
         return Up().next( coordinate )&lt;br /&gt;
     &lt;br /&gt;
 class Up( Direction ):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW] - 1, coordinate[COL])&lt;br /&gt;
     def previous(self, coordinate):&lt;br /&gt;
         return Down().next( coordinate )&lt;br /&gt;
 &lt;br /&gt;
 class Right(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW], coordinate[COL] + 1 )&lt;br /&gt;
     def previous(self, coordinate):&lt;br /&gt;
         return Left().next( coordinate )&lt;br /&gt;
 &lt;br /&gt;
 class Left(Direction):&lt;br /&gt;
     def next(self, coordinate):&lt;br /&gt;
         return (coordinate[ROW], coordinate[COL] - 1 )&lt;br /&gt;
     def previous(self, coordinate):&lt;br /&gt;
         return Right().next( coordinate )&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class Board:&lt;br /&gt;
     def __init__(self, initialSize):&lt;br /&gt;
         self.size = initialSize&lt;br /&gt;
         self.setBoundary( 0, self.size )&lt;br /&gt;
     def setBoundary( self, start, end ):&lt;br /&gt;
         self.start = start&lt;br /&gt;
         self.end = end&lt;br /&gt;
     def isWall( self, coordinate ):&lt;br /&gt;
         if ( coordinate[ROW] &amp;amp;lt; self.start ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[ROW] &amp;amp;gt;= self.end ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[COL] &amp;amp;lt; self.start ):&lt;br /&gt;
             return True&lt;br /&gt;
         elif ( coordinate[COL] &amp;amp;gt;= self.end ):&lt;br /&gt;
             return True&lt;br /&gt;
         return False&lt;br /&gt;
     def decreaseBoundary(self, amount):&lt;br /&gt;
         self.setBoundary( self.start+amount, self.end-amount )&lt;br /&gt;
     &lt;br /&gt;
 &lt;br /&gt;
 class Mover:&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.coordinate = (0,0)&lt;br /&gt;
         self.history = []&lt;br /&gt;
     def position(self):&lt;br /&gt;
         return self.coordinate&lt;br /&gt;
     def goStraight(self, direction, board):&lt;br /&gt;
         while ( not board.isWall( self.coordinate ) ):&lt;br /&gt;
             self.history.append( Point( self.coordinate, self.moveCount() ) )&lt;br /&gt;
             self.coordinate = direction.next( self.coordinate )&lt;br /&gt;
         self.coordinate = direction.previous( self.coordinate )&lt;br /&gt;
     def mark(self, point, value):&lt;br /&gt;
         point.value = value&lt;br /&gt;
     def moveCount(self):&lt;br /&gt;
         return len( self.history ) + 1&lt;br /&gt;
     def setPosition(self, coordinate):&lt;br /&gt;
         self.coordinate = coordinate&lt;br /&gt;
     def getHistory(self):&lt;br /&gt;
         return self.history&lt;br /&gt;
     def turnRound(self, board):&lt;br /&gt;
         for direction in [Right(), Down(), Left()]:&lt;br /&gt;
             self.goStraight( direction, board )&lt;br /&gt;
             self.eraseLastMovement()&lt;br /&gt;
         self.goStraight( Up(), board )&lt;br /&gt;
         if ( board.end - board.start != 1 ):&lt;br /&gt;
             self.eraseLastMovement()&lt;br /&gt;
         self.setPosition( self.nextFloor() )&lt;br /&gt;
     def nextFloor(self):&lt;br /&gt;
         return (self.coordinate[ROW]+1, self.coordinate[COL]+1 )&lt;br /&gt;
     def eraseLastMovement(self):&lt;br /&gt;
         self.history.pop()&lt;br /&gt;
     def isFinished( self, board ):&lt;br /&gt;
         return board.size * board.size &amp;amp;lt; self.moveCount()&lt;br /&gt;
     def lastHistory( self ):&lt;br /&gt;
         return self.history[-1]&lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
 class Point:&lt;br /&gt;
     def __init__(self, coordinate, value):&lt;br /&gt;
         self.coordinate = coordinate&lt;br /&gt;
         self.value = value&lt;br /&gt;
 &lt;br /&gt;
 class Array:&lt;br /&gt;
     def __init__(self, size):&lt;br /&gt;
         self.matrix = []&lt;br /&gt;
         for i in range(size):&lt;br /&gt;
             self.matrix.append( [Point((-1,-1),-1)] * size )&lt;br /&gt;
     def get(self, row, col):&lt;br /&gt;
         return self.matrix[row][col]&lt;br /&gt;
     def construct(self, pointList):&lt;br /&gt;
         for p in pointList:&lt;br /&gt;
             self.matrix[p.coordinate[ROW]][p.coordinate[COL]] = p&lt;br /&gt;
     def printValues(self):&lt;br /&gt;
         for row in self.matrix:&lt;br /&gt;
             for point in row:&lt;br /&gt;
                 print point.value,&lt;br /&gt;
                 print &amp;quot;\t&amp;quot;,&lt;br /&gt;
             print&lt;br /&gt;
 &lt;br /&gt;
 class SpiralArrayTest(unittest.TestCase):&lt;br /&gt;
     def setUp(self):&lt;br /&gt;
         self.size = 10&lt;br /&gt;
         self.board = Board(self.size)&lt;br /&gt;
         self.board.setBoundary(start=0, end=self.size)&lt;br /&gt;
         self.mover = Mover()&lt;br /&gt;
         self.array = Array( self.size )&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class DirectionTest(SpiralArrayTest):&lt;br /&gt;
     def testNext(self):&lt;br /&gt;
         self.assertEquals( (1,0), Down().next( (0,0) ) )&lt;br /&gt;
 &lt;br /&gt;
     def testPrevious(self):&lt;br /&gt;
         self.assertEquals( (0,0), Down().previous( (1,0) ) )&lt;br /&gt;
 &lt;br /&gt;
 class BoardTest(SpiralArrayTest):&lt;br /&gt;
     def testIsWall(self):&lt;br /&gt;
         self.assertEquals( False, self.board.isWall( (0,0) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (-1,0) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (0,-1) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (0,self.size) ) )&lt;br /&gt;
         self.assertEquals( True, self.board.isWall( (self.size,0) ) )&lt;br /&gt;
 &lt;br /&gt;
 class MoverTest(SpiralArrayTest):&lt;br /&gt;
     def testGoStraightRight(self):&lt;br /&gt;
         self.mover.goStraight(Right(), self.board)&lt;br /&gt;
         self.assertEquals( (0,self.size-1), self.mover.position() )&lt;br /&gt;
 &lt;br /&gt;
     def testStorePointCoordinate(self):&lt;br /&gt;
         self.mover.goStraight( Down(), self.board )&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( (self.size-1,0), points.pop().coordinate )&lt;br /&gt;
         self.assertEquals( (self.size-2,0), points.pop().coordinate )&lt;br /&gt;
     def testStoreMoveCount(self):&lt;br /&gt;
         self.mover.setPosition((self.size-1, self.size-1))&lt;br /&gt;
         self.mover.goStraight( Left(), self.board )&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( self.size, points.pop().value )&lt;br /&gt;
         self.assertEquals( self.size-1, points.pop().value )&lt;br /&gt;
     def testStoreMovementWhenTurnRoundAndBoudaryNotOne(self):&lt;br /&gt;
         self.mover.setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( (self.size-1) * 4 , len( points ) )&lt;br /&gt;
     def testStoreMovementWhenTurnRoundAndBoudaryOne(self):&lt;br /&gt;
         self.board = Board( initialSize = 1 )&lt;br /&gt;
         self.mover.setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         points = self.mover.getHistory()&lt;br /&gt;
         self.assertEquals( 1 , len( points ) )&lt;br /&gt;
     def testTurnRoundWithBoundary0(self):&lt;br /&gt;
         self.mover.setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.assertEquals( (1,0), self.mover.lastHistory().coordinate )&lt;br /&gt;
     def testIsFinished(self):&lt;br /&gt;
         self.board = Board( initialSize = 1 )&lt;br /&gt;
         self.assertEquals( False, self.mover.isFinished( self.board ) )&lt;br /&gt;
         self.mover.turnRound( self.board )&lt;br /&gt;
         self.assertEquals( True, self.mover.isFinished( self.board ) )&lt;br /&gt;
     def testRun(self):&lt;br /&gt;
         self.board = Board( initialSize = 3 )&lt;br /&gt;
         self.mover.setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.assertEquals( (1,0), self.mover.lastHistory().coordinate )&lt;br /&gt;
         self.assertEquals( (1,1), self.mover.position() )&lt;br /&gt;
 &lt;br /&gt;
         self.board.decreaseBoundary(1)&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.assertEquals( (1,1), self.mover.lastHistory().coordinate )&lt;br /&gt;
 &lt;br /&gt;
 class ArrayTest(SpiralArrayTest):    &lt;br /&gt;
     def testConstructArray(self):&lt;br /&gt;
         self.mover.setPosition( (0,0) )&lt;br /&gt;
         self.mover.turnRound(self.board)&lt;br /&gt;
         self.array.construct( self.mover.getHistory() )&lt;br /&gt;
         self.assertEquals( (0,0), self.array.get(0,0).coordinate )&lt;br /&gt;
         self.assertEquals( (self.size-1, self.size-1),&lt;br /&gt;
                            self.array.get(self.size-1, self.size-1).coordinate )&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
     &lt;br /&gt;
 if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
     unittest.main()&lt;br /&gt;
     inputSize = input()&lt;br /&gt;
     board = Board(inputSize)&lt;br /&gt;
     mover = Mover()&lt;br /&gt;
     mover.setPosition((0,0))&lt;br /&gt;
     while ( not mover.isFinished( board ) ):&lt;br /&gt;
         mover.turnRound(board)&lt;br /&gt;
         board.decreaseBoundary(1)&lt;br /&gt;
     array = Array(inputSize)&lt;br /&gt;
     array.construct(mover.getHistory())&lt;br /&gt;
     array.printValues()&lt;/div&gt;</summary>
		<author><name>imported&gt;Unknown</name></author>
	</entry>
</feed>