A First Emacs Challenge

Xah Lee has contributed a challenge that serves as an excellent example of one of the types of problems I think we should concentrate on if we start an EmacsGolf site. I like this problem because it is a real problem of the type that Emacs users encounter every day.

Lee has a minor mode, xmsi-mode, that is useful for mathematical input (it's very handy if you do that sort of thing; check it out). Recently, he was refactoring the code and wanted to change lines like

(puthash "■" "□" xmsi-abrvs)
(puthash "□" "■" xmsi-abrvs)
(puthash "●" "○" xmsi-abrvs)
(puthash "○" "●" xmsi-abrvs)
(puthash "◆" "◇" xmsi-abrvs)
(puthash "◇" "◆" xmsi-abrvs)
(puthash "▲" "△" xmsi-abrvs)
(puthash "△" "▲" xmsi-abrvs)
(puthash "◀" "◁" xmsi-abrvs)
(puthash "◁" "◀" xmsi-abrvs)
(puthash "▶" "▷" xmsi-abrvs)
(puthash "▷" "▶" xmsi-abrvs)
(puthash "▼" "▽" xmsi-abrvs)
(puthash "▽" "▼" xmsi-abrvs)
(puthash "★" "☆" xmsi-abrvs)
(puthash "☆" "★" xmsi-abrvs)
(puthash "♠" "♤" xmsi-abrvs)
(puthash "♤" "♠" xmsi-abrvs)
(puthash "♣" "♧" xmsi-abrvs)
(puthash "♧" "♣" xmsi-abrvs)
(puthash "♥" "♡" xmsi-abrvs)
(puthash "♡" "♥" xmsi-abrvs)
(puthash "♦" "♢" xmsi-abrvs)
(puthash "♢" "♦" xmsi-abrvs)

into lines like this

(xmsi-add-cycle ["■" "□"])
(xmsi-add-cycle ["●" "○"])
(xmsi-add-cycle ["◆" "◇"])
(xmsi-add-cycle ["▲" "△"])
(xmsi-add-cycle ["◀" "◁"])
(xmsi-add-cycle ["▶" "▷"])
(xmsi-add-cycle ["▼" "▽"])
(xmsi-add-cycle ["★" "☆"])
(xmsi-add-cycle ["♠" "♤"])
(xmsi-add-cycle ["♣" "♧"])
(xmsi-add-cycle ["♥" "♡"])
(xmsi-add-cycle ["♦" "♢"])

This isn't a hard problem but how efficiently (in terms of keystrokes) can you solve it? You can use anything in core Emacs, ELPA, or any external tool accessed in the usual way from Emacs. As a baseline, I did it in 29 keystrokes without trying too hard. I'm sure many of you can do better. I'll be trying too.

Thanks to Xah Lee for generously donating this challenge rather than posting it himself.

This entry was posted in General and tagged , . Bookmark the permalink.

8 Responses to A First Emacs Challenge

  1. Fuco says:

    Well, I can do it in 24 using smartparens & macro, where I waste 15 keys on typing out "xmsi-add-cycle" (I tried some trickery with copying xmsi-a from the end but I can't do it in any way with less than 6 characters.

    • Fuco says:

      Hehe, using magnar's idea of hippie-expand (SO obvious!) and MC here's mine solution with 17 strokes:

      C-f - forward-char
      s-/ - mc/mark-all-like-this (why do you need er/expand-region here? MC selects the region automatically)
      x
      TAB hippie-expand
      C-i backward-kill-word
      a
      d
      d
      -
      c
      y
      c
      l
      e
      C-2 C-M-] sp-select-next-thing
      [ - wraps the strings in []
      C-u C-M-k sp-kill-sexp -- that this leaves up the space is actually smartparens bug, I just found about it yesterday so it will be fixed :P Then you don't need the C-u so teoretically it's one less.

      19 if you count the prefix as separate stroke.

      • Magnar Sveen says:

        > why do you need er/expand-region here? MC selects the region automatically

        Huh, multiple-cursors is better than even I know. ^^

      • jcs jcs says:

        > MC selects the region automatically

        That doesn't work for me and looking at the code, I don't see how it could because mc/mark-all-like-this throws an error if region-active-p is not t. Do you have Super+/ mapped to mc/mark-all-like-this-dwim? That does work, of course.

        Magnar, do you use mc/mark-all-like-this-dwim as the default (instead of mc/mark-all-like-this)?

        • Fuco says:

          Yes, you're right. I should know since I contributed the sort of proto version of that :/

          Seems like we've both fallen to the same fate with Magnar :D

        • Magnar Sveen says:

          Yes, mc/mark-all-like-this-dwim is pretty much a drop-in replacement for mark-all-like-this. It's pretty nice. :-)

  2. Magnar Sveen says:

    21:

    forward-char
    er/expand-region
    mc/mark-all-like-this
    x
    hippie-expand
    backward-kill-word
    a
    d
    d
    -
    c
    y
    c
    l
    e
    paredit-open-square
    paredit-forward-slurp-sexp
    paredit-forward-slurp-sexp
    paredit-forward-delete
    paredit-forward-up
    paredit-kill

  3. d german says:

    Would one replace-regexp count as one keystroke:

    Meta-X replace-regexp
    (puthash "." "." xmsi-abrvs)Ctrl-Q(puthash "\2" "\1" xmsi-abrvs)
    (xmsi-add-cycle ["\1" "\2"])

    --dmg

Comments are closed.