challenge 与えられた並べ替えを実現するあみだくじの生成

お題#4476を見て思いつきました。

0からn (n>=1) までの数字を任意の順で並べたリストが与えられた時、0からnまでが順に並んだ状態から出発して、与えられたリストの順で結果が得られるようなあみだくじを作成して出力するプログラムを書いてください。

与えられたリストが (3 5 2 4 0 1) の場合、出力の1例を示します:

 0 1 2 3 4 5
 | | |-| |-|
 | |-| |-| |
 |-| |-| | |
 | |-| |-| |
 | | |-| |-|
 | | | |-| |
 3 5 2 4 0 1

一応、制約条件を示しておきます。

  • あみだの横棒は縦棒をまたぐことはできません。常に隣接する縦棒同士の交換となります 。
  • 同じ行に複数の横棒があっても良いですが、ひとつの縦棒の同じ点からふたつ横棒が出ることはありません。

一つのリストに対して複数の解があり得ます。ナイーブな解に飽き足らなければ出力行数をなるべく少なくする解を求める方法を考えてみてください。

Posted feedbacks - Common Lisp

行数減らす工夫は何もしてないのに表示の方が長い……

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
(defun make-amida (list)
  (unless (equal list '(0))
    (let ((n (1- (length list))))
      (nconc (make-amida (remove n list))
             (loop for x from (1- n) downto (position n list) collect x)))))

(defun print-amida (x result)
  (let ((n (1- (length result))))
    (format t "~{~D~^ ~}~&" (loop for x from 0 to n collect x))
    (dolist (i x)
      (let ((str (format nil "~V@{| ~}|" n t)))
        (setf (aref str (+ i i 1)) #\-)
        (write-line str)))
    (format t "~{~D~^ ~}~&" result)))

(let ((list '(3 5 2 4 0 1)))
  (print-amida (make-amida list) list))

Index

Feed

Other

Link

Pathtraq

loading...