[emacs] 二分移動

二分移動コマンドを書いてみました。行内を二分探索の要領で移動します。


ctrl+U ctrl+U ctrl+U ctrl+Fとかよく打つ人にお勧めです。


defvarとか使い方よくわかってないのでまずいところあったら教えてくださると嬉しいです。


D

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 二分移動
(defvar binary-move-fence-beginning nil)
(defvar binary-move-fence-end nil)
(defvar binary-move-overlay nil)

(defun binary-move-set-overlay ()
  (if binary-move-overlay
      (move-overlay binary-move-overlay 
                    binary-move-fence-beginning binary-move-fence-end
                    (current-buffer))
    (progn
      (setq binary-move-overlay
            (make-overlay binary-move-fence-beginning 
                          binary-move-fence-end))
      (make-face 'binary-move-face)
      (set-face-background 'binary-move-face "LightSteelBlue1")
    )
    (overlay-put binary-move-overlay 'face 'binary-move-face))
  )

(defun binary-move-forward (arg)
  (interactive "p")
  (while (save-excursion (beginning-of-line) (looking-at "[ \t]*$"))
    (next-line))
  (dotimes (i arg)
    (if (or
         (eq last-command 'binary-move-forward)
         (eq last-command 'binary-move-backward))
        (setq binary-move-fence-beginning (point))
      (progn
        (setq binary-move-fence-beginning (point))
        (setq binary-move-fence-end (line-end-position))))
    (binary-move-set-overlay)
    (goto-char (/ (+ binary-move-fence-beginning 
                     binary-move-fence-end) 2))
    (if (= (1- arg) i) (sit-for 1.0))
    (move-overlay binary-move-overlay (point) (point))
    ))

(defun binary-move-backward (arg)
  (interactive "p")
  (while (save-excursion (beginning-of-line) (looking-at "[ \t]*$"))
    (previous-line)
    (end-of-line))
  (dotimes (i arg)
    (if (or
         (eq last-command 'binary-move-forward)
         (eq last-command 'binary-move-backward))
        (setq binary-move-fence-end (point))
      (progn
        (setq binary-move-fence-beginning (line-beginning-position))
        (setq binary-move-fence-end (point))))
    (binary-move-set-overlay)
    (goto-char (/ (+ binary-move-fence-beginning 
                     binary-move-fence-end) 2))
    (if (= (1- arg) i) (sit-for 1.0))
    (move-overlay binary-move-overlay (point) (point))
    ))

(global-set-key [?\C-\M-,]  'binary-move-backward)
(global-set-key [?\C-\M-.]  'binary-move-forward)

例外

上のやつを上のstd::promiseのように例外に対応させようかと思って
実装に入ったら手が止まった。

template <class T>
catch(T& x) { }

とかできないw


stdではどうやるのかと思ってboost.Promiseのコードのぞいたら
すげえめんどくさそう&アドホックな感じなことしてた。


−−−−− 糸冬 了 −−−−−



−−−−− 再 開 −−−−−

おおここでboost.exceptionを使うのか!
期せずして最近のboostの勉強になってしまっている。

追記

多少本気出してググったら結構あるな。
Futureパターンってやつかな?

0xにもfutureってのあんのね?
でもよく意味がわからなかった
したいことが違うのかな?


……ああやっとわかった
もっとプリミティブな同期関係の話で
スレッド起こすのは自分でやれって話か
俺のしたかったのはだいたいstd::packaged_taskなわけね

暇つぶし

遅延評価のカスタマイズって
言語がサポートすれば簡単にサポートできるはずなのに
なんでそれやってる言語ってみかけないのかね、
なんて思ってたが
最近は私ごときでは
言語オタクとはとても名乗れない状況なので
誰か教えてくれないかななんておもいつつ
C++で実装してみることにした。
(それ自体すでに存在しそうな気もする)


テンプレートパラ−メータへのキャストあたりを
使うと、字面上で普通の変数と区別できなくなってしまうが、
とりあえずそれをやってみる。
クラス名はschemeに習ってpromise。
あとせっかくなので遅延評価じゃなくてスレッドにしてみた。

  #include <boost/thread.hpp>
  #include <iostream>

  template < class T >
  class promise {
   public:
    template < class F >  // T ()
    promise(F f)
        : thread_(boost::bind(
            &stub<F>, boost::ref(value_), f )) {
    }
    ~promise() { thread_.join(); }

    operator T () {
      thread_.join();
      return value_;
    }

   private:
    template < class F >
    static void stub(T& value, F f) {
      value = f();
    }

   private:
    T             value_;
    boost::thread thread_;

  };

int main() {
  promise<int> p([]()->int{ return std::cin.get(); });

  std::cout << (int)p << std::endl;
  
  return 0;
}

まあなんかそれなりに使えそうな気がしないでもない。


キャストだと字面でわからなくて危険なので、forceとかしてみようか。

T force() {
  thread_.join();
  return value_;
}

でも字面が面倒だとlambdaをautoで持つのとどう違うのか、という
疑問が生ずるな。


ならいっそのこともっと手を抜いて

template < class R >
operator R () {
  thread_.join();
  return static_cast<R>(static_cast<T>(value_));
}

とするか。


気が向いたらcopyableにしとくかな。
内部でthread_pool使うようにしたら
TopCoderでmemoization代わりに使ったりできないかな。

Round2で敗退

A,Bのsmall通して1700位位。まあ実力通り。

以前は問題を読んでも
解法の見当がつかないことが多かったが、
今回の大会では解法の見当はつくが実装ができない
感じになった。
今まで実は「書くだけ」問題と
再帰memoization DPで解ける問題しか解けなかったのが、
再帰じゃ難しいDPとBFSの問題も
時間内に書けなくもない感じになってきた。
一応進歩はしている模様。
TopCoderの過去問30問くらいとけば、
Round2勝ち抜き位の水準になりそうかな?
足りない?