어제 deview의 여파인지 오늘은 일도 하기 싫다. 최근에 간단한 문제를 풀면서 스칼라 연습도 하고 있는데 최근 programming in scala 책에 나오는 spiral 문제를 풀었다.
요구사항은 다음과 같다. 앗. 깨진다. 좀 더 확실한 그림을 보고 싶다면 spiral 문제를 보면 된다.
---------+
|
+-----+ |
| | |
| +-+ | |
| | + | |
| | | |
| +---+ |
| |
+-------+
위와 같은 spiral 문제를 어떻게 구현하면 좋을까? 책에서는 이 예를 상속 관련 주제로 활용했는데 나는 그냥 내 멋대로 구현해 봤다. 첨부하는 코드에 지적질 하고 싶은 분들은 마음껏 지적질을...
일단 각 방향을 담당하는 Direction과 이 Direction을 구현하는 클래스들..
trait Direction {
def symbol(): String
def next(): Direction
def difference(): (Int, Int)
}
case class West() extends Direction {
override def symbol() = "-"
override def next() = new North
override def difference() = (0, -1)
}
case class South() extends Direction {
override def symbol(): String = "|"
override def next(): Direction = new West
override def difference() = (1, 0)
}
case class East() extends Direction {
override def symbol(): String = "-"
override def next(): Direction = new South
override def difference() = (0, 1)
}
case class North() extends Direction {
override def symbol(): String = "|"
override def next(): Direction = new East
override def difference() = (-1, 0)
}
다음은 위 Direction을 활용해 spiral 문제 구현하는 코드. 나의 접근 방식은 한번에 sprial을 구현하지 않고 단계를 나눠 구현했다. 성능은 고려하지 않고 일단 문제를 푸는데 집중했다.
- spiral 로직을 구현하면서 1차원 Array에 모든 문자열을 생성함. 즉, 나선형 구조를 1차원 구조로 쭈욱 풀어냈다고 생각하면 됨. 즉, 길이가 4라면 "---+|||+--++"와 같은 형태로 데이터 생성
- 앞에서 생성한 1차원 구조를 출력을 위해 matrix 구조로 변경함.
- 2차원 matrix를 출력함.
위와 같이 3단계로 나뉘어 구현되어 있다.
class Spiral {
def draw(row: Array[String]): Unit = {
row.foreach({
case null => print(" ")
case s => print(s)
})
println("")
}
def drawSpiral(matrix: Array[Array[String]]) {
matrix.foreach(row => draw(row))
}
def spiral(stream: List[String], matrix: Array[Array[String]], position: (Int, Int), direction: Direction): Array[Array[String]] = {
stream match {
case Nil => matrix
case head :: Nil => {
matrix(position._1)(position._2) = head
matrix
}
case "+" :: tail => {
matrix(position._1)(position._2) = "+"
val nextDirection = direction.next()
spiral(tail, matrix, position + nextDirection.difference(), nextDirection)
}
case head :: tail => {
matrix(position._1)(position._2) = head
spiral(tail, matrix, position + direction.difference(), direction)
}
}
}
def createSprialArray(spiral: List[String], length: Int, direction: Direction): List[String] = {
if (length == 0) spiral
else {
val newSpiral = spiral ::: goDirection(length, direction)
createSprialArray(newSpiral, length - 1, direction.next())
}
}
def goDirection(length: Int, direction:Direction) = {
(1 to length).map({
case i if (i == length) => "+"
case _ => direction.symbol()
}).toList
}
implicit class TuppleAdd(t: (Int, Int)) {
def +(p: (Int, Int)) = (p._1 + t._1, p._2 + t._2)
}
}
0개의 의견 from FB
0개의 의견 from SLiPP
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.