season's quarterly

数学/物理/プログラミング

純LISPインタプリタを作る

C言語で純LISPインタプリタを作りました。 github.com

LISP

LISPLISPの方言で、ごく少数の基本的な関数やプリミティブからなる。コンパイラとかは作ったことなかったけど、純LISPなら記述が少なくて済むだろうなと思って作ってみた。

LISPには二種類のデータ型アトムとペアがある。ペアは二つのデータのペア。アトムはペアでないもの。真偽値はt,niltrue,falseに対応する。ABのペアを(A . B)と表す。またリスト(A B C)(A . (B . (C . nil)))という風に入れ子にしたペアの略記とみなす。純LISPの要素は人によって異なるが、今回は以下の関数

  • atom 値がアトムのときt
  • eq 二つの値が等しいときt
  • car ペアの左側
  • cdr ペアの右側
  • cons 二つの値のペア

と特殊形式

のみからなるとする。

データの表現

LISPのリストは以下のようなコンスセルで表現される。

リスト`(A B C)`
しかしこのままでは各要素がアトムなのかペアなのか判定できない。そこで隣接する二つのアドレスp, p + 1を用いてデータを表現し、pで表すことにした。アトムの場合はpにその値を格納し、p + 1に0を格納する。ペアの場合はpにcarのアドレス、p + 1にcdrのアドレスを格納した。C言語ではメモリ0番地に値を書き込むことは基本的にできないらしいので、多分これで識別できそう。アドレスはlongなのでポインタの型はlong*で統一した。例えば((A B) C) となる。ただしtには1,0をnilには0,0をそれぞれ格納する。つまりt = 1,nil = 0。またnilと空リスト()も等しい。(実際はどう割り当てるのが良いんだろう)

構文解析(parse.c)

まず全体をexprに渡す。空白と改行は無視して、(が来たらparentheses、それ以外の文字が来たらnumbersymbolに渡す。)が来て括弧の収支が合ったら終了。parenthesesでは括弧の収支が合うまでexprで読む。

long* parentheses(){
    long *begin = calloc(2, sizeof(long));
    long *p, *q; p = begin;
    int cnt = parentheses_count - 1;
    while(true){
        *p = (long)expr();
        if(eq(p, nil) == t){
            return begin;
        }else{
            q = calloc(2, sizeof(long));
            *(p + 1) = (long)q;
            p = q;
        }
        if(cnt == parentheses_count) return begin;
    }
}

long* expr(){
    char c;
    while(!feof(fp)){
        c = fgetc(fp);
        if(c == EOF) return nil;
        if(c == ' ') continue;
        if(c == '\n'){
            line_number++;
            continue;
        }
        if(c == '('){
            parentheses_count++;
            return parentheses();
        }else if(c == ')'){
            parentheses_count--;
            if(parentheses_count < 0){
                printf("error %d : parnetheses don't correspond.\n", line_number);
            }
            return (long*)0;
        }
        else if('0' <= c && c <= '9') return number(c - '0');
        else return symbol(c);
    }
}

評価(eval.c)

読み込んだ結果をevalに渡す。evalの中身を順番に見ていく。 まず文字列がt,nilに一致したらそれを返す。

    if(equal(p, "t")) return t;
    else if(equal(p, "nil")) return nil;

次に宣言された変数名に等しければその値を返す。varが変数名の配列、valueが値の配列となっている。

    for(int i = var_count - 1; i >= 0; i--){
        if(eq(p, var[i]) == t) return value[i];
    }

それ以外の場合は最初の要素が関数や特殊形式なので、関数名tokenと引数argsに分ける。

    long* token = car(p);
    long* args = cdr(p);

基本関数の評価。

    if(equal(token, "atom")) return atom(eval(car(args)));
    else if(equal(token, "eq")) return eq(eval(car(args)), eval(car(cdr(args))));
    else if(equal(token, "car")) return car(eval(car(args)));
    else if(equal(token, "cdr")) return cdr(eval(car(args)));
    else if(equal(token, "cons")) return cons(eval(car(args)), eval(car(cdr(args))));

特殊形式の評価。quoteについては引数をそのまま返す。lambdaは引数の組と処理の内容を返す。definevar,valueに変数を登録する。

    if(equal(token, "cond")){
        while(eq(args, nil) == nil){
            long* condition = car(car(args));
            long* expression = car(cdr(car(args)));
            if(eval(condition) == t) return eval(expression);
            args = cdr(args);
        }
        return nil;
    }
    else if(equal(token, "quote")){
        return car(args);
    }
    else if(equal(token, "lambda")){
        return args;
    }
    else if(equal(token, "define")){
        var[var_count] = car(args);
        value[var_count] = eval(car(cdr(args)));
        var_count++;
        return value[var_count - 1];
    }

最後にラムダ式の展開。tokenがそれ以前に登録したラムダ式の名前に一致するとき、引数を評価してvar,valueに加えた上で、ラムダ式の内容をevalで評価する(defineで定義した変数とラムダ式の引数は分けた方が良いかもしれない)。再帰呼び出しする場合は引数の名前を複数登録することになるが、evalの冒頭で新しい順に変数名を照合しているので問題ない。

        for(int i = var_count - 1; i >= 0; i--){
            if(eq(token, var[i]) == t){
                token = value[i];
                break;
            }
        }
        long* params = car(token);
        int n = 0;
        while(eq(params, nil) == nil){
            var[var_count] = car(params);
            value[var_count] = eval(car(args));
            var_count++;
            n++;
            params = cdr(params);
            args = cdr(args);
        }
        long* ret = eval(car(cdr(token)));
        for(int i = 0; i < n; i++){
            var_count--;
            var[var_count] = 0;
            value[var_count] = 0;
        }
        return ret;

テスト

バグってるかもしれないけど。sample.lisp

(quote 1)
(quote (1 2 3 4))
(atom (quote 1))
(atom (cons (quote 1) (quote 1)))
(eq (cons (quote 2) (quote 3)) (cons (quote 2) (quote 3)))
(car (cons (cons (quote 1) (quote 2)) (quote 3)))
(cdr (cons (cons (quote 1) (quote 2)) (quote 3)))
(cond
    ((eq (quote 1) (quote 1)) (quote 2))
    ((quote t) (quote 3))
)

(define inc (lambda (x) (cons (quote 1) x)))
(inc (quote (1 1)))

(define append
    (lambda (x y)
        (cond
            ((eq x nil) y)
            (t (cons (car x) (append (cdr x) y)))
        )
    )
)
(append (quote (1 2 3)) (quote (4 5 6 7)))

(define f (lambda (x) (cons x (quote 2))))
(define g (lambda (f x) (f x)))
(g f (quote 3))

に対して実行すると

> .\lisp sample.lisp
1
1 2 3 4 0
1
0
1
1 2
3
2
((120 0) 0) ((99 111 110 115 0) ((113 117 111 116 101 0) 1 0) (120 0) 0) 0
1 1 1 0
((120 0) (121 0) 0) ((99 111 110 100 0) (((101 113 0) (120 0) (110 105 108 0) 0) (121 0) 0) ((116 0) ((99 111 110 115 0) ((99 97 114 0) (120 0) 0) ((97 112 112 101 110 100 0) ((99 100 114 0) (120 0) 0) (121 0) 0) 0) 0) 0) 0
1 2 3 4 5 6 7 0
((120 0) 0) ((99 111 110 115 0) (120 0) ((113 117 111 116 101 0) 2 0) 0) 0       
((102 0) (120 0) 0) ((102 0) (120 0) 0) 0
3 2

となる。リスト末尾のnil(0)が表示されてる。ごちゃごちゃしてるのはdefineとかlambdaの返り値で、文字コードをそのまま出力している。

関連文献

簡易LISP処理系の実装例【各言語版まとめ】

簡易LISP処理系の実装例(C言語版)

ICTSC2021夏の陣参加記[osushi]

icttoracon.net 8/28,29に開催されたICTトラブルシューティングコンテストにanko氏, fomidtk氏, seasonの三人で参加しました。ネットワークとか分かるんですか??いいえ。本番二日前にあるよって言われたときは、「過去の自分、こんなものに手を挙げたのか」と思った。

一日目

最初は皆で14 Webサーバが立ち上がらないを読んだ。Pythonモジュールがないのでinstallするのかなあと分かった。偶然にもつい最近Pythonを始めたので「分かった。凄い」となった。この問題はfomidtkさんが回答を作成しました。

その後は三人で別々の問題を考えた。9 止まらないを見るも全然分からない。ankoさんの指示通りにMakefileのコマンドにオプション-t -iを付けるとなんか分からんけどできる。ところがankoさんもよく分からないそうなので自分が調べることに。ICTSCはトラブルを解決するだけではだめで、原因とか対策をちゃんと説明しないといけないのです。そもそもdockerが何か知らないのに分かるかーと思いつつググってみると次のページを見つけた。 docs.docker.jp qiita.com ふむふむ。普通にdocker runをやると標準入力が使えないけどこのオプションを付けると使えるようになる、と理解して次のような回答を作成した。

お世話になっております。チームosushiです。

この問題ではdockerの起動中に標準入力が機能しないことが原因でトラブルが発生したと>考えられました。

そのため、docker runのオプション

-t, --tty : 疑似ターミナルの追加

-i, --interactive : コンテナのstdinにアタッチ

を追加することで正しく動くことを確認いたしました。

確認のほどよろしくお願いします。

手順

1./home/user/test/Makefileの編集

変更前:docker run --rm -v $(PWD)/:/go/src/app -w /go/src/app -p 8080:8080 golang:latest go run main.go

変更後:docker run --rm -t -i -v $(PWD)/:/go/src/app -w /go/src/app -p 8080:8080 golang:latest go run main.go

20分後に見てみると無事50点を獲得。やったね。

その後も問題を考えたが何も分からず。もはや自分に分かる問題はなかった。 f:id:season1618:20210829155917p:plain f:id:season1618:20210829155853p:plain

二日目

問題は一日目と同じです。もう分かるやつがないのでその場でネットワークのお勉強を始めました。結果何も分かりませんでした。すみません... f:id:season1618:20210829162649p:plain f:id:season1618:20210829162232p:plain 一位と二位のチームだけずっと不動だったの凄い。

感想

コンテストは両日とも10:00-16:30の6時間30分でした。つらーい。大学入って初めての大会だった。

2020年度の読書記録

2020年1-3月も含む。全体的に内容を覚えていない。

シャーロック・ホームズの推理学』

ホームズがどういう風に推理してるかを分析してる。

Excelで分かるディープラーニング超入門』

この時期にN予備校の教材が公開されてて、機械学習のやつを読んでた。

『正多面体を解く』

多面体の話。

愚者のエンドロール米澤穂信

丁度この時期に『氷菓』の再放送がやってて、自分も二回目だけどアニメと並行して小説も読もうとなった。

生物と無生物のあいだ福岡伸一

動的平衡で知られてる人の本。

すべてがFになる森博嗣

文章や言葉選びから独特な思考が感じられて良かった。これ読んだ後にアニメをもう一回見た。

『生命の物理』

様々な生命現象の数理を扱っている。固体内の分子の運動、神経系のモデル、個体数の変動を扱うロトカ=ヴォルテラ方程式とか。チューリングの形態形成の研究とか正規表現オートマトンが対応するという話とか、情報科学の話も出てきて面白かった。

『熱・統計力学

印象に残った文をメモしておいた。

仕事と熱の区別がどの程度のスケールの自由度でされるかに依存せず、仕事と熱に関する一意的な法則が成立するのであって、この意味において熱力学的あるいは巨視的な法則も客観性をもつのである。

レオナルド・ダ・ヴィンチの世界』

高三の4,5月とはいえコロナで暇ができたので本読んでた。 レオナルドの仕事を解剖学・数学・天文学・土木・絵画など、色々な分野について分析している。それから手稿そのものを取り上げていたのが面白かった。レオナルドに限らず、昔の人間が何を知っていて何を知らなかったのかを知るのは面白い。

クドリャフカの順番米澤穂信

古典部」シリーズでは文化祭の話が一番好き。古典部4人の視点が次々と切り替わるの文化祭のごちゃごちゃ感があって良い。

ソードアートオンライン アインクラッド川原礫

SAOはアインクラッドが一番好き。命がけだからエモくなるんだよなあ。アニメ版とは構成が異なり、いくつかの話が2巻に回されている。

『情報トレーニング』

競プロっぽいパズルの問題があって面白かった。

化学の教科書

化学の教科書を通読した。時間の無駄だった気がする。

『古文の読解』

こんなの読んでる暇あったら古文単語を覚えような。

竹取物語

高畑勲監督の「かぐや姫の物語」が面白かったので読んでみた。

『物質と光』ルイ・ド・ブロイ

光学の歴史とか量子力学について。

『幕末思想集』

色々な人が開国・倒幕を主張した本をまとめたもの。

方丈記鴨長明

旅したいってなった。

岡潔 数学を志す人に』岡潔

『春宵十話』など。自分の思考を分析していたのが興味深い。理解はできなかったけど。

国家の品格藤原正彦

数学者である著者のベストセラー。

『色彩学概説』

眼の構造から色の物理的・心理的性質について。色を表現するための体系など。

レオナルド・ダ・ヴィンチの手記(上・下)』レオナルド・ダ・ヴィンチ

レオナルド・ダ・ヴィンチの世界』のほとんどの章でこの本が参考文献に挙げられてたので読んだ。遠近法の説明や絵の上達について。寓話をたくさん書いてたのが意外だった。それから地理や天文学の細かい記述があった。科学については、ガリレオ以前ということもありアリストテレスの影響を受けていたようだ。

奥の細道松尾芭蕉

平安より江戸の古文の方が読みやすい。

『日本人の美意識』ドナルド・キーン

幽玄の話とかだった気がする。

キノの旅 the Beautiful World時雨沢恵一

アニメを完走したので小説も読んだ。世界観が好き。

『絵画論』レオン・バッティスタ・アルベルティ

遠近法の解説など。

ようこそ実力至上主義の教室へ衣笠彰梧

綾小路の性格がアニメと違う。堀北のツンデレが良い。

星の王子さまアントワーヌ・ド・サン=テグジュペリ

読んだことなかったので。

冷たい密室と博士たち森博嗣

すべFの続編。

『魔法の世紀』落合陽一

再読。以前よりは理解して読めたのではないか。

AtCoder に登録したら解くべき精選過去問 10 問を Common Lisp で解いてみた

始めに

数日前に唐突にLISPに入門したのでやってみました。 qiita.com

参考資料

Common Lisp

AtCoderCommon Lispで解いた人の記事

第1問 ABC 086 A - Product

A - Product
提出

(defun solve (a b)
    (if (= (mod (* a b) 2) 0) "Even" "Odd")
)
(format t "~A~%" (solve (read) (read)))

入力は(read), (read-char), (read-line)を使う。それぞれ整数、文字、文字列を読み込む。出力にはprincformatがある。
関数の定義にはdefunを使う。関数は前置記法つまり(関数名 引数1 引数2 ...)で書く。 余りにはmod, 'rem'がある。違いは負の数の扱い。

第2問 ABC 081 A - Placing Marbles

A - Placing Marbles
提出

(defun solve (a b c)
    (+ (if (equal a #\1) 1 0) (if (equal b #\1) 1 0) (if (equal c #\1) 1 0))
)
(princ (solve (read-char) (read-char) (read-char)))

文字や文字列の比較にはchar=, string=, equalがある。

第3問 ABC 081 B - Shift Only

B - Shift only
提出

(defun two_count (a)
    (if (= (mod a 2) 1) 0 (+ (two_count (/ a 2)) 1))
)
(defun solve (n)
    (if (> n 0) (min (two_count (read)) (solve (- n 1))) 30)
)
(princ (solve (read)))

LISPは動的型付けなので/だと有理数になることに注意。切り捨てにはfloor, truncateを使用する。違いは負の数の扱い。

第4問 ABC 087 B - Coins

B - Coins
提出

(defun solve (a b c x)
    (if (> a 0)
        (+ (solve (- a 1) b c x) (solve 0 b c (- x (* 500 a))))
        (if (> b 0)
            (+ (solve a (- b 1) c x) (solve a 0 c (- x (* 100 b))))
            (if (> c 0)
                (+ (solve a b (- c 1) x) (solve a b 0 (- x (* 50 c))))
                (if (= x 0) 1 0)
            )
        )
    )
)
(princ (solve (read) (read) (read) (read)))

第5問 ABC 083 B - Some Sums

B - Some Sums
提出

(defun digit_sum (n)
    (if (> n 0) (+ (digit_sum (floor n 10)) (mod n 10)) 0)
)
(defun solve (n a b)
    (let ((x (digit_sum n)))
        (if (> n 0) (+ (solve (- n 1) a b) (if (and (<= a x) (<= x b)) n 0)) 0)
    )
)
(princ (solve (read) (read) (read)))

変数にはletを使う。

第6問 ABC 088 B - Card Game for Two

B - Card Game for Two
提出

(defun solve (n a)
    (if (equal a nil)
        0
        (if (= n 0)
            (+ (solve 1 (cdr a)) (car a))
            (- (solve 0 (cdr a)) (car a))
        )
    )
)
(defun init (n)
    (if (> n 0) (append (init (- n 1)) (list (read))) (list))
)
(let ((a (init (read)) ))
    (princ (solve 0 (sort a #'>)))
)

listでリストを作ることができる。carで先頭の要素を取得し、cdrで以降の要素を取得する。sortで比較関数を指定してソートする。
ちなみにlengthで長さが取得できるが、線形時間なので注意。空リストかどうかを判定したいときは(equal l nil)(null l)を使う。

第7問 ABC 085 B - Kagami Mochi

B - Kagami Mochi
提出

(defun solve (s a)
    (if (equal a nil)
        1
        (+ (solve (car a) (cdr a)) (if (< s (car a)) 1 0))
    )
)
(defun init (n)
    (if (> n 0) (append (init (- n 1)) (list (read))) (list))
)
(let ((a (sort (init (read)) #'<)))
    (princ (solve (car a) (cdr a)))
)

append, consでリストを結合する。
https://www.nak.ics.keio.ac.jp/class/lisp/union.pdf

第8問 ABC 085 C - Otoshidama

C - Otoshidama
提出

(defun select (l1 l2)
    (if (> (car l1) (car l2)) l1 l2)
)
(let ((n (read)) (y (read)))
    (defun solve1 (a b)
        (let ((c (- n (+ a b))))
            (if (and (>= c 0) (= (+ (* 10000 a) (+ (* 5000 b) (* 1000 c))) y))
                (list a b c)
                (if (> a 0) (select (solve1 (- a 1) b) (solve2 a b)) (solve2 a b))
            )
        )
    )
    (defun solve2 (a b)
        (let ((c (- n (+ a b))))
            (if (and (>= c 0) (= (+ (* 10000 a) (+ (* 5000 b) (* 1000 c))) y))
                (list a b c)
                (if (> b 0) (solve2 a (- b 1)) (list -1 -1 -1))
            )
        )
    )
    (format t "~{~A~^ ~}" (solve1 n n))
)

第9問 ABC 049 C - Daydream

C - Daydream
提出

(defun solve (s)
    (let ((n (length s)))
    (cond
        ((and (>= n 5) (equal (subseq s (- n 5) n) "dream")) (solve (subseq s 0 (- n 5))))
        ((and (>= n 7) (equal (subseq s (- n 7) n) "dreamer")) (solve (subseq s 0 (- n 7))))
        ((and (>= n 5) (equal (subseq s (- n 5) n) "erase")) (solve (subseq s 0 (- n 5))))
        ((and (>= n 6) (equal (subseq s (- n 6) n) "eraser")) (solve (subseq s 0 (- n 6))))
        ((= n 0) "YES")
        (t "NO")
    )
    )
)
(princ (solve (read-line)))

第10問 ABC 086 C - Traveling

C - Traveling
提出

(defun calc (b)
    (let ((ti (car b)) (x (car (cdr b))) (y (car (cdr (cdr b)))))
        (if 
            (and
                (= (mod ti 2) (mod (+ (abs x) (abs y)) 2))
                (>= ti (+ (abs x) (abs y)))
            )
        0 1)
    )
)
(defun solve (a)
    (if (= (loop for l in a sum (calc l)) 0) "Yes" "No")
)
(defun init (n)
    (loop for i below n collect (list (read) (read) (read)))
)
(defun delta (a)
    (loop for b on a collect 
        (if (null (cdr b))
            (car b)
            (diff (car b) (car (cdr b)))
        )
    )
)
(defun diff (s1 s2)
    (list
        (- (car s1) (car s2))
        (- (car (cdr s1)) (car (cdr s2)))
        (- (car (cdr (cdr s1))) (car (cdr (cdr s2))))
    )
)
(princ (solve (delta (reverse (init (read))))))

105オーダーで再帰するとスタックオーバーフローするのでループを用いる。ループにはloopを使う。返り値にはcollectsumなどがある。
【Common Lisp】loopマクロの使い方まとめ - プログラミング原人の進化論

最後に

間違いなどありましたら指摘していただけるとありがたいです。

高校時代にやったこと

1年(2018/04-2019/03)

4月

高校に入学する。一番最初の学力調査みたいなやつで学年一位だったのを覚えてる。
最初は帰宅部。なんかパソコン部は興味あったんだけど、中学の時みたいに休日出勤あったら辛いなあとか思ってた。実際は文化部はゆるゆるだった。
図書館が広くて、大学の数学と物理の本が揃ってた。蔵書数は15000冊とからしい。

7月

友達に誘われてクイ研に入ったのが多分この頃。高校の夏季講習みたいなやつに強制参加させられたので高校生クイズは参加しなかった。

8月

解析力学の本を借りて読んでた。
解析力学 (物理入門コース 2) | 小出 昭一郎 |本 | 通販 | Amazon
夏休みの最後当たりに数学・物理のアカウントを作りました。


2019年の終わりまでは基本的に数学オリンピックの問題を解いて解答を載せるだけのアカウントだった。

10月

人生で初めて折り紙を設計した。これめっちゃ楽しい。


設計理論とか全然知らないんだけど、立体を平面に広げたときの余白をどう折れば良いか考えていろいろ試行錯誤してたらできた。

11月

情報の授業の前に先生にパソコン部に誘われた。当時の部長がpublic_yusuke氏だった。タイピングめっちゃ早かったり、数学基礎論の本持ってたり、理数科の課題研究見せてもらったりしたけど色々やばかった。この人に競プロを教えてもらって、その場でAtCoderのアカウント作って、D - Five, Five Everywhereを解かされた。Twitter教えたときめっちゃ「キモい」って言われた。その場でパソコン部に入ることになって、一か月後の情報オリンピック予選に出ることも決まった。
これがなかったらPCKもJOIもSuperConも出てなかったし、情報科学の達人に参加することもなかった。自分の人生がかなり劇的に変わったのはずなので感慨深い。

12月

JOI予選に参加して予選落ちします。過去問では300点取れてたのに本番では140点しか取れなくて悔しかった。

1月

数オリの予選に通った。

2月

2年(2019/04-2020/03)

5月

電磁気学のpdfを書いた。物理学のpdfは大体EMANの物理学と専門書を読んで書いてる。他にもpdf書いてるけど、別に検証とかされてないし勝手な解釈もあるので、内容の正しさは保証できないです。あと図を入れるべきところを面倒臭がって入れてなかったりする。ちなみに日付は手動のままなので更新されてない。
復刻版 バークレー物理学コース 電磁気 (バークレー物理学コース 復刻版 2) | 飯田 修一, 飯田 修一 |本 | 通販 | Amazon
Electromagnetism.pdf - Google ドライブ

6月

競プロのアカウントを作ります。

7月

高校生クイズに出た。


相対性理論やる前に微分幾何やらないとなあと思って学校の図書館で本借りた。
Differential Geometry.pdf - Google ドライブ

9月

public_yusuke氏とPCK出たら予選通過してしまった。
season1618.hatenablog.jp

10月

電気回路とか制御工学(古典制御)を多少齧ってた。「サイバネティクス」を借りた。

11月

PCK本選は同年代の競プロerと知り合うきっかけになったのでとても良かった。旅費が1万円を超過する場合にはその超過分を会津大学が払ってくれるし、その一万円は学校が払ってくれたので、会津旅行にただで行けて最高でした。顧問がステーキ奢ってくれたのと、夜中に皆でコンテスト出たのが楽しかった。
season1618.hatenablog.jp

12月

JOI予選通過した。
season1618.hatenablog.jp
この記事を読んで言オリ面白いなって思ったので出た。なお勉強は全くしていない。
zohe.hatenablog.com

1月

この年の数オリは予選落ちした。
season1618.hatenablog.jp

2月

一瞬だけ関数解析の本読んでた。綺麗に忘れたけど。


JOI本選も何人かと名刺交換した。PCKに比べて全体的に質素だった。部屋が独房って呼ばれてるし。
season1618.hatenablog.jp
熱・統計力学の勉強してた。
熱・統計力学 (物理入門コース 7) | 戸田 盛和 |本 | 通販 | Amazon
VSCodeが使えるようになったので、Webブラウザのようなものを作ろうとしてた。
弊学は数学の授業中に折り紙折ってても何も言われません。

3月

コロナでN予備校が教材出してたので機械学習のやつだけやった。実装はしてない。


コロナの影響で数学甲子園の中止が発表されて悲しかった。
この本が結構面白かった。生物の本だけど情報の話も出てきた。オートマトンとか正規表現の話に初めて触れたんだけど結構深いんだなあと思った。
生命の物理 (新装版 現代物理学の基礎 第8巻) | 大沢 文夫, 寺本 英, 斎藤 信彦, 西尾 英之助 |本 | 通販 | Amazon

情報科学の達人」プログラム受講生に採択されてしまった。
JOI本選erから一定数採るということだったので、自分のとこにも宣伝が来ていて応募したんだけど、まさか選ばれるとは思ってなかった。内容としてはこんな感じ。第一段階では、色んな分野の先生からオンライン講義を受講しつつ、グループ分けされてメンターの先生から出された課題をこなす。第二段階では研究をしたりする。グループは再編成された。
休校になったのでこの頃から競プロの精進を始めた。

3年(2020/04-2021/03)

4月

文化祭のゲーム作ろうと思っててUnityを触ってた。結局文化祭中止になったけど。達人の講義動画を見るようになった。この時はアニメとかいっぱい見てた。

5月

波動光学とか色彩に興味を持ってた。


AtCoder青になりました。
season1618.hatenablog.jp
PAST中級だった。悲しい。

6月

適当に後輩を誘ってSuperCon予選に参加して予選通過しました。予選通過したと同時に本選の中止が発表されました。
season1618.hatenablog.jp
物理チャレンジの実験課題をやりました。

7月

なんかJavaの逆アセンブラ作ってる。


JPhO理論問題コンテストに出た(一次予選落ち)。今年はオンラインだった。

8月

達人の課題でAmoebaSATのパラメータを調整して高速化するというのをやってた。AmoebaSATというのは、粘菌の動きを模倣したアルゴリズムでSATを解くやつ。粘菌を使って首都圏の交通網をシミュレーションする研究を知ってる人も多いかもしれない。
粘菌コンピュータ - Wikipedia
粘菌から着想した解探索コンピュータ | 理化学研究所
まあ大したことはできなかったなあ。
量子力学をやらんとなーと思って本読んでた。あんまり深入りできなかったけど。
量子力学 I 原子と量子 (物理入門コース 5) | 中嶋 貞雄 |本 | 通販 | Amazon
量子力学 II 基本法則と応用 (物理入門コース 6 ) | 中嶋 貞雄 |本 | 通販 | Amazon
例年APIOはJOI本選通過者が参加できるんですけど、この年はコロナの影響で、本選erで参加を希望した者のうち本選成績上位60名が参加できることになりました。
season1618.hatenablog.jp
ニュース博識甲子園に出た。本来は二週間前にやるはずだったんだけど、ネットのトラブルでほとんどの参加者が参加できない事態になってやり直しになった。


数学検定一級を受検したんだけど一次しか合格できなかった。

9月

適当に後輩を誘ってPCK予選に出て予選通過しました。
season1618.hatenablog.jp
筑波AC入試の出願をした。
本選が中止になったSuperCon本選ですが、代わりにスーパーコンピュータの富岳を使わせてもらえることになりました。SuperConを主催してるのは東工大と阪大で、富岳持ってるのは理研だったから、そんなことできるんだーとか思ってた。


この時期は特に忙しかった。

10月

高校生クイズに出た。


JChOに出た(一次予選落ち)。
学校で「色彩学概説」を借りて絵具とかメディアについて調べてた。
色彩学概説 | 千々岩 英彰 |本 | 通販 | Amazon

網羅的じゃないけどpdfも書いた。
Visual Art.pdf - Google ドライブ

11月

志望校を東工大に変えるなどした。
PCK本選は今回は学校からだった。いやー会津行きたかったなー。
season1618.hatenablog.jp

12月

情報科学の達人の第二段階がこのあたりに始まって、週一の進捗報告会も始まった。第二段階ではStochastic ComputingでReservoir Computingを実装する取り組みをやってた。


まあ大したことはできなかったなあ。
冬休みはずっと共通テストの勉強をしてた。

1月

共通テスト
season1618.hatenablog.jp

2月

個別試験
season1618.hatenablog.jp
これは受験の反動。

3月

東工大受かった。

大学受験記(個別試験)

season1618.hatenablog.jp

前置き

イキリ受験記です。生存バイアスです。

志望校

昔から大学では理学をやるんだろうなって思ってたんですけど、数学や物理の本は高校でだいぶ読んだし、高校に入ってからは情報系との縁に恵まれるところが多かったし、結構興味も出てきたので夏休みくらいから情報系に志望変更しました。お金がないので国立が良かったです。ある程度上位になるとあんまり違いはないと思っていたので、競プロが盛んな東大京東工大筑波大のどれかが良いなあと思いました。阪大は積分サークルのノリが苦手だった(偏見)。文系は好きでも得意でもなかったので、東大と京大はやめました。東工大は後期が無かったので後期は筑波大に決まりました。第一志望は最初東工大だったんですけど、筑波では他学群の授業が受けられると聞いて筑波に変更して、東工大では他学院の授業が受けられると聞いて東工大に変更しました。11月のことです。ちなみにこれは東工大の先生に直接聞きました。達人erはメンターの先生に大学のことを聞くのもありだと思います。オープンキャンパス(オフライン)も行ってないし、冠模試は既に終わってました。
というわけで前期を東工大、後期を筑波にしました。筑波の後期は情報科学類がないので理工学群です。私大は記念受験的な意味合いが強かったのでまともに調べませんでした(カス)。せっかくの受験なので有名所は押さえておきたいと思って早稲田と慶應理科大に出願しました。ちなみに共通テストですが、私大は独自試験のみで使用せず、国立は両方とも足切りがなかったので、完全に塗り絵でした。
試験日程ですが、第n+1志望の入学金振り込み期限が過ぎる前に第n志望の合否発表があると嬉しいです。国立志望の場合、そんな気の利いた私大はないのですが。僕は最初の合否発表が遅くて、前期の三日前までどこも受かってない状態だったのであまり精神的によろしくなかったです。

勉強

参考書は完全におさがりです。理科大慶應の赤本は兄、東工大と筑波の赤本は先輩からのものです。お金をあまり使いたくなかったので塾も行きませんでした。模試の判定はずっとC以下で、直近の東進模試でも東工大D、早慶E判定だったけど結局全部受かりました。なんか過去問を見る限り普通に受かるよなあと思いつつ、模試の判定では一貫してD,Eとかだったのでおかしいなあと思っていました。まあだから判定とかじゃなくて問題が解けるかどうかを見た方が良いんだと思います。大体どこの大学でも6割取れれば合格できるっぽいです。とはいえ理科大以外はあんまり自信なかった。

筑波大学情報学群情報科学類AC

ACというのはアドミッションセンター入試(AOみたいなやつ)で、ACしたわけではないです。賞状(数オリ、情オリ、PCK、SuperCon)、pdf(電磁気学微分幾何相対性理論)とかを送ったんですけど、書類選考で落ちました。自己推薦書と志願理由書が適当だったかもしれないし、実績が足りなかったかもしれないです。
俺「†情報科学の達人†と申しますw」
情報科学類「書類落ちですw」


俺を落としたこと、後悔させてやるぜ。

東京理科大学理工学部物理学科

理科大って同じ物理学科でも理学部とか理工学部とかあるんですけど、そういうのはちゃんと調べましょう。僕は適当に選びました。共通テスト終わってから赤本を開きました。10年前の赤本です。理科は物理と化学のどちらか一方だったので物理を選択した。
自信はありました。
f:id:season1618:20210222165007p:plain

慶應義塾大学理工学部学門A

本番二週間前から過去問をやり始めました。10年前の赤本です。
ちなみにスマホに頼らず電車に乗るぞと思って15分くらい路線図を睨んでたけど、結局何も分かりませんでした。悲しい。
感触は微妙でした。数学は終了20分前くらいから見直してたのでほぼ満点取れた自信があるけど、化学は3割くらいしか取れてないと思います。半分空欄だったので。
f:id:season1618:20210222165153p:plain

早稲田大学先進理工学部物理学科

QuizKnockの山本氏と同じところですね。学科は応用物理なので違うけど(応用物理は第二志望だった)。先進理工という響きがかっこよくて出願しました(カス)。よく調べると基幹理工の方が良かったかもなあという気持ちにもなってくる。早稲田は赤本持ってないので直前に一年分やっただけです。有名大学はネットに過去問載ってるから良いよね。数学は全部記述なんですよね。解答用紙配られたときに知りました。英語は慶應より難しい印象を受けたのですが、後半の方に英語というよりも英語で算数の問題を解くような大問があったので、本番でもそれから先にやりました(←素晴らしい学習能力)。結局英語できないままなんですけど、できないなりに矛先を見つけて戦えたかなあという気がします。当日は強風で電車が遅延したので試験時間が繰り下がって、試験後も遅延してたので帰宅したのが翌日でした。
自信はありませんでした。
f:id:season1618:20210226191425p:plain
この時点でまだどこも受かってないのでとにかく東工大の勉強を死に物狂いでする必要があります。

東京工業大学情報理工学院

10日前に赤本を開いたときは馬鹿なんじゃないかと思いました。この赤本はpublic_yusukeに譲っていただきました。かなり助かったので大変感謝しています。この赤本は問題を年度ごとではなく分野別に分けていて、難易度も付与されていたので、こちらの方が合っている受験生もいるのではないかと思います。
f:id:season1618:20210309180540j:plain
本番まであまり時間がなかったので、化学は物質の構造、有機化学、高分子化合物に絞って勉強しました。英語と物理は4問くらいやった気がする。数学は6割くらい解きました。ちなみに数学は去年と一昨年の分を授業中に解いていた。それから前年の物理と化学をやりました(これもネットに載ってた)。このころは一日10時間くらい勉強してた気がする。
解答用紙に名前を書く欄がなくて、受験番号(とその下二桁)を書くだけでした。なんで?大岡山キャンパスだったので二日目帰るときにチーズケーキだけ撮ってきた。f:id:season1618:20210309213016j:plainf:id:season1618:20210309213020j:plain
体感が

  • 数学180/300
  • 英語70/150
  • 物理120/150
  • 化学80/150
  • 合計450/750

だったので手応えは微妙でした。


一般選抜合格者学院別得点
https://admissions.titech.ac.jp/admission/college/pdf/R3_zen_kou_tokuten3018406.pdf
数学230点はかなり驚いたし、他の人の開示を見る限り結構高いみたい。一方で他の三教科はあんまり取れてない。特に物理で点が取れなかったのが悔しい。本番で誤読しまくってたし計算大変だった記憶。合計は情報理工学院の中では低い方だし、首席には到底及ばないですね。

感想

筑波に落ちた以外は全て望み通りの結果だった。4年間社会から放っておいてもらえる権利を得ることができました。いっぱい勉強します。

大学受験記(共通テスト)

season1618.hatenablog.jp

全体の感想

2020年って結構やばくて、受験を差し引いても高校三年間で一番忙しかった気がする。具体的には、JPhO予選(一次予選落ち)出たり、
SuperCon予選に参加したり、コロナの影響でJOI本選落ちでもAPIOに参加できるようになったり、
PCK予選出て、SuperCon予選通過したけどコロナで本選が立ち消えになった代わりに富岳使えることになったり、JChO予選(一次予選落ち)に出たり、PCK予選通ったので今度は
本選出たりしてました。あと夏休みにSATの研究始めたり、11月から毎週進捗会に参加したりと、本当にわけが分かりません。共通テストの前日も進捗会に参加してたのはイカれてたと思う。本格的に受験勉強を開始したのは9月の下旬くらいだったと思います。
時間とお金の無駄だと思っていたため塾には行きませんでした。金銭に余裕がある方ではないのでね。あと参考書も買うつもりはなかったんですが、親が勝手にZ会の共通テスト攻略演習というのを注文していました(12か月分3万円)。国語と英語と地理はこの問題集を使いました。
競プロは8月に休止したけど、アニメはずっと見てたしTwitterもやめなかった。

9月

ここで9月の進研模試の結果を見てみましょう。

  • 国語98(現80 + 古18)
  • 英語96(R61 + L35)
  • 数学187(IA87 + IIB100)
  • 物理100
  • 化学63
  • 地理52


...
当時の自分の実力をまとめるとこんな感じだと思います。

  • 国語:現代文は運、rand(60, 90)。古文漢文はカス。
  • 英語:Rは最後まで文章が読み終わらない。語彙力が壊滅的。Lはカス。
  • 数学:まあできる。
  • 物理:まあできる。
  • 化学:計算問題はできる。無機有機はカス。
  • 地理:常識がない(「ロシアは社会主義」「スイスは経済的に少し貧困だよね~」)。

というわけでこの時期から頑張って勉強します。

10月

英語Rはそれまで本文を全部読んでから設問を読んでいました。WPMを改善する方向の努力はあんまり効果が無かったので、立ち回りを工夫することにします。設問を読みつつ本文を読んでいくと意外と最後まで読み切れました。それからコミュ英の授業が教科書の読解から私大過去問の演習に変わりました。貰ったテキストに載っていた英単語がレベル別に分かれていたのが単語を覚えるモチベーションになったと思います。これで20点上がります。
英語Lは中学からほとんど勉強したことがありませんでした(CDプレイヤーを持ってなかったのでしょうがない)。ちなみにYouTubeで英語聴いてもまともに上達しませんでした。初心者がやっても効果ないかもしれん。今回はウェブ音声が入手できたのでやっと勉強します。サンプル問題を一回分復習するとなぜか平均に到達しました。これで30点上がります。
単語を覚えるにあたってそもそもどの単語を覚えれば良いか分からなかったりしたので、よく出てくる評論のテーマで調べてました。WikipediaYouTubeでglobal warming, climate change, air polution, earthquake, volcano, extinction, civilization, hierachy, social class, solar system, self-driving carなどで検索してみると多少対策になります。volcanoの記事を読んでいて、「eruptってなんだっけ...噴火か(n回目)」みたいな。文章の中で同じ単語が何度も出てくるので覚えやすいと思う。
無機化学有機化学の勉強をします。20点上がります。

11月

11月のマーク模試の結果です。

  • 国語122(現68 + 古54)
  • 英語153(R86 + L67)
  • 数学177(IA92 + IIB85)
  • 物理87
  • 化学81
  • 地理50

古典が上がってるのは、現代文を急いで読んで古典をしっかり読んだら意外と内容が取れたからだと思う。
古典の授業が演習になりました。古文単語を少し覚えます。あと基本的に恋と仏教と自然を愛でるくらいしかしないので単語の意味を決め打ちできるのかなあと思ったりしました。漢文は親しみのない意味でも結構熟語で使われてるんだなって気付いた。例えば、

  • 少:若い→少年
  • 経:営む→経営
  • 済:救う→救済

ちなみに「経」と「済」は経世済民で覚えれば良いと思います。こういうのは漢字一字で検索すると少 | 漢字一字 | 漢字ペディアとかが出てくるので、熟語と合わせて馴染みのない意味が見つかったりする。ばらつきが酷いけど古典で50点ほど取れるようになってたと思う。

12月

地理で山脈の位置とか覚え始める(は?)。あと地誌と各国の経済成長とか。一番意外だったのはイスラエルが先進国だったことです。10点上がります。
本番までの足掻き

1月

国名と位置を覚えます(は?)。地誌は民族・言語・宗教、移民難民、紛争の内容とかを調べた。半導体って精密機械じゃないらしいです(時計とか)。
青パックやりました。

本番

本番前日にごちうさの最終話をもう一周しました。「チノおねえちゃん...」で萌え尽きた。
規則正しい生活習慣を送りましょう。


本番で最も重要なのは、受験票を持っていくこと、電車を乗り間違えないこと、名前と受験番号を書くこと、選択問題を間違えないこと、マークをずらさないことです。これが本質だと言っても過言ではない。
本番に自己最高点、受験生の鑑では。でも満点は取れませんでした。英語Rが何故か8割いってた。嬉しい。現代文で運が良くて94点だったの嬉しい。
ありがとう...