SATySFiでドドスコ（ラブ注入）してみた話

:::note info
これは「[SATySFi Advent Caleandar 2022](https://adventar.org/calendars/7515)」の3日目の記事です。
（2日目は [bd_gfngfn さん](https://github.com/gfngfn/SATySFi/wiki/v0.1.z-%E3%81%A7%E3%81%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E8%A8%AD%E8%A8%88%E6%A1%88)、4日目は [yozu さん](https://qiita.com/yasuo-ozu/items/bc8f4615ae20d936add9)です。）
:::

先日[「TeX言語でドドスコ」][tex-ddsk]のネタを披露したわけですが、その**当然の帰結**として**​「SATySFiでドドスコ」​**のネタを披露する強い必要性に迫られた気がする<sub>（えっ）</sub>ので、**やってみました**:smiley:

※前提とするSATySFiのバージョンは**0.0.7～0.0.8**です。

※「ドドスコ問題」の詳細については[TeX言語の方の記事][tex-ddsk]を参照してください。ここでは、問題の定義を書いたツイートを載せておきます。

https://twitter.com/Sheeeeepla/status/1554028833942441984

## SATySFiでドドスコしてみた話

というわけで、「ドドスコ問題」を実行するためのSATySFiパッケージ「ddsk」をつくりました。

* [SATySFiでドドスコ（ラブ注入♡）][gist]（Gist）

`ddsk`パッケージの実装コードは以下の通りです。

```text:ddsk.satyg
let_=`888888888888888888888888888888888888888888888888888888888888888888888
~#;}-\$"@`let([(-*);(-/)],nj,(^/)::(&/+-'+.>.*:/),(&-),(!))=((*)::[(/)],(!)
,[`@.]='}#*?;@=#\:<\=$<"|&^?"}~{?;ve;;`;`).':_,,`],[],8)let(*)o(*/)=((o))::
(*/)let([(//);(/-)],[_;(^-);(&/.''<);rec-;(^--)],(/<+->),(/),_::(^*-)::_)=(
[(!)-(!);(!)-/(!)],(^/)*`ドド`*`スコ`*`スコ`*`スコ`*(&-),(!)-*8,(let-rec(>)
`@`i=i|(-)r=(-)^(r)in(>)),(^/)*`ラブ注入♡`*[`\-,::]${'<@,_>:~}"#_#"(`])let
(-:)(*<*+-)(*>-)=(*<*+-)-((*<*+-)-/(*>-)-*(*>-))let-rec(!->)|8=(^-)|_=(^--)
let((/--)::[(/->);(/.>);(/.-)],ov)=([(/-)+(/-);(!)>>(/-);(!)-(/-);(/<+->)-*
(/<+->)],{,'=~[__]:?(})let((!),(/.--)::[(/.*-);(/.->)],_)=(nj,[(/.>)-*(/.>)
-*(/.>)-*(/.>)-*(/.>);((/-)<<((/->)-*(!)-(/-)))-(/-);(!)-*((/--)-*8+(/-))<<
(/->)],`,);[,=$!{vi}{_}/?@~(`)let-rec(&--)|j(*/)8=(*/)^(^*-)|(*-)(*--)(**-)
=let(*/)=((*-)>>((/.>)+(/.>)))-:((/--))in(&--)((*-)-*(/.--)-:(/.*-))((*--)/
!->((*/)-*8))((((**-)+(/.->))-*(/--)+(*/))-:(/.-)-(/.->))let(&*-)(*-)%__._~
=(&--)((*-)-*(/.--)-:(/.*-)-*(/.--)-:(/.*-))`@`((//)-(/.->))let((*),(%./|_>
((/))),(&/'~-:'?.-**>+!<),([love-injector]),_)=((-*),(-/),(),[(&*-)],%/_|.\
.8888888888888888888888888888888888888888888888888888888888888888888888888)
```

……**やっぱり**:upside_down_face::upside_down_face::upside_down_face:

エッ、もしかしたら「TeX言語のドドスコ実装に比べると全然フツーに読めるじゃん:slightly_smiling_face:」ですか？ そうですね……。思い切り努力はしたのですが、これが限界でした……やっぱりSATySFiムズカシイ:cry:<sub>（えっ）</sub>

:::note info
英文字を全く使わないのは無理なので「`love-injector`に含まれる文字だけを使う」という制限規則にしています。SATySFiの英文字名の予約語・プリミティヴのうち実際に使っているのは`in`と`let`と`let-rec`の3つだけです（それ以外は実質的に有意義に使えない）。数字も完全に除くのは無理なので`8`だけ使っています。
:::

このddskパッケージを読み込むと、次の函数が（トップレベルに）定義されます。

* `love-injector`: int → string  
  `love-injector` *seed* は、乱数種[^random]を *seed* としたときの「ドドスコ問題」の出力の文字列。

[^random]: 現状のSATySFiには「コンパイルする度に変わる」ような値を得る方法がおそらく存在しないため、乱数種を入力する形式にしています。ちなみに、擬似乱数発生器は単純な線形合同法で実装しました。

`love-injector`函数の値は文字列（string型）なので、テキスト出力モードでも利用できます。例として「乱数種を80000としてドドスコ問題を実行」するテキスト出力のSATySFI文書を作ってみましょう。

```text:sample.saty
@import: ddsk
love-injector 80000
```

このsample.satyとddsk.satygの2つのファイルを同一のディレクトリに置いた上で、そこで次のコマンドを実行します。

```bash
satysfi --text-mode plain -o out.txt sample.saty
```

出力されたout.txtを見ると……[^outtxt]。

[^outtxt]: ここでは見やすさのため適宜改行を入れた形で掲載します。

```text:out.txt(出力)
ドドドドドドドドドドスコドドスコスコスコドドドドドドスコドド
ドドドドスコスコドドスコスコスコドドスコスコスコスコドドドド
スコスコドドスコスコドドドドドドドドドドドドスコスコスコドド
ドドスコドドスコスコスコドドドドドドドドスコドドドドドドドド
スコスコドドスコスコスコドドドドスコスコスコスコスコスコドド
スコドドドドスコスコスコドドドドスコドドドドスコドドドドスコ
ドドドドスコドドドドスコスコスコスコスコドドスコスコスコドド
ドドドドスコドドスコドドスコスコドドドドドドスコスコドドスコ
スコドドスコドドスコスコスコスコスコドドスコスコスコドドスコ
スコスコドドスコスコスコラブ注入♡
```

ちゃんと**ドドスコできてますね！​**:smiley:

## まとめ

**​「[SATySFi Advent Calendar 2022][satysfiadvent]」ではまだまだ参加者を募集しています！** SATySFiに関するくだらないネタを思いついたら、カレンダーに登録してどんどん披露していきましょう！:information_desk_person:

アッ、**くだらなくない**記事ももちろん大歓迎です:upside_down_face:

[awesome-ddsk]: https://github.com/Comamoca/Awesome-DDSK
[gist]: https://gist.github.com/zr-tex8r/ce69621031ee5030355cef7fec2ecc4c
[satysfiadvent]: https://adventar.org/calendars/7515
[tex-ddsk]: https://qiita.com/zr_tex8r/items/0cc96144dd46c212a989