Spiral Array

문제는 다음과 같다:

6 6

  0   1   2   3   4   5
 19  20  21  22  23   6
 18  31  32  33  24   7
 17  30  35  34  25   8
 16  29  28  27  26   9
 15  14  13  12  11  10

위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

2개의 풀이가 있습니다.

Clojure 로 작성하였습니다.

accumulator 형태의 재귀함수입니다.

(defn spiral
  [x y]
  (let [vs (range (* x y))
        walk {:right [1 0]
              :down  [0 1]
              :left  [-1 0]
              :up    [0 -1]}
        turn {:right :down
              :down  :left
              :left  :up
              :up    :right}
        vertical? #{:up :down}
        table (into
                {}
                (loop [v (first vs)
                       vs (rest vs)
                       loc [0 0]
                       way :right
                       to-go (dec x)
                       cols (dec x)
                       rows (- y 2)
                       acc []]
                  (cond (empty? vs) (conj acc [loc v])
                        (zero? to-go) (recur (first vs)
                                             (rest vs)
                                             (map + loc (walk (turn way)))
                                             (turn way)
                                             (if (vertical? way) cols rows)
                                             (if (vertical? way) cols (dec cols))
                                             (if (vertical? way) (dec rows) rows)
                                             (conj acc {loc v}))
                        true (recur (first vs)
                                    (rest vs)
                                    (map + loc (walk way))
                                    way
                                    (dec to-go)
                                    cols
                                    rows
                                    (conj acc [loc v])))))]
    (doseq [y (range y)]
      (doseq [x (range x)]
        (print (format "%4d" (table [x y]))))
      (println))))
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Common Lisp 입니다. 배열 다루는 것도 어렵네요 ㅜ 포맷팅 출력 아직 몰라서 REPL에서 보여주는 배열 값으로 확인을 했습니다;

(defun array-slice (arr row)
  "http://stackoverflow.com/a/12327524"
  (make-array (array-dimension arr 1) 
              :displaced-to arr 
              :displaced-index-offset (* row (array-dimension arr 1))))

(defun spiral-array (N)
  (let ((data (make-array `(,N ,N) :initial-element 0))
        (x 0)
        (y 0)
        (counter 0))
    (labels ((move-horizontal (step amount)
                              (loop for i from 1 to amount
                                    do
                                    (setf x (+ x step))
                                    (setf counter (1+ counter))
                                    (setf (aref data y x) counter)))
             (move-vertical (step amount)
                            (loop for i from 1 to amount
                                  do
                                  (setf y (+ y step))
                                  (setf counter (1+ counter))
                                  (setf (aref data y x) counter)))
             (left (amount)
                   (move-horizontal -1 amount))

             (right (amount)
                    (move-horizontal +1 amount))

             (up (amount)
                 (move-vertical -1 amount))

             (down (amount)
                   (move-vertical +1 amount))
             (ready-next-turn ()
                              (setf x (1+ x))
                              (setf counter (1+ counter))
                              (setf (aref data y x) counter)))
            ;; start spinning
            (loop for n from (1- N) downto 1 by 2
                  do
                  (right n)
                  (down n)
                  (left n)

                  (when (> n 1)
                    (up (1- n))
                    (ready-next-turn))))
    ;; print array
    (loop for row from 0 to (1- (array-dimension data 1)) do
      (print (array-slice data row)))))

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 146
기 타 x 17
java x 31
cpp x 35
python x 45
lisp x 2
ruby x 2
cs x 6
scala x 3
clojure x 1
objectivec x 1
go x 1
delphi x 1
javascript x 1