Bealの$ 1,000,000を取得しましょう


17

あなたがそれを証明/反証すると、Beal's Conjectureの賞金は100万ドルになります。

それは場合と述べA ^ x + B ^ y = C ^ zA、B、C、X、Y、及びZは、X、Y、Z> 2、次にA、Bとの正の整数であり、そしてCここで、共通の素因数を有します。

これに反論する反例を検索するプログラムを作成することが課題です!

ルール

  • ビールの予想の反例を検索するプログラムを書く
  • 徹底的な検索(つまり、この形式に適合する数値のすべての可能な組み合わせ)を実行するか、いくつかの最適化を使用できます(たとえば、AとBは対称です)。
  • 任意精度の整数を使用する必要があります。

ノート

  • これは人気コンテストです。クリエイティブに!
  • 速度は必要ありませんが、より面白くなります。最適化!
  • また、最短のコードを見ることにも興味があります。あなたは私から+1を受け取ります!
  • 私がアクセスできるスーパーコンピューターで優勝プログラムを実行します!
  • この推測は真実であると考えられていますが、それは私たちが試すことができないという意味ではありません!
  • GoogleのPeter Norvigもこの問題を試みました。彼のページをガイダンスとして使用できます。彼には、例として使用できる短いPythonプログラムがあります。
  • 他の人(たまたまGoogleで働いている人)はNorvigのアプローチを大幅に改善しまし。彼のページ(ソースコード付き)はここにあります
  • 2年前のこれに関連する私のSO質問も役立つかもしれません:Fin all A ^ x in a given range

1
スーパーコンピューター?今、それはクールです。現金を分割する可能性はありますか?
ɐɔıʇǝɥʇuʎs

@Syntheticaこの推測はすでに非常に大きな数字でテストされているので、これは主に楽しみのためです。しかし、もちろん現金を分割できます:)
オースティンヘンリー14

2
「いつまでも継続するか、有限の上限を許可する必要があります(どんなに大きくても)。」...どのような選択肢とは対照的に?
地下

@undergroundmonorail少数でのみ機能します。
オースティンヘンリー14

2
小さい数字は有限の上限です。
地下

回答:


4

私は哀れに怠laです(しゃれを意図しています)が、なぜ...ルールを満たしているようです。

ハスケル、204

import Control.Monad
import Control.Monad.Omega
main=print.filter(\[(a,x),(b,y),(c,z)] 
 ->and$(a^x+b^y==c^z):zipWith(((>1).).gcd)[a,b,c][b,c,a])
 .runOmega$mapM(\_->liftM2(,)(each[1..])$each[3..])"123"

これは、印刷さ1つの反例プロパティを満たすすべての組み合わせを。diagonal 6 ... を対角化するためにcontrol- monad -omegaパッケージを使用しました。しかし、誰かが後でAPLの答えを投稿して、これらすべてが言語に組み込まれている(またはそうではない)と思うので、私はそれについてあまり説明しません...

もちろん、プログラムは遅すぎて(単純な枯渇とデータ構造としてのリンクリスト)、実際に反例をもたらすことは期待できませんが、Haskell自体は実際に適切なパフォーマンスを達成できます。


1が1行、すなわち、リスト形式でタプルを出力しますので、あなたはオフにバッファリングターミナルのを切り替える必要があるか、結果がで来るときは表示されません。また、あなたは置き換えることができprintmapM_ print、あなたはそれぞれの結果の後に改行を取得するので、ラインバッファリングされた端末をフラッシュします。

プログラムをテストするには、に変更each[3..]each[2..]、結果として単純にすべての非素数のピタゴラスタプルを取得します。


2

C#、ループなし

わかりました、私はそれらのリンクのいくつかをスキムしました、しかし正直に言うと、それらは少し退屈でした。ハッシュテーブルなどで地獄を最適化することに興味はありません。なぜ必要なのですか?あなたはひどいスーパーコンピューターを持っています!

地獄、私はループに煩わされたくさえありません!このソリューションは、ループなしのルールに従います

私がこれから書くコードは、良いコードでも、実際の生活で書くような種類のコードでもありません(将来の雇用主がこれを読んだ場合に備えて)。このコードは、簡潔さと物語で働く能力を強調し、適切な慣習と儀式、ループなどを強調しません。

私が話していることを示すために、方程式のオペランドを格納するパブリックフィールドを持つ衝撃的なクラスから始めます。

class BealOperands
{
    public BigInteger A, B, C, x, y, z;
}

OK、おそらく最も難しい課題から始めましょう。これらのオペランドのすべての組み合わせを変更する方法を見つけ出す必要があります。すべての順列をチェックするよりも効率的に行う方法は間違いなくありますが、それらを理解するのは面倒です。そして、なぜ私はする必要がありますか?私たちはひどいスーパーコンピューターを持っています!

これが私が思いついたアルゴリズムです。それは信じられないほど非効率的で、同じオペランドを何度も繰り返しますが、誰が気にしますか?スーパーコンピューター!

  • 6つのオペランドを基数2の数として扱い、すべての組み合わせを順列します。
  • 6つのオペランドを基数3の数として扱い、すべての組み合わせを順列します。
  • 6つのオペランドを基数4として扱い、すべての組み合わせを順列します。
  • (...)

ループなしでこれをすべて行う方法は?簡単!を実装して、順列をポンプアウトするためにIEnumerable関連付けIEnumeratorます。後で、LINQを使用してクエリします。

class BealOperandGenerator : IEnumerable<BealOperands>
{
    // Implementation of IEnumerable<> and IEnumerable -- basically boilerplate to get to BealOperandGeneratorEnumerator.
    public IEnumerator<BealOperands> GetEnumerator() { return new BealOperandGeneratorEnumerator(); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

class BealOperandGeneratorEnumerator : IEnumerator<BealOperands>
{
    public BealOperandGeneratorEnumerator() { Reset(); }

    private BealOperands operands;
    private BigInteger @base;

    public void Reset()
    {
        // A is set to 0, which is "before" its minimum value, because IEnumerators are supposed to
        // point to their first element *after* the first call to MoveNext().
        // All other operands are set to their minimum values.
        operands = new BealOperands { A = 0, B = 1, C = 1, x = 3, y = 3, z = 3 };
        @base = 2;
    }

    public BealOperands Current
    {
        get 
        {
            // We need to return a copy, since we'll be manipulating our internal one.
            return new BealOperands { 
                A = operands.A, B = operands.B, C = operands.C, 
                x = operands.x, y = operands.y, z = operands.z };
        }
    }

    public bool MoveNext()
    {
        // Increment the lowest "digit" and "carry" as necessary.
        operands.A++;
        if (operands.A - 1 >= @base)
        {
            operands.A = 1; operands.B++;
            if (operands.B - 1 >= @base)
            {
                operands.B = 1; operands.C++;
                if (operands.C - 1 >= @base)
                {
                    operands.C = 1; operands.x++;
                    if (operands.x - 3 >= @base)
                    {
                        operands.x = 3; operands.y++;
                        if (operands.y - 3 >= @base)
                        {
                            operands.y = 3; operands.z++;
                            if (operands.z - 3 >= @base)
                            {
                                operands.z = 3; @base++;
                            }
                        }
                    }
                }
            }
        }
        // There will always be more elements in this sequence.
        return true;
    }

    // More boilerplate
    object System.Collections.IEnumerator.Current { get { return Current; } }
    public void Dispose() { }
}

今、私たちは仕事をしています!する必要があるのは、インスタンスを列挙し、BealOperandGeneratorBeal's Conjectureの反例を見つけることだけです。

私たちの次の大きな問題は、a BigIntegerをa のべき乗する組み込みの方法がないように見えることですBigIntegerBigInteger.Pow(BigInteger value, int exponent)、およびがありますが、BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus)a BigIntegerを別の累乗BigInteger無限大で累乗する方法はありません。

問題のなんて光沢のある爪!IEnumerable/ IEnumeratorハンマーで解決するように作られたようです!

class BigIntegerPowerEnumerable : IEnumerable<Tuple<BigInteger, BigInteger>>
{
    public BigIntegerPowerEnumerable(BigInteger @base, BigInteger exponent) { this.@base = @base; this.exponent = exponent; } 
    BigInteger @base, exponent;

    public IEnumerator<Tuple<BigInteger, BigInteger>> GetEnumerator() { return new BigIntegerPowerEnumerator(@base, exponent); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

class BigIntegerPowerEnumerator : IEnumerator<Tuple<BigInteger, BigInteger>>
{
    public BigIntegerPowerEnumerator(BigInteger @base, BigInteger exponent) 
    {
        originalBase = @base; 
        originalExponent = exponent;
        Reset(); 
    }

    BigInteger originalBase, currentBase, originalExponent, currentExponent;
    bool finished;

    public void Reset()
    {
        // IEnumerable.Reset() is a silly method. You're required to implement it when you implement IEnumerable,
        // but it isn't used by foreach or LINQ or anything. If you want to re-enumerate the enumerable, just get
        // a brand new enumerator.
        // In this case it gets in the way. The only reason I'm storing the original values is so I can implement 
        // this useless method properly. I supposed I could just throw a NotImplementedException or something, 
        // but it's done now.
        currentBase = originalBase;
        currentExponent = originalExponent;
        finished = false;
    }

    public bool MoveNext()
    {
        if (finished) return false;

        if (currentExponent <= Int32.MaxValue)
        {
            currentBase = BigInteger.Pow(currentBase, (Int32)currentExponent);
            currentExponent = 1;
            finished = true;
        }
        else
        {
            currentBase = BigInteger.Pow(currentBase, Int32.MaxValue);
            currentExponent -= Int32.MaxValue;
        }
        return true;
    }

    public Tuple<BigInteger, BigInteger> Current
    {
        get { return new Tuple<BigInteger, BigInteger>(currentBase, currentExponent); }
    }

    object System.Collections.IEnumerator.Current { get { return Current; } }
    public void Dispose() { }
}

static class BigIntegerPowExtension
{
    public static BigInteger Pow(this BigInteger @base, BigInteger exponent)
    {
        return new BigIntegerPowerEnumerable(@base, exponent).Last().Item1;
    }
}

今、私たちは、拡張メソッド持っPowAで呼び出すことができ、BigIntegerでがあり、BigInteger指数を受け取り、モジュラスは受け取りません。

さて、一歩下がろう。特定のものBealOperandsがビールの予想の反例であるかどうかはどうすればわかりますか?さて、次の2つが真実である必要があります。

  • オペランドは、ページの上部でその数式にプラグインされると、真の方程式を形成する必要があります。
  • A、B、およびCに共通の素因数があってはなりません(つまり、GCDは1です)。

最初の条件を確認するために必要なものが揃っています。そして、2番目の条件は、音よりも確認がはるかに簡単であることがわかります。BigInteger素敵なGreatestCommonDivisorメソッドを提供します。これにより、ループなしで実装しようとする悪夢全体を便利に回避できます。

したがって、a BealOperandsが反例かどうかをチェックするメソッドを作成する準備ができました。ここに行く...

static class BealOperandsExtensions
{
    public static bool IsBealsConjectureCounterExample(this BealOperands o)
    {
        // If the equation isn't even true, we don't have a counter example unfortunately
        if (o.A.Pow(o.x) + o.B.Pow(o.y) != o.C.Pow(o.z))
        {
            return false;
        }

        // We have a counterexample if A, B and C are coprime
        return BigInteger.GreatestCommonDivisor(o.A, o.B) == 1 &&
               BigInteger.GreatestCommonDivisor(o.A, o.C) == 1 &&
               BigInteger.GreatestCommonDivisor(o.B, o.C) == 1;
    }
}

そして最後に、このかなり滑らかなMain方法ですべてをまとめることができます。

static class Program
{
    static void Main()
    {
        var bealOperandGenerator = new BealOperandGenerator();
        if (bealOperandGenerator.Any(o => o.IsBealsConjectureCounterExample()))
        {
            Console.WriteLine("IN YOUR FACE, BEAL!");
        }
    }
}

2

C ^ Z <= 1.0E27の反例はありません。

2019年2月現在、「X」および/または「Y」指数のいずれかまたは両方が5以上でなければならないという前提で、C ^ Z <= 1.0E29にチェックアウトしています。

このプログラムの現在のバージョン( "X"および/または "Y"> = 5)は、AMD 2920Xで1秒未満でC ^ Z <= 1.0E15のすべてのソリューションを見つけます。(ただし、gcd(A、B、C)はすべて2以上です)

詳細は http://www.durangobill.com/BealsConjecture.htmlで

現在のコード(「C」とOpenMPを使用)をこれらの制限を超えて変更できますが、実行するには128GB以上のRAMが必要です。(数百のCPUも役立ちます。数千のCPUがさらに優れているでしょう。)(このようなものに無料でアクセスできる場合は、私に連絡してください。)

私のメールアドレスはホームページのhttp://www.durangobill.comにあります


1
いくつかのコードでこれを具体化できる場合、これは有効な答えである可能性があります。しかし、いずれにせよ、あなたがこれに関して行った仕事は印象的です。
Οurous

多くの大学には高性能クラスターがあります。あなたが誰かに手を差し伸べれば、彼らはあなたにアクセスを許可できるかもしれません。アイドル状態のクラスターが多すぎます。
オースティンヘンリー

1

Bealの検索プログラムの2番目のバリエーションが終了しました。結果は次のとおりです。

CZ<1026Aバツ+BY=CZバツY> =4

バツY> =5CZ<1028Aバツ+BY=CZバツY> =5

詳細:http : //www.durangobill.com/BealsConjecture.html

次の2つの質問は次のとおりです。1)スーパーコンピューターは検索を拡張できますか?2)スーパーコンピューターで検索範囲を広げることができれば、実用的でしょうか?

1)上記の検索のいずれかを1.0E30に拡張するには、コアが300GBを共有できない限り、コアごとに300GBのRAMが必要です。1.0E30を超える指数関数の電力がさらに増加するごとに、必要なRAMの量は少なくとも2.2倍に増加します。

2)1.0E30以上に指数がさらに増加するごとに必要な処理能力は、合計CPU時間に約3.8を掛けます。1.0E29への検索には、12コアを使用して2週間かかりました。スーパーコンピューターの時間は一般に「無料」ではなく、反例があるという見込みはほとんどありません。

durangobill.com/BealE29code.txtのコードの効率性のガイドとして、12個のコアのそれぞれは、内部ループの1秒あたり平均2億2000万回のループ反復を行いました。(平均は2週間の実行です。)(RAMメモリが私が持っているものを超えて増加すると、この平均速度は最大2倍になります。)

彼はスーパーコンピューターにアクセスできますが、そうではないので、オースティンに1)と2)に答えさせます。(1)と2)の両方が "go"である場合は、大規模なスーパーコンピュータークラスターのマルチスレッド命令に慣れていないという警告とともに "C"コードを提供できます。


質問を3つに広げるのではなく、1つだけ答えてください。以前の回答を編集できることを知っていますか?
ジョーキング

あなたが反例を見つけてそれを印刷しないことを感謝します...また、これはあまりコードゴルフではありません
...-Axman6

0

適合させるためにこれを2つのコメントに入れなければなりませんでした。

主要な配列は次のように割り当てられます。

SortHeads = calloc(PRIME1+1, 8);
X2YmodPrime1 = calloc(ARRAYSIZE+1, 4);
X2YmodPrime2 = calloc(ARRAYSIZE+1, 4);
Base = calloc(ARRAYSIZE+1, 4);
Power = malloc(ARRAYSIZE+1);

(これらのアレイには128GBのRAMが必要です)

で:

#define PRIME1 2147483647LLU
#define PRIME2 2147483629LLU
#define ARRAYSIZE 4700000000LL

「ベース」には実際に33ビットが必要です(cbrt(1.0E29)) -余分なビットは「パワー」に詰め込まれています(7ビットのみが必要です)。

配列はハッシュテーブルと同様に動作します。ただし、これらはPRIME1によってソートされ、ルックアップテーブルとしてのみ使用されるため、それらにアクセスするためにリンクリストは必要ありません。したがって、結果は、試行A ^ X + B ^ Y = any C ^ Zかどうかを確認するための非常に高速な線形時間ルックアップです。

したがって、最も内側のループ内のステートメントは、深さ2ループのみです。

「プラグマ」ステートメントは、使用されるマルチプロセッシングコアの数(この場合は12)を制御します。すべてがアレイの単一コピーにアクセスできます。

「メイン」コード(「C」)(コメントが投稿された行の長さに合うことを望みます。そうでない場合は、コピーして、より長い行の長さを持つドキュメントにコードを貼り付けます。)


コメントボックスでは600文字しか使用できず、コードには3,000以上必要です。(提案はありますか?)(ここに投稿できない場合、Webページにコードを投稿できます。)
ビルバトラー

ここに「メイン」「C」コードを配置します。durangobill.com/BealE29code.txt 他に何もない場合、これは「C」での複数スレッド処理の「方法」の例です。
ビルバトラー

1
サイトへようこそ。コメントボックスは600文字に制限されていますが、答えはそうではありません。コードを簡単に答えに収めることができるはずです。コメントを削除しない場合。また、コードブロックを使用するように回答を再フォーマットしました。これらは私がやったように4つのスペースで行うことができます。コードを回答に移動するときは、コードブロックに配置する必要があります。そうしないと、コードが完全に判読できなくなります。
ポストロックガーフハンター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.