【问题标题】:Evaluating Knuth's arrow notation in a function在函数中评估 Knuth 的箭头符号
【发布时间】:2016-06-24 04:26:22
【问题描述】:

我在计算 Knuth 的箭头符号时遇到问题,它是 ↑,可以在函数中找到 here。到目前为止我所做的是:

int arrowCount = (int)arrowNum.Value; // Part of
BigInteger a = (int)aNum.Value;       // the input I
BigInteger b = (int)bNum.Value;       // already have
BigInteger result = a;
BigInteger temp = a;
for(int i = 0; i < arrowCount; i++)
{
    result = Power(temp, b);
    temp = r;
    b = a;
}

有能力

BigInteger Power(BigInteger Base, BigInteger Pow)
    {
        BigInteger x = Base;
        for(int i = 0; i < (Pow-1); i++)
        {
            x *= Base;
        }
        return x;
    }

但它的值不正确,我无法找到修复它的方法。它可以处理 1 个箭头问题,例如 3↑3(即 3^3 = 9),但不能处理更多箭头比起那个来说。

我需要一种找出更多箭头的方法,例如3↑↑3

应该是 7625597484987 (3^27),我得到 19683 (27^3)。如果您能帮助我弄清楚如何获得正确的输出并解释我做错了什么,我将不胜感激。

【问题讨论】:

  • 你知道什么会更好吗?知道人们为什么不赞成你的东西。
  • 这正是我在帖子中提到的链接。我理解它,但我似乎无法创建一个实现这种东西的函数。
  • 你必须弄清楚 1 个箭头,2 个箭头的大小写,并为 3 个或更多箭头的大小写使用循环或递归函数。
  • 不难吧? :D 我在回答中发布了,我使用了 java 和 double 但这不是问题 :D

标签: c# function math knuth


【解决方案1】:

我用java写的,输入参数用double:

    private static double knuthArrowMath(double a, double b, int arrowNum)
{
    if( arrowNum == 1)
        return Math.pow(a, b);
    double result = a;
    for (int i = 0; i < b - 1; i++)
    {
        result = knuthArrowMath(a, result, arrowNum - 1);
    }
    return result;
}

【讨论】:

  • 完美运行 :D,我只需将一些双精度数更改为 BigIntegers,一个幂函数,也许看看我是否可以让它更快 :D
  • 你也得重写你的幂函数,Power(a, 0) 等于1,你的函数返回a
  • 是的,但是输入部分严格禁止任何小于1的东西,所以我觉得我很好。不过谢谢你提醒我:P
【解决方案2】:

如果您期望 7625597484987 (3^27) 但得到 19683 (27^3),那么在调用您的幂函数?

查看您的 Power 函数,您的代码 sn-p 似乎以 temp 为基础调用 Power,b 为电源:

int arrowCount = (int)arrowNum.Value; // Part of
BigInteger a = (int)aNum.Value;       // the input I
BigInteger b = (int)bNum.Value;       // already have
BigInteger result = a;
BigInteger temp = a;
for(int i = 0; i < arrowCount; i++)
{
    result = Power(temp, b);
    temp = result;
    b = a;
}

不应该交换 temp 和 b 以便获得 result = Power(b, temp) 以获得所需的结果吗?

所以传递 1 个结果调用 Power(3, 3) 导致 temp = 27 并传递 2 个调用 Power(3, 27)。它现在只适用于单箭头的原因是因为交换第一个 Power(base, power) 调用的参数并不重要。

正如您在回答中指出的那样,这并不涵盖所有情况。鉴于您提供的示例,我创建了这个小控制台应用程序:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Arrow(3, 3));
            Console.WriteLine(Arrow(4, 4, 1));
            Console.WriteLine(Arrow(3, 4, 1));
            Console.ReadKey();
        }

        private static BigInteger Arrow(BigInteger baseNumber, BigInteger arrows)
        {
            return Arrow(baseNumber, baseNumber, arrows-1);
        }

        private static int Arrow(BigInteger baseNumber, BigInteger currentPower, BigInteger arrows)
        {
            Console.WriteLine("{0}^{1}", baseNumber, currentPower);
            var result = Power(baseNumber, currentPower);

            if (arrows == 1)
            {
                return result;
            }
            else
            {
                return Arrow(baseNumber, result, arrows - 1);
            }
        }

        private static BigInteger Power(BigInteger number, BigInteger power)
        {
            int x = number;
            for (int i = 0; i < (power - 1); i++)
            {
                x *= number;
            }
            return x;
        }
    }

【讨论】:

  • 谢谢,但尽管这确实给了我正确的答案 3↑↑3,但 4↑↑2(即 4^4 = 256)却给了我 65536 (4^8)。交换这两个值也会导致 3↑4 (3^4 = 81) 计算为 4↑3 (4^3 = 64)。
  • 啊,我明白了,我更新了我的答案以适应您的其他示例。我重写了一个小控制台应用程序来解决这个问题,因为你原来的 sn-p 有点难读 imo。
  • 谢谢,我会尝试你所做的以获得我需要的正确值。
【解决方案3】:

我想出了一种使用BigInteger.Pow() 函数的方法。 它可能看起来有点奇怪,但那是因为 C#BigInterger.Pow(x, y) 只接受 y 的 int,并且 teterations 有巨大的指数。对于这种特定情况,我不得不“翻转脚本”并转换 x^y = y^x。 我没有添加任何错误检查,它希望所有数字都是正整数。

知道这适用于 x^^2 和 x^^3。我也知道它适用于 2^^4 和 2^^5。我没有计算能力/内存/数学知识来知道它是否适用于任何其他数字。 2^^4 和 2^^5 是我唯一可以检查和测试的。它可能适用于其他号码,但我无法确认。

int baseNum = 4;
int exp = 3;
// this example is 4^^3
BigInteger bigAnswer = tetration(baseNum, exp);

// Here is what the method that "does the work" looks like.  

    // This looks a little odd but that is because I am using BigInteger.Pow(x,y)
    // Unfortunately, y can only be an int.  Tetrations have huge exponents, so I had to figure out a
    // way to have x^y work as y^x for this specific application
    // no error checking in here, and it expects positive ints only
    // I *know* this works for x^^2, x^^3, but I don't know if it works for
    // any other number than 2 at ^^4 or higher
    public static BigInteger tetration(int baseNum, int exp)
    {
        if (exp > 2)
        {
            exp = (int)Math.Pow(baseNum, (exp - 3));
        }
        else
        {
            exp = exp - 2;
        }

        Func<BigInteger, int, BigInteger> bigPowHelper = (x, y) => BigInteger.Pow(x, y);
        BigInteger bigAnswer = baseNum;

        for (int i = 0; i < Math.Pow(baseNum, exp); i++)
        {
            bigAnswer = bigPowHelper(bigAnswer, baseNum);
        }
        return bigAnswer;
    }

【讨论】:

    猜你喜欢
    • 2018-10-04
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2016-05-28
    • 2011-09-18
    • 2015-07-30
    相关资源
    最近更新 更多