Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-05-23

10分でコーディングx2〜リストの破壊的操作篇〜【まとめ】

| 19:53 | 10分でコーディングx2〜リストの破壊的操作篇〜【まとめ】 - わだばLisperになる を含むブックマーク はてなブックマーク - 10分でコーディングx2〜リストの破壊的操作篇〜【まとめ】 - わだばLisperになる

元ネタが10分だったのでそれを踏襲して10分ということにしましたが、どうも10分は短過ぎたようですw

自分の解答は、

(defun nalist-to-plist (alist)
  (do ((a alist (cddr a)))
      ((endp a) alist)
    (rotatef (cdr a) (caar a))
    (rotatef (caar a) (cdar a))
    (rotatef (cdr a) (car a))))
(defun nplist-to-alist (plist)
  (do ((p plist (cdr p)))
      ((endp p) plist)
    (rotatef (cdr p) (car p))
    (rotatef (caar p) (cdar p))
    (rotatef (cdr p) (caar p))))

という感じです。

解答に掛った時間ですが、「そういえば、alist/plistの変換ができるな〜」と考えてからコードが完成するまで2〜30分掛ったと思います、当人が10分で解けてなくて、すいません(笑)

考え方

((foo . 1) (bar . 2)...)→(foo 1 bar 2 ...)

という形で考えると難しいので、セル一つ一つを省略しないで記述したものを元に考えると良いかなと思いました。

'((foo . 1)) ⇒ '((foo . 1) . ())

ということで、更に分かりやすいように

'((1 . 2) . 3)

と置きます。

alist->plistの場合、これが、

'(1 . (2 . 3))

となれば良いわけなので順番は色々ありますが、

  1. ((3 . 2) . 1) ;1と3を交換
  2. ((2 . 3) . 1) ;2と3を交換
  3. (1 . (2 . 3)) ;1と(2 . 3)を交換
  4. 以下、3の指しているコンスでも同様

とすれば良いことになります。

ちなみに交換の方法はCLには色々あります。

rotatefかsetfとvaluesを組み合わせたものが一番分かりやすいかなと個人的には思っています。

;; setf+valuesの場合
(defun nplist-to-alist (plist)
  (mapl (lambda (p)
          (setf (values (cdr p) (car p)) 
                (values (car p) (cdr p))
                
                (values (caar p) (cdar p))
                (values (cdar p) (caar p))
                
                (values (cdr p) (caar p))
                (values (caar p) (cdr p))))
        plist))

交換の部分は、rotatefを駆使すれば1式で書けると思い最初はそれで書いたのですが、意図したように動かないので自分は分割しました。

この件についてはquekさんが探究されています。さすが!