Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

畳の敷き詰め方は何通り? -プログラミング編-

$
0
0

昨日の謎の部分でした数式をプログラミングしてみましょう。



前者でも後者でもいいけど、計算量の少ないのは後者ですね。

途中の値の推移も見たいというのもありますね。

有理数、無理数、いろいろと出てきた上で、掛け算を繰り返すと、最終的に整数になるという不思議なところも見たいですよね。

途中経過も含めて表示するようなプログラムを書いてみましょう。

まずはC言語で。

tatami.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[])
{
    int i, j, m, n;
    long double p, c, ci, cj;

    if ( argc != 3 ) return EXIT_SUCCESS;
    m = atoi(argv[1]);
    n = atoi(argv[2]);
    if ( n < 1 || m < 1 ) return EXIT_SUCCESS;
    printf("%.1f[間]×%.1f[間]=%.1f[坪] (%.1f[畳間])\n", m/2.0, n/2.0, m*n/4.0, m*n/2.0);
    printf("での畳の敷き詰めパターン数は、\n");
    if ( m*n%2 ) {
        printf("半畳が必要なので計算しません。\n");
        return EXIT_SUCCESS;
    }
    if ( m*n > 100 ) {
        printf("広すぎるため計算しません。\n");
        return EXIT_SUCCESS;
    }
    fprintf(stdout, "Π[i=1, %d/2] Π[j=1, %d/2] (4cos(iπ/(%d+1))^2 + 4cos(jπ/(%d+1))^2)\n", m, n, m, n);
    p = 1;
    fprintf(stdout, "= %f\n", (double)p);
    for (i=1; i<=m/2; i++)
    for (j=1; j<=n/2; j++) {
        ci = cosl(i*M_PI/(m+1));
        cj = cosl(j*M_PI/(n+1));
        c = 4*ci*ci+4*cj*cj;
        p *= c;
        printf("* (4*%f^2 + 4*%f^2) = * %f = %20.6f\n", (double)ci, (double)cj, (double)c, (double)p);
    }
    printf("%.f通りです。\n", (double)p);

    return EXIT_SUCCESS;
}

m、nの値を実行時の引数に与えると途中経過も表示して解を求めます。

m=10、n=10を与えたときの出力です。

> tatami 10 10
5.0[間]×5.0[間]=25.0[坪] (50.0[畳間])
での畳の敷き詰めパターン数は
Π[i=1, 10/2] Π[j=1, 10/2] (4cos(iπ/(10+1))^2 + 4cos(jπ/(10+1))^2)
= 1.000000
* (4*0.959493^2 + 4*0.959493^2) = * 7.365014 =             7.365014
* (4*0.959493^2 + 4*0.841254^2) = * 6.513337 =            47.970820
* (4*0.959493^2 + 4*0.654861^2) = * 5.397877 =           258.940603
* (4*0.959493^2 + 4*0.415415^2) = * 4.372786 =          1132.291740
* (4*0.959493^2 + 4*0.142315^2) = * 3.763521 =          4261.403876
* (4*0.841254^2 + 4*0.959493^2) = * 6.513337 =         27755.959926
* (4*0.841254^2 + 4*0.841254^2) = * 5.661660 =        157144.809517
* (4*0.841254^2 + 4*0.654861^2) = * 4.546200 =        714411.787943
* (4*0.841254^2 + 4*0.415415^2) = * 3.521109 =       2515521.460545
* (4*0.841254^2 + 4*0.142315^2) = * 2.911844 =       7324806.269918
* (4*0.654861^2 + 4*0.959493^2) = * 5.397877 =      39538406.144045
* (4*0.654861^2 + 4*0.841254^2) = * 4.546200 =     179749515.829040
* (4*0.654861^2 + 4*0.654861^2) = * 3.430741 =     616673970.216517
* (4*0.654861^2 + 4*0.415415^2) = * 2.405649 =    1483501030.706768
* (4*0.654861^2 + 4*0.142315^2) = * 1.796384 =    2664938073.674485
* (4*0.415415^2 + 4*0.959493^2) = * 4.372786 =   11653202827.517490
* (4*0.415415^2 + 4*0.841254^2) = * 3.521109 =   41032192205.400810
* (4*0.415415^2 + 4*0.654861^2) = * 2.405649 =   98709046220.157761
* (4*0.415415^2 + 4*0.415415^2) = * 1.380557 =  136273471061.544750
* (4*0.415415^2 + 4*0.142315^2) = * 0.771293 =  105106717745.688050
* (4*0.142315^2 + 4*0.959493^2) = * 3.763521 =  395571351925.112180
* (4*0.142315^2 + 4*0.841254^2) = * 2.911844 = 1151842098836.071800
* (4*0.142315^2 + 4*0.654861^2) = * 1.796384 = 2069151150226.681200
* (4*0.142315^2 + 4*0.415415^2) = * 0.771293 = 1595920939166.662800
* (4*0.142315^2 + 4*0.142315^2) = * 0.162028 =  258584046368.000670
258584046368通りです。

これと同様のことを、多倍長電卓LMで行うと、

= 1.0000000000
* (4*0.9594929736^2 + 4*0.9594929736^2) = * 7.3650141313 =             7.3650141313
* (4*0.9594929736^2 + 4*0.8412535328^2) = * 6.5133370917 =            47.9708197222
* (4*0.9594929736^2 + 4*0.6548607339^2) = * 5.3978773891 =           258.9406031158
* (4*0.9594929736^2 + 4*0.4154150130^2) = * 4.3727855978 =          1132.2917399832
* (4*0.9594929736^2 + 4*0.1423148383^2) = * 3.7635211184 =          4261.4038756546
* (4*0.8412535328^2 + 4*0.9594929736^2) = * 6.5133370917 =         27755.9599258706
* (4*0.8412535328^2 + 4*0.8412535328^2) = * 5.6616600520 =        157144.8095174240
* (4*0.8412535328^2 + 4*0.6548607339^2) = * 4.5462003495 =        714411.7879434985
* (4*0.8412535328^2 + 4*0.4154150130^2) = * 3.5211085581 =       2515521.4605448070
* (4*0.8412535328^2 + 4*0.1423148383^2) = * 2.9118440788 =       7324806.2699182778
* (4*0.6548607339^2 + 4*0.9594929736^2) = * 5.3978773891 =      39538406.1440454570
* (4*0.6548607339^2 + 4*0.8412535328^2) = * 4.5462003495 =     179749515.8290402616
* (4*0.6548607339^2 + 4*0.6548607339^2) = * 3.4307406469 =     616673970.2165163577
* (4*0.6548607339^2 + 4*0.4154150130^2) = * 2.4056488556 =    1483501030.7067675365
* (4*0.6548607339^2 + 4*0.1423148383^2) = * 1.7963843762 =    2664938073.6744829039
* (4*0.4154150130^2 + 4*0.9594929736^2) = * 4.3727855978 =   11653202827.5174821530
* (4*0.4154150130^2 + 4*0.8412535328^2) = * 3.5211085581 =   41032192205.4007785946
* (4*0.4154150130^2 + 4*0.6548607339^2) = * 2.4056488556 =   98709046220.1576707648
* (4*0.4154150130^2 + 4*0.4154150130^2) = * 1.3805570642 =  136273471061.5446081319
* (4*0.4154150130^2 + 4*0.1423148383^2) = * 0.7712925849 =  105106717745.6879098829
* (4*0.1423148383^2 + 4*0.9594929736^2) = * 3.7635211184 =  395571351925.1116438744
* (4*0.1423148383^2 + 4*0.8412535328^2) = * 2.9118440788 = 1151842098836.0702488018
* (4*0.1423148383^2 + 4*0.6548607339^2) = * 1.7963843762 = 2069151150226.6779917580
* (4*0.1423148383^2 + 4*0.4154150130^2) = * 0.7712925849 = 1595920939166.6599375288
* (4*0.1423148383^2 + 4*0.1423148383^2) = * 0.1620281055 =  258584046368.0000000000

小数点以下10桁まで表示させています。
最終的に小数点以下オールゼロがやってきます。
不思議ですよね。

C言語で書いたプログラムは、精度的にm=10、n=10程度が限界で、それ以上はおそらく正しい値を示せないものと思われるので、プログラムでは、m*n > 100を広すぎるという理由で計算させていません。

m=nで、共に偶数となるような正方形の間取りで、どんどんと広くしていったとして、パターン数の推移をみてみましょう。

2
36
6728
12988816
258584046368
53060477521960000
112202208776036178000000
2444888770250892795802079170816
548943583215388338077567813208427340288
1269984011256235834242602753102293934298576249856
30273700492231603015150204108772562780931587428193514539008
7435775679122922965141930394167684120105535297322308613569173527105536
18818218480813456762421856963999286650475155898066955228295925806777884028153700352
490705382430044396584844668594853686545442654322252039155636063994159671359376052625754522402816
131841545472244027406496188757912375363891696443221279694626947912188459956437700105571773334900360294912000000
364982661733625107998314878133750234067320091670089660297647663460799361991486518266376931355483757336443179285926592651526144
10410706176212149483659346800515174527957199561842740723990155189696083839694248931927230021264311032522366488503555184991593015325742728347648
3059678529326412620589446172019416175540431956089783031026457785251580682865894468940096683515460188396944341988114423302044289603689198425594167991711681478656
9265285330902534296217455546927257004290162245091913313458591264554575948250767793997514044880093549146921515939373549897041444032535459925072418148825381473704969149494394880000
289087282163113328743610185163908044770725939303538279677232590242783491136127669408356195744411950145370951939712965145774240924617228224722535628416515766823057081561443443293702226008700932325376
92936477367322445738501452632582961968924991945450841798195322474197555956474480978005219302755830140281321186616569343797239109561138740112615434391588335144141188385810055115632436415132910364391384804190842968342528
307843749107238691431368879957372095992678272679739296806409798770667614086080693117195542342120049619227689790662329321349081185074151181570148407447296211603155462013937493377956933680428688147507647409848097564853701222334674305024000000
10506577951158284586001016616574484330668110901608593779825104486711730588882176555614500727722686420437858438808399124865322214607759812909209499834239671450873461871968057369932682025844381603866183334155544251569114826736811827513823974678292263721643370610688
3694698231128372058963013010765726266395952882470015111954934263423931452690929073735432067081129909826959334285803448784669434439330367405894259082011099903807928460196105609682585291941797298952410692979733661623342461656391893198756141450423028230454738437116041887543951921801854976
13387002183802072716437005804888384441697410003874375430286852581949300261913933145386680332191206245205836916128245329463697459788523703869716797516723198428105735536547489363891924530854843281971402707682104980441345554496849387939828560297900082136731589456819325959305128048082453866925961423503570646335488

m=n=50まで、多倍長電卓LMで計算させてみました。

組み合わせ爆発していますね。

この数式があるから、簡単に計算出来ていますが、もしこの数式が無かったら、もっと計算が長くなって、時間も掛かっていたことでしょう。


ではでは


Viewing all articles
Browse latest Browse all 5376

Trending Articles