Comment detail

文字列で+を表示する (Nested Flatten)

最初にこんなリストを作って,

("   abc    "
 "          "
 "          "
 "abc   abc "
 "          "
 "          "
 "          "
 "          "
 "          "
 "          ")

90°ずつ回転させたのと合わせました。

   abca
   c  b
   b  c
abca  abca
c        b
b        c
acba  acba
   c  b
   b  c
   acba
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(defun rotate (m) (apply #'map 'list #'vector (reverse m)))

(defun merge-line (&rest lines)
  (apply #'map 'string
         (lambda (&rest chars)
           (or (find #\Space chars :test #'char/=)
               #\Space))
         lines))

(defun merge-matrix (&rest matrices)
  (apply #'mapcar #'merge-line matrices))

(defun write-cross (s)
  (let* ((m (let* ((n (length s))
                   (empty (format nil "~V@T~V@T~V@T " n n n))
                   (line1 (format nil "~V@T~A~V@T " n s n))
                   (line2 (format nil "~A~V@T~A " s n s)))
              `(,line1 ,@(make-list (1- n) :initial-element empty)
                ,line2 ,@(make-list (* 2 n) :initial-element empty))))
         (m1 (rotate m))
         (m2 (rotate m1))
         (m3 (rotate m2)))
    (mapc #'write-line (merge-matrix m m1 m2 m3))))
#10105に感銘。Haskellで再現させてみました。
quarterが1/4。
quarterとquarterの上下左右を入れ替えたものの合成がhalf。
rot90halfがhalfを90度回転させたもの。
halfとrot90halfの合成が最終結果。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
doukaku291 s = zipWith (\x y -> zipWith max x y) half rot90Half
  where
    ss n      = replicate n ' '
    len       = length s
    width     = len * 3 + 1
    quartar   = [(ss len) ++ s ++ (ss len) ++ " "] ++
                (replicate (len - 1) $ ss width)   ++
                [s ++ (ss len) ++ s ++ " "]        ++
                replicate (len * 2) (ss width)
    half      = zipWith max quartar $ reverse $ map (\x -> reverse x) quartar
    rot90Half = reverse $ take width $ foldr rot (replicate width []) half
      where rot (c:cs) (r:rs) = (c:r):(rot cs rs)

main = mapM_ putStrLn $ doukaku291 "doukaku"

Index

Feed

Other

Link

Pathtraq

loading...