- ''TODO:''小笠原さんからのメールを貼って,ついでに解説も書いて行こう. -- [[けいご]] &new{2006-06-12 (月) 21:35:54}; * 尋ね人 [#sdf98c23] - 場違いな質問で恐縮ですが、ご存じありませんか? 名大の方みたいなんですが。 - http://www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/index.html -- [[源馬]] &new{2006-07-11 (火) 04:30:06}; *[[AA折れ線グラフ:http://oss.timedia.co.jp/index.fcgi/kahua-web/show/column/%ba%a3%c6%fc%a4%ce%b0%ec%b9%d4/%a3%b2%a3%b0%a3%b0%a3%b6%c7%af%a3%b3%b7%ee#H-1bpntk8]] [#j83662b2] >AAで折れ線グラフを書くというお題. >入力は'R','F','C'の3種類も文字からなる長さ1以上の文字列 >'R'は上昇を表し,折れ線グラフの要素としては '/' (スラッシュ)1文字に対応 >'F'は下降を表し,折れ線グラフの要素としては '?' (バックスラッシュ)1文字に対応 >'C'は変化なしを表し,折れ線グラフの要素としては'_'(アンダスコア)1文字に対応 >たとえば, $ ./plot RCRFCRFFCCRFFRRCRRCCFRFRFF >とすると __ / ?/?/? _/?_/? _/ ? / ?__/? / ?/ >が出力されるようなスクリプトを書け. > --nobsun 源馬のSchemeでの回答はこちら。~ http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?gemma -- [[源馬]] &new{2006-07-01 (土) 12:00:06}; **解答 in Haskell [#nd70223e] 下村です。 無駄に長い上に汚いですけど…。 output str = let result = graph str output' :: [String] -> IO () output' mat = if any null mat then return () else do if any (' '/=) h then putStrLn h else return () output' t where h = map head mat t = map tail mat in output' result graph :: String -> [String] graph str = let height = (length str) * 2 graph' [] _ = [] graph' (x:xs) pos = case x of 'R' -> oneline (pos) '/' height : graph' xs (pos-1) 'F' -> oneline (pos+1) '??' height : graph' xs (pos+1) 'C' -> oneline pos '_' height : graph' xs pos in graph' str (length str) -- n番目の文字がcであるような、長さlの文字列を生成する oneline :: Int -> Char -> Int -> String oneline _ _ 0 = "" oneline n c l = (if n==0 then c else ' ') : oneline (n-1) c (l-1) で、結果は… Main> output "RCRFCRFFCCRFFRRCRRCCFRFRFF" __ / ?/?/? _/?_/? _/ ? / ?__/? / ?/ Main> **解答 in OCaml [#yc2d1595] また下村です。OCamlで書き換えたので書いときます。Haskell版より関数とかをちょっと整理しました。あと、文字列はコマンドライン引数で指定するようにしてあります。explodeとimplodeは拡張ライブラリ関数なので、コンパイルするためにはExtLibをインストールする必要があります。 (* <<COMPILE>> "ocamlopt -I +extlib extlib.cmxa lineGraph.ml" *) open ExtString.String;; open List;; exception NotRFC;; let any = List.fold_left (or) false;; let graph charlist = let height = (length charlist) * 2 in let rec transpose mat = if any (map (fun x -> x=[]) mat) then [] else map hd mat :: transpose (map tl mat) in let rec oneline n c l = if l=0 then [] else (if n=0 then c else ' ') :: oneline (n-1) c (l-1) in let rec graph' charlist pos = match charlist with [] -> [] | c::cs -> match c with 'R' -> oneline (pos) '/' height :: graph' cs (pos-1) | 'F' -> oneline (pos+1) '??' height :: graph' cs (pos+1) | 'C' -> oneline pos '_' height :: graph' cs pos | otherwise -> raise NotRFC in transpose (graph' charlist (length charlist));; let output = try let result = map (fun l -> if any (map (fun x -> x<>' ') l) then implode l ^ "?n" else "") (graph (explode Sys.argv.(1))) in let rec output' list = match list with [] -> () | (""::ls) -> output' ls | (l::ls) -> print_string l; output' ls in output' result with NotRFC -> print_string ("Usage : " ^ Sys.argv.(0) ^ " [RFC]*?n") | Invalid_argument _ -> print_string ("Usage : " ^ Sys.argv.(0) ^ " [RFC]*?n");; 実行結果は… mac{sho}% ./a.out RCRFCRFFCCRFFRRCRRCCFRFRFF [~/src/ocaml] __ / ?/?/? _/?_/? _/ ? / ?__/? / ?/ mac{sho}% [~/src/ocaml] - Ocamlがわかってないので、おぼろげにしかわからないです。なんかすごい。今度、教えてください。 -- [[源馬]] &new{2006-07-04 (火) 03:35:28}; #comment *マルチスレッドなデーモン [#ccec3996] 普通 daemon というと listen していて accept するとプロセスをフォークするアレですが、 プロセスでは無くスレッドを作って対処するなんちゃって daemon を作成しました。 OCaml の Thread,Event ライブラリを利用した concurrent programming を体験するにはちょうどいい題材です。 daemon.tar.gz -compile.sh -daemon.ml -listen.ml -main.ml 少し解説すると、daemon.ml の select [wrap (receive cmdCh) cmd_fsm; wrap accept_evt do_action] という部分は、 - コマンドチャネルにコマンドが送られてくる - accept が起きる という2つのイベントの内、どちらか先に起きた方だけ実行しろ、かつ、どちらかのイベントが来るまで待ってろ、という意味になります。 * HaskellでOS。 [#s0a682d7] http://www.cse.ogi.edu/~hallgren/House/ -- [[源馬]] &new{2006-07-04 (火) 16:16:05}; #comment