どうも、108Hassiumです。
皆さんは「4つの4」という数学パズルをご存知でしょうか?
4つの4(よっつのよん)は、4つの4と数学記号を使い、さまざまな数(普通は整数)を作ることを目指すパズル(数学パズル)である。フォーフォーズ(Four fours)ともいう。
4つの4 - Wikipedia「4つの0」は、4つの4を基にした数学パズルです。
起源は不明ですが、私が知る限りでは私が診断メーカーで作成・公開したものが最古です。
診断メーカーでの説明には「細かいルールはご自由に」とありますが、私は普段以下のような演算セットで遊んでいます。
例えば、このルールでは0~8は以下のように作ることができます。
0=0+0+0+0
1=0!+0+0+0
2=0!+0!+0+0
3=0!+0!+0!+0
4=0!+0!+0!+0!
5=(0!+0!+0!)!−0!
6=(0!+0!+0!)!+0
7=(0!+0!+0!)!+0!
8=(0!+0!+0!+0!)!!
ちょっと複雑なものとして、29は以下のように表せます。
29=((((0!+0!+0!)!)!!!!)!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+0!
このように、使える演算をフル活用していけば4つの0だけという厳しそうな制限の下でもで結構自由に数を作ることができます。
では、このルールは万能なのでしょうか?
さっきの診断では0~999までの数が出題されるようになっていますが、全ての数を作れるのでしょうか?
というわけで、括弧、加法、平方根、多重階乗と4つの0で0~999を作れるかどうか考えました。
作戦1:多重階乗による乗法
多重階乗を使うと、ある数に対して小さめの数を掛けることができます。
例えば12に3を掛けて36を作りたい場合、12-3=9かつ12-9*2<0なので36=12!!!!!!!!!となります。
この方法により、小さい約数を多く持つ数を簡単に作れるようになります。
例えば、以下のように2の冪乗と3の冪乗の積で表せる数は3つの0で作れます。
6=(0!+0!+0!)!
12=((0!+0!+0!)!)!!!!
18=((0!+0!+0!)!)!!!
24=(((0!+0!+0!)!)!!!!)!!!!!!!!!
54=(((0!+0!+0!)!)!!!)!!!!!!!!!!!!!!!
※6!!=6*4*2=48のような二つ以上の数が掛けられるパターンについては、使いどころが難しいので極力考えないことにします。
なお、逆に3つの0で作れる数は0~3以外では6の倍数に限られます。
4つの0を使う場合は、3で割り切れない偶数や6n±1型素数なども作れるようになります。
作戦2:平方根による素因数減らし
平方根を使うと、素因数の個数を減らして小さい数を作ることができます。
例えば、29という数を作ることを考えます。
29=30-1と表せるので「3つの0で30を作ってから0!を引く」という方法で作れそうに見えます。
しかし、3つの0でまず6を作り、次に多重階乗で5を掛けようとしてもそれはできないことに気付きます。
この場合、30ではなく30を2乗した900を作り、平方根で30にするという方法があります。
6に5を掛けることはできなくても、まず36を作ってから25を2回に分けて掛けることで900を作ることができます。
ちなみに記事の最初の方で紹介した以下の式では、ちょっと違うルートで900を作っています。
29=((((0!+0!+0!)!)!!!!)!!!!!!!)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+0!
この式では以下の順序で900を作っています。
0!+0!+0!=3
3!=6
6!!!!=12
12!!!!!!!=60
60!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!=900
最後の掛け算を180×5ではなく60×15にすることで、"!"の個数を減らして式を短くしています。
さて、実はこの方法を応用すれば全ての偶数をつくることができます。
例えば998(=2×499)を作る場合、以下のような方法があります。
0!+0!+0!+0!=4
4!!=8
8!!!!=32
32!!!!!!!!!!!!!!!!=512
512!384=216=65536 ※"!"が多すぎるので下付き数字で略記
65536!65037=216×499=32702464
32702464!32453463=216×4993=8142946238464
8142946238464!8080944740463=216×4997=504874864926376165310464
504874864926376165310464!501030679172008158314463=216×49915=1940832763488446995929601024556685640171454464
(216×49915)!1940832763488446995929601024556685640171453965=216×49916=99816=968475548980735050968870911253786134445555777536
968475548980735050968870911253786134445555777536=998
要するに、2を掛けまくって大きい数を作り、残りの約数を掛けてから平方根で小さくするという手法です。
非効率的で非現実的な方法ですが、重要なのは任意の偶数が作れるということです。
これにより、0~999のうち偶数は作れるかどうかを調べる必要が無くなります。
また、作りたい数Nが奇数の場合も、(N+1)²か(N-1)²が3つの0で作れれば4つの0でNが作れます。
作戦3:N²-1法
作戦2により任意の偶数が作れるようになったので、あとは奇数だけを考えればOKです。
ある奇数Nを作りたい場合、N²-1を作ってから0!を足して平方根でNにする、という方法があります。
例えば113を作る場合、113²-1は12768(=32×3×7×19)といういかにも3つの0で作れそうな数になるのでこの方法が使えます。
先述の(N±1)²を使う方法(以下、(N±1)²法)を使う場合、113+1=6×19になるので(113+1)²をつくればいい、と思いきや36!₁₇=36×19×2になってしまうのでうまくいきません。
なお、(N±1)²法が上手くいかなくても(N±1)⁴や(N±1)⁸が作れればNは作れるし、N²-1法も同様にN⁴-1法やN⁸-1法などの代替手段があるのですが、指数がデカいと計算途中で出てくる数が大きくなりすぎたり式が長くなりすぎたりするので、一応両方の手段を覚えておく必要があります。
総当たり
以上の解法を用いて、0~999の整数が4つの0で作れるかどうかを機械的に判定したいと思います。
作成したコードはこちら。
void setup(){
for(int a=0;a<500;a++){
if(!fm(a*2+1)){
println((a*2+1));
}
}
println("end");
}
boolean fm(int a){
if(a<5||tm(a)||tm(a-1)||tm(a+1)||tm(a*a-1)||tm(a*a+1)||tm((a-1)*(a-1))||tm((a+1)*(a+1))){
return true;
}else{
boolean r=false;
for(int b=2;2*b*b<a+2*b&&!r;b++){
if(a%b==0&&fm(a/b)){
r=true;
}
}
return r;
}
}
boolean tm(int a){
if(a<4||a==6){
return true;
}else{
boolean r=false;
for(int b=2;2*b*b<a+2*b&&!r;b++){
if(a%b==0&&tm(a/b)){
r=true;
}
}
return r;
}
}
※言語はProcessingです。
これを実行すると、以下のような結果が出力されます。
9
27
81
173
187
243
247
283
317
437
519
653
677
729
787
823
849
877
907
943
951
977
997
end
これは「4つの0で作れないと判定された数のリスト」なのですが、一部の解法は判定に組み込まれていないため、ここからさらに未使用の解法で作れるものを手作業で潰していく必要があります。
そして試行錯誤の結果、以下のような解を見つけることができました。
173=((((((0!+0!+0!)!)!!!!)!!!!!!!)!31)!1576)!282221+0!
187=((((0!+0!+0!)!)!!)!42+0!)!168
247=(((((0!+0!+0!)!)!!!!)!!!!!!!!!)!26+0!)!192
283=(((((((0!+0!+0!)!)!!!!)!10)!14)!193)!11209)!792871+0!
317=(((((0!+0!+0!)!)!!)!35)!359)!104293+0!
437=(((((0!+0!+0!)!)!!)!37+0!)!510)!10032
519=(((((((0!+0!+0!)!)!!!!)!!!!!!!)!31)!1576)!282221+0!)!170
653=(((((((0!+0!+0!)!)!!!!)!10)!14)!131)!25997)!4221439+0!
677=(((((((0!+0!+0!)!)!!!!)!10)!14)!127)!26951)!4537447+0!
787=(((((((0!+0!+0!)!)!!!)!12)!18)!386)!169645)!22223495+0!
823=((((((0!+0!+0!)!)!!)!38)!377)!49303)!6705547+0!
849=((((((((0!+0!+0!)!)!!!!)!10)!14)!193)!11209)!792871+0!)!280
877=(((((((0!+0!+0!)!)!!!!)!10)!14)!167)!17081)!7614367+0!
907=(((((((0!+0!+0!)!)!!!)!12)!24)!281)!65081)!9781629+0!
943=(((((0!+0!+0!)!)!!!!)!!!!!!!)!32+0!)!1152
951=((((((0!+0!+0!)!)!!)!35)!359)!104293+0!)!948
977=(((((((0!+0!+0!)!)!!!!)!10)!19)!67)!6116)!964714+0!
997=(((((((0!+0!+0!)!)!!!!)!10)!14)!157)!19421)!9840679+0!
Nが大きな素数2つの積のときはN²を作ってから平方根で小さくする解法を、それ以外の場合は3つの0でN⁴-1を作る解法を用いました。(素因数が大きすぎてN⁴-1法が使えないケースでは(N±1)⁴法で代用しています。N⁴-1法を優先して使っているのは単に好みの問題です)
さて、これらの方法でも作れなかった数として、残ったのは以下の5つです。
最終決戦
最後に残った5つの数は、どれも3n(1<n)と書ける数です。
というわけで、3の冪乗数が4つの0で作れるかどうかを考えます。
とりあえず、式の最後で計算される演算が何になるかで場合分けしてみます。
平方根の場合
Mが3の冪乗数になる場合、Mも3の冪乗数でなければなりません。
よって、他の手段で3の冪乗数を作らない限り、平方根の計算で終わる式で3の冪乗数を作ることはできません。
なお3¹は平方数でないため、3¹を作れても平方根により他の3の冪乗数にすることはできません。
多重階乗の場合
3の冪乗数の約数は全て3の冪乗数なので、平方根の場合と同様に他の手段で3の冪乗数を作らない限り多重階乗の計算で終わる式で3の冪乗数を作ることはできません。
3¹は4つの0で作れますが、多重階乗で増やせる約数が2しかないので3²以上の3の冪乗数を作ることはできません。
加法の場合
a+bが3の冪乗数になる場合、aとbを作るのに使う0の個数で以下の2ケースに場合分けすることができます。(加法の可換性により一部のケースを除外しています)
aとbにそれぞれ2個ずつ使う場合
aに3個、bに1個使う場合
まずaとbにそれぞれ2個ずつ使う場合、2個の0で作れる数は0、1、2のみなのでそれらの和で作れる3の冪乗数は3¹のみです。
aに3個使う場合、3個の0で作れる数は0~3と6の倍数(の一部)に限られます。
b=0とする場合、3の冪乗数は6の倍数にはなり得ないため3¹以外の3の冪乗数は作れません。
b=1(=0!)の場合、つまりa+b=a+1の場合、aが3の倍数であればa+bは決して3の倍数になりません。
よってa+bが3の冪乗数になるのはaが3の倍数でないときに限られ、実際にはa=2のときのa+b=3¹しかありえません。
以上より、4つの0と括弧、加法、平方根、多重階乗により3n(1<n)を作ることは不可能であることがわかります。

最後に
以上より、「4つの0」はコンプ不可のクソゲーであることがわかりました。
ところで、診断メーカーにはこんなものもあります。
108Hassiumさんは98を使って99を作りましょう。
多重階乗ゲーム (shindanmaker.com)99=(((((98???????)?????)!!!!)!!!!!!!!!!)??????????????????????????)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
・・・それでは、さようなら。