https://school.programmers.co.kr/learn/courses/30/lessons/68645
한 30분 동안 메모장 열고 계산하다가, 여기에 공식 같은 건 없다는 생각이 든 건 모양이 계속 회전한다는 걸 느꼈을 때쯤이었다.
공식을 포기 못 하고 2차 도전, 사각형 외부는 규칙이 있을지 몰라도 내부로 들어갈수록 고려할 요소가 너무 많았다.
없었음.
타일 지도의 이동처럼 움직이는 건 재미없어서 고려는 안 했는데, 결국 '처음부터 달팽이를 그릴걸...' 이라는 생각이 들었다. 그래도 그냥 그리기는 아쉬워서 조금만 더 생각.
결론은 층을 클래스로 만들어서 숫자를 앞뒤 교대로 숫자를 채우게 만들고, 순서는 스택을 2개 만들어서 넣기로 결정.
class Triple
{
public int index;
public int[] array;
public int first;
public int last;
public bool front;
public Triple(int n)
{
index = n;
array = new int[n];
first = -1;
last = n;
front = true;
}
public int FillStraight(int n)
{
int count = 0;
for (int i = first + 1; i < last; i++)
{
array[i] = n + i - first - 1;
count++;
}
first = last - 1;
return count;
}
public void FillSingle(int n)
{
if (front)
{
first++;
array[first] = n;
front = false;
}
else
{
last--;
array[last] = n;
front = true;
}
}
public bool IsFull()
{
return first + 1 == last;
}
public void WriteArray(ref int[] answer)
{
var myIndex = index * (index - 1) / 2;
for (var i = 0; i < array.Length; i++)
{
answer[myIndex + i] = array[i];
}
}
}
앞에서 공식을 계산했다고 했는데, 시간을 미리 날려버린 덕분에 WriteArray 메소드는 구현하는데 시간이 별로 안걸렸다.
원래는 index 기준으로 정렬해서 정답 배열에 숫자를 한 개씩 쓰려고 했는데 실행 시간이 좀...
public int[] solution(int n)
{
Stack<Triple> box1 = new Stack<Triple>();
Stack<Triple> box2 = new Stack<Triple>();
for (int i = n; i > 0; i--)
{
box1.Push(new Triple(i));
}
int max = n * (n + 1) / 2;
int[] answer = new int[max];
int lastLine = n;
Stack<Triple> fullBox = box1;
Stack<Triple> emptyBox = box2;
for (int i = 1; i < max + 1; i++)
{
if (box1.Count == 0)
{
fullBox = box2;
emptyBox = box1;
}
else if (box2.Count == 0)
{
fullBox = box1;
emptyBox = box2;
}
var temp = fullBox.Pop();
if (temp.front && lastLine == temp.index)
{
i += temp.FillStraight(i) - 1;
lastLine--;
}
else
{
temp.FillSingle(i);
}
if (!temp.IsFull())
{
emptyBox.Push(temp);
}
else
{
temp.WriteArray(ref answer);
}
}
return answer;
}
가장 오래 걸렸던 부분은 해당 층의 제일 밑에 있는 층인지 체크하는 부분. 피곤해서 그런지 자꾸 위로 올라가면서 한 줄을 채우는 걸 고치느라 시간이 좀 걸렸다.
11초나 걸려도 풀었으면 된 게 아닐까.