まえがき
この記事は、esolang Advent Calendar 2024 の18日目の記事です。
申し訳程度のCSSでFizzBuzz
レギュ ・html使用禁止 ・jsDOM生成のみ ・処理部はcssで書く ・変数を用意する<script>
let i = 100;
onload = () => document.body.innerHTML = '<p></p>'.repeat(i) + `<style>
body {
counter-reset: i 0;
}
p::before {
counter-increment: i 1;
}
p::before {
content: counter(i) " ";
}
p:nth-child(3n)::before {
content: "Fizz";
}
p:nth-child(5n)::before {
content: "Buzz";
}
p:nth-child(15n)::before {
content: "FizzBuzz";
}
</style>`</script>
この記事には、「HTML5 + CSS3がなぜプログラミング言語と言えるか」に関する証明は含まれませんのでご注意ください。
すでにこのあと何をいうか察しがついている方もいらっしゃるでしょうが、頑張ってQuine書いたので許してください。
プログラミング言語とは
プログラミング言語(プログラミングげんご、英語: programming language)とは、コンピュータに対して命令を行うために考案された、正確に定義された記号と規則からなるコンピュータ言語である。
プログラミング言語は、情報を組織し処理するタスクについての理解を容易にし、アルゴリズムを正確に表現することができる。特に、チューリング完全であることが特徴である。
( 引用元: https://ja.wikipedia.org/wiki/プログラミング言語 )
ここにも書いているように、一般的なプログラミング言語の特徴として「チューリング完全」であることが挙げられます。
ということはチューリング完全ならばプログラミング言語であるということです!!!※曲解
チューリング完全であることの証明
チューリング完全を示すための方法としてよくあるのが、すでにチューリング完全であるものを再現するという方法です。
HTML5 + CSS3 は Rule110が再現できるため、チューリング完全であることが示されている他、なぜかBrainfuckのインタプリタが作られていたりします。
すごいですね(困惑)
Quineとは
Quineとは、自身のソースコードと全く同じ見た目の文字列を出力するものです。(一部のずるを除く)
ズルの例をwikipediaから引用させていただくと
入力をそのまま出力するだけのプログラム(Unixではcatというプログラムが利用される)の入力を、そのプログラムのソースファイルとするとか、いくつかのプログラミング言語(の処理系)は空のソースコードを受け取って、何も行わない、という動作をするので、それを利用する手もある。そのような空のプログラムがIOCCCで「規則のはなはだしい悪用」賞を受賞したこともある。以上のようなプログラムはいずれも通常、この問題を解いたものとはみなされない。
(引用元: https://ja.wikipedia.org/wiki/クワイン_(プログラミング) )
また、どうやらチューリング完全であるとQuineができるということが証明されているらしいので、Quineします。
Quineする
CSSって特にQuineしにくいんですよね。
文字挿入もevalも出来ない上に疑似要素で文字出力をするという若干めんどくさい仕様のため文字数が長くなってしまいそうな気がします、、、(事後報告)
スタイリッシュなQuine書きたい(bfのほうが短いレベルで長い)
方針
代入が出来ないので左と右を分けて代入する。
バックスっラッシュをなくすためにクオーテーションを使い分けて変数に代入する。
こんなところですかね、、、?
書く
まあとりあえずstyleタグを用意しないと始まらないのでaタグを用意します。
<style></style>
CSSの変数をcontentで表示ができるようにbefore要素に作ります。
<style>body::before{--a:"<style>body::before{--a:";}</style>
つぎに、エスケープが必要なのは"
と'
で、
右側を代入するための変数がいるので、
全部で4つですね。
<style>body::before{--a:"<style>body::before{--a:";--b:'"';--c:"'";--d:"";}</style>
この4つの変数のみで上の数式を表していくので
<style>body::before{--a:
"
<style>body::before{--a:
"
;--b:
'
"
'
;--c:
"
'
"
;--d:
"
(dの中身)
"
(dの中身)
となるので
それぞれを変数に置き換えていくと
abab';--b:'cbc';--c:'bcb';--d:'bdbd
となるので、これを置き換えると
(styleの閉じタグはcssの文字列内でもhtmlが優先的に処理されてしまうため消しています)
<style>body::before{--a:"<style>body::before{--a:";--b:'"';--c:"'";--d:";content:var(--a)var(--b)var(--a)var(--b)';--b:'var(--c)var(--b)var(--c)';--c:'var(--b)var(--c)var(--b)';--d:'var(--b)var(--d)var(--b)var(--d);}";content:var(--a)var(--b)var(--a)var(--b)';--b:'var(--c)var(--b)var(--c)';--c:'var(--b)var(--c)var(--b)';--d:'var(--b)var(--d)var(--b)var(--d);}
乱雑にCodeGolfして〜 (bodyを消してbeforeをafterにして::を:にしてラストの閉じタグ系を全部消して〜)
完成!!!
<style>:after{--a:"<style>:after{--a:";--b:'"';--c:"'";--d:";content:var(--a)var(--b)var(--a)var(--b)';--b:'var(--c)var(--b)var(--c)';--c:'var(--b)var(--c)var(--b)';--d:'var(--b)var(--d)var(--b)var(--d";content:var(--a)var(--b)var(--a)var(--b)';--b:'var(--c)var(--b)var(--c)';--c:'var(--b)var(--c)var(--b)';--d:'var(--b)var(--d)var(--b)var(--d
あとがき
ここまでお読みいただきありがとうございました!!!!!
今記事を書いているこのコード、記事を書き始める前のコードの4分の1位の長さになりました笑笑
ちなみに、Quineが出来たからと言って確実にチューリング完全であるわけではないですから気をつけてください。
感想です