在函数中评估 Knuth 的箭头符号
Evaluating Knuth's arrow notation in a function
我在计算 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)。如果您能帮助我弄清楚如何获得正确的输出并解释我做错了什么,我将不胜感激。
如果你期望7625597484987(3^27)却得到19683(27^3),那岂不是很简单调用幂函数时交换参数的问题?
查看您的 Power 函数,您的代码片段似乎以 temp 为基础调用 Power,以 b 作为 power:
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;
}
}
我写在了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;
}
我想出了一个使用 BigInteger.Pow()
函数的方法。
它可能看起来有点奇怪,但那是因为 C# BigInterger.Pow(x, y)
只接受 y 的 int,并且 teterations 有巨大的指数。对于这种特定情况,我不得不“翻转脚本”并转换 x^y = y^x。
我没有添加任何错误检查,它希望所有数字都是正整数。
我知道这适用于 x^^2 和 x^^3。我也知道它适用于 2^^4 和 2^^5。我没有计算 power/memory/math 知识来知道它是否适用于任何其他数字。 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;
}
我在计算 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)。如果您能帮助我弄清楚如何获得正确的输出并解释我做错了什么,我将不胜感激。
如果你期望7625597484987(3^27)却得到19683(27^3),那岂不是很简单调用幂函数时交换参数的问题?
查看您的 Power 函数,您的代码片段似乎以 temp 为基础调用 Power,以 b 作为 power:
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;
}
}
我写在了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;
}
我想出了一个使用 BigInteger.Pow()
函数的方法。
它可能看起来有点奇怪,但那是因为 C# BigInterger.Pow(x, y)
只接受 y 的 int,并且 teterations 有巨大的指数。对于这种特定情况,我不得不“翻转脚本”并转换 x^y = y^x。
我没有添加任何错误检查,它希望所有数字都是正整数。
我知道这适用于 x^^2 和 x^^3。我也知道它适用于 2^^4 和 2^^5。我没有计算 power/memory/math 知识来知道它是否适用于任何其他数字。 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;
}