完璧なナンバープレート


33

完璧なナンバープレート

数年前から、私は車で走りながら小さなゲームを作りました。近くのナンバープレートが「完璧」かどうかを確認しました。比較的まれですが、見つけたときは刺激的です。

ナンバープレートが完璧かどうかを確認するには:

  1. A = 1、B = 2、... Z = 26で文字を合計します。
  2. 数字の連続した各チャンクを取り、それらを合計します。これらの合計を乗算します。

パート1とパート2の値が等しい場合、おめでとうございます!完璧なナンバープレートが見つかりました!

License plate: AB3C4F

Digits -> 3 * 4 
        = 12
Chars  -> A + B + C + F 
        = 1 + 2 + 3 + 6 
        = 12
12 == 12 -> perfect!


License plate: G34Z7T

Digits -> (3 + 4) * 7 
        = 49
Chars  -> G + Z + T 
        = 7 + 26 + 20 
        = 53
49 != 53 -> not perfect!


License plate: 10G61

Digits -> (1 + 0) * (6 + 1)
        = 7
Chars  -> G
        = 7
7 == 7 -> perfect!

チャレンジ

長さ5と6のナンバープレートを例として使用しましたが、この手順はどのプレートの長さでも有効です。あなたの挑戦は、与えられた長さNに対して、その長さの完璧なナンバープレートの数を返すことです。チャレンジの目的上、有効なナンバープレートは、数字0〜9と文字A〜Zの任意の組み合わせです。潜在的に完全と見なされるためにはプレートに文字と数字の両方が含まれている必要があります。チェックの目的で、ここに私が得た値があります(ただし、その正確性について100%になることはできません)

N < 2: 0
N = 2: 18
N = 3: 355
N = 4: 8012 

ノート

どういうわけかあなたの言語で問題を簡単にするなら、あなたは与えられたNの完璧なナンバープレートの割合を、少なくとも2桁の有効数字で出力できます。

N < 2: 0
N = 2: 0.0138888...
N = 3: 0.0076088...
N = 4: 0.0047701...

または、同等の値mod 256を出力できます

N < 2: 0
N = 2: 18
N = 3: 99
N = 4: 76

最短勝ち!


2
サイトへようこそ!これは良い挑戦だと思いますが、追加の許可された出力により、実際に回答を採点することは難しくなります。PPCGは客観的な勝利基準を探しますが、非常に多くの自由がある場合、それを行うのは困難です。これは出力形式を変更するだけでなく、実際に出力できるものを変更します。他のオプションを編集し、完璧なナンバープレートの数を出力するために必要にすることをお勧めしますN
ハイパーニュートリノ

11
特定のナンバープレートが完全であるかどうかを検証するだけであれば(特にテストケースの明確な数値がないため、潜在的に計算された結果が得られる限りは、おそらく問題ありません)。他の人がどのように感じているかはわかりませんが、いい考えです!
-MildlyMilquetoast

4
私はMistah Figginsに同意します。このように、パターンを見つけることの方が重要だと感じていますが、これはまだ興味深い課題ですが、検証チェックだけであれば、より多くの回答を集めることができると思います。ナイスチャレンジ!
ハイパーニュートリノ

1
私は密接に関連した課題を投稿しました。この素晴らしい質問に注意を引くことを期待し、これを少し簡略化し、(ほぼ)完全なナンバープレートをチェックするだけです。
Mr Xcoder

1
@carusocomputing最善を尽くしましたが、空っぽになりました。私は数学の先生にそれを送りました、そして、彼はこれまで空です
クリストファー

回答:


9

Python 3.6、150バイト

f=lambda n,t=-1,p=-1,a=0:sum(f(n-1,*((t,c+p*(p>=0),a),((t<0 or t)*(p<0 or p),-1,a-c))[c<0])for c in range(-26,10))if n else 0<(t<0 or t)*(p<0 or p)==a

結果:

f(2) = 18
f(3) = 355
f(4) = 8012
f(5) = 218153

説明付きのゴルフバージョン:

digits=[*range(10)]
letters=[*range(1,27)]

def f(n, dt=-1, dp=-1, lt=0):
    if n:
        for d in digits:
            yield from f(n - 1,
                         dt,
                         d if dp < 0 else dp + d,
                         lt
                         )

        for l in letters:
            yield from f(n - 1,
                         dp if dt < 0 else dt if dp < 0 else dt*dp,
                         -1,
                         lt + l
                         )
    else:
        yield 0 < lt == (dt<0 or dt)*(dp<0 or dp)

問題は、ツリーの各レベルがナンバープレート番号の位置に対応し、各ノードに36個の子(10桁と26文字)があるツリーを検索することです。この関数は、ツリーの再帰検索を行い、数字と文字の値を累積します。

n is the number of levels to search. 
dp accumulates the sum of a group of digits.
dt accumulates the product of the digit sums.
lt accumulates the sum of the letter values.

For dp and dt, a value < 0 indicates it is not initialized.

ゴルフが含まれており、forループをジェネレーターの合計に変換します。

sum(f(n-1, 
      dt,
      d if dp < 0 else dp + d,
      lt) for d in digits)
+
sum(f(n-1,
      dp if dt<0 else dt if dp<0 else dt*dp,
      -1,
      lt+l) for l in letters)

次に、ジェネレーターを組み合わせます。文字A〜Zを-1〜-26、数字を0〜9としてエンコードします。したがって、合計は次のようになります。

sum(f(n-1, *args) for c in range(-26, 10)),

argsは次のとおりです。

((dp if dt<0 else dt if dp<0 else dt*dp, -1, lt-l) if c <0 else
 (dt, d if dp<0 else dp+d, lt))

ゴルフの残りの部分では、関数をラムダに変換し、変数名を短縮し、式を単純化します。


これは雄弁なソリューションですが、ランタイムはどうなりますか?n*n*log(n)または何か似たような?
魔法のタコUr

@carusocomputingありがとう。ソリューションは、指定された長さのすべての可能な順列を生成するため、他のソリューションと同じ複雑さを持ちます。k ** nのようなもの。kはアルファベットの記号の数(10桁+ 26文字= 36など)で、nはナンバープレートの記号の数です。n = 5で実行するには、36 ^ 5 = 60,466,176の順列をチェックする必要があり、1〜2分かかりました(メモ化により高速化される可能性がありますが、多くのバイトがかかります;-))。
RootTwo

6

Dyalog APL、57 56バイト

+/(+/0⌈a-9)=×/c*⍨-2-/0,⌈\(+\a×b)×c←2>/0,⍨b←9≥a←↑1↓,⍳⎕⍴36

(想定⎕io←0

a有効なすべてのナンバープレートのマトリックス(を除く00...0)でエンコード:数字の場合は0-9、文字の場合は10-35

b 数字が現れる場所のビットマスク

c 連続する数字のすべてのグループの最後の数字のビットマスク


1〜4 でオンライン試してみると、4でより多くのメモリが必要になりますが、それ以外の方法もあります。
アダム

4

Python 2、359 295バイト

かなり長い。これは簡単な解決策です。チャレンジのテストケースとは一致しませんが、これは正しいと確信しています。私が得ている解決策は、ダダの答えに匹敵します。

import itertools as i,re as r,string as s
print len([''.join(x)for x in i.product(s.lowercase+s.digits,repeat=input())if(lambda t:r.search('\\D',t)and r.search('\\d',t)and reduce(int.__mul__,[sum(map(int,k))for k in r.split('\\D+',t)if k])==sum([k-96 for k in map(ord,t) if k>96]))(''.join(x))])

@numbermaniacからの提案のおかげで-64バイト


1
c(x)と最後の行に約3バイトを保存できます。96とfor;の間のスペースを削除します。間map(ord,x)if、そして最後の行で、間.join(x)for。関数をラムダに再定義すると、さらに節約できると思います。
numbermaniac

@numbermaniacありがとう!(64総バイト)
HyperNeutrino

4

Pythonの2291の 287 276 273バイト

lambda n:sum(1for x in s.product(y+z,repeat=n)if(lambda p,s=set:reduce(int.__mul__,[sum(map(int,i))for i in re.findall(r"\d+",p)],1)==sum(ord(i)-64for i in p if ord(i)>64)and s(p)&s(y)and s(p)&s(z))(''.join(x)))
import re,itertools as s,string as t
y=t.uppercase
z=t.digits

オンラインでお試しください!


結果:

0 0
1 0
2 18
3 355
4 8012

3

Perl 5、117バイト

116バイトのコード+ -pフラグ。

$"=",";@F=(A..Z,0..9);map{$r=1;$r*=eval s/./+$&/gr for/\d+/g;$r+=64-ord for/\pl/g;$\+=!$r*/\pl/*/\d/}glob"{@F}"x$_}{

オンラインでお試しください!

まったく最適とは言えませんが、私は今アイデアを失っています。
コード自体はa..z,0..9、長さのすべての順列を計算するnためn=3、非常に非効率的です(では約1秒、で約15秒n=4、約7分かかりますn=5)。
アルゴリズムは非常に単純です。サイズの可能なすべてのプレートn(演算子で生成されますglob"{@F}"x$_- glob演算子は非常に魔法です)で、$r*=eval s/./+$&/gr for/\d+/g;すべての桁の積を計算し、それに$r+=64-ord for/\pl/g文字の重みを引きます。その後、我々は、カウンタをインクリメント$\場合$rである0!$r)とプレートは数字と文字が含まれている場合(/\pl/*/\d/)。フラグの$\おかげで、最後に暗黙的に印刷され-pます。

私は取得数であることに注意してくださいn=2 -> 18n=3 -> 355n=4 -> 8012n=5 -> 218153。これらは正しいものであると確信していますが、間違っている可能性があります。その場合はお知らせください。この回答を削除します。



2

Scala、265バイト

(n:Int)=>{val i=('A'to'Z')++('0'to'9');Seq.fill(n)(i).flatten.combinations(n).flatMap(_.permutations).map(_.mkString).count(l=>"(?=.*[A-Z])(?=.*\\d)".r.findAllIn(l).size>0&&l.map(_-64).filter(_>0).sum==l.split("[A-Z]").filter(""<).map(_.map(_-48).sum).reduce(_*_))}

説明:

(n:Int) => {
    val i = ('A' to 'Z') ++ ('0' to '9');                       // All license plates available characters.
    Seq.fill(n)(i).flatten                                      // Simulate combination with repetition (each character is present n times)
        .combinations(n)                                        // and generate all combinations of size n (all license plates).
        .flatMap(_.permutations)                                // For each combination, generate all permutations (ex. : Seq('A', '1') => Seq('A', '1') and Seq('1', 'A')), and
        .map(_.mkString)                                        // convert each permutation to String (Seq('A', '1') => "A1").
        .count ( l =>                                           // Then count all strings having :
            "(?=.*[A-Z])(?=.*\\d)".r.findAllIn(l).size > 0 &&   // at least 1 character and 1 digit and
            l.map(_ - 64).filter(_ > 0).sum ==                  // a sum of characters (> 'A' or > 64) equals to
            l.split("[A-Z]").filter(""<)
                .map(_.map(_ - 48).sum)
                .reduce(_*_)                                    // the product of sum of digits groups (split String by letters to get digits groups)
        )
}

ノート :

  • -64そして、-48変換するために使用されているCharそのに(それぞれの文字と数字を)Int値('A' - 64 = 1'B' - 64 = 2、...、 '9' - 48 = 9
  • フィルターは、文字で始まる場合に値l.split("[A-Z]").filter(""<)を削除するために使用され""ますl(例:)"A1".split("[A-Z]") => Array("", 1)。より良い、より短い解決策があるかもしれません

テストケース:

val f = (n:Int) => ...  // assign function
(1 to 5).foreach ( i =>
    println(s"N = $i: ${f(i)}")
)

結果 :

N = 1: 0
N = 2: 18
N = 3: 355
N = 4: 8012
N = 5: 218153

n > 4すべての組み合わせを生成する必要があるため、関数はかなり低速です。


2

Java、382 365バイト

  • Kevin Cruijssenのおかげで17バイト節約

ゴルフ

int h(String s){int m=0;for(int c:s.toCharArray())m+=c-48;return m;}
int g(String t){int d=1,c=0;for(String s:t.split("[^0-9]"))d*=h(s);for(String s:t.split("[^A-Z]"))c+=s.charAt(0)-65;return d==c?1:0;}
int f(String t,int n){int m=0;if(t.length()==n)return g(t);for(int d=48;d<58;)m+=f(t+d++,n);for(int c=65;c<91;)m+=f(t+c++,n);return m;}
int s(int n){return f("",n);}

詳細

// return sum of adjecent digits
int h(String s)
{
    int sum = 0;
    for(char c : s.toCharArray()) sum += c-'0';
    return sum;
}

// check if perfect
int g(String t)
{
    int d = 1;
    int c = 0;

    for(String s : t.split("[^0-9]")) d *= h(s);
    for(String s : t.split("[^A-Z]")) c += s.charAt(0)-'A';

    return d == c ? 1 : 0;
}

// tree of enumerations
int f(String t, int n)
{
    // base case
    if(t.length() == n)
    {
        return g(t);
    }

    // enumeration
    int sum = 0;
    for(char d='0'; d<='9'; d++) sum += f(t+d, n);
    for(char c='A'; c<='Z'; c++) sum += f(t+c, n);

    return sum;
}

int s(int n){ return f("",n); }

n入力としてのみ受け取る関数が必要だと思います。
クリスチャンシーバーズ

@ChristianSievers修正
Khaled.K

1
現在のコードでゴルフをするためのいくつかのこと:int h(String s){int m=0;for(int c:s.toCharArray())m+=c-48;return m;}int g(String t){int d=1,c=0;for(String s:t.split("[^0-9]"))d*=h(s);for(String s:t.split("[^A-Z]"))c+=s.charAt(0)-65;return d==c?1:0;}int f(String t,int n){int m=0;if(t.length()==n)return g(t);for(int d=48;d<58;)m+=f(t+d++,n);for(int c=65;c<91;)m+=f(t+c++,n);return m;}int s(int n){return f("",n);}365バイト)現在のバージョンとこのバージョンを比較して、私が行った変更を確認できます(このコメントの残りの部分に収まるには多すぎます)。:)
ケビンクルーッセン

@KevinCruijssen THX、17は今バイトoff
Khaled.K

2

GAP、416バイト

コードサイズで勝つことはなく、一定の時間からはほど遠いですが、数学を使用して大幅にスピードアップします!

x:=X(Integers);
z:=CoefficientsOfUnivariatePolynomial;
s:=Size;

f:=function(n)
 local r,c,p,d,l,u,t;
 t:=0;
 for r in [1..Int((n+1)/2)] do
  for c in [r..n-r+1] do
   l:=z(Sum([1..26],i->x^i)^(n-c));
   for p in Partitions(c,r) do
    d:=x;
    for u in List(p,k->z(Sum([0..9],i->x^i)^k)) do
     d:=Sum([2..s(u)],i->u[i]*Value(d,x^(i-1))mod x^s(l));
    od;
    d:=z(d);
    t:=t+Binomial(n-c+1,r)*NrArrangements(p,r)*
         Sum([2..s(d)],i->d[i]*l[i]);
   od;
  od;
 od;
 return t;
end;

不要な空白を絞り出し、416バイトの1行を取得するには、これをパイプ処理します。

sed -e 's/^ *//' -e 's/in \[/in[/' -e 's/ do/do /' | tr -d \\n

私の古い「Windows XP用に設計された」ラップトップはf(10)、1分未満で計算でき、さらに1時間以内にさらに計算できます。

gap> for i in [2..15] do Print(i,": ",f(i),"\n");od;
2: 18
3: 355
4: 8012
5: 218153
6: 6580075
7: 203255386
8: 6264526999
9: 194290723825
10: 6116413503390
11: 194934846864269
12: 6243848646446924
13: 199935073535438637
14: 6388304296115023687
15: 203727592114009839797

使い方

最初に、パターンLDDLLDLに適合する完全なナンバープレートの数のみを知りたいとします。ここで、Lは文字をD示し、数字を 示します。文字が値を与えることができる方法の数ll[i]与えるような数字のリストと、数字から 得られる値iの同様のリストがあると仮定dします。それから、共通の価値を持つ完全なナンバープレートの数iはちょうどです l[i]*d[i]、そして、私たちはこれをすべて合計することによって私たちのパターンですべての完全なナンバープレートの数を得ますi。この合計を取得する操作をで示しましょうl@d

今、これらのリストを取得するための最良の方法は、すべての組み合わせを試してみてカウントするようにした場合でも、我々は見て、文字と数字のために独立してこれを行うことができます26^4+10^3例の代わりに、26^4*10^3 私たちはパターンを当てはめるすべてのプレートを介して実行する際のケース。しかし、私たちはもっとうまくやることができます:ここでの文字数はどこにあるかlの係数のリスト です。(x+x^2+...+x^26)^kk4

同様に、一連の桁数の合計を取得する方法のk数をの係数として取得します(1+x+...+x^9)^k。複数桁の数字がある場合、対応するリストを、d1#d2position iに値としてすべてのd1[i1]*d2[i2]whereの合計を持つ演算と組み合わせる必要がありi1*i2=iます。これはディリクレ畳み込みであり、リストをDirchletシリーズの係数として解釈した場合の積にすぎません。しかし、すでにそれらを多項式(有限べき級数)として使用しており、それらの操作を解釈する良い方法はありません。この不一致が、単純な式を見つけるのを難しくしている原因の一部だと思います。とにかく多項式でそれを使用して、同じ表記法を使用してみましょう#。1つのオペランドが単項式の場合、計算は簡単です。p(x) # x^k = p(x^k)。双線形であるという事実と併せて、これはそれを計算するための素晴らしい(しかし、あまり効率的ではない)方法を提供します。

k文字がせいぜい値を与えることに注意してください、 一桁が値を与えることができる26k間。そのため、多項式で不必要な高出力が得られることがよくあります。それらを取り除くために、moduloを計算できます。これは大きな速度を断念して、私はすぐに気付かなかったけれども、私たちは今の度合いがいることを知っているのででも、ゴルフを支援すること、次に大きなではありません最終的に上限を簡素化しています、。 (コメントを参照)の最初の引数で計算を行うことでさらに高速化され、計算全体を低レベルで実行すると信じられないほど高速化されます。しかし、私たちはまだゴルフの問題に対する正当な答えを目指しています。k9^kdx^(maxlettervalue+1)dlSummodValue#

だから私たちは私たちを持っているldし、パターンとの完璧なナンバープレートの番号を計算するためにそれらを使用することができますLDDLLDL。それはパターンと同じ数字LDLLDDLです。一般的に、さまざまな長さの数字の実行順序を好きなように変更することができ NrArrangements、可能性の数が与えられます。また、数字の連続間に1つの文字が必要ですが、他の文字は固定されていません。Binomialこれらの可能性をカウントします。

これで、実行桁数の可能なすべての方法を実行することができます。rすべての実行回数、cすべての合計桁数、および被加数のpすべてのパーティションを実行crます。

調べるパーティションの総数は、のパーティション数よりも2つ少なくn+1、パーティション関数はのように成長し exp(sqrt(n))ます。そのため、結果を再利用して(異なる順序でパーティションを実行することで)実行時間を改善する簡単な方法がまだありますが、根本的な改善のために、各パーティションを別々に見ないようにする必要があります。

高速計算

ことに注意してください(p+q)@r = p@r + q@r。単独で、これは単に乗算を回避するのに役立ちます。しかし、(p+q)#r = p#r + q#rそれとともに、異なるパーティションに対応する単純な加算多項式で結合できることを意味します。我々はまだどのと知っておく必要があるので、私たちはただ、すべてのそれらを追加することはできませんl私たちがしなければならない@、我々が使用する必要がどの要因、-combine、そしてどの#-extensionsはまだ可能です。

同じ合計と長さのパーティションに対応するすべての多項式を組み合わせて、桁数の長さを分散する複数の方法をすでに説明しましょう。コメントで推測したものとは異なり、その値で拡張しないことを確認すれば、最小の使用値や使用頻度を気にする必要はありません。

これが私のC ++コードです。

#include<vector>
#include<algorithm>
#include<iostream>
#include<gmpxx.h>

using bignum = mpz_class;
using poly = std::vector<bignum>;

poly mult(const poly &a, const poly &b){
  poly res ( a.size()+b.size()-1 );
  for(int i=0; i<a.size(); ++i)
    for(int j=0; j<b.size(); ++j)
      res[i+j]+=a[i]*b[j];
  return res;
}

poly extend(const poly &d, const poly &e, int ml, poly &a, int l, int m){
  poly res ( 26*ml+1 );
  for(int i=1; i<std::min<int>(1+26*ml,e.size()); ++i)
    for(int j=1; j<std::min<int>(1+26*ml/i,d.size()); ++j)
      res[i*j] += e[i]*d[j];
  for(int i=1; i<res.size(); ++i)
    res[i]=res[i]*l/m;
  if(a.empty())
    a = poly { res };
  else
    for(int i=1; i<a.size(); ++i)
      a[i]+=res[i];
  return res;
}

bignum f(int n){
  std::vector<poly> dp;
  poly digits (10,1);
  poly dd { 1 };
  dp.push_back( dd );
  for(int i=1; i<n; ++i){
    dd=mult(dd,digits);
    int l=1+26*(n-i);
    if(dd.size()>l)
      dd.resize(l);
    dp.push_back(dd);
  }

  std::vector<std::vector<poly>> a;
  a.reserve(n);

  a.push_back( std::vector<poly> { poly { 0, 1 } } );
  for(int i=1; i<n; ++i)
    a.push_back( std::vector<poly> (1+std::min(i,n+i-i)));
  for(int m=n-1; m>0; --m){
    //    std::cout << "m=" << m << "\n";
    for(int sum=n-m; sum>=0; --sum)
      for(int len=0; len<=std::min(sum,n+1-sum); ++len){
        poly d {a[sum][len]} ;
        if(!d.empty())
          for(int sumn=sum+m, lenn=len+1, e=1;
              sumn+lenn-1<=n;
              sumn+=m, ++lenn, ++e)
            d=extend(d,dp[m],n-sumn,a[sumn][lenn],lenn,e);
      }
  }
  poly let (27,1);
  let[0]=0;
  poly lp { 1 };
  bignum t { 0 };
  for(int sum=n-1; sum>0; --sum){
    lp=mult(lp,let);
    for(int len=1; len<=std::min(sum,n+1-sum); ++len){
      poly &a0 = a[sum][len];
      bignum s {0};
      for(int i=1; i<std::min(a0.size(),lp.size()); ++i)
        s+=a0[i]*lp[i];
      bignum bin;
      mpz_bin_uiui( bin.get_mpz_t(), n-sum+1, len );
      t+=bin*s;
    }
  }
  return t;
}

int main(){
  int n;
  std::cin >> n;
  std::cout << f(n) << "\n" ;
}

これはGNU MPライブラリを使用します。debianでは、をインストールしlibgmp-devます。でコンパイルしg++ -std=c++11 -O3 -o pl pl.cpp -lgmp -lgmpxxます。プログラムは標準入力から引数を取ります。タイミングについては、を使用しますecho 100 | time ./pl

最後に 、実行a[sum][length][i]中のsum数字がlength数を与えることができる方法の数を与えますi。計算中、mループの開始時に、より大きい数で実行できる方法の数を示しますm。すべてはで始まり a[0][0][1]=1ます。これは、より小さい値の関数を計算するために必要な数値のスーパーセットであることに注意してください。そのため、ほぼ同時に、までのすべての値を計算できましたn

再帰はないため、ネストされたループの数は固定されています。(最も深いネストレベルは6です。)各ループはn、最悪の場合に線形であるいくつかの値を通過します。したがって、多項式時間のみが必要です。私たちは、ネストされた時によく見る場合ijでは、ループextend、我々は上限見つけjフォームのをN/i。これは、jループの対数係数のみを提供する必要があります。f (with with sumn)の最も内側のループも同様です。また、急速に成長する数値で計算することにも留意してください。

またO(n^3)、これらの数値を保存していることにも注意してください。

実験的に、妥当なハードウェア(i5-4590S)でこれらの結果を取得し f(50)ます。1秒と23 MB、f(100)21秒と166 MB、f(200)10分と1.5 GB、f(300)1時間と5.6 GBが必要です。これは時間より複雑なことを示唆しO(n^5)ます。


これはコードゴルフの課題であるため、この答えゴルフをする必要があります。ごめんなさい。
Rɪᴋᴇʀ

1
@Riker私は自分のコードが最初から過度に冗長であるとは思わないが、私はもう少しゴルフをし、空白が絞り出されたときにそのサイズを決定する負担を取った。
クリスチャンシーバーズ

1
@carusocomputing私はそれがずっと悪いのではないかと心配しています。私は、3桁の実行がある、2桁と1桁の実行がある、または3桁の単一桁があるように、数字の実行間で数字を分配する各ケースを別々に処理していますn=5が、数字を区切るのに十分な文字がないためです。これは、3つの外側のforループが行うことです:数字のすべての有用なパーティションを実行します<n。(そして、n数字も許可することに気付きました。運が良ければ、別の最適化ではこれが0としてカウントされます)。
クリスチャンシーバーズ

1
@carusocomputing数値の場合<n/2すべてのパーティションが有用であることに注意してください。そして、残りの計算はまだ一定ではありません。何が起こっているかを見るためPrint(p,"\n");に、for p...ループの本体の先頭に追加することができます。-ループを1つ少なくするというアイデアを思いつきましたが、コードサイズの改善にしか役立ちません。
クリスチャンシーバーズ

2
mod(すでに多くの助けになった)をValueに変更し、それをに変更することで、驚くほど高速になりValue(d mod x^(1+QuoInt(s(l)-1,i-1)),x^(i-1))ます。それだけでf(15)、80秒で計算できます。
クリスチャンシーバーズ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.