Arantium Maestum

プログラミング、囲碁、読書の話題

2018-01-01から1年間の記事一覧

AtCoder Beginner Contest 097に事後参加してみた

とりあえずこれから何週間か、1日1つ以上ABCの4問題を解いていこうと思っている。 D問題は読んでから少し放置して暇なときにつらつら考えて、半日たってから実装したりしているので全然コンテスト形式は再現できていないのだが、とりあえず今は自分で問題に…

AtCoder Beginner Contest 098に事後参加してみた

「事後参加」って変な言い回しだな。「の問題を解いてみた」が正しい・・・ abc098.contest.atcoder.jp 例によってPythonで。 第1問 abc098.contest.atcoder.jp abc098.contest.atcoder.jp 入力値二つの和、差、積のうちの最大値を出力する問題。本当に問題…

AtCoder Beginner Contest 099に事後参加してみた

ツイッターでいろいろ流れてきて面白そうだったので競技プログラミングサイトのAtCoderで問題を解き始めている。 手始めに直近のこれをやってみた: abc099.contest.atcoder.jp コンテスト開催中に参加したわけではないのだが、とりあえずPythonで解いてみた…

HaskellでLisp to LLVM IRコンパイラ その5 ( LispValの定義、パーサ作成とSSA中間言語への変換)

LispValという再帰的なデータ型を定義して、まずコードをそのLispValとしてパースする。流れはインタプリタを作った時とまったく同じ。 インタプリタの場合はそこでevalを適用したが、コンパイラの場合はそこからSSA中間言語に変換を加えていく。 LispVal型 …

Haskell私的メモ Monadをリストで探る1

今回はHaskell初心者にとって理解が困難だといわれているMonadの話。 駆け足で頑張って抽象的な概念を理解しようとするのではなく、親しみ深い「リスト型」をモナドとして使ってみることで具体的な感覚を蓄積していこう、という考え。 >>= 前回FunctorとAppl…

Haskell私的メモ FunctorとApplicativeをリストで探る

「モナドとはなにか」「Applicativeとはなにか」といった抽象的な共通性の探索からはじめると挫折するのが目に見えているので、いったんそういったことは置いておいて、まずはいくつかの具体的なモナドと戯れて個別に挙動を理解していきたい。そういった具体…

HaskellでLisp to LLVM IRコンパイラ その4 (SSA中間言語)

LLVM IRに落とし込む前のステップとして簡略化した独自のSSA中間言語に変換しておく、という話を前回した。 その中間言語の各行を表現するデータ型がこれ: data SSA = Alloc String | Store String String | Load String String Lispと違ってこの言語は再帰…

HaskellでLisp to LLVM IRコンパイラ その3 LLVM IRへの出力(数字の出力)

前回に続いてLLVM IRで数字を返す方法を考える。 比較的簡単でこのような形になる: %1 = alloca i32 store i32 3, i32* %1 %2 = load i32, i32* %1 スタック上に%1という変数をalloca命令で用意する %1に3という値を代入 %1に含まれている値を一時変数%2に…

HaskellでLisp to LLVM IRコンパイラ その2 LLVM IRへの出力(簡単なテンプレート)

LLVM IRというのはLLVMコンパイラ・フレームワークが定義・利用する中間言語だ。 https://en.wikipedia.org/wiki/LLVM#Intermediate_representation LLVMフレームワークでは、コンパイラのFront Endはソース言語をこのIRに翻訳することに集中し、Back Endは…

HaskellでLisp to LLVM IRコンパイラ その1

とりあえず作り始めた。 github.com 基本戦略としては、まずは数値計算だけのコードをLLVM IRに変換するのを目的に: Lispコード→LispVal型データ構造→SSA IR→LLVM IR の流れでコンパイルしていく。 長期的にはLLVM IR上でLispValを表すStructを作る必要があ…

`foldr`で`dropWhile`と不動点コンビネータ 補足

以下の記事の補足: zehnpaard.hatenablog.com 式をいじっていて気付いたのだが、不動点コンビネータを使った解は: dropWhile p = foldr (const f) undefined (repeat undefined) where f _ [] = [] f g ys@(x:xs) = if p x then g xs else ys に落とし込め…

Haskellで50行以内のミニマルコンパイラ

こんなツイートが流れてきた: A complete #compiler to x86 in one page for my lecture today. pic.twitter.com/PwFl4V5czy— Joe Gibbs Politz (@joepolitz) 2018年4月11日 元となっているのは"An Incremental Approach to Compiler Construction"という論…

`foldr`で`dropWhile`と不動点コンビネータ

前回のブログの問題元は今は亡き?Monad.Reader第6号の"Getting a Fix from the Right Fold"という記事。 私が考えた答えの「失敗例」は出てくるけど、パターンマッチを使わないで遅延評価が無限リストにも効く解は出てこない。 しかし別解は非常にエレガン…

`foldr`を使って`dropWhile`を定義する

Haskellの高階関数のfoldrでdropWhileを定義せよ、という問題を見たのでやってみる。 foldr foldrの定義は以下のとおり: foldr :: (a -> b -> b) -> b -> [a] -> b foldr f e [] = e foldr f e (x:xs) = f x (foldr f e xs) 「わかってるねんで?foldrがred…

HaskellとParsecでLisp REPL その8(変数定義)

今回の変更 github.com 「ユーザによる変数定義」機能を追加する。 これはかなり大きな変更で、変数の内容を保持・評価するために、変更可能な「状態」を導入する必要がある。 Haskellだと状態をStateやSTモナドで管理することも可能(らしい)のだが、基本…

HaskellとParsecでLisp REPL その7(if構文)

今回の変更 github.com 条件分岐のための構文を追加。 (if a b c)という式は、まずaを評価し、もし真ならbを、偽ならcを評価してその結果が値となる。 bとcのどちらかひとつしか評価されないのが重要なので、関数ではなく構文として定義。 実装としてはeval…

HaskellとParsecでLisp REPL その6(数値比較と論理演算)

今回の変更 github.com 前回Bool値を定義できたので、=、/=、<、>などやand/orを実装する。 Functions Functionsモジュールのprimitivesにどんどん追加していく: primitives :: [(String, [LispVal] -> LispVal)] primitives = [ ... ("=", numBoolBinOp (=…

HaskellとParsecでLisp REPL その5(Bool型の追加)

今回の変更点 github.com ブール値の追加。データ型とパーサの拡張のみ。 データ型 data LispVal = Atom String | List [LispVal] | Number Integer | Bool Bool ちゃんとshowできるようにしておく: showVal (Bool True) = "#t" showVal (Bool False) = "#f…

HaskellとParsecでLisp REPL その4(四則演算)

今回の変更点 github.com ついに四則演算の実装。入力をそのまま返すのではなく、入力を評価・変換して出力するようになり、「ちゃんとしたREPL」にちょっと近づく。 データ型とパーサ 今回は変更なし。四則演算ならAtom、List そしてNumber型だけで十分。演…

HaskellとParsecでLisp REPL その3(Number型の追加)

今回の変更点 github.com REPLで数字を入力するとパースエラーになる。Atom、Listに続いてNumberもパースしデータとして扱えるようにしたい。 LispValにNumber型を追加 LispValに新たにNumber型を定義し、Haskellの整数を保持させる: data LispVal = Atom S…

HaskellとParsecでLisp REPL その2(Listも使えるREPL)

LISPとはそもそもLISt Processingの略なので、リストを全く扱えない状態からいち早く脱却したい。 というわけで次はリストの実装。ユーザから(a1 a2 a3)といった文字列を受けとり、List型として表現できるようにする。 gistからちゃんとしたgithub repoに変…

HaskellとParsecでLisp REPL その1(Atomをパースし表示するREPL)

ここ一週間ほどHaskellを試しがてら、以下のチュートリアルをいじっていた: Write Yourself a Scheme in 48 Hours - Wikibooks, open books for an open world まずは全部通しで実装してみて、その後コードをいろいろ書き換えたり。 このチュートリアル、非…

4月の抱負

今月は以下の本を読みたい: Thinking Functionally with Haskell (終わらせる!) プログラミングのための確率統計 証明の楽しみ 基礎編 他にもいろんな本やClojureや機械学習やギター曲や水泳にも手を出すつもりだが、とりあえず上記の3冊は終わらせる勢…

『アホでマヌケなプログラミング』読んだ

lepton著『アホでマヌケなプログラミング』を読んだ。 非プログラマ(ゆるくプログラマ志望な人?)に「プログラマの実態」を紹介する本。 著者は企業の新卒向けプログラミング研修の講師などをよく務めていたらしい。「文系卒、プログラミング経験なし」の…

Thinking Functionally with Haskell勉強メモ: 第7章1 メモリ、計算量、`seq`

Thinking Functionally with Haskell全12章の折り返し地点に到達。第7章は最適化に関する話題。 メモリと計算量のトレードオフ Haskellの評価戦略は完全にナイーブではない: sqr (sqr (3+4)) = (sqr (3+4)) * (sqr (3+4)) = ((3+4) * (3+4)) * ((3+4) * …

Clojure/QuilでShepherding Random Numbersその3

最後。今までは「移動する円」がポイントだったが、今回は「移動する円の残す残像」が中心の映像になる。 inconvergent.net 前回と同様、左の円と連動して上下に動いていく円。今度は速度の線は描かず、そのかわり跡が残るようにした: Quil -L8sgTy8ZVQK2Q3…

Clojure/QuilでShepherding Random Numbersその2

続いてここから: inconvergent.net 過去の状態から次に移動する場所を決めていく。 まずは単純に、「現在地からあまり離れていない場所」を次の目的地に決定するパターン: Quil -L8sSIr9XEm-gow3mH4- 次に、「目的地」という概念を消して、上下方向の移動…

Clojure/QuilでShepherding Random Numbersその1

昔からすごく好きなジェネラティブ・アーティストのAnders Hoffのウェブサイトに、いくつかチュートリアル的な記事が載っている。 inconvergent.net ClojureとQuilで試していきたい。 まずは非常に簡単なボール一つが上下に動くもの: Quil -L8r5DqZjda9OSxY…

Thinking Functionally with Haskell勉強メモ: 第6章問題4

Exercise K 第一部 takePrefix pをリストxsに適用すると、xsの頭から連続してpを満たし続ける最も長いセグメントを返す。 takePrefix :: ([a] -> Bool) -> [a] -> [a] takePrefix nondec [1, 3, 7, 6, 8, 9] = [1, 3, 7] -- リストの先頭から上がり続ける最…

『What I wish I knew when I was 20』

Tina Seelig『What I wish I knew when I was 20』を読んだ。 二十代前半の頃に買って読んだ本。本棚を片付けているので、とりあえず処分する前に読み直した。作者はスタンフォード大の創造性関連のプログラムの教授とのこと。 印象としては「ざ・ポジティブ…