Project Eulerというサイトを見つけた。
このサイトにはコンピュータを使って解くタイプの数学の問題がたくさん載っている。
アカウントを取得すると各問題に回答したかどうかをサイト上で見ることができる。
10問くらい解いてみたけど、問題のタイプとしては素数とか数列とかそういった類のものが多い印象。
新しい言語を覚えるときに、このサイトに載ってる問題をその言語で解いたりすると勉強になりそう。
Project Eulerというサイトを見つけた。
このサイトにはコンピュータを使って解くタイプの数学の問題がたくさん載っている。
アカウントを取得すると各問題に回答したかどうかをサイト上で見ることができる。
10問くらい解いてみたけど、問題のタイプとしては素数とか数列とかそういった類のものが多い印象。
新しい言語を覚えるときに、このサイトに載ってる問題をその言語で解いたりすると勉強になりそう。
Schemeチュートリアルの内容をゴリゴリ写経してます。
基本的な制御構造が繰り返しでなく再帰のため、初っぱなから再帰の洗礼に見舞われてます。
ということで再帰関数について調べたことについて書いてみます。
再帰関数とは
再帰関数とは関数それ自体が自らを呼び出す処理を持つ関数のこと。
例えば階乗の計算なんかがよく例として挙げられる。
(define (fact n) (if (= n 1) 1 (* fact (- n 1)))))
上記の関数factは関数本体からfact自身を呼び出している。
factに渡す引数は1ずつ減算されていて、n=1となったところで再帰処理の終端に到達する。
再帰処理を関数として記述するときは終端の設定を必ず行う(そうしないと無限ループに陥る)。
Flat recursion
リストのトップレベルのアイテム(アトム)を処理対象とする再帰処理をFlat recursionという(この語に関して日本語訳が見つからなかった)。
例えば下記のようなリストのトップレベル要素のみの総和を計算する関数が挙げられる。
;Flat recursion (define (sum_list l) (if (null? l) 0 (+ (car l) (sum_list (cdr l)))))
Deep recursion
Flat recursionとは対照的に、リストの要素全てを処理対象とする再帰処理をDeep recursionという。
Deep recursionバージョンのsum_listを示すと下記のようになる。
;Deep recursion (define (sum_list l) (cond ((null? l) 0) ((number? l) l) (else (+(sum_list (car l)) (sum_list (cdr l))))))
Tail recursion(末尾再帰)
関数の末尾が再帰呼び出しのみで終わっている再帰処理を末尾再帰という。
末尾再帰で階乗を計算する関数を書くと以下のような形になる。
;Tail recursion version (define (fact n) (define (iter product counter) (if (> counter n) product (iter (* counter product) (+ counter 1)))) (iter 1 1))
この方法だと、引数に計算結果を渡しているので、計算の途中経過を再帰呼び出しの都度保存しておく必要が無い。そのため、末尾再帰を利用することでメモリの消費量を抑えることができる(らしい)。
…とりあえずこんな感じか。
現状、用語の確認がメインみたいな感じですな。
まだ実用的なプログラムに触れてないので、イマイチ再帰の効用について理解できてないのがちょっと。。
Schemeはリスト構造を基本に構成されているので、木構造のデータ(xmlとか)処理なんかが強いんだろうな、とかそのくらいの認識
Github漁って色んなコードを読んでみるべきかなー。
関数型プログラミング言語”Scheme”で遊んでます。
SchemeはLispの流れを汲んだプログラミング言語。
方々を調べ回ったところによると下記のような特徴を持った言語とのこと。
Schemeを通じて特に身につけたいのは再帰処理の実装センスと関数型プログラミングのエッセンスを吸収すること。
Processingで再帰使って絵を描いたりしたこともあったけど、どうにも再帰使った独自の実装にこぎ着けるところまでは行かなかった。
というか自分で考えた再帰処理を実装してみると、大抵ヒープを食いつぶしてエラーを吐くという残念な結果にしかならないというトラウマが。。
再帰は読むのも苦手なので、勘所をつかんでおきたい。
遅ればせながら今年初投稿。
昨年は結構更新をサボってしまったので今年はもうちょっと更新頻度を上げたい(とかいいつつもう既に2月も半ば)。
今年の抱負、とまでは行かないけど方針くらいは決めておきたいので、今勉強したい/やってみたいことをとりあえず挙げてみる。
こんなところかな。
どれもあんまり具体的な目標でないので、尻すぼみになりそうなのが非常にコワいところ。
今年は上記に関することに関して、取り組んだ内容を出来るだけ書くようにしていきたいなぁと思ってます。