mokeheheのScheme日記

ツッコミ、添削大歓迎です。いろいろ教えてください。

2007-11-24

[] LEDcounter

anarchy golf - LED counterを解く

(use srfi-1)

; LEDデータ
(define LEDData
  '((" _ "
     "| |"
     "|_|")
    ("   "
     "  |"
     "  |")
    (" _ "
     " _|"
     "|_ ")
    (" _ "
     " _|"
     " _|")
    ("   "
     "|_|"
     "  |")
    (" _ "
     "|_ "
     " _|")
    (" _ "
     "|_ "
     "|_|")
    (" _ "
     "  |"
     "  |")
    (" _ "
     "|_|"
     "|_|")
    (" _ "
     "|_|"
     "  |")
    (" _ "
     "|_|"
     "| |")
    ("   "
     "|_ "
     "|_|")
    (" _ "
     "|  "
     "|_ ")
    ("   "
     " _|"
     "|_|")
    (" _ "
     "|_ "
     "|_ ")
    (" _ "
     "|_ "
     "|  ")))

; 数値を2桁の16進数で出力
(define (print-LED2 i)
        (for-each print
                  (ref LEDData (quotient i 16))
                  (ref LEDData (remainder i 16))))

; エントリ
(dotimes (x 256)
  (print-LED2 x))

[] echo

anarchy golf - echoを解く。以下、ダメ回答

(port-for-each
 print
 (lambda () (read-line (current-input-port) #t)))
  • echoごときにこの長さ…!
  • 一見うまく動いてる風、だけど
  • print で出力するのはいいのか?
  • read-line
    • 改行が削除されてしまうので、ファイルの最後とかで改行があったかなかったか分からない。
    • SJISの日本語を使ってるファイルとか食わせるとエラーが出るので、3番目の引数に #t を渡す
  • ググッても案外回答がみあたらない
  • port-for-each

[] xyzzyscmの編集

エディタxyzzyを使っているんだけど、拡張子が .l じゃなくて .scm だと lispモードになってくれない。以下

(push '("\\.scm$" . lisp-mode) *auto-mode-alist*)

を追加すれば拡張子で判別してくれる。

で、lispモードになってくれたのはいいが、インデントにタブが使われてしまう。以下

(setq *lisp-indent-tabs-mode* nil)

を追加すればスペースだけになる。

goshの使い勝手に慣れない

Gaucheインタラクティブ環境goshの使い勝手にどうも慣れない。

  • 一度エラーが出るとどうやって復旧させるのかわからないので、いったん抜けてやり直してる
  • ヒストリを出すつもりで上を押すとフリーカーソルになっていて、エラーが出て死ぬ
  • プログラムバグってるとファイルを確保しっぱなしになるときがある
  • exitしても死なないときがある

みんなemacs上からしか使わないんですかね。

[] httpから取得

anarchy golf - example_comを解いてみる。HTTPからの取得はHTTPでGET Schemeでどう書く?orgをモロ参照してできた。

(use rfc.uri)
(use rfc.http)

; uri-parse が分解してしまったpathとqueryとfragmentをつなげる
(define (uri-path path query fragment)
        (string-append path
                       (if query
                           (string-append "?" query)
                         "")
                       (if fragment
                           (string-append "#" fragment)
                         "")))

; uri を http-get して本文を返す
(define (get-http-text uri)
        (receive (scheme auth host port path query fragment)
                 (uri-parse uri)
                 (values-ref (http-get host
                                       (uri-path path query fragment))
                             2)))

(display
 (get-http-text
  (read-line (current-input-port))))
  • uri-parseを呼び出すと多値で返ってくるので、receiveで受け取って処理。メンドイ。
  • 「?hoge=fuga」とかのクエリ文字の「?」と、アンカー「#name」の「#」が削られてしまうので再構築。削らなければ単に結合するだけですむのに、なんか微妙にメンドイ。

[] Summation

anarchy golf - Summationを解く。

(use srfi-1)

(define (sum ls)
        (reduce + 0 ls))

(define (atob a b)
        (if (> a b)
            ()
          (iota (+ b (- a) 1) a)))

(port-for-each (lambda (n)
                 (if (= n 0)
                     (exit)
                   (print (sum (atob 0 n)))))
               read)
  • シンボルの負の数って -a と直接書けなくて、(- a) としないといけないんでしょうか。
    • 数値なら直接 -1 と書ける。シンボルだと「-a」の一続きがシンボルとみなされてしまう。
    • Lispは - に与える引数が1個のときは引数の符号反転した値、2個以上のときは1個目の引数から残りの引数を引いた値になるんですね。
  • reduce
    • reduceはfoldの特別版、初期値が使われるのはリストが空のときだけ
    • Haskellのなごりで sum → reduce と思ってしまったけど、わざわざ reduce を使わなくても (apply + ls) で十分だった…

[] FizzBuzz

Haskellの時に思ったけど、言語を覚えるにはgolfが一番!

anarchy golf - FizzBuzzを解く

(use srfi-1)

(define (fizzbuzz x)
        (cond ((zero? (modulo x 15)) "FizzBuzz")
              ((zero? (modulo x 3)) "Fizz")
              ((zero? (modulo x 5)) "Buzz")
              (else x)))

(for-each print
          (map fizzbuzz (iota 100 1)))

Schemeはじめました

Gaucheインストールしました。ちょっとずつやってきます。

以前SICPを読もうとして、2章の途中で挫折経験あり。

トラックバック - http://sicp.g.hatena.ne.jp/mokehehe/20071124