[C#/Codewars] Snail ํ๊ธฐ (4kyu)
๋งํฌ: https://www.codewars.com/kata/521c2db8ddc89b9b7a0000c1
Codewars์์ 4๊ธ์ธ Snail๋ฌธ์ ๋ฅผ ํ์ด๋ดค๋ค.
4๊ธ ๋ฌธ์ ์ค ๊ฐ์ฅ ์ ๋ช ํ ๋ฌธ์ ์ด๋ฉฐ, ๋์ด๋๋ 4๊ธ ์ค ๋ค์ ์ฌ์ด ํธ์ ์ํ๋ค. (๋ค๋ง ํ์๋ ๊ฝค๋ ํ๊ฒน๊ฒ ํ์๋ค.)
๋ฌธ์ ์ค๋ช :
ํฌ๊ธฐ ๋ถํน์ ์ n*n ์ด์ฐจ์ ๋ฐฐ์ด์ ๋ฐ์ผ๋ฉด, ๊ทธ ๋ฐฐ์ด์ ๋ง์น ๋ฌํฝ์ด ๊ป์ง์ ๋ชจ์๊ณผ ์ ์ฌํ๊ฒ ์๊ณ๋ฐฉํฅ์ผ๋ก ํ์ผ๋ฉฐ ์ผ์๋ก ํด์ง ๋จ์ผ์ฐจ์๋ฐฐ์ด์ ๋ฐํํ๋ ํจ์๋ฅผ ์ง๋ ๋ฌธ์ ์ด๋ค.
Q. int[][]๋ ์ด์ฐจ์ ๋ฐฐ์ด์ด ์๋์์ด~
A.์๋ฐํ ๋ฐ์ง๋ฉด int[,] ์ด์ฐจ์ ๋ฐฐ์ด์ ์๋๋ผ์ .GetLength(1)๊ฐ์ ํจ์๋ ๋ชป์ด๋ค. ๊ทธ ๋์ , ๋ฐฐ์ด์ ๊ธธ์ด๋ฅผ ๊ตฌํ๊ธฐ ์ํด array[0].Length๋ฅผ ์ฐ๋๋ก ํ์.
(array.Length ๋๋ array.GetLength(0)์ ๋น ๋ฐฐ์ด์์๋ 1์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.)
์์:
array = [[1,2,3],
[4,5,6],
[7,8,9]]
snail(array) #=> [1,2,3,6,9,8,7,4,5]
(codewars ์์๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ์๋ค.)
๋ฐ์ ํด๋ฒ์ ๋ณด๊ธฐ ์ ์ ํ๋ฒ ํ์ด๋ณด๊ธธ ๋ฐ๋๋ค.
ํ์์ ์ ๊ทผ:
๋ฌํฝ์ด ๊ป์ง๊ณผ ๊ฐ์ด ํ ์ ์ฉ ์ด๋ํ๋ฉด์ ์์๋ฅผ ํ๋ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์, ์ง๊ด์ ์ผ๋ก ๋ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค. ์ด๋ ๊ฒ ํ๊ณ ๋์ ๋ค๋ฅธ ํ์ด๋ฅผ ๋ณด๋ฉด ํํ+๊ฐํ์ด ๋ณด๋ค ์ธ๊ฒ ์ค๊ธฐ ๋๋ฌธ์ ์ฃผ์ ๋ฐ๋๋ค.
direction = โRโ;
pos = new int[] { 0, 0 };
int length = array[0].Length;
var snailed = new int[length * length];
var map = new bool[length, length];
charํ์ direction์ ์ ์ญ๋ณ์๋ก ์ ์ธํ๋ค. ์์๊ณผ ๋์์ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ๋ฏ๋ก โRโ๋ก ์ด๊ธฐํ ํ๋ค.
pos ๋ํ ์ ์ญ๋ณ์๋ก ์ ์ธํ๋ค. ์์ ์์น๋ ์ผ์ชฝ ์์ด๋ฏ๋ก { 0, 0 }์ผ๋ก ์ด๊ธฐํ ํ๋ค.
int[] snailed๋ ๋ฐํ๋ ๊ฐ์ ๋ด๊ธฐ ์ํ ๋ฐฐ์ด์ด๋ค.
bool[length, length]์ ์ด๋ฏธ ํ์ ์ ๋ก ๋ค์ ์ด๋ํ๋ ์ผ์ด ์๋๋ก ๊ฒ์ฌํ๊ธฐ ์ํด ๋์ ์ฅ์น์ด๋ค.
for (int i = 0; i < length * length; i++)
{
snailed[i] = array[pos[0]][pos[1]];
map[pos[0], pos[1]] = true;
if (!Movable(map, length))
Turn();
Move();
}
๊ฐ์ฅ ์ค์ํ for ๋ฐ๋ณต๋ฌธ. ๋ฐ๋ณต ํ์๋ ๋น์ฐํ ๋ชจ๋ ์์๋ฅผ ๋์์ผ ํ๊ธฐ ๋๋ฌธ์ length * length์ด๋ค.
์ด์ return๋ ์ด๋ช ์ธ snailed์ ํ๋ํ๋ ๊ฐ์ ๋ฃ์ด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋์ด๋ค.
array[][]์ ๊ฐ๊ฐ์ index์ pos[0](x์ขํ)์ pos[1](y์ขํ)๋ฅผ ๋ฃ์ด snailed์ ๋ค์ด๊ฐ ๊ฐ์ ์ง์ ํ๋ค.
map[,]์ ๊ฐ์ ๋ฃ์ ๋ถ๋ถ์ true๋ก ๋ฐ๊ฟ์ฃผ๋ฉฐ, ๋ฃจํ๋ฅผ ํ ๋ฒ ๋ ๋๋ง๋ค ์ค๋ฅธ์ชฝ์ผ๋ก ํ ์นธ์ฉ ์ด๋ํด์ฃผ๋ฉด ๋๋ค.
ํ์ง๋ง ๊ณ์ ์ค๋ฅธ์ชฝ์ผ๋ก๋ง ๊ฐ๋ค๊ฐ๋ ์ฐ๋ฆฌ ์์๋ IndexOutOfRangeException๋ง์ด ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ค. ์ด์ ๋ฐฉ๋ฒ์ ์๋๊ฑธ๊น?
์๋๋ค, ํธ๋์ด ๊ตด์ ๋ค์ด๊ฐ๋ ์ ์ ๋ง ์ฐจ๋ฆฌ๋ฉด ์ด ์ ์๊ณ , ์ด์ฐจ์ ๋ฐฐ์ด ์์ ๋ค์ด๊ฐ๋ Border๋ง ์ ์ค์ ํ๋ฉด ์ด ์ ์๋ค ํ๋ค. ์ ์ ํ ํ์ด๋ฐ์ ๋ฐฉํฅ์ ํ์ด์ค๋ณด์.
bool Movable() ํจ์์์๋ ์์ผ๋ก ์ด๋ํ๋ฉด ์ด๋ฏธ ํ์ ์์์ธ์ง, ๋ญ๋ ๋ฌ์ง์ธ์ง, ์๋๋ฉด ์ด๋ํ ์ ์๋ ์ ์ธ์ง๋ฅผ ๋ถ์ธ๊ฐ์ผ๋ก ์๋ ค์ค๋ค.
public static bool Movable(bool[,] map, int length)
{
bool movable = true;
switch (direction)
{
case โRโ :
if (pos[1] + 1 == length ||
map[pos[0], pos[1] + 1)
movable = false;
break;
โฆ
}
return movable;
}
switch๋ฌธ์ ์ฌ์ฉํด ๊ฐ๋จํ ๋ง๋ค ์ ์๋ค.
direction์ด R์ธ ๊ฒฝ์ฐ ํ์ฌ ์์น์์ ํ ์นธ ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ์ ๋ length์ ๊ฐ์์ง ๋น๊ตํด์ค๋ค. (์ ์ญ ๋ณ์๋ก ์ ์ธํ๊ธฐ ๋๋ฌธ์ ์ธ์๋ก ์ ๋ฌํ ํ์๊ฐ ์๋ค.)
๋ํ, ์ธ์๋ก ์ ๋ฌ๋ฐ์ map์์ ์ค๋ฅธ์ชฝ์ผ๋ก ํ ์นธ ์ด๋ํ ๊ณณ์ ๋ถ์ธ ๊ฐ์ ์ฝ์ด, true๋ฉด ์ด๋ํ ์ ์๊ณ , false๋ฉด ์ด๋ํ ์ ์๋๋ก ํ๋ค.
direction์ด โDโ, โLโ, โUโ์ธ ๊ฒฝ์ฐ์๋ ๋์ผํ๊ฒ ์ฒ๋ฆฌํด์ฃผ๋ฉด ๋๋ค.
์ด์ ํด๋น ํ์ ๋์ ๋ฌํ๊ฑฐ๋ ์ด๋ฏธ ์ง๋์จ ๋ ์ ๋ค์ ๋ฐ์ ์๊ธฐ์ ์ฒํ์ ๋, ์ด๋ํ ์ ์๋์ง ์๋์ง ์ฌ์ ์ ์ ์ ์๋ค.
๊ทธ๋ผ Movable()์ด false๋ฅผ ๋ฐํํ๋ฉด, ๋ฐฉํฅ์ ํ์ด์ค ๋ค ์์ผ๋ก ๋์๊ฐ๋ฉด ๋๋ค.
public static void Turn()
{
switch (direction)
{
case โRโ :
direction = โDโ;
break;
โฆ
}
}
public static void Move()
{
switch (direction)
{
case โRโ :
pos[1]++;
break;
โฆ
}
}
์ด๋ ๊ฒ Turn()๊ณผ Move()ํจ์๋ switch๋ฌธ์ ์ฌ์ฉํด ๊ฐ๋จํ ๋ง๋ค ์ ์์ ๊ฒ์ด๋ค.
for๋ฃจํ๋ฅผ ๋น ์ ธ๋์จ ๋ค, snailed๋ฐฐ์ด์ ๊ทธ๋๋ก ๋ฐํํ ์ ์๋๋ก ๋ชจ๋ ์ค๋น๊ฐ ๋๋ ์ํ์ด๋ค.
์ด๋๋ก ์ ์ถํ๋ฉด ์คํ ์๊ฐ์ ์ฝ 3์ด์ ๋ ๊ฑธ๋ฆฐ๋ค.
Solutions:
Solutions ์ฑ๋์์๋ ๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ์์ ์ ์ฝ๋๋ฅผ ๊ณต์ ํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๋ฌผ๋ก ์ฝ๋๋ฅผ ์ง์ ํด๊ฒฐํ๋ฉด์๋ ๋ง์ ๊ฒ์ ๋ฐฐ์ธ ์ ์์ง๋ง, ๋ค๋ฅธ ์ฌ๋์ ์ฝ๋๋ฅผ ๊ฒํ ํด๋ณด๋ ๊ฒ๋ ์ ๋ง ์ค์ํ๋ค. (์ฌ์ค์ Codewars๋ฅผ ์ด์ฉํ๋ ๊ฐ์ฅ ํฐ ์ด์ โฆ)
๋ค๋ฅธ ์ฌ๋๋ค์ ํ์ด์ ์์ ์ ํ์ด๋ฅผ ๋น๊ตํด๋ณธ ๋ค, ์์ ์ ์คํ๊ฒํฐ ์ฝ๋์๋ ์ ํ ๋ค๋ฅธ ์์ดํ 250 ์ ์ธ์ ํ์ด๋ฅผ ๋ณด๊ณ ๊ฐํ์ ๊ธ์น ๋ชปํ ์ฌ๋๋ค์ด ํด๋น ์ฝ๋๋ฅผ ์ถ์ฒํ ์๋ ์๋ค.
ํ์ด๊ฐ ๊ธฐ๋งํ๊ฒ ์ฐธ์ ํ๋ฉด Clever์ถ๋ฅผ,
ํจ์จ์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋ชจ๋ ์ก์ ์ ์ฌ ํ ์คํธ ์ ์ฉ ์ฝ๋์๋ Best Practices์ถ๋ฅผ ๋ฐ๋๋ค.
Snail Kata์ ํ์ด ์ค Best Practices์ Clever์ ๋ ์ ํ dlcoe์ํ์ด๋ฅผ ํ๋ฒ ๋ณด๋๋ก ํ์.
public static int[] Snail(int[][] array)
{
int l = array[0].Length;
int[] sorted = new int[l * l];
Snail(array, -1, 0, 1, 0, l, 0, sorted);
return sorted;
}
public static void Snail(int[][] array, int x, int y, int dx, int dy, int l, int i, int[] sorted)
{
if (l == 0)
return;
for (int j = 0; j < l; j++)
{
x += dx;
y += dy;
sorted[i++] = array[y][x];
}
Snail(array, x, y, -dy, dx, dy == 0 ? l - 1 : l, i, sorted);
}
๋๋๊ฒ๋ ์ด๊ฒ ์ฝ๋์ ์ ๋ถ์ด๋ค.
ํ ์ค ํ ์ค ๋ฏ์ด๋ณด๋ฉด,
๋จผ์ array์ ๊ธธ์ด๋ฅผ ๊ตฌํ ํ, ๋ฐํํด์ผ ํ๋ ๋ฐฐ์ด์ ํฌ๊ธฐ์ ๋ง๋ int[]๋ฅผ ์ ์ธํ๋ค.
์ฌ๊ธฐ๊น์ง๋ ๋๊ฐ์ง๋ง, recursive๋ฅผ ์ฌ์ฉํด ์์ฃผ ๊ฐ๊ฒฐํ๊ฒ ํ์ด๋๋ค.
(์ฌ๊ธฐ์ ์ ๊น!) Recursive๋?

์ฌ๊ท ํจ์ ๋ผ๊ณ ๋ ํ๋๋ฐ, ์ ํฉํ ๋ฆฌ์ผ์ ๊ณ์ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ด, ํจ์๊ฐ ์๊ธฐ ์์ ์ ํธ์ถํ๋ ํํ๋ฅผ ๋งํ๋ค.
๋ชจ๋ฅด๋ ์ฌ๋ ์์ง๋ง ์๋ฌดํผ
Snail()ํจ์์ array์ int x, y(๊ฐ๊ฐ pos[0]๊ณผ pos[1]์ ์์ํ๋ค.), ๊ทธ๋ฆฌ๊ณ int dx, dy, ๊ธธ์ด๋ฅผ ๋ํ๋ด๋ l๊ณผ sorted[]์ ์ธ๋ฑ์ค ์์น๋ฅผ ์ง์ ํ๋ i, ๋ง์ง๋ง์ผ๋ก ๋ฐฐ์ด sorted๋ฅผ ์ ๋ฌํ๋ค.
Snail()ํจ์์ ๋ค์ด์๋ฉด if (l == 0) return;์ ํตํด empty matrix๋ฅผ ์ก์๋ธ๋ค.
์ดํ ,
for (int j = 0; j < l; j++) ์์๋ x += dx;์ y += dy;๋ฅผ ํตํด ํ์นธ ํ์นธ ์ด๋ํ๋ฉฐ sorted๋ฅผ ์ฑ์ด๋ค.
์ฌ๊ธฐ์์ ์ ๋ฌ๋ฐ์ dx์ dy๋ ๊ฐ๊ฐ 1๊ณผ 0์ผ๋ก, ์ฒ์ ์ด ํจ์๊ฐ ํธ์ถ๋์์ ๋์๋ ์ค๋ฅธ์ชฝ์ผ๋ก๋ง ์์ง์ธ๋ค. ์ด ๋ค์์ด ํต์ฌ์ด๋ค.
Snail(array, x, y, -dy, dx, dy == 0 ? l - 1 : l, i, sorted);
์ด ์ฝ๋์ ์ฒ์ฌ์ฑ์ ์ฟ๋ณผ ์ ์๋ ๋ถ๋ถ์ด๋ค.
์ ๋ฌ๋ฐ์๋ dx์ dy๋ฅผ ์๋ก ๊ต์ฐจ์์ผ dx์ ์๋ฆฌ์ -dy๋ฅผ, dy์ ์๋ฆฌ์ dx๋ฅผ ์ ๋ฌํ๋ค.
๋ค์ ํ๋ฒ ํธ์ถ๋ Snailํจ์๋ ์ด๋ฒ์ dx๊ฐ 0์ด๊ณ , dy๊ฐ -1์ด๊ธฐ ๋๋ฌธ์ ๋ฐ์ผ๋ก๋ง ์์ง์ธ๋ค.
int l์ for๋ฌธ์ ๋ฐ๋ณต ํ์๋ฅผ ์ ํ๋๋ฐ, dy == 0, ์ฆ, ์ค๋ฅธ์ชฝ ๋๋ ์ผ์ชฝ์ผ๋ก ์์ง์ด๋ค๊ฐ ์ด ํจ์๋ฅผ ํธ์ถํ๋ฉด l - 1์ ํตํด ๋ฐ๋ณต ํ์๋ฅผ ์กฐ์ ํ๋ฉฐ ํ์์ ํด๋ฒ์ Movable()ํจ์๋ฅผ ๋์ ํ๋ค. ์์ฃผ ๊ฐ๋จํ ์ผํญ ์กฐ๊ฑด ์ฐ์ฐ์๋ก ๋ง์ด๋ค.
์ด๋ ๊ฒ l == 0์ด ๋๋ฉด ์๊น empty matrix๋ฅผ ๊ฑธ๋ฌ๋๋ ์กฐ๊ฑด๋ฌธ์ ๊ฑธ๋ฆฌ๋ฉฐ ๊ทธ๋๋ก ๋ฐํ๋๋ค.
Snail Kata๋ 4๊ธ๋์ด๋๊ฐ ์๋๊ฒ์ ์๋์ง๋ง ๋ค๋ฅธ Kata์ ๋นํ๋ฉด ๋น๊ต์ ์ฝ๋ค. ์ง๊ด์ ์ธ ํด๋ฒ์ด ์๋ฟ๊ณ , ๊ทธ ํด๋ฒ๋ ๊ตฌํํ๊ธฐ ์ฌ์์ ๋ค์ ์ฝ๊ฒ ๋๊ปด์ง๋ค.
https://www.codewars.com/kata/5c2fd9188e358f301f5f7a7b
Bird Mountain - the river๋ 4๊ธ์ธ ๊ฒ์ ๋ณด๋ฉด Snail์ด ํ์คํ ์ฌ์ด ํธ์ ๋ง๋ค. (๊ทผ๋ฐ ์ ๊ฑด ์ง์ฌ ์ 3๊ธ์ด ์๋์ง ๋ชจ๋ฅด๊ฒ ์)
ํ์ง๋ง ๊ทธ๋ ๋ค๊ณ dlcoe๊ฐ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ด ๊ฒ์ ์๋๋ค. ๊ฐ์ ๋ฐฉ๋ฒ์ recursive๋ฅผ ์ฌ์ฉํด ๋ค๋ฅด๊ฒ ๊ตฌํํ์ ๋ฟ.
๊ฒฐ๋ก : ์ฌ๊ทํจ์๋ฅผ ์ ์ฉํฉ์๋ค.