ドグラ・マグラのキチガイ地獄外道祭文が読んでて楽しい

ドグラ・マグラ夢野久作の長編小説で、構想十年執筆十年という大傑作だ。この本は小説の枠組みにとらわれず論文、演説、詩、歌、映画、漢文などで物語が構成されていて、あまりに奇妙なもんだから日本三大奇書の一つに数えられている。本記事のタイトルの、なんとも禍々しく文字列「キチガイ地獄外道祭文」は、この本の歌の部分だ。この歌は精神医学の専門家・正木博士が精神病と精神病院の実態を暴き、博士の新しい最先端の精神病院を建設する金を集めるために日本全国各地で歌ったものだ。なんとなく話がつかめたところで、二度か三度下の文章音読してほしい。これは歌の最初の部分から引用したものである。

▼あ――ア。外道祭文キチガイ地獄。さても地獄をどこぞと問えば。娑婆シャバというのがここいらあたりじゃ。ここで作った吾が身の因果が。やがて迎えに来るクル、クルリと。眼玉まわして乗る火の車じゃ。めぐりメグって落ち行く先だよ。修羅や畜生、餓鬼道越えて。ドンと落ちたが地獄の姿じゃ。針の山から血の池地獄大寒地獄に焦熱地獄剣樹ケンジュ地獄や石斫イシキリ地獄。火煩カボン、熱湯、倒懸 サカヅリ地獄と。数をつくした八万地獄じゃ。娑婆で作った因果のムクいで。切られ、砕かれ、アブられ、煮られ。阿鼻アビや叫喚七転八倒。死ぬに死なれぬ無限の責め苦じゃ。もしもその声、聞いたら最後じゃ。頭張り裂けクタバルなんぞと。高いトコから和尚オショウの談義じゃ。……スカラカ、チャカポコチャカポコチャカポコチャカポコチャカポコ……

 

まず真っ先に句読点が不自然なこと、次に文体が普通に喋るのとなにか違うことが分かるだろう。そして音読を終えるころにはあるリズムに気づいたはずだ。「言葉が七音ごとに切れるようになっている!」七音、七音、ああまた七音。次のその次も。なかなかイメージできない方は西村俊彦さんの音読動画を聞いてみるといい。該当箇所は5:16:21あたりだ。

 

youtu.be

西村俊彦さんの朗読は歌とマッチして、とてもリズミカルで中毒性が高い。歌は動画で1時間20分くらい、文庫本で30ページ(だったはず)はあるのだが、僕はもう150回以上

聴いてるし半分くらい空で歌えるようになってきた。何遍も聞いてると自分でも七七調の文章を作文してみたい気持ちになってきた。「話にならない」とか「未来が見えない」とか、会話の中で出てくる言葉が七音だと気持ちい感じになる。

 

七七調について調べていくとこのサイトを見つけた。

ナナナナ|俳句でも短歌でもない七七を投稿しよう

確かにこれは心地よい。でも、コレジャナイ感..

キチガイ地獄外道祭文は全体が長い文章のようで、まとまり・軸がある。一方こっちは短く、短歌のお尻14音を切り取ったようにしか見えず、キチガイ地獄外道祭文と違う。

 

もっと七七調の文章が読みたい。もし誰かいい文章を知っているなら、コメント欄に貼ってほしい。

AtCoderで使えるRustのクレートについて調べてみた

使えるライブラリは下のファイルから取ってきた。

github.com

日本語の不自然な点やクレートの説明で間違っている点などがあったらコメントやDMでぜひ教えてください。

ac-library-rs

ac_library - Rust C++AtCoder LibraryのRust版。 セグ木に関数ではなく型を渡すなど細かいところが違って、初めに使ったときは戸惑った。いつか使い方をブログに書く。

once_cell

once_cell - Rust 一回しか初期化されない値に使うらしい。Javaでいうシングルトン的な? 同じような機能が標準ライブラリに追加されたそうなので、AtCoderのRustのバージョンが更新されたら使うことはなくなるかもしれない。(参考:https://zenn.dev/reoring/articles/470db2fa949b44)

static_assersion

static_assertions - Rust 名前の通り、静的(=コンパイル時)アサーションが使える。

extern crate static_assertions as sa;

sa::const_assert!(true);

varisat

varisat - Rust Varisat - Varisat Manual SATソルバーという、なにやら数学の論理代数の問題を解くライブラリらしい。僕にはよくわからなかった。

memoise

memoise - Rust 関数をメモ化してくれる超絶便利なライブラリ。再帰関数と一緒に使いたい。

use memoise::memoise_map;

#[memoise_map(n, k)]
fn comb(n: usize, k: usize) -> usize {
    if k == 0 {
        return 1;
    }
    if n == 0 {
        return 0;
    }
    comb(n - 1, k - 1) + comb(n - 1, k)
}

argio

argio - Rust 標準入力と出力の流れを関数みたいに書けるライブラリ。テストしやすそう。

#[argio]
fn main(n: usize, x: [i64; n]) -> i64 {
    x.into_iter().sum()
}

bitvec

bitvec - Rust C/C++のビットフィールドみたいに、1 bitごとの演算ができるライブラリ。メモリが制限されてるときに使うのかな。

counter

counter - Rust 配列の要素をカウントしてくれるライブラリ。A問題やB問題で使えそう。

let by_common = "eaddbbccc".chars().collect::<Counter<_>>().most_common_ordered();
let expected = vec![('c', 3), ('b', 2), ('d', 2), ('a', 1), ('e', 1)];
assert!(by_common == expected);

hashbag

hashbag - Rust 重複できるSetを提供するライブラリ。これも要素をカウントするときに使えそう。

use hashbag::HashBag;
// Type inference lets us omit an explicit type signature (which
// would be `HashBag<String>` in this example).
let mut books = HashBag::new();

// Add some books.
// Since we are a library, we have many copies.
books.insert("A Dance With Dragons".to_string());
books.insert("To Kill a Mockingbird".to_string());
books.insert("To Kill a Mockingbird".to_string());
books.insert("The Odyssey".to_string());
books.insert("The Odyssey".to_string());
books.insert("The Odyssey".to_string());
books.insert("The Great Gatsby".to_string());
books.insert("The Great Gatsby".to_string());
books.insert("The Great Gatsby".to_string());
books.insert("The Great Gatsby".to_string());

// When we count the number of books, duplicates are included.
assert_eq!(books.len(), 10);

// Check for a specific one.
if books.contains("The Winds of Winter") == 0 {
    println!("We have {} books, but The Winds of Winter ain't one.",
             books.len());
}

// Remove a book.
let had_copies = books.remove("The Odyssey");
// Remove returns how many copies of that book we had.
assert_eq!(had_copies, 3);

// Iterate over everything.
// Duplicates will be listed multiple times.
for book in &books {
    println!("{}", book);
}

// Iterate over each distinct book.
for (book, copies) in books.set_iter() {
    println!("{} ({} copies)", book, copies);
}

// Extract the books and their counts.
for (book, copies) in books {
    println!("{} ({} copies)", book, copies);
}

pathfinding

pathfinding - Rust BFSやDFS、ダイクストラなど経路探索アルゴリズムを提供するライブラリ。使いこなせたら強そう。いつか使い方の記事を書きたい。

recur-fn

recur_fn - Rust クロージャ再帰ができるライブラリ。クロージャ再帰することなんてあるのかな。

use recur_fn::{recur_fn, RecurFn};

let fib = recur_fn(|fib, n: i32| {
    if n <= 1 {
        n
    } else {
        fib(n - 1) + fib(n - 2)
    }
});

assert_eq!(55, fib.call(10));

indexing

indexing - Rust 配列とかベクターの要素を境界チェックなしで取得できるライブラリ。これを使わないといけないくらい時間がシビアなことあるのかな。

amplify

amplify - Rust Rustの標準ライブラリの拡張というか糖衣構文的なのが使えるライブラリ。例えばB木やHashMapを生成するマクロとかが使える。

amplify_derive

amplify_derive - Rust deriveの拡張。競プロで使うことはなさそう。

amplify_num

amplify_num - Rust i1024とかu1とか数値のいろんな型が使えるライブラリ。

easy-ext

easy_ext - Rust 簡単に既存の構造体に関数を生やせるライブラリ。 例えば、

use easy_ext::ext;

#[ext(ResultExt)]
pub impl<T, E> Result<T, E> {
    fn err_into<U>(self) -> Result<T, U>
    where
        E: Into<U>,
    {
        self.map_err(Into::into)
    }
}

これが

pub trait ResultExt<T, E> {
    fn err_into<U>(self) -> Result<T, U>
    where
        E: Into<U>;
}

impl<T, E> ResultExt<T, E> for Result<T, E> {
    fn err_into<U>(self) -> Result<T, U>
    where
        E: Into<U>,
    {
        self.map_err(Into::into)
    }
}

こうなるらしい。

multimap

multimap - Rust 鍵と値の関係が一対多のMapを提供するライブラリ。

btreemultimap

btreemultimap - Rust B木のmultimapを提供するライブラリ。

bstr

bstr - Rust バイト文字列を扱えるライブラリ。u8の配列にStringの関数を使えるってことかな?

az

az - Rust キャストを関数でできるライブラリ。isizeをusizeにキャストするときとかに、負の値だった場合のエラー処理みたいなのを書くときに使えそう。

glidesort

glidesort - Rust 特殊な条件下での最適なソートを提供するライブラリらしい。

tap

tap - Rust

use tap::prelude::*;

struct One;
fn start() -> One { One }
struct Two;
fn end(_: One) -> Two { Two }

let val: Two = start().pipe(end);

// without pipes, this would be written as
let _: Two = end(start());

こんな感じに処理の流れをわかりやすくするライブラリらしい。他にも機能がいくつかあったけどよくわからなかった。

omniswap

omniswap - Rust 変数の値を簡単に入れ替えれるマクロを提供するライブラリ。標準のstd::mem::swapだとどうしてもエラーが起きてしまうケースがあるらしい。

multiversion

multiversion - Rust CPUの拡張機能を利用してプログラムを高速化するライブラリ。

num

num - Rust num-bigint、num-complex、num-integer、num-iter、num-rational、num-traits、num-deriveをpub useしたクレート。このライブラリ群は本当に競プロに使えるので覚えておきたい。

num-bigint

num_bigint - Rust 名前の通り、多倍長整数を扱えるライブラリ。

num-complex

num_complex - Rust 複素数を扱えるライブラリ。競プロで複素数を使うことなんてあるのかな。

num-integer

num_integer - Rust 最小公倍数や累乗根などを計算してくれるライブラリ。自分でコードを書くとバグを生んでしまうかもしれないのでこういうライブラリに頼っていきたい。

num-iter

num_iter - Rust Rangeを拡張したものをが扱えるライブラリ。標準のものとどう違うのかわからなかった。

num-rational

num_rational - Rust 分数が扱えるライブラリ。これは使える。 例えば、

use  num_rational::Ratio;
let one_third = Ratio::new_row(1, 3);

みたいに。丸誤差とか四則演算はもちろんできる。

num-traits

num_traits - Rust 数値型にいろんな関数を生やすライブラリ。これ使うことあるのかな..

num-derive

num_derive - Rust num-traitsを利用して簡単に列挙型とかに関数を生やせるライブラリ。これも使うことあるのかな..

ndarray

ndarray - Rust n次元のコンテナ、例えばベクトルや行列を表現できるライブラリ。numpy的な?

nalgebra

nalgebra - Rust ベクトルとか行列とか線形代数のライブラリ。

alga

alga - Rust これも代数のライブラリ。アフィン変換とか回転とかの行列を簡単に作れる。

libm

libm - Rust muslっていうCのライブラリ(https://musl.libc.org/)のRust版らしい。対数とか三角関数とか基本的な数学の関数が使える。

rand

rand - Rust 名前の通り、乱数を生成できるライブラリ。ヒューリスティックで使うのかな?

getrandom

getrandom - Rust これも乱数を生成できるライブラリ。こっちはOSの乱数生成機を使うらしい。WinからHaikuBSD3DSまでサポートしてる。

rand_chacha

rand_chacha - Rust randクレートの内部で使われているライブラリ。

rand_core

rand_core - Rust randクレートの内部で使われているライブラリ。

rand_hc

rand_hc - Rust HC128の乱数生成機を使えるライブラリ。よく分からない。

rand_pcg

rand_pcg - Rust randクレートの内部で使われているライブラリ。

rand_distr

rand_distr - Rust randクレートのrand::distributionsの上位互換のライブラリ。確率分布から乱数を生成するらしい。

petgraph

petgraph - Rust グラフデータ構造とグラフ関連のアルゴリズムを提供するライブラリ。

indexmap

indexmap - Rust イテレートするときの順序が保証されるmapとsetを提供するライブラリ。

regex

regex - Rust 正規表現を提供するライブラリ。標準ライブラリにありそうだけどないらしい。

lazy_static

lazy_static - Rust 遅延評価をマクロで扱えるようにするライブラリ。遅延評価された値を配列に入れるとか関数に入れるとかいう使い方はできない。コレジャナイ感

ordered-float

ordered_float - Rust 比較できる浮動小数点を実装するライブラリ。比較演算子で比較するのとどう違うんだろう..🤔

ascii

ascii - Rust ASCIIのみの文字列、文字を提供するライブラリ。

permutohedron

permutohedron - Rust 順列を生成するライブラリ。ドキュメント貧弱だし使いづらそう。

superslice

superslice - Rust スライスを拡張するライブラリ。lower_boundとか順列の生成とかができる。

itertools

itertools - Rust 順列とかzipとか便利なのが使えるライブラリ。順列を作るならドキュメントもしっかりしてるしこれが一番良さそう。

itertools-num

itertools_num - Rust itertoolsを拡張したライブラリ。これにどういう機能があるのかよく分からなかった。

maplit

maplit - Rust B木とかHashMapを簡単に作れるマクロを提供するライブラリ。

either

either - Rust Eitherって名前の、LeftとRightの二要素を持つ列挙型を提供するライブラリ。これ使うことあるのかな..?

im-rc

im_rc - Rust 普遍のコレクションを提供するライブラリ。ドキュメントがめちゃくちゃ長い。

fixedbitset

fixedbitset - Rust 固定長のビットセットを提供するライブラリ。CPUの拡張命令SIMDが使われているので多分高速。

bitset-fixed

bitset_fixed - Rust こっちも固定長のビットセットを提供するライブラリ。ドキュメントがあんまり充実してない。

proconio

proconio - Rust めちゃくちゃ簡単に標準入力から値を受け取れるようにしてくれるライブラリ。これなしでRust使って競プロは難しそう。

text_io

text_io - Rust プロンプト付きで標準入力から値を受け取れるようにしてくれるライブラリ。プロンプトなんて出したらプログラムの標準出力の結果が変わってしまいWAになるので、競プロで出番はなさそう。

rustc-hash

rustc_hash - Rust 高速な非暗号ハッシュを提供しているライブラリ。Rustのコンパイラfirefoxで使われているらしい。

smallvec

smallvec - Rust 小さなサイズのvectorを提供するライブラリ。stdに依存していないので組み込みとかに使えそう。競プロでは使わないかな。