※この記事には通常では考えられないような記法が多々登場します
クソコードって見るたびにイラッときますよね?
ということでその憂さ晴らしで逆にどこまでクソコードかけるかなっていうやつです。
(EsolangでFizzBuzz回です)
おまけクソコード集
とあるプロジェクト(個人開発)でタイマー周りを作っていたんですけど、
天災的にコピペが駆使されていて()
なんかもうすごくて、、、
まあEsolang、CodeGolf勢なんで耐性はあるんですけども
<input type="button" id="start">
<input type="button" id="rap" value="lap">
︙
<button id="start_button" onclick="start()">
︙
<script>
startButton = document.getElementById('start');
let startTime;
function start() {
setInterval("updateClock();", 1000);
updateClock();
// document.getElementById("osareta").click();
}
︙
function start() {
︙
}
まあ一から全部書き直させていただいたんですけも、、
コード
先に今回書いたFizzBuzzのコードを乗せます
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
ᅠ=ᅠ=>(ㅤ=ᅠ=>String.fromCharCode(ᅠ))(ᅠ[ᅟ++]),ᅟ=ᅠᅠ=0,ᅠ=[66,70,105,117,122],ᅠᅟ=ᅠ(),ᅟᅠ=ᅠ()+ᅠ(),ᅠ[-ᅟ/ᅟ]=this[ㅤ(ᅠ[ᅠᅠ]/(ᅟ+ᅟ)*ᅟ**--ᅟ)+(ᅠ[ᅠᅟ]=ㅤ(ᅠ[ᅟ]+ᅟ++*ᅟ))+ㅤ(ᅠ[--ᅟ]+ᅟ+++ᅟ)+ㅤ(ᅠ[ᅟ--]-ᅟ)+ᅠ[ᅠᅟ]+(ᅠ[ᅟᅠ]=ㅤ(ᅠ[ᅟ++]+ᅟ))+ㅤ(ᅠ[--ᅟ]-ᅟ-ᅟ++)][ᅠ[ᅟᅠ]+ᅠ[ᅠᅟ]+ㅤ(ᅠ[--ᅟ]-ᅟ++)],ᅠᅟ+=ᅠ(),ᅠᅟ+=ᅠ=(ᅠ=ᅠ())+ᅠ,ᅟᅠ+=ᅠ,ᅠ[ᅟ]=ᅟ/ᅟ,ᅠ[ᅟ+ᅠ[ᅟ]]=ᅟ-ᅠ[ᅟ]-ᅠ[ᅟ],ᅠ=ᅠ=>ᅠᅠ%ᅠ,(ㅤ=()=>{ᅠᅠ+=ᅠ[ᅟ],ᅠ[-ᅟ/ᅟ](ᅠ(ᅠ[ᅟ+ᅠ[ᅟ]]*ᅟ)?ᅠ(ᅠ[ᅟ+ᅠ[ᅟ]])?ᅠ(ᅟ)?ᅠᅠ:ᅠᅟ:ᅟᅠ:ᅟᅠ+ᅠᅟ),ᅠᅠ<ᅠ[ᅠ[ᅟ]+ᅠ[ᅟ]]-ᅟ?ㅤ():ᅟ})()
はい。
解説
じゃあ解説していきます。
変数
まず見たときにスペースが多いと思ったことでしょう。
まあ初っ端からᅠ=
なんて入っていますので。
なんでこれが成り立っているのかと言うと、
U+115F:ᅟ
、U+1160:ᅠ
、U+3164:ㅤ
、U+FFA0:ᅠ
この4つです。
これらは、空白文字の中で"唯四"空白として扱われていない文字です。
変数はすべて、この4字の組み合わせでできています。
このままだと解説に影響が出るので、とりあえず変数名を変えて、整形していきます。
a=a=>(b=a=>String.fromCharCode(a))(c[d++]),
d=e=0,
c=[66,70,105,117,122],
f=a(),
g=a()+a(),
c[-d/d]=this[
b(c[e]/(d+d)*d**--d)+
(c[f]=b(c[d]+d++*d))+
b(c[--d]+d+++d)+
b(c[d--]-d)+
c[f]+
(c[g]=b(c[d++]+d))+
b(c[--d]-d-d++)
][
c[g]+c[f]+b(c[--d]-d++)
],
f+=a(),
f+=a=(a=a())+a,
g+=a,
c[d]=d/d,
c[d+c[d]]=d-c[d]-c[d],
a=a=>e%a,
(b=()=>{
e+=c[d],
c[-d/d](a(c[d+c[d]]*d)?
a(c[d+c[d]])?
a(d)?
e
:
f
:
g
:
g+f
),
e<c[c[d]+c[d]]-d?b():d
})()
これはひどい
誰だよこんなクソコード書いたやつ
実務でこんなコード来たら発狂しますね。
1~5行目
a=a=>(b=a=>String.fromCharCode(a))(c[d++]),
d=e=0,
c=[66,70,105,117,122],
f=a(),
g=a()+a(),
まず1行目です
変数を使いまわし始められかけています。
はじめに
b = a => String.fromCharCode(a)
が行われています。
返り値は
a => String.fromCharCode(a)
です。
つぎに
c[d++]
が行われます
c
のd
番目を参照したあとにd
をインクリメントしてますね(?)
まあまだそんな変数定義されていないわけですが。
最後に
a = a => (a => String.fromCharCode(a))[c[d]]
が行われます。
fromCharCode
内のa
は(a =>
のa
なのでa = a =>
の2つ目のa
は一切使われないダミーですね。
2行目と3行目は見たままですね。
4行目と5行目はa
を実行してるだけです。
a()
の1回目ではc[d++]
はc[0]
で66
、
2回目は70
、
3回目は105
なので、
文字はそれぞれ'B'
、'F'
、'i'
、
f = 'B';
g = 'F' + 'i';
なので、要するに
a = () => {
String.fromCharCode(c[d]);
d++;
};
b = num => {
String.fromCharCode(num);
};
c = [66,70,105,117,122];
d = 3;
e = 0;
f = 'B'
g = 'Fi'
です。
6~16行目
c[-d/d]=this[
b(c[e]/(d+d)*d**--d)+
(c[f]=b(c[d]+d++*d))+
b(c[--d]+d+++d)+
b(c[d--]-d)+
c[f]+
(c[g]=b(c[d++]+d))+
b(c[--d]-d-d++)
][
c[g]+c[f]+b(c[--d]-d++)
],
まず6行目です
これはc == [66,70,105,117,122]
の-d/d == -1
個目に右辺を代入します。
ここで留意するべきなのが、
↓
↓
↓
↓
↓
右から1個目に代入しているわけではなく、c[-1]に代入している点です
pythonのように高性能ではありません!!(笑)
何わろとんねん
つぎは7行目です
b(c[e]/(d+d)*d**--d)
b
はString.fromCharCode
、
e
は0
なので、c[e]
は66
になって、
String.fromCharCode(66 / (d+d) * d**(--d))
d
はこの時点では3
なので、
(d+d)
は6
、 * d
は3
、 --d
は2
になります。
終わってますね!
なので、66 / (d+d) * d**(--d)
は99
になるので、
この行は'c'
になり、d = 2
になります。
つぎに8行目です
(c[f]=b(c[d]+d++*d))
f
は'B'
なので、c['B']
に代入します。(???)
bはfromCharCode
なので、
c['B'] = String.fromCharCode(c[d] + d++ * d)
d
はこの時点では2
なので、
c[d]
は105
、 d++
は2
、 * d
は3
になります。
なので、c[d] + d++ * d
は111
になるので、
この行は'o'
になり、d = 3
になります。
つぎに9行目です
b(c[--d]+d+++d)
d+++d
は(d++) + d
として処理されるので(結果は一緒)
String.fromCharCode(c[--d] + (d++) + d)
dはこの時点では3
なので、
c[--d]
は105
、 d++
は、2
+ d
は3
になります。
なので、c[--d]+d+++d
は110
になるので、
この行は'n'
になり、d = 3
になります。
これ以上言うこともないので最終的にどうなるかと言うと、
c[-1] = this['console']['log'];
です。
ただconsole.log
を代入するためだけにこんなに作業していたんですね。
いや直接代入するな 今更っすね
17~22行目
f+=a(),
f+=a=(a=a())+a,
g+=a,
c[d]=d/d,
c[d+c[d]]=d-c[d]-c[d],
a=a=>e%a,
まず17行目です
f
にa()
を足しています。
この時点でd
は3
なのでc[d++]
は117
、a()
は'u'
になります
これにより、f = 'Bu'
になります。
18行目です。
f+=a=(a=a())+a
まず、
a = a()
が処理されて、
この時点でd
は4
なのでc[d++]
は122
、a()
は'z'
になります。
なのでa = 'z'
に、d = 5
変わります。
このあとに
a = a + a
が実行されて、a = 'zz'
になります。
それがf
に足されるので、
f = Buzz
になります。
19行目!
g
にa
が足されて
g = 'Fizz'
になる!!!
終
制作・著作
━━━━━
ⓃⒽ③
20行目です(笑)
c[d]=d/d
d
は5
なので、c[5] = 1
になります
21行目です
c[d+c[d]]=d-c[d]-c[d]
d
は5
、c[5]
は1
なのでc[6]
に代入しているようです
d - c[d] - c[d]
は5 - 1 - 1
で3
になるので
c[6] = 3
となります。
シンガポールに初音ミクを添えて!!!!
やっと22行目です!
a=a=>e%a
e
を割って余りを求める関数をaに入れています。
終わりたい
23、24行目
おめでとうございます!!
ここからがmainです!!
結構簡単だけどね(ぼそっ)
(b=()=>{
e+=c[d],
23行目はそのままです
24行目だっ!!
dはもうずっと固定です。
e+=c[d]
なのでc[5]
は1
、e
をインクリメントしてるだけです。
25~35行目、、、!!
c[-d/d](a(c[d+c[d]]*d)?
a(c[d+c[d]])?
a(d)?
e
:
f
:
g
:
g+f
),
の部分です
c[-d/d]
はc[-1]
でconsole.log
が入っています。
いったんif
に書き直します。
if(a(c[d+c[d]]*d)) {
if(a(c[d+c[d]])) {
if(a(d)) {
console.log(e);
} else {
console.log(f);
}
} else {
console.log(g);
}
} else {
console.log(g + f)
}
25~27行目
a(x)
はe % x
と同義で、
d
が5
でc[5]
が1
なことを踏まえると、
c[d + c[d]]
はc[5 + 1]
でc[6]
より3
d
をかけると15
になるので、
if(e % 15) { //25
if(e % 3) { //26
if(e % 5) { //27
︙ //28
} else { //29
︙ //30
}
} else { //31
︙ //32
}
} else { //33
︙ //34
} //35
となり、
e % x
は割り切れなかったときにTruthy
になります。
ということは15
で割り切れたら1つ目のif
のelse
が
15
で割り切れず、3
で割り切れたら2つ目のif
のelse
が
3
で割り切れず、5
で割り切れたら3つ目のif
のelse
が
何も割り切れなかったら3つ目のif
がの上側が実行されます!!
28、30、32、34
console.log(e);
} else {
console.log(f);
}
} else {
console.log(g);
}
} else {
console.log(g + f)
e
には数字が、f
には'Buzz'
が、g
には'Fizz'
が入っていて、
g + f
は'FizzBuzz'
になります。
##37、38行目!!!ラスト!!
(b=()=>{
︙
e<c[c[d]+c[d]]-d?b():d
})()
先に、38行目はb=(){}
で返される関数b
を実行しています!
37行目!
e<c[c[d]+c[d]]-d?b():d
c[d]
はc[5]
で1
c[1 + 1]
はc[2]
で105
書き直すと、
e < 105 - 5 ? b() : 5
e < 100
ならb()
を実行して、そうでないなら5を返す再帰関数!!!!
終わりいいいい!!!!!!!!!!!
最後に
ここまでのご閲読、ありがとうございました!!!そしてお疲れ様です!
タイトル的にも選手権なのでコメントに、、、
明らかにわざとなものでも、
ほんとにあるものでも構わないので!!(露骨な稼ぎ)
企画とかも募集してます!↖今回初めてsup使った
じゃあ、さようなら!