Lets take Beal's $1,000,000

I'm being pathetically lazy (pun intended), but why not... seems to fulfill the rules.

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"

This prints1 all combinations which fulfill the counterexample property. I used the control-monad-omega package for diagonalising ℕ6... might be considered library-cheating. But seeing as someone will later post an APL answer where all this stuff is built into the language (or isn't it?), I don't give too much about it...

Of course, the program is way too slow (naïve exhaustion, and linked-lists as data structure) to be expectable of actually yielding a counterexample, but Haskell itself can actually achieve decent performance.


1Since it prints the tuples in list format, i.e. in one line, you need to switch your terminal's buffering off or you won't see when a result comes in. Alternatively, you can replace print with mapM_ print so you get a newline after each result, flushing a line-buffered terminal.

To test the program, change each[3..] to each[2..], then you'll simply get all non-coprime pythagorean tuples as result.


C#, no loops

OK, I skimmed a couple of those links, but to be honest they were a bit boring. I'm not interested in optimizing the hell out of it with hash tables and whatnot. Why should I need to? You've got a goddamn supercomputer!

Hell, I don't even want to bother with loops! This solution will follow the no-loops rule.

Please note that the code I'm about to write is not good code, or the kind of code I'd write in real life (in case any prospective employers happen to read this). This code emphasises brevity and the ability to work in a narrative, and deemphasises the proper conventions and rituals and loops and so on.

To demonstrate what I'm talking about, we'll start with a shocking class with public fields to store the operands of the equation:

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

OK, we'll start with what is probably the hardest challenge. We need to figure out a way to permute through every combination of those operands. There are undoubtedly ways to do it more efficiently than checking every permutation, but I can't be bothered figuring them out. And why should I? We've got a goddamn supercomputer!

Here's the algorithm I came up with. It's incredibly inefficient, and goes over the same operands over and over again, but who cares? Supercomputer!

  • Treat the six operands as a base-2 number, and permute through every combination.
  • Treat the six operands as a base-3 number, and permute through every combination.
  • Treat the six operands as a base-4 number, and permute through every combination.
  • (...)

How to do all this without loops? Easy! Just implement an IEnumerable and associated IEnumerator to pump out the permutations. Later, we'll use LINQ to query it.

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

Now we're in business! All we need to do is enumerate an instance of BealOperandGenerator and find a counterexample of Beal's Conjecture.

Our next big problem is that there doesn't seem to be a built-in way to raise a BigInteger to the power of a BigInteger. There's BigInteger.Pow(BigInteger value, int exponent), and BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus), but no method to raise a BigInteger, to the power of another BigInteger, modulo infinity.

What a shiny nail of a problem! It looks like it was made to be solved with our IEnumerable/IEnumerator hammer!

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

Now we've got an extension method Pow, that can be called on a BigInteger, and takes a BigInteger exponent and no modulus.

OK, let's step back. How can we tell if a particular BealOperands is a counterexample of Beal's Conjecture? Well, two things need to be true:

  • The operands, when plugged into that formula up at the top of the page, must form a true equation.
  • A, B, and C must NOT have a common prime factor (i.e. their GCD is 1).

We've got what we need to check the first condition. And it turns out the second condition is a lot easier to check than it sounds. BigInteger provides a lovely GreatestCommonDivisor method, which allows us to conveniently sidestep the whole nightmare of trying to implement that without loops.

So we're ready to write a method to check if a BealOperands is a counterexample. Here goes...

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

And finally we can bring it all together with this rather slick Main method:

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

There are no counterexamples with C^Z <= 1.0E27.

As of Feb. 2019 I’m checking out to C^Z <= 1.0E29 on the assumption that either the “X” and/or “Y” exponent must be >= 5.

Current version of this program (“X” and/or “Y” >= 5) takes less than 1 second on an AMD 2920X to find all solutions out to C^Z <= 1.0E15. (But all of the gcd(A,B,C) are >= 2)

Details at http://www.durangobill.com/BealsConjecture.html

I can modify the current code (Uses “C” and OpenMP) out beyond these limits but will need more than 128GB of RAM to run it. (Hundreds of CPUs would also help. Thousands of CPUs would be even better.) (If you have free access to something like this, please contact me.)

My email address is on my home page at http://www.durangobill.com