とりとめのないことを書いております。
by tempurature
カテゴリ
全体
プログラミング
scheme
verilog
未分類
以前の記事
2016年 04月
2016年 03月
2016年 02月
2016年 01月
2015年 12月
2015年 11月
2015年 10月
2015年 09月
2015年 08月
2015年 07月
2015年 06月
2015年 03月
お気に入りブログ
PHPで競技プログラミング
メモ帳
最新のトラックバック
ライフログ
検索
タグ
人気ジャンル
ブログパーツ
最新の記事
情報処理技術者試験 お疲れ様..
at 2016-04-17 18:55
基本情報技術者試験 平成27..
at 2016-04-14 04:48
基本情報技術者試験 平成27..
at 2016-04-13 23:03
苦い薬(ハーブ、サプリメント..
at 2016-04-09 14:03
「おバカ度チェックリスト」を..
at 2016-03-24 09:54
外部リンク
ファン
記事ランキング
ブログジャンル
画像一覧
カテゴリ:scheme( 54 )
bash上で (exit) と入力しても、何も起きなかった
そりゃそーかー



[PR]
by tempurature | 2015-11-11 22:57 | scheme
GaucheをWindowsで使う
Gaucheの本家では、WindowsにおいてはGaucheをEmacs環境上で使用することを強く推奨しています。けれども私はEmacsが嫌いです。

以下では私なりのGauche環境を紹介します。

i) Widowsインストーラパッケージ(msi)でGaucheをインストールする
ii) Cygwinをインストールする
iii) .bashrc等に「alias go='gosh -i -I .'」の一行を追加する
iv) Gaucheのソースコードを作成・編集する時は、「notepad <filename>」とCygwinのコマンドラインに入力する
v) Gaucheのソースコードの先頭に必ず「;; -*- coding: shift_jis -*-」を追加する
vi) goshで変な動作になったらすぐ[Ctrl+C]で抜ける

(iv)でnotepadを使うのは、改行コードがCR+LFであることを保証するためです。(i)でCygwin上でGaucheをコンパイルしないのは、それが素人には難しいからです。また、コマンドプロンプト上でgoshを起動しても、日本語が文字化けします。(iii)のおまじないで、Gaucheがracket並に使い勝手が良くなるはずです。

以上です

【2015.11.22 追記】
上記の設定だと、(char-alphabetic? #\あ)が#tになる不具合があります。
Cygwinの代わりにgit Bashで試しても同じでした。

ちなみに、コマンドプロンプトとPowershellでは、(char-alphabetic? #\あ)が#fとなり正しいのですが、ターミナルの文字コードをutf-8にできないのでgoshの文字化けを解消できないです。


[PR]
by tempurature | 2015-11-11 22:48 | scheme
【racket】世界のナベアツのネタをプログラムで再現しました
「プログラミングGauche」という本を中古で購入しました。
今は絶版になっているようです。

その本の、68ページの練習問題に触発されて、世界のナベアツのネタをプログラムで再現してみました。

[ソースコード]

#lang racket

(define (hiragana-exp num)
  (cond ((<= num 10)
         (list-ref '("ぜろ" "いち" "に" "さん" "し" "ご"
                     "ろく" "なな" "はち" "きゅう" "じゅう") num))
        ((<= num 19) (string-append "じゅう" (hiragana-exp (- num 10))))
        ((and (<= num 99) (zero? (remainder num 10)))
         (string-append (hiragana-exp (quotient num 10)) "じゅう"))
        ((<= num 99) (string-append (hiragana-exp (* (quotient num 10) 10))
                                    (hiragana-exp (remainder num 10))))
        ((= num 100) "ひゃく")
        ((and (<= num 999) (zero? (remainder num 100)))
         (string-append (hiragana-exp (quotient num 100)) "ひゃく"))
        ((<= num 999) (string-append (hiragana-exp (* (quotient num 100) 100))
                                     (hiragana-exp (remainder num 100))))
        (#t "たくさん")))

(define hiragana-matrix
  '("あかさたなはまやらわん"
    "いきしちにひみ り  "
    "うくすつぬふむゆる  "
    "えけせてねへめ れ  "
    "おこそとのほもよろ  "))

(define (stressed-hiragana-exp num)
  (let* ((hexp (hiragana-exp num))
         (tail (~a (string-ref hexp (sub1 (string-length hexp))))))
    (string-append
      hexp
      (cond
        ((equal? tail "ん") "っ")
        ((regexp-match tail (list-ref hiragana-matrix 0)) "ぁ")
        ((regexp-match tail (list-ref hiragana-matrix 1)) "ぃ")
        ((regexp-match tail (list-ref hiragana-matrix 2)) "ぅ")
        ((regexp-match tail (list-ref hiragana-matrix 3)) "ぇ")
        ((regexp-match tail (list-ref hiragana-matrix 4)) "ぉ")
        (#t "っ")))))

(define (nabeatsu-function num)
  (or (= (remainder num 3) 0)
      (regexp-match "3" (~a num))))

(define (nabeatsu-print num)
  (if (nabeatsu-function num) (stressed-hiragana-exp num) (~a num)))

[出力例]

> (string-join (map nabeatsu-print (range 1 100)) " ")
"1 2 さんっ 4 5 ろくぅ 7 8 きゅうぅ 10 11 じゅうにぃ じゅうさんっ 14 じゅうごっ 16 17 じゅうはちぃ 19 20 にじゅういちぃ 22 にじゅうさんっ にじゅうしぃ 25 26 にじゅうななぁ 28 29 さんじゅうぅ さんじゅういちぃ さんじゅうにぃ さんじゅうさんっ さんじゅうしぃ さんじゅうごっ さんじゅうろくぅ さんじゅうななぁ さんじゅうはちぃ さんじゅうきゅうぅ 40 41 しじゅうにぃ しじゅうさんっ 44 しじゅうごっ 46 47 しじゅうはちぃ 49 50 ごじゅういちぃ 52 ごじゅうさんっ ごじゅうしぃ 55 56 ごじゅうななぁ 58 59 ろくじゅうぅ 61 62 ろくじゅうさんっ 64 65 ろくじゅうろくぅ 67 68 ろくじゅうきゅうぅ 70 71 ななじゅうにぃ ななじゅうさんっ 74 ななじゅうごっ 76 77 ななじゅうはちぃ 79 80 はちじゅういちぃ 82 はちじゅうさんっ はちじゅうしぃ 85 86 はちじゅうななぁ 88 89 きゅうじゅうぅ 91 92 きゅうじゅうさんっ 94 95 きゅうじゅうろくぅ 97 98 きゅうじゅうきゅうぅ"


[PR]
by tempurature | 2015-11-01 20:40 | scheme
【racket】ソーシャルゲームのAP充電時間を計算するスクリプト
#!/usr/local/bin/racket
#lang racket/base

(require racket/format)

(define ap-unit-time 5) ; in minute

(define (print-usage)
  (map (lambda (str) (printf "~a\n" str))
       '("Usage: ap-charging-time.rkts [current-ap] [max-ap]"
         "Calculates \"AP\" charging time of social games")))

(unless (= (vector-length (current-command-line-arguments)) 2)
        (print-usage)
        (exit 1))
(define current-ap
  (string->number
    (vector-ref (current-command-line-arguments) 0)))
(define max-ap
  (string->number
    (vector-ref (current-command-line-arguments) 1)))
(when (or (not (integer? current-ap))
          (not (integer? max-ap)))
      (print-usage)
      (exit 1))

(define total
  (* (- max-ap current-ap) ap-unit-time))
(define minute 
  (remainder total 60))
(define hour
  (remainder (quotient total 60) 24))
(define day
  (quotient total (* 60 24)))

(define (%02d num)
  (~a #:min-width 2 #:align 'right #:pad-string "0" num))

(printf "rest time: ")
(unless (zero? day) (printf "%d day(s), " day))
(printf (string-append (%02d hour) ":" (%02d minute) "\n"))


[PR]
by tempurature | 2015-10-21 00:27 | scheme
らららラケットプログラミング / Lalala, racket programming!!
ラケットプログラミングをエンジョイするためのロゴが頭にうかびました。これはひどい(笑)

c0364169_03310654.png

[PR]
by tempurature | 2015-10-08 03:33 | scheme
【決定版】どうしてracketは流行らないのか?
一重にライセンス形態に問題があると思います。

Racket : LGPL
Clojure : Eclipse Public License
Gauche : BSD License

LGPLで商業製品をリリースするのはGPLほどではありませんが、あまり良い選択肢とはいえないかもしれません。
(そこら辺の事情は「LGPL 商用」で検索すると詳しく書いてあります)

RacketはグラフィックやWeb系のライブラリが充実しているので、非常に使いやすいですが、これらはLGPLのライブラリを援用しているためと推測できます。したがって、例えばracketのBSD実装をするのは意外にハードルが高いように思います。

なので開発環境が貧弱でもClojureやGaucheがもてはやされるのではないかと考えるのです。


[PR]
by tempurature | 2015-09-28 00:23 | scheme
【racket】Cygwinでracketを実行する方法
1. DrRacketのインストールディレクトリを確認します。

デフォルトでは、C:\Program Files\Racketになっているはずです。

2. Cygwin上の認識名を確認します。

Cygwinでは、C:\は/cygdrive/c/というパスなので、
C:\Program Files\Racketというパスは、/cygdrive/c/Program Files/Racketになります。実際にCygwinのターミナルでDrRacketのパスまでたどってみます。
Program Filesのように半角スペースが入っているディレクトリ名は、シングルスペース(')かダブルスペース(")でくくります。

$ cd /cygdrive/c
$ cd 'Program Files'
$ cd Racket
$ pwd
/cygdrive/c/Program Files/Racket
$ ls
collects          mred-text.exe   plt-r6rs.exe              share
doc               mzc.exe         plt-web-server.exe        slatex.exe
DrRacket.exe      mzpp.exe        Racket Documentation.exe  Slideshow.exe
etc               mzscheme.exe    Racket.exe                swindle.exe
GRacket.exe       mztext.exe      raco.exe                  Uninstall.exe
gracket-text.exe  pdf-slatex.exe  README.txt
include           PLT Games.exe   scribble.exe
lib               plt-r5rs.exe    setup-plt.exe

3. /usr/local/binにRacket.exe, DrRacket.exe, raco.exeのシンボリックリンクを張ります。

$ ln -s '/cygdrive/c/Program Files/Racket/Racket.exe' /usr/local/bin/racket
$ ln -s '/cygdrive/c/Program Files/Racket/DrRacket.exe' /usr/local/bin/drracket
$ ln -s '/cygdrive/c/Program Files/Racket/raco.exe' /usr/local/bin/raco
$ ls /usr/local/bin
drracket racket raco

4. /usr/local/binにパスが通っていることを確認します。

$ perl -e 'if (":$ARGV[0]:" =~ m|:/usr/local/bin/{0,1}:|) {print "OK\n";}' $PATH
OK

手順は以上です。


Cygwinでracketを使うメリットとしては、racketスクリプトがあります。
racketスクリプトは、拡張子が.rktsで、次のようにshebangを書きます。

#!/usr/local/bin/racket

shebangを半角スペースを含むパスに適用するとうまく行かないのですが、上記の方法ではうまく行きます。


[PR]
by tempurature | 2015-09-20 18:30 | scheme
【racket】中居のミになる図書館で紹介されていたソウルナンバーを求める関数
簡単そうなので作ってみました。2時間かかって夜更かしになってしまったので、少し後悔してます。

#lang racket

(define (substring-all str)
  (map (lambda (i) (substring str i (add1 i))) (range (string-length str))))
(define (str-sum str)
  (apply + (map string->number (substring-all str))))
(define (accumulate enough? go-next init)
  (if (enough? init) init (accumulate enough? go-next (go-next init))))

(define (solve-soul-number date)
  (let* ((r (regexp-match #px"([0-9]{4})\\/([0-9]{1,2})\\/([0-9]{1,2})" date))
         (s (apply + (map str-sum (rest r)))))
    (accumulate (lambda (n) (< n 10))
                (lambda (n) (str-sum (number->string n)))
                s)))


[PR]
by tempurature | 2015-09-16 01:06 | scheme
カメとウサギのアルゴリズム、もしくは・・・
Exercise 3.19について他の人の解答を見てみると、メモリ消費量を抑えつつ線形時間で完了するやり方があるということで、うならされました。

私の考えたdepthを使ったやり方は、リストをカントールの証明のように操作する方法ですが、それだとリスト長(もしくは無限ループの大きさ)に対して2乗オーダで計算時間が増えます。

Barry Allisonさんのコードでは「カメとウサギのアルゴリズム」として紹介されていた方法ですが、最初このコードを読んでも何をやっているのかわかりませんでした。

その方法は、リストの先頭から、1歩ずつ進むポインタ(カメ)と2歩ずつ進むポインタ(ウサギ)を同時に動かしてやるやり方なのですが、直感的にはカメとウサギがどんどん離れていくのでうまくいかないように思えます。

しかし、循環リストの構造としては、L = (a1 ... an b1 ... bm b1 ... bm b1 ...)というような構造をしていて、2つのポインタがanより後ろにあれば、ポインタの距離がmの整数倍の条件で一致するという特徴があります。

なので、カメポインタで必ず1歩は進むようにすればとっととanよりも先に進むことができ、カメポインタとウサギポインタの距離を常に離していくことで距離mを同時に探索することもできるということです。アタマいい〜

以下は私がアレンジした「カメとウサギのアルゴリズム」のコードです。
(optional lineの行はあってもなくてもいいです)

(define (cycle? lst)
  (define (go-downstairs walker runner)
    (cond ((null? runner) #f)
          ((null? (cdr runner)) #f)
          ((eq? runner walker) #t)
          ;((eq? (cdr runner) walker) #t) <- optional line ->
          (#t (go-downstairs (cdr walker) (cddr runner)))))
  (and (not (null? lst))
       (not (null? (cdr lst)))
       (go-downstairs lst (cddr lst))))


[PR]
by tempurature | 2015-08-26 00:59 | scheme
SICP Exercise 3.18, 3.19の解答
Exercise 3.18は循環リストを判別せよという問題、Exercise 3.19はメモリを一定以上消費しないようにそれを実装せよという問題でした。

; Exercise 3.18

(define (check-circulation lst)
  (define (get-next tadpole)
    (cond ((null? (cdr tadpole)) #f)
          ((memq (cadr tadpole) (car tadpole)) #t)
          (#t (cons (cons (cadr tadpole) (car tadpole))
                    (cddr tadpole)))))
  (define (iter tadpole)
    (if (pair? tadpole) (iter (get-next tadpole)) tadpole))
  (iter (cons '() lst)))

; Exercise 3.19

(define (find elem lst depth)
  (cond ((<= depth 0) #f)
        ((null? lst) #f)
        ((eq? elem lst) #t)
        (#t (find elem (cdr lst) (- depth 1)))))
(define (infinite-loop? lst)
  (define (go-downstairs lst node depth)
    (cond ((null? node) #f)
          ((find node lst depth) #t)
          (#t (go-downstairs lst (cdr node) (+ depth 1)))))
  (go-downstairs lst lst 0))


[PR]
by tempurature | 2015-08-25 23:15 | scheme