Hãy lấy $ 1.000.000 của Beal


17

Beal's Conjecture có giải thưởng triệu đô nếu bạn chứng minh / từ chối nó.

Nó nói rằng nếu A ^ x + B ^ y = C ^ zA, B, C, x, y và z là các số nguyên dương với x, y, z> 2, thì A, B và C có một thừa số nguyên tố chung.

Thách thức là viết một chương trình tìm kiếm một ví dụ phản biện để từ chối điều này!

Quy tắc

  • Viết chương trình tìm kiếm ví dụ phản biện của Beal's Conjecture
  • Bạn có thể thực hiện tìm kiếm toàn diện (nghĩa là tất cả các tổ hợp số có thể phù hợp với biểu mẫu này) hoặc sử dụng một số tối ưu hóa (ví dụ: A và B là đối xứng).
  • Bạn phải sử dụng số nguyên chính xác tùy ý.

Ghi chú

  • Đây là một cuộc thi phổ biến, hãy sáng tạo!
  • Tốc độ không cần thiết, nhưng làm cho nó thú vị hơn. Tối ưu hóa!
  • Tôi cũng quan tâm đến việc xem mã ngắn nhất quá. Bạn sẽ nhận được +1 từ tôi!
  • Tôi sẽ chạy chương trình chiến thắng trên một siêu máy tính mà tôi có quyền truy cập!
  • Giả thuyết này được coi là đúng, nhưng điều đó không có nghĩa là chúng ta không thể thử!
  • Peter Norvig của Google cũng đã cố gắng giải quyết vấn đề này. Bạn có thể sử dụng trang của mình như hướng dẫn. Anh ta có một chương trình Python ngắn mà bạn có thể sử dụng làm ví dụ.
  • Một số anh chàng khác (cũng tình cờ làm việc tại Google) đã cải thiện rất nhiều về cách tiếp cận của Norvig, trang của anh ấy (với mã nguồn) có thể được tìm thấy ở đây .
  • Câu hỏi SO của tôi liên quan đến vấn đề này từ hai năm trước cũng có thể hữu ích: Vây tất cả A ^ x trong một phạm vi nhất định .

1
Siêu máy tính? Bây giờ thì thật tuyệt. Bất kỳ cơ hội chia tiền mặt?
ɐɔıʇǝɥʇuʎs

@Synthetica Giả thuyết này đã được thử nghiệm với những con số rất, rất, rất lớn nên điều này chủ yếu là để giải trí. Nhưng tất nhiên chúng ta có thể chia tiền mặt :)
Austin Henley

2
"Nó nên tiếp tục mãi mãi hoặc cho phép giới hạn trên hữu hạn (cho dù lớn đến đâu)." ... trái ngược với những gì thay thế?
undergroundmonorail

@undergroundmonorail Chỉ hoạt động với số lượng nhỏ.
Austin Henley

2
Số nhỏ là một giới hạn trên hữu hạn.
undergroundmonorail

Câu trả lời:


4

Tôi đang lười biếng một cách thảm hại (ý định chơi chữ), nhưng tại sao không ... dường như hoàn thành các quy tắc.

Haskell, 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"

Điều này in 1 tất cả các kết hợp đáp ứng thuộc tính mẫu. Tôi đã sử dụng gói kiểm soát monad-omega cho đường chéo ℕ 6 ... có thể được coi là gian lận thư viện. Nhưng khi thấy ai đó sau đó sẽ đăng câu trả lời APL trong đó tất cả nội dung này được tích hợp vào ngôn ngữ (hoặc không phải vậy?), Tôi không cung cấp quá nhiều về nó ...

Tất nhiên, chương trình quá chậm (kiệt sức ngây thơ và danh sách liên kết dưới dạng cấu trúc dữ liệu) có thể dự kiến ​​sẽ thực sự mang lại một ví dụ, nhưng bản thân Haskell thực sự có thể đạt được hiệu suất tốt.


1 Kể từ khi nó in các bản ghi trong định dạng danh sách, tức là trong một dòng, bạn cần phải chuyển đổi của thiết bị đầu cuối của bạn đệm tắt hoặc bạn sẽ không nhìn thấy khi một kết quả do thỏa thuận. Ngoài ra, bạn có thể thay thế printvới mapM_ printđể bạn có được một dòng mới sau mỗi kết quả, tuôn ra một thiết bị đầu cuối đệm dòng.

Để kiểm tra chương trình, hãy thay đổi each[3..]thành each[2..], sau đó bạn sẽ chỉ cần lấy tất cả các bộ dữ liệu pythagore không phải là tiền lãi.


2

C #, không có vòng lặp

OK, tôi đã lướt qua một vài trong số các liên kết đó, nhưng thành thật mà nói họ hơi nhàm chán. Tôi không quan tâm đến việc tối ưu hóa địa ngục với bảng băm và không có gì. Tại sao tôi cần phải? Bạn đã có một siêu máy tính chết tiệt!

Chết tiệt, tôi thậm chí không muốn làm phiền với các vòng lặp! Giải pháp này sẽ tuân theo quy tắc không vòng lặp .

Xin lưu ý rằng mã tôi sắp viết không phải là mã tốt hoặc loại mã tôi viết trong đời thực (trong trường hợp bất kỳ nhà tuyển dụng tiềm năng nào tình cờ đọc được mã này). Mã này nhấn mạnh đến tính ngắn gọn và khả năng làm việc trong một bài tường thuật, và coi thường các quy ước và nghi thức và vòng lặp thích hợp, v.v.

Để giải thích những gì tôi đang nói, chúng ta sẽ bắt đầu với một lớp gây sốc với các trường công khai để lưu trữ các toán hạng của phương trình:

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

OK, chúng ta sẽ bắt đầu với những gì có lẽ là thử thách khó khăn nhất. Chúng ta cần tìm ra một cách để thẩm thấu qua mọi sự kết hợp của các toán hạng đó. Chắc chắn có nhiều cách để làm điều đó hiệu quả hơn là kiểm tra mọi hoán vị, nhưng tôi không thể bận tâm tìm ra chúng. Và tại sao tôi phải? Chúng ta đã có một siêu máy tính chết tiệt!

Đây là thuật toán tôi nghĩ ra. Nó cực kỳ kém hiệu quả, và lặp đi lặp lại cùng một toán hạng, nhưng ai quan tâm? Siêu máy tính!

  • Coi sáu toán hạng là số cơ sở-2 và hoán vị qua mọi kết hợp.
  • Coi sáu toán hạng là số cơ sở 3 và hoán vị qua mọi kết hợp.
  • Coi sáu toán hạng là số cơ sở 4 và hoán vị qua mọi kết hợp.
  • (...)

Làm thế nào để làm tất cả điều này mà không có vòng lặp? Dễ dàng! Chỉ cần thực hiện một IEnumerablevà liên quan IEnumeratorđể bơm ra hoán vị. Sau đó, chúng tôi sẽ sử dụng LINQ để truy vấn nó.

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() { }
}

Bây giờ chúng tôi đang kinh doanh! Tất cả những gì chúng ta cần làm là liệt kê một ví dụ BealOperandGeneratorvà tìm một ví dụ về phỏng đoán của Beal.

Vấn đề lớn tiếp theo của chúng tôi là dường như không có cách tích hợp nào để nâng cao BigIntegersức mạnh của a BigInteger. Có BigInteger.Pow(BigInteger value, int exponent), và BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus), nhưng không có phương pháp nào để nâng cao BigIntegersức mạnh của người khác BigInteger, vô hạn modulo.

Thật là một móng tay sáng bóng của một vấn đề! Có vẻ như nó đã được thực hiện để được giải quyết bằng IEnumerable/ IEnumeratorbúa của chúng tôi !

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;
    }
}

Bây giờ chúng ta đã có một phương thức mở rộng Pow, có thể được gọi làBigInteger và mất mộtBigInteger số mũ và không có mô đun.

OK, hãy lùi lại. Làm thế nào chúng ta có thể biết nếu một cụ thể BealOperandslà một ví dụ về phỏng đoán của Beal? Vâng, hai điều cần phải đúng:

  • Các toán hạng, khi được cắm vào công thức đó ở đầu trang, phải tạo thành một phương trình đúng.
  • A, B và C KHÔNG phải có thừa số nguyên tố chung (nghĩa là GCD của chúng là 1).

Chúng tôi đã có những gì chúng ta cần kiểm tra điều kiện đầu tiên. Và hóa ra điều kiện thứ hai dễ kiểm tra hơn nhiều so với âm thanh. BigIntegercung cấp một GreatestCommonDivisorphương pháp đáng yêu , cho phép chúng ta thuận tiện vượt qua cơn ác mộng cố gắng thực hiện điều đó mà không cần vòng lặp.

Vì vậy, chúng tôi đã sẵn sàng để viết một phương pháp để kiểm tra xem a BealOperandscó phải là một ví dụ không. Ở đây đi ...

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;
    }
}

Và cuối cùng chúng ta có thể kết hợp tất cả lại với nhau bằng Mainphương pháp khá lắt léo này:

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

2

Không có phản ứng mẫu với C ^ Z <= 1.0E27.

Kể từ tháng 2 năm 2019, tôi đang kiểm tra C ^ Z <= 1.0E29 với giả định rằng số mũ lũy thừa của X X và / hoặc của Cameron Y phải> = 5.

Phiên bản hiện tại của chương trình này (Thời X. và / hoặc Sức Y>> 5) mất chưa đến 1 giây trên AMD 2920X để tìm tất cả các giải pháp cho C ^ Z <= 1.0E15. (Nhưng tất cả các gcd (A, B, C) là> = 2)

Chi tiết tại http://www.durangobill.com/BealsConjecture.html

Tôi có thể sửa đổi mã hiện tại (Sử dụng C C và OpenMP) ngoài các giới hạn này nhưng sẽ cần nhiều hơn 128GB RAM để chạy nó. (Hàng trăm CPU cũng sẽ có ích. Hàng ngàn CPU thậm chí còn tốt hơn.) (Nếu bạn có quyền truy cập miễn phí vào một cái gì đó như thế này, vui lòng liên hệ với tôi.)

Địa chỉ email của tôi là trên trang chủ của tôi tại http://www.durangobill.com


1
Nếu bạn có thể xác nhận điều này bằng một số mã thì đây có thể là một câu trả lời hợp lệ, nếu không thì nó có thể phù hợp nhất với tư cách là một nhận xét cho câu hỏi. Tuy nhiên, dù bằng cách nào thì công việc bạn đã làm trên này đều ấn tượng.
Οurous

Nhiều trường đại học có cụm hiệu suất cao. Nếu bạn liên hệ với một người, họ có thể cấp cho bạn quyền truy cập. Tôi đã thấy quá nhiều cụm chỉ nhàn rỗi!
Austin Henley

1

Biến thể thứ 2 của chương trình tìm kiếm của Beal đã kết thúc. Kết quả là:

1) Không có phản ứng với CZ<1026. Một danh sách đầy đủ của tất cả các giải pháp chung đểMộtX+BY= =CZ với ít nhất một trong các số mũ (X,Y)> =4có thể xem tại: http://www.durangobill.com/BealXgt3e27.txt

2) Nếu bạn cho rằng ít nhất trong số các số mũ (X,Y) cần phải > =5, không có phản ứng với CZ<1028. Một danh sách đầy đủ của tất cả các giải pháp chung đểMộtX+BY= =CZ với ít nhất một trong các số mũ (X,Y)> =5và C ^ Z <1.0E29 có thể được xem tại: http://www.durangobill.com/BealXgt4e29.txt

Chi tiết tại: http://www.durangobill.com/BealsConjecture.html

Hai câu hỏi tiếp theo là :: 1) Siêu máy tính có thể mở rộng tìm kiếm không? 2) Nếu một siêu máy tính có thể mở rộng tìm kiếm, nó có thực tế không?

1) Để mở rộng một trong các tìm kiếm ở trên lên 1.0E30, sẽ cần 300 GB RAM cho mỗi lõi trừ khi các lõi có thể chia sẻ 300 GB. Đối với mỗi lần tăng thêm về công suất theo cấp số nhân vượt quá 1.0E30, lượng RAM cần thiết tăng theo hệ số ít nhất là 2.2.

2) Lượng công suất xử lý cần thiết cho mỗi lần tăng thêm theo cấp số nhân đến và vượt quá 1.0E30 nhân thời gian CPU kết hợp thêm khoảng 3,8. Việc tìm kiếm tới 1.0E29 mất 2 tuần sử dụng 12 lõi. Thời gian của siêu máy tính nói chung không phải là miễn phí, và có rất ít triển vọng rằng có bất kỳ phản ứng nào.

Là một hướng dẫn về hiệu quả của mã tại durangobill.com/BealE29code.txt, mỗi lõi trong số 12 lõi trung bình 220 triệu lần lặp mỗi giây cho vòng lặp bên trong. (Trung bình dành cho hoạt động 2 tuần.) (Việc tăng bộ nhớ RAM vượt quá mức tôi có sẽ tăng tốc độ trung bình này lên tới 2 lần).

Tôi sẽ để Austin trả lời 1) và 2) vì anh ta có quyền truy cập vào siêu máy tính và tôi thì không. (Nếu có bất kỳ cơ hội từ xa nào mà cả 1) và 2) là "đi", tôi có thể cung cấp mã "C" với cảnh báo mà tôi không quen với các hướng dẫn đa luồng cho các cụm siêu máy tính lớn.)


Bạn có thể vui lòng chỉ sử dụng một câu trả lời cho câu hỏi, thay vì trải rộng ra ba câu không? Bạn biết bạn có thể chỉnh sửa câu trả lời trước đó của bạn, phải không?
Jo King

Tôi đánh giá cao việc bạn tìm thấy một bản mẫu và sau đó không in nó ... Ngoài ra, đây không phải là môn đánh gôn ...
Axman6

0

Phải đặt nó trong 2 bình luận để làm cho nó phù hợp.

Các mảng chính được phân bổ như sau:

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

(Bạn sẽ cần 128GB RAM cho các mảng này)

với:

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

Cơ sở cơ sở thực sự cần 33 bit ( cbrt(1.0E29)) - bit bổ sung được nhồi vào trong Power Power (chỉ cần 7 bit.)

Các mảng hoạt động tương tự như một bảng băm. Tuy nhiên, vì chúng được sắp xếp theo PRIME1 và chỉ được sử dụng làm bảng tra cứu, bạn không cần các danh sách được liên kết để truy cập chúng. Do đó, kết quả là tìm kiếm thời gian tuyến tính rất nhanh để xem thử nghiệm A ^ X + B ^ Y = any C ^ Z.

Do đó, các câu lệnh trong vòng lặp trong cùng chỉ có hai vòng sâu.

Các báo cáo của Geo Pragma kiểm soát số lượng lõi xử lý được sử dụng (trong trường hợp này là 12) - tất cả đều có thể truy cập vào bản sao duy nhất của mảng.

Đây là mã chính của Edward (trong C Cv) (Hy vọng các bình luận phù hợp với độ dài dòng đã đăng. Nếu không, hãy sao chép chúng ra và dán mã vào một số tài liệu có độ dài dòng dài hơn.)


Hộp bình luận sẽ chỉ cho tôi sử dụng 600 ký tự và tôi cần hơn 3.000 mã cho mã. (Bạn có đề xuất nào không?) (Tôi có thể đăng mã lên trang web của mình nếu tôi không thể đăng nó ở đây.)
Bill Butler

Tôi đặt mã chính của Cốt-tô Cốt ở đây. durangobill.com/BealE29code.txt Nếu không có gì khác, đó là một ví dụ về cách làm thế nào để thực hiện việc xử lý nhiều luồng trong Xử Ciên .
Bill Butler

1
Chào mừng đến với trang web. Trong khi các hộp bình luận được giới hạn ở 600 ký tự, câu trả lời của bạn là không. Bạn sẽ có thể phù hợp với mã của bạn trong câu trả lời của bạn một cách dễ dàng. Nếu bạn không thử cắt bớt các bình luận. Ngoài ra tôi định dạng lại câu trả lời của bạn để sử dụng các khối mã. Đây có thể được thực hiện với 4 không gian như tôi đã làm. Khi bạn di chuyển mã của mình đến câu trả lời, bạn nên đặt nó vào một khối mã nếu không nó sẽ hoàn toàn không thể đọc được.
Thuật sĩ lúa mì
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.