Hitung probabilitas dengan tepat dan cepat

10

[Ini adalah pertanyaan mitra untuk Menghitung probabilitas dengan tepat ]

Tugas ini adalah tentang menulis kode untuk menghitung probabilitas secara tepat dan cepat . Outputnya harus berupa probabilitas tepat yang ditulis sebagai pecahan dalam bentuk yang paling dikurangi. Itu seharusnya tidak pernah output 4/8melainkan 1/2.

Untuk beberapa bilangan bulat positif n, pertimbangkan string acak seragam panjang 1s dan -1s ndan menyebutnya A. Sekarang digabungkan Adengan nilai pertama. Itu A[1] = A[n+1]jika pengindeksan dari 1. Asekarang memiliki panjang n+1. Sekarang juga pertimbangkan string acak kedua panjang ndengan nnilai pertama -1, 0, atau 1 dengan probabilitas 1 / 4,1 / 2, masing-masing 1/4 dan menyebutnya B.

Sekarang perhatikan produk dalam A[1,...,n]dan Bdan produk dalam A[2,...,n+1]dan B.

Sebagai contoh, pertimbangkan n=3. Nilai yang mungkin untuk Adan Bbisa A = [-1,1,1,-1]dan B=[0,1,-1]. Dalam hal ini dua produk dalam adalah 0dan 2.

Kode Anda harus menampilkan probabilitas bahwa kedua produk dalam adalah nol.

Menyalin tabel yang diproduksi oleh Martin Büttner kami memiliki hasil sampel berikut.

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

Bahasa dan perpustakaan

Anda dapat menggunakan bahasa dan perpustakaan yang tersedia secara bebas yang Anda suka. Saya harus dapat menjalankan kode Anda jadi tolong sertakan penjelasan lengkap tentang cara menjalankan / kompilasi kode Anda di linux jika memungkinkan.

Tugas

Kode Anda harus mulai dengan n=1dan memberikan output yang benar untuk setiap peningkatan n pada baris terpisah. Seharusnya berhenti setelah 10 detik.

Nilai

Skor ini hanyalah yang tertinggi yang ndicapai sebelum kode Anda berhenti setelah 10 detik saat dijalankan di komputer saya. Jika ada seri, pemenanglah yang mendapatkan skor tertinggi tercepat.

Daftar entri

  • n = 64dalam Python . Versi 1 oleh Mitch Schwartz
  • n = 106dalam Python . Versi 11 Juni 2015 oleh Mitch Schwartz
  • n = 151dalam C ++ . Jawaban Port of Mitch Schwartz oleh kirbyfan64sos
  • n = 165dalam Python . Versi 11 Juni 2015 versi "pemangkasan" oleh Mitch Schwartz dengan N_MAX = 165.
  • n = 945dalam Python oleh Min_25 menggunakan rumus yang tepat. Luar biasa!
  • n = 1228dalam Python oleh Mitch Schwartz menggunakan rumus lain yang tepat (berdasarkan jawaban Min_25 sebelumnya).
  • n = 2761dalam Python oleh Mitch Schwartz menggunakan implementasi yang lebih cepat dari formula yang persis sama.
  • n = 3250di Python menggunakan Pypy oleh Mitch Schwartz menggunakan implementasi yang sama. Skor ini perlu pypy MitchSchwartz-faster.py |tailmenghindari overhead konsol bergulir.
Komunitas
sumber
Saya ingin tahu apakah solusi numpy akan berjalan lebih cepat daripada Boost C ++?
qwr
@ qwr Saya pikir numpy, numba dan cython semua akan menarik karena mereka tetap berada dalam keluarga Python.
2
Saya ingin melihat lebih banyak masalah kode tercepat ini
qwr
@ qw, ini pertanyaan favorit saya ... Terima kasih! Tantangannya adalah menemukan yang tidak hanya melibatkan pengodean algoritma yang persis sama dalam bahasa tingkat terendah yang dapat Anda temukan.
Apakah Anda menulis hasilnya ke konsol atau ke file? Menggunakan pypy dan menulis ke file sepertinya yang tercepat bagi saya. Konsol memperlambat proses secara signifikan.
gnibbler

Jawaban:

24

Python

Formula bentuk tertutup p(n)adalah

masukkan deskripsi gambar di sini

Fungsi menghasilkan eksponensial p(n)adalah

masukkan deskripsi gambar di sini

di mana I_0(x)fungsi Bessel yang dimodifikasi dari jenis pertama.

Edit pada 2015-06-11:
- memperbarui kode Python.

Edit pada 2015-06-13:
- menambahkan bukti rumus di atas.
- memperbaiki time_limit.
- menambahkan kode PARI / GP.

Python

def solve():
  # straightforward implementation

  from time import time
  from itertools import count

  def binom(n, r):
    return facts[n] // (facts[r] * facts[n - r])

  def p(N):
    ans = 0
    for i in range(1 + N // 2):
      t = binom(2 * (N - 2 * i), N - 2 * i)
      t *= binom(N, 2 * i)
      t *= binom(4 * i, 2 * i)
      ans += t
    e = (ans & -ans).bit_length() - 1
    numer = ans >> e
    denom = 1 << (3 * N - 1 - e)
    return numer, denom

  facts = [1]
  time_limit = 10.0 + time()

  for i in count(1):
    facts.append(facts[-1] * (2 * i - 1))
    facts.append(facts[-1] * (2 * i))

    n, d = p(i)

    if time() > time_limit:
      break

    print("%d %d/%d" % (i, n, d))

solve()

PARI / GP

p(n) = polcoeff( (exp(x/2) + 1) * besseli(0, x/4) ^ 2, n) * n!;

Bukti:
Masalah ini mirip dengan masalah jalan acak 2 dimensi (terbatas).

Jika A[i] = A[i+1], kita dapat beralih dari (x, y)ke (x+1, y+1)[1 arah], (x, y)[2 arah] atau (x-1, y-1)[1 arah].

Jika A[i] != A[i+1], kita dapat beralih dari (x, y)ke (x-1, y+1)[1 arah], (x, y)[2 arah] atau (x+1, y-1)[1 arah].

Mari a(n, m) = [x^m]((x+1)^n + (x-1)^n), b(n) = [x^n](1+x)^{2n}dan c(n)menjadi sejumlah cara untuk bergerak dari (0, 0)ke (0, 0)dengan nlangkah-langkah.

Kemudian, c(n) = \sum_{i=0}^n a(n, i) * b(i) * b(n-i).

Karena p(n) = c(n) / 8^n, kita bisa mendapatkan formula bentuk tertutup di atas.

Min_25
sumber
1
Ini .. yah .. luar biasa! Bagaimana Anda menghitung formula yang tepat?
1
Wow! Bentuk tertutup selalu rapi!
qwr
1
@Lembik: Saya menambahkan bukti (kasar).
Min_25
1
@ qwr: Terima kasih. Aku pikir juga begitu !
Min_25
1
@ mbomb007: Ya. Tapi, ini adalah tugas implementasi daripada tugas komputasi. Jadi, saya tidak akan kode dalam C ++.
Min_25
9

Python

Catatan: Selamat kepada Min_25 karena menemukan solusi bentuk tertutup!

Terima kasih atas masalah yang menarik! Ini dapat diselesaikan dengan menggunakan DP, meskipun saat ini saya tidak merasa sangat termotivasi untuk mengoptimalkan kecepatan untuk mendapatkan skor yang lebih tinggi. Itu bisa bagus untuk golf.

Kode dicapai N=39dalam 10 detik pada laptop lama ini yang menjalankan Python 2.7.5.

from time import*
from fractions import*
from collections import*

X={(1,0,0,0):1,(-1,0,0,0):1}

T=time()
N=0

while 1:
    Y=defaultdict(lambda:0)
    n=d=0
    for a,b,s,t in X:
        c=X[(a,b,s,t)]
        for A in ( (1,-1) if N else [a] ):
            for B in 1,0,0,-1:
                n+=c*(s+A*B==0==t+A*b+a*B)
                d+=c
                Y[(a,B,s+A*B,t+A*b)]+=c
    if time()>T+10: break
    N+=1
    print N,Fraction(n,d)
    X=Y

Untuk tuple (a,b,s,t): aadalah elemen pertama A, badalah elemen terakhir B, sadalah produk dalam A[:-1]dan B, dan tmerupakan produk dalam A[1:-1]dan B[:-1], menggunakan notasi irisan Python. Kode saya tidak menyimpan array Aatau di Bmana pun, jadi saya menggunakan surat-surat itu untuk merujuk ke elemen berikutnya yang akan ditambahkan ke Adan B, masing-masing. Pilihan penamaan variabel ini membuat penjelasan sedikit canggung, tetapi memungkinkan untuk terlihat bagus A*b+a*Bdi kode itu sendiri. Perhatikan bahwa elemen yang ditambahkan Aadalah elemen kedua dari belakang, karena elemen terakhir selalu sama dengan yang pertama. Saya telah menggunakan trik Martin Büttner untuk memasukkan 0dua kaliBkandidat untuk mendapatkan distribusi probabilitas yang tepat. Kamus X(yang diberi nama Yuntuk N+1) melacak jumlah semua kemungkinan array sesuai dengan nilai tuple. Variabel ndan dsingkatan dari pembilang dan penyebut, itulah sebabnya saya menamai ulang npernyataan masalah sebagai N.

Bagian utama dari logika adalah bahwa Anda dapat memperbarui dari Nke N+1hanya menggunakan nilai-nilai dalam tupel. Dua produk dalam yang ditentukan dalam pertanyaan diberikan oleh s+A*Bdan t+A*b+a*B. Ini jelas jika Anda memeriksa definisi sedikit; perhatikan bahwa [A,a]dan [b,B]adalah dua elemen terakhir dari array Adan Bmasing - masing.

Perhatikan bahwa sdan tkecil dan dibatasi menurut N, dan untuk implementasi cepat dalam bahasa cepat kita dapat menghindari kamus yang mendukung array.

Dimungkinkan untuk mengambil keuntungan dari simetri mengingat nilai yang berbeda hanya dalam tanda; Saya belum melihat itu.

Catatan 1 : Ukuran kamus tumbuh dalam kuadratik N, di mana ukuran berarti jumlah pasangan nilai kunci.

Catatan 2 : Jika kita menetapkan batas atas N, maka kita dapat memangkas tuple untuk yang N_MAX - N <= |s|dan juga untuk t. Ini dapat dilakukan dengan menentukan kondisi penyerap, atau secara implisit dengan variabel untuk menahan jumlah kondisi prun (yang perlu dikalikan dengan 8 pada setiap iterasi).

Pembaruan : Versi ini lebih cepat:

from time import*
from fractions import*
from collections import*

N_MAX=115

def main():
    T=time()

    N=1
    Y={(1,0,0,0):1,(1,1,1,0):1}
    n=1
    thresh=N_MAX

    while time() <= T+10:
        print('%d %s'%(N,Fraction(n,8**N/4)))

        N+=1
        X=Y
        Y=defaultdict(lambda:0)
        n=0

        if thresh<2:
            print('reached MAX_N with %.2f seconds remaining'%(T+10-time()))
            return

        for a,b,s,t in X:
            if not abs(s)<thresh>=abs(t):
                continue

            c=X[(a,b,s,t)]

            # 1,1

            if not s+1 and not t+b+a: n+=c
            Y[(a,1,s+1,t+b)]+=c

            # -1,1

            if not s-1 and not t-b+a: n+=c
            Y[(a,1,s-1,t-b)]+=c

            # 1,-1

            if not s-1 and not t+b-a: n+=c
            Y[(a,-1,s-1,t+b)]+=c

            # -1,-1

            if not s+1 and not t-b-a: n+=c
            Y[(a,-1,s+1,t-b)]+=c

            # 1,0

            c+=c

            if not s and not t+b: n+=c
            Y[(a,0,s,t+b)]+=c

            # -1,0

            if not s and not t-b: n+=c
            Y[(a,0,s,t-b)]+=c

        thresh-=1

main()

Optimasi diterapkan:

  • memasukkan semuanya ke dalam main()- akses variabel lokal lebih cepat daripada global
  • menangani N=1secara eksplisit untuk menghindari tanda centang (1,-1) if N else [a](yang menegaskan bahwa elemen pertama dalam tuple konsisten, ketika menambahkan elemen ke Amulai dari daftar kosong)
  • membuka gulungan loop bagian dalam, yang juga menghilangkan multiplikasi
  • gandakan penghitungan cuntuk menambahkan 0ke Balih-alih melakukan operasi itu dua kali
  • penyebutnya selalu 8^Njadi kita tidak perlu melacaknya
  • sekarang dengan mempertimbangkan simetri: kita dapat memperbaiki elemen pertama Aas 1dan membagi penyebut dengan 2, karena pasangan yang valid (A,B)dengan A[1]=1dan mereka dengan A[1]=-1dapat dimasukkan ke dalam korespondensi satu-ke-satu dengan meniadakan A. Demikian pula, kita dapat memperbaiki elemen pertama Bsebagai non-negatif.
  • sekarang dengan pemangkasan. Anda perlu bermain-main N_MAXuntuk melihat skor apa yang bisa didapat di mesin Anda. Bisa ditulis ulang untuk menemukan yang sesuai N_MAXsecara otomatis dengan pencarian biner, tetapi sepertinya tidak perlu? Catatan: Kita tidak perlu memeriksa kondisi pemangkasan sampai mencapai sekitar N_MAX / 2, jadi kita bisa mendapatkan sedikit percepatan dengan mengulangi dalam dua fase, tapi saya memutuskan untuk tidak kesederhanaan dan kebersihan kode.
Mitch Schwartz
sumber
1
Ini jawaban yang sangat bagus! Bisakah Anda menjelaskan apa yang Anda lakukan dalam mempercepat?
@Lembik Terima kasih :) Menambahkan penjelasan, ditambah optimasi kecil lainnya, dan membuatnya sesuai dengan Python3.
Mitch Schwartz
Di komputer saya, saya N=57dapat versi pertama dan N=75kedua.
kirbyfan64sos
Jawaban Anda luar biasa. Hanya saja jawaban Min_25 lebih dari itu :)
5

Python

Dengan menggunakan gagasan Min_25 tentang jalan acak, saya dapat sampai pada rumus berbeda:

p (n) = \ begin {cases} \ frac {\ sum _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ text {odd} \ \ frac {\ binom {n} {n / 2} ^ 2 + \ jumlah _ {i = 0} ^ {\ lfloor n / 2 \ rfloor} \ binom {2i} {i} ^ 2 \ binom {n} {2i} 4 ^ {n-2i}} {8 ^ n} & n \ teks {even} \ \ end {cases}

Berikut ini adalah implementasi Python berdasarkan Min_25:

from time import*
from itertools import*

def main():
    def binom(n, k):
        return facts[n]/(facts[k]*facts[n-k])

    def p(n):
        numer=0
        for i in range(n/2+1):
            t=binom(2*i,i)
            t*=t
            t*=binom(n,2*i)
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)
        return numer, denom

    facts=[1]
    time_limit=time()+10

    for i in count(1):
        facts.append(facts[-1]*i)

        n,d=p(i)

        if time()>time_limit:
            break

        print("%d %d/%d"%(i,n,d))

main()

Penjelasan / bukti:

Pertama kita memecahkan masalah penghitungan terkait, di mana kita mengizinkan A[n+1] = -A[1]; yaitu, elemen tambahan yang disatukan Adapat berupa 1atau -1terlepas dari elemen pertama. Jadi kita tidak perlu melacak berapa kali A[i] = A[i+1]terjadi. Kami memiliki jalan acak berikut:

Dari (x,y)kita dapat pindah ke (x+1,y+1)[1 arah], (x+1,y-1)[1 arah], (x-1,y+1)[1 arah], (x-1,y-1)[1 arah], (x,y)[4 cara]

di mana xdan yberdiri untuk produk dua titik, dan kami menghitung jumlah cara untuk beralih dari (0,0)ke (0,0)dalam nlangkah-langkah. Hitungan itu kemudian akan dikalikan dengan 2memperhitungkan fakta yang Adapat dimulai dengan 1atau -1.

Kami menyebut tinggal di (x,y)sebagai langkah nol .

Kami beralih pada jumlah gerakan non-nol i, yang harus genap untuk kembali (0,0). Gerakan horisontal dan vertikal membentuk dua jalan acak satu dimensi yang independen, yang dapat dihitung dengan C(i,i/2)^2, di mana C(n,k)koefisien binomial. (Untuk jalan dengan klangkah ke kiri dan klangkah ke kanan, ada C(2k,k)cara untuk memilih urutan langkah.) Selain itu ada C(n,i)cara untuk menempatkan gerakan, dan 4^(n-i)cara untuk memilih gerakan nol. Jadi kita dapatkan:

a(n) = 2 * sum_{i in (0,2,4,...,n)} C(i/2,i)^2 * C(n,i) * 4^(n-i)

Sekarang, kita perlu kembali ke masalah semula. Tetapkan pasangan yang diizinkan (A,B)untuk dapat dikonversi jika Bmengandung nol. Tentukan pasangan (A,B)menjadi hampir diijinkan jika A[n+1] = -A[1]dan dua produk dot keduanya nol.

Lemma: Untuk yang diberikan n, pasangan yang hampir diijinkan berada dalam korespondensi satu-ke-satu dengan pasangan yang dapat dikonversi.

Kami dapat (secara reversibel) mengubah pasangan yang dapat dikonversi (A,B)menjadi pasangan yang hampir diijinkan (A',B')dengan meniadakan A[m+1:]dan B[m+1:], di mana mindeks dari nol terakhir di B. Pemeriksaan untuk ini mudah: Jika elemen terakhir Badalah nol, kita tidak perlu melakukan apa pun. Kalau tidak, ketika kita meniadakan elemen terakhir A, kita bisa meniadakan elemen terakhir Buntuk mempertahankan suku terakhir dari produk titik bergeser. Tapi ini meniadakan nilai terakhir dari produk titik yang tidak bergeser, jadi kami memperbaikinya dengan meniadakan elemen kedua hingga terakhir A. Tapi kemudian ini membuang nilai kedua-ke-terakhir dari produk yang dipindahkan, jadi kami meniadakan elemen kedua-ke-terakhir dari B. Demikian seterusnya, hingga mencapai nol elemen dalam B.

Sekarang, kita hanya perlu menunjukkan bahwa tidak ada pasangan yang hampir diijinkan yang Btidak mengandung nol. Agar produk titik sama dengan nol, kita harus memiliki jumlah 1dan -1syarat yang sama untuk dibatalkan. Setiap -1istilah terdiri dari (1,-1)atau (-1,1). Jadi paritas jumlah -1yang terjadi tetap sesuai dengan n. Jika elemen pertama dan terakhir Amemiliki tanda yang berbeda, kami mengubah paritas, jadi ini tidak mungkin.

Jadi kita dapatkan

c(n) = a(n)/2 if n is odd, else a(n)/2 + C(n,n/2)^2

p(n) = c(n) / 8^n

yang memberikan rumus di atas (pengindeksan ulang dengan i' = i/2).

Pembaruan: Ini adalah versi yang lebih cepat menggunakan rumus yang sama:

from time import*
from itertools import*

def main():
    time_limit=time()+10

    binoms=[1]
    cb2s=[1]
    cb=1

    for n in count(1):
        if n&1:
            binoms=[a+b for a,b in zip([0]+binoms,binoms)]
        else:
            binoms=[a+b for a,b in zip([0]+binoms,binoms+[binoms[-1]])]
            cb=(cb<<2)-(cb+cb)/(n/2)
            cb2s.append(cb*cb)

        numer=0
        for i in xrange(n/2+1):
            t=cb2s[i]*binoms[min(2*i,n-2*i)]
            t<<=2*(n-2*i)
            numer+=t
        if not n&1:
            numer+=t
        e=(numer&-numer).bit_length()-1
        numer>>=e
        denom=1<<(3*n-e)

        if time()>time_limit:
            break

        print("%d %d/%d"%(n,numer,denom))

main()

Optimasi diterapkan:

  • fungsi sebaris p(n)
  • gunakan rekurensi untuk koefisien binomial C(n,k)dengank <= n/2
  • gunakan rekurensi untuk koefisien binomial pusat
Mitch Schwartz
sumber
Asal tahu saja, p(n)tidak perlu menjadi fungsi piecewise. Secara umum, jika f(n) == {g(n) : n is odd; h(n) : n is even}maka Anda dapat menulis f(n) == (n-2*floor(n/2))*g(n) + ((n+1)-2*(floor((n+1)/2)))*h(n)atau menggunakan n mod 2bukan (n-2*floor(n/2)). Lihat di sini
mbomb007
1
@ mbomb007 Itu jelas dan tidak menarik.
Mitch Schwartz
3

Penjelasan rumus Min_25

Min_25 memposting bukti yang bagus tetapi butuh beberapa saat untuk mengikuti. Ini adalah sedikit penjelasan yang harus diisi.

a (n, m) mewakili sejumlah cara untuk memilih A sedemikian rupa sehingga A [i] = A [i + 1] m kali. Rumus untuk (n, m) setara dengan a (n, m) = {2 * (n pilih m) untuk nm genap; 0 untuk nm aneh.} Hanya satu paritas yang diizinkan karena A [i]! = A [i + 1] harus terjadi beberapa kali genap sehingga A [0] = A [n]. Faktor 2 adalah karena pilihan awal A [0] = 1 atau A [0] = -1.

Setelah jumlah (A [i]! = A [i + 1]) ditetapkan menjadi q (dinamai i dalam rumus c (n)), ia berpisah menjadi dua jalan acak 1D panjang q dan nq. b (m) adalah sejumlah cara untuk mengambil langkah acak satu dimensi dari langkah-langkah m yang berakhir di tempat yang sama dengan yang dimulainya, dan memiliki peluang 25% untuk bergerak ke kiri, 50% peluang untuk tetap diam, dan peluang 25% untuk bergerak ke kanan. Cara yang lebih jelas untuk menyatakan fungsi pembangkit adalah [x ^ m] (1 + 2x + x ^ 2) ^ n, di mana 1, 2x dan x ^ 2 masing-masing mewakili kiri, tidak bergerak, dan kanan. Tapi kemudian 1 + 2x + x ^ 2 = (x + 1) ^ 2.

feersum
sumber
Namun alasan lain untuk mencintai PPCG! Terima kasih.
2

C ++

Hanya port jawaban Python (luar biasa) oleh Mitch Schwartz. Perbedaan utama adalah bahwa saya dulu 2mewakili -1untuk avariabel dan melakukan sesuatu yang serupa b, yang memungkinkan saya untuk menggunakan array. Dengan menggunakan Intel C ++ -O3, saya dapat N=141! Versi pertamaku didapat N=140.

Ini menggunakan Boost. Saya mencoba versi paralel tetapi mengalami beberapa masalah.

#include <boost/multiprecision/gmp.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/rational.hpp>
#include <boost/chrono.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <utility>
#include <map>

typedef boost::multiprecision::mpz_int integer;
typedef boost::array<boost::array<std::map<int, std::map<int, integer> >, 3>, 2> array;
typedef boost::rational<integer> rational;

int main() {
    BOOST_AUTO(T, boost::chrono::high_resolution_clock::now());

    int N = 1;
    integer n = 1;
    array* Y = new array, *X = NULL;
    (*Y)[1][0][0][0] = 1;
    (*Y)[1][1][1][0] = 1;

    while (boost::chrono::high_resolution_clock::now() < T+boost::chrono::seconds(10)) {
        std::cout << N << " " << rational(n, boost::multiprecision::pow(integer(8), N)/4) << std::endl;
        ++N;
        delete X;
        X = Y;
        Y = new array;
        n = 0;

        for (int a=0; a<2; ++a)
            for (int b=0; b<3; ++b)
                for (BOOST_AUTO(s, (*X)[a][b].begin()); s != (*X)[a][b].end(); ++s)
                    for (BOOST_AUTO(t, s->second.begin()); t != s->second.end(); ++t) {
                        integer c = t->second;
                        int d = b&2 ? -1 : b, e = a == 0 ? -1 : a;

                        if (s->first == -1 && t->first+d+e == 0) n += c;
                        (*Y)[a][1][s->first+1][t->first+d] += c;

                        if (s->first == 1 && t->first-d+e == 0) n += c;
                        (*Y)[a][1][s->first-1][t->first-d] += c;

                        if (s->first == 1 && t->first+d-e == 0) n += c;
                        (*Y)[a][2][s->first-1][t->first+d] += c;

                        if (s->first == -1 && t->first-d-e == 0) n += c;
                        (*Y)[a][2][s->first+1][t->first-d] += c;

                        c *= 2;

                        if (s->first == 0 && t->first+d == 0) n += c;
                        (*Y)[a][0][s->first][t->first+d] += c;

                        if (s->first == 0 && t->first-d == 0) n += c;
                        (*Y)[a][0][s->first][t->first-d] += c;
                    }
    }

    delete X;
    delete Y;
}
kirbyfan64sos
sumber
Ini perlu g++ -O3 kirbyfan64sos.cpp -o kirbyfan64sos -lboost_system -lboost_timer -lboost_chrono -lrt -lgmpdikompilasi. (Terima kasih kepada aditsu.)