- 追加された行はこの色です。
- 削除された行はこの色です。
- ''TODO:''小笠原さんからのメールを貼って,ついでに解説も書いて行こう. -- [[けいご]] &new{2006-06-12 (月) 21:35:54};
#contents
* 尋ね人 [#sdf98c23]
がしがし書いてください
- 場違いな質問で恐縮ですが、ご存じありませんか? 名大の方みたいなんですが。
- http://www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/index.html -- [[源馬]] &new{2006-07-11 (火) 04:30:06};
#ls(ネタ記録庫)
*[[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