ラベル Gauche の投稿を表示しています。 すべての投稿を表示
ラベル Gauche の投稿を表示しています。 すべての投稿を表示

2014/08/04

gaucheでワンライナー

簡単な数値計算をするときはbcコマンドよりgoshを使うことが多い。

% gosh -e '(print (+ 1 1))' -E exit

なので、こういうコマンドを用意している。

#!/bin/sh
gosh -e "(print $1)" -E exit

~/binにgでシンボリックリンクを張って使っている。

% g '(+ 1 1)'

状態を持ちたかったり、少し複雑な計算をする時は、rlwrap gosh。

gaucheでワンライナーについて同僚と話題になった時、下記の様にbeginで囲って書いていたそうなのでメモがてら。

% gosh -e '(begin (print (+ 1 1))(exit))'

2013/11/14

transpose コマンド(tsv/csvの行列転置)

行列転置したいことは結構あるのに、shellでやろうと思うとちょっと面倒くさい。普段はExcelで「形式を指定して貼り付け」しているけど悔しい。

ので、簡単なコマンドにした。以前作ったcsv2sqlをコピってちょっと書き換えただけ。

ソースはこちら。

2013/08/03

複数のTwitterアカウントに連投するアレ

Gaucheスクリプト。ネタ元はこちら。

Gauche-net-twitterがTwitterのapi v1.1に対応してないっぽくて間に合わんなーと思ったら

対応してるのがあった。

で、スクリプトの使い方は、consumer-keyなんかを書いたファイルを用意してコマンドを実行。それぞれのtweetは別スレッドで投稿されます。

% ./tweet-bals-batch-balk.scm ばるす > bals.log

結果はこんな感じでわかる。

% cat bals.log | grep done | awk '{print $1}'| sort | uniq -c

合計はこれで。

% cat bals.log | grep done | awk '{print $1}'| sort | uniq -c | awk '{ total+= $1}END{print total}'

コマンド名が長いのでシンボリックリンクを作成した。

% ln -s `realpath ./tweet-bals-batch-balk.scm` ~/bin/bals
% bals ばるす > bals.log

詳しくはでたらめ英語なhelpをご覧ください。

% bals -h
Usage: bals [option ...] message
  h|help     : Show this help
  n|number   : Number of continuous tweets (default:endress)
  k|key-file : The path of the file for which have listed the Consumer-key and Access-token
                 ex) twitter-id1 consumer-key1 consumer-secret1 access-token1 access-token-secret1
                     twitter-id2 consumer-key2 consumer-secret2 access-token2 access-token-secret2
                     ...
                     twitter-idn consumer-keyn consumer-secretn access-tokenn access-token-secretn
                 (default: ~/.tbbbrc)
  i|interval :Interval (default: 0.1)
  s|suffix   :Message suffix (default: !)
  d|debug    :Debug mode. Print message to console, Twitter not update

ソースはこちら。

2013/07/26

CygwinでGaucheのHEADを./DIST genするとコケるのでubuntuで./DIST tgzしてる

タイトルが全てだ。autotools周りとm4のバージョンの関係でコケてるっぽい。調べたけど解決できなくて諦めてる。

2013/07/10

Re: 僕と契約してLisperになってよ!-Gaucheの開発環境を整えよう-

Vim派であれば、またはEmacsもVimも嫌いなら。

Vim派なら

EmacsもVimも嫌い

EmacsもVimもSublime Text 2も嫌いなら

Gauche本体とrlwrapを入れるだけでも十分書ける。

  1. 好きなエディタでGaucheのコードを書く。
  2. shellでgoshに書いたコードのファイルを渡す。

hoge.scm

#!/usr/local/bin/gosh
(print "Hello, world !!")
% gosh hoge.scm

または

  1. 好きなエディタでGaucheのコードを書く。
  2. 先頭行に #!/usr/local/bin/gosh などとgoshのパスを書く。
  3. 実行できるようにpermissionを設定する。
% sudo chmod 755 ./hoge.scm
% ./hoge.scm

といった感じ。

rlwrapについては、サンプルを動かしたり、コード片の実行結果を確かめたりするのに便利。rlwrapを使うとgoshのreplでC-pとかC-nとかC-aとかC-eとかShellのやEmacsで慣れ親しんだキーが使えます。プロンプトに色をつけたり。

% rlwrap gosh

-pオプションでプロンプトに色がつくのでaliasにしとくといいかも

% rlwrap -pCYAN

ubuntuであれば

% sudo apt-get install rlwrap

でインストールできます。

Emacs

一応Emacsのことも。

余談

自分は、SchemeやLispつまりS式を書くときはEmacsを使います。その理由はEmacs標準のC-p、C-n、C-a、C-e、C-kなどのキーバインド以外に、C-M-tとかC-M-f、C-M-b、C-M-u、C-M-d、M-(、C-x r、C-xC-eなどのS式用のコマンドが便利過ぎるからです。これがVimにあったらVimに完全に移行するのになあ。今はS式以外ではVim、S式を書くのとorg書式の文章を書くときにEmacs。両方とも使ってる。でもVisual StudioもChromeもVimキーバインド。

完全に引きこもる覚悟があればEmacsはすごくいいけど、Shellを拠点にしているのであればEmacsは大げさで邪魔なことが多い。起動遅いし(serverあるけどさ)。CTRLキー押しっぱなしでの移動はtypoが多くなるし。Vimだとそういう心配がなくて、なんというかストレスが少ない。Emacsでも閲覧専用のViewモードでVimキーバインドを設定しているけど、やっぱり本家Vimには負ける。

CSVをSQL文に変換する

以前、必要だったのでザックリ書いたスクリプトだけど、便利だったんで結構使用頻度が高い。使うたびに修正したり機能追加されてる。あんまりちゃんとしたスクリプトでもないけど重宝してる。こういうのって普通はExcelとかで生成したりするもんなんだろうか?昔いた会社ではExcelで生成してたなあ。あれはあれで慣れれば便利なのかもしれん。慣れたくないけどな。

SQLつながりだけど、プログラマのためのSQL第4版が出てるんですね。ちょっと読んでみたい。第2版だったかなー、本屋で数時間立ち読m(ゲフンゲフン

2013/07/06

Gaucheで各種ソートアルゴリズム

ソートアルゴリズムって、ふざけたもの含めて結構あるんだなー。ふざけてる系がすごく面白い。ボゴソートとかボゾソートとかパーミューテーションソートとか(笑)あとは基数ソート、ビーズズートなんかのバケツっぽいのが好きだなあ。スパゲティソートもいいなあ(w
Wikipediaにあったソート。ソートじゃないのも入ってるかも。

Gauche

Gaucheで書いてみたのが、今んとこ以下のもの。
気が向いたらsortカテゴリで追加していこうかな。
ところでGaucheのsortはイントロソートの親戚なのかな?
Gaucheの組み込みの(Cで実装された)ソートはデフォルトではQuick Sortで始めて、 再帰の深さが ceiling(2*log(N)) を越えた時にHeap Sortにスイッチするように してる。

参考



「リストをn個ずつのサブリストに分割 (Python)」をGaucheで

Gaucheにはそのものズバリなslicesという手続きがある。
(slices '(a b c d e f g) 3)
  ⇒ ((a b c) (d e f) (g))
(slices '(a b c d e f g) 3 #t 'z)
  ⇒ ((a b c) (d e f) (g z z))
で、それは置いといて、Pythonのzip(*[iter(s)]*n)ってのは、n個のiteraterを作ってzipしてるってことだと思う(python知らね)。
Gaucheだとgeneratorを使って実現できるんじゃないかな。Gaucheにもzip手続きはあるけど、gzipはない。gzipなしで書くとこんな感じのことかな。
(use gauche.generator)
(generator->list (apply gmap list (make-list 3 (giota 15))))
;; => ((0 1 2) (3 4 5) (6 7 8) (9 10 11) (12 13 14))
gzipを定義するとしたらこんなんでいいのかな。
(use gauche.generator)

(define (gzip . list-of-list)
  (apply gmap list list-of-list))

(generator->list (apply gzip (make-list 3 (giota 15))))
;; => ((0 1 2) (3 4 5) (6 7 8) (9 10 11) (12 13 14))

Gaucheでstrand sort

その他のソート

ソース

(define (strand-sort ls)
  (define (merge ls1 ls2)
    (let rec ((ls1 ls1)(ls2 ls2)(acc '()))
      (cond ((null? ls1)
             (reverse (append (reverse ls2) acc)))
            ((null? ls2)
             (reverse (append (reverse ls1) acc)))
            ((< (car ls1)(car ls2))
             (rec (cdr ls1) ls2 (cons (car ls1) acc)))
            (else (rec ls1 (cdr ls2)(cons (car ls2) acc))))))
  (define (filter-sorted-elements ls)
    (if (null? ls)
        '()
        (let rec ((ls (cdr ls))(sorted (list (car ls)))(acc '()))
          (if (null? ls)
              (values (reverse sorted)
                      (reverse acc))
              (let1 sorted? (< (car sorted)(car ls))
                (rec (cdr ls)
                     (if sorted?
                         (cons (car ls)
                               sorted)
                         sorted)
                     (if sorted?
                         acc
                         (cons (car ls) acc))))))))
  ;; body
  (let rec ((ls ls)(acc '()))
    (if (null? ls)
        acc
        (receive (sorted rest)
            (filter-sorted-elements ls)
          (rec rest (merge sorted acc))))))


(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test strand-sort 5)
; length = 100
;(time (sorter ls))
; real   0.000
; user   0.000
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   0.005
; user   0.000
; sys    0.000

; length = 10000
;(time (sorter ls))
; real   0.215
; user   0.210
; sys    0.010

; length = 100000
;(time (sorter ls))
; real   6.727
; user   6.710
; sys    0.000

; length = 1000000
;(time (sorter ls))
; real 205.260
; user 204.550
; sys    0.100


Gaucheでbogo sort

これはsleep sortを見て以来の衝撃だな・・・。

その他のソート

ソース

(use gauche.sequence)

(define (bogo-sort ls)
  (if (apply < ls)
      ls
      (bogo-sort (shuffle ls))))


(define data-5 (shuffle (iota 5)))
(define data-10 (shuffle (iota 10)))
(define data-15 (shuffle (iota 15)))

(time (bogo-sort data-5))
;(time (bogo-sort data-5))
; real   0.001
; user   0.000
; sys    0.000

(time (bogo-sort data-10))
;(time (bogo-sort data-10))
; real  12.053
; user  12.010
; sys    0.000




Gaucheでmerge sort

その他のソート

ソース

(use srfi-1)
(define (merge-sort ls)
  (define (merge ls1 ls2)
    (let rec ((ls1 ls1)(ls2 ls2)(acc '()))
      (cond ((null? ls1)
             (reverse (append (reverse ls2) acc)))
            ((null? ls2)
             (reverse (append (reverse ls1) acc)))
            ((< (car ls1)(car ls2))
             (rec (cdr ls1) ls2 (cons (car ls1) acc)))
            (else (rec ls1 (cdr ls2)(cons (car ls2) acc))))))
  (if (or (null? ls)
          (null? (cdr ls)))
      ls
      (let1 split-index (quotient (length ls) 2)
        (receive (head tail)
            (split-at ls split-index)
          (merge (merge-sort head)
                 (merge-sort tail))))))



(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test merge-sort 6)


; length = 100
;(time (sorter ls))
; real   0.000
; user   0.000
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   0.002
; user   0.010
; sys    0.000

; length = 10000
;(time (sorter ls))
; real   0.025
; user   0.030
; sys    0.000

; length = 100000
;(time (sorter ls))
; real   0.288
; user   0.280
; sys    0.000

; length = 1000000
;(time (sorter ls))
; real   3.422
; user   3.370
; sys    0.030

; length = 10000000
;(time (sorter ls))
; real  40.993
; user  40.620
; sys    0.240


Gaucheでselection sort

その他のソート

ソース

(use srfi-43)
(define (selection-sort ls)
  (define (vector-min-index vect start-index)
    (do ((i start-index (+ i 1))
         (min-value +inf.0)
         (min-index 0))
        ((= i (vector-length vect))(values min-index min-value))
      (when (< (vector-ref vect i) min-value)
        (set! min-value (vector-ref vect i))
        (set! min-index i))))
  ;; body
  (do ((i 0 (+ i 1))
       (vect (list->vector ls)))
      ((= i (length ls))(vector->list vect))
    (vector-swap! vect i (vector-min-index vect i))))


(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test selection-sort 4)
; length = 100
;(time (sorter ls))
; real   0.001
; user   0.000
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   0.030
; user   0.030
; sys    0.000

; length = 10000
;(time (sorter ls))
; real   2.614
; user   2.610
; sys    0.000

; length = 100000
;(time (sorter ls))
; real 255.403
; user 254.710
; sys    0.020



Gaucheでbozo sort

これもボゴソートと同じ類か(笑)

その他のソート

ソース

(use srfi-43)
(use srfi-27)

(define (bozo-sort ls)
  (random-source-randomize! default-random-source)
  (let ((vect (list->vector ls))
        (len (length ls)))
    (until (apply < (vector->list vect))
      (vector-swap! vect
                    (random-integer len)
                    (random-integer len)))
    (vector->list vect)))


(use gauche.sequence)

(dotimes (10)
  (let1 data (shuffle (iota 10))
    (time (bozo-sort data))
    (print)))

;(time (bozo-sort data))
; real  30.852
; user  30.740
; sys    0.000

;(time (bozo-sort data))
; real   0.862
; user   0.860
; sys    0.000

;(time (bozo-sort data))
; real   5.286
; user   5.280
; sys    0.000

;(time (bozo-sort data))
; real   0.598
; user   0.600
; sys    0.000

;(time (bozo-sort data))
; real   2.561
; user   2.560
; sys    0.000

;(time (bozo-sort data))
; real   4.554
; user   4.540
; sys    0.000

;(time (bozo-sort data))
; real   4.434
; user   4.420
; sys    0.000

;(time (bozo-sort data))
; real  12.168
; user  12.130
; sys    0.000

;(time (bozo-sort data))
; real  11.710
; user  11.670
; sys    0.000

;(time (bozo-sort data))
; real  20.846
; user  20.790
; sys    0.000



Gaucheでstooge sort

その他のソート

ソース

(use srfi-43)

(define (stooge-sort ls)
  (let1 vect (list->vector ls)
    (let rec ((head 0)(tail (- (vector-length vect) 1)))
      (when (< (vector-ref vect tail)
               (vector-ref vect head))
        (vector-swap! vect head tail))
      (when (<= 3 (+ (- tail head) 1))
        (let1 index-of-1/3 (quotient (+ (- tail head) 1) 3)
          (rec head (- tail index-of-1/3))
          (rec (+ head index-of-1/3) tail)
          (rec head (- tail index-of-1/3))))
      vect)))

(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test stooge-sort 2)

; length = 100
;(time (sorter ls))
; real   0.031
; user   0.030
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   7.330
; user   7.310
; sys    0.000


Gaucheでbead sort(ビーズソート)

これすごく面白かった。rosetta codeのracketのソースを参考にしたんだけど、そのコードに出てくるcolumnって手続きが目からウロコだった。これはビーズを通したヒモを立てることそのものだ。かっこいい。自分で書く時には末尾再帰にして名前もbead-downにした。

ここの図解がわかりやすい。

その他のソート

ソース

(define (bead-sort ls)
  (define (bead-down ls)
    (let rec ((ls (remove null? ls))(acc '()))
      (if (null? ls)
          (reverse acc)
          (rec (remove null? (map cdr ls))
               (cons (map car ls) acc)))))
  ;; body
  (map length (bead-down (bead-down (map (cut make-list <> 1) ls)))))



(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test bead-sort 3)

; length = 100
;(time (sorter ls))
; real   0.004
; user   0.000
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   0.406
; user   0.410
; sys    0.000

; length = 10000
;(time (sorter ls))
; real  49.590
; user  47.500
; sys    1.380


Gaucheでpermutation sort

その他のソート

ソース

(use util.combinations)

(define (permutation-sort ls)
  (if (or (null? ls)
          (null? (cdr ls)))
      ls
      (let rec ((candidates (permutations* ls)))
        (if (apply <= (car candidates))
            (car candidates)
            (rec (cdr candidates))))))


(use gauche.sequence)
(dotimes (i 11)
  (let1 data (shuffle (iota i))
    (time (permutation-sort data))
    (print)))


;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.000
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.002
; user   0.000
; sys    0.000

;(time (permutation-sort data))
; real   0.011
; user   0.010
; sys    0.000

;(time (permutation-sort data))
; real   0.084
; user   0.080
; sys    0.000

;(time (permutation-sort data))
; real   0.760
; user   0.750
; sys    0.010

;(time (permutation-sort data))
; real  10.210
; user  10.180
; sys    0.000


2013/07/05

Gaucheでquick sort

自分も書いてみた。

書いたといっても、検索して出てきたshiroさんが書いたクイックソートのコードを参考にした。match使ってないだけ。

その他のソート

ソース

(use srfi-1)

(define (quick-sort ls)
  (if (null? ls)
      '()
      (receive (ws ys)
          (partition (pa$ > (car ls))(cdr ls))
        (append (quick-sort ws)
                (list (car ls))
                (quick-sort ys)))))


(use gauche.sequence)
(define (test sorter n)
  (for-each (^i (let1 ls (shuffle (iota (expt 10 i)))
                  (print "; length = " (expt 10 i))
                  (time (sorter ls))
                  (print)))
            (iota n 2)))

(test quick-sort 6)
; length = 100
;(time (sorter ls))
; real   0.001
; user   0.000
; sys    0.000

; length = 1000
;(time (sorter ls))
; real   0.004
; user   0.000
; sys    0.010

; length = 10000
;(time (sorter ls))
; real   0.060
; user   0.060
; sys    0.000

; length = 100000
;(time (sorter ls))
; real   0.737
; user   0.730
; sys    0.000

; length = 1000000
;(time (sorter ls))
; real   9.191
; user   9.110
; sys    0.050

; length = 10000000
;(time (sorter ls))
; real 124.532
; user 123.700
; sys    0.450



2013/06/23

ライフゲーム

以前も何度か書いたことがある。

以前書いたやつはすべてのセルを何度もなめてた。プログラミング・セミナーでは生きてるセルだけに注目する方法が載ってたので、それっぽいのを書いてみた。

ソースはこちら。

左の終端は右の終端と、上の終端は下の終端とつながるようにした。こういうのをトーラスと言うんですってね。

ところで、こういう↓マジキチレベルのライフゲーム

ハッシュライフってやつなのかな?

アルゴリズムの筋がよく了解され、確かに素晴らしいとわかっていても、つまらない字句の誤りでなんとなく全体の信用が落ちるから怖い。プログラミング・セミナー P.175

2013/06/22

Re: Unicodeで遊ぶ

Unicodeには、Ⓐ、ⓐなどといったマル付きの英文字があるみたいなので、英文字列を入力するとマル付き文字に変換する簡単なスクリプトを作ってみました。
というのを見かけたので、試しにGaucheで。