gpt4 book ai didi

仅使用加法、除法和乘法以固定数量的步骤达到数字的算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:23:26 24 4
gpt4 key购买 nike

在工作中玩游戏,在游戏的某一时刻,玩家被扔进了奖励游戏。他们需要赢得的金额是预先确定的,但是我们想提出一种算法,该算法使用加法、乘法和除法在 x 步中达到该金额。步数也会提前知道,因此算法只需要弄清楚如何使用该步数来达到这个数字。

您唯一可以使用的计算是 +1 到 +15、x2、x4、/2、/4。您可以在步骤中超过目标数量,但必须在最后一步达到目标数量。步数通常在 15 到 30 之间,您始终从 0 开始。

例如:数量:100,步数:10 ==+10, +2, x2, +4, x4, +10,/2, +15, +15, +9

数量:40,步数:12 ==+15, +1, +5, +2, +1,/2, *4, +6, +6,/4, +5, *2

我很好奇是否已经存在这样的东西?我相信我们可以想出一些办法,但如果有一个通用算法可以处理这项工作,我不想重新发明轮子。


更新:对@FryGuy 的代码做了一些小改动,使其成为达到目标数字的路线,有点随机。他的解决方案按原样运行良好,但在看到它运行并考虑了@Argote 和@Moron 的评论后,我意识到它需要有一定程度的随机化才能吸引我们的玩家。在 10 个步骤中添加 +1 以达到目标数量 10 效果很好,但就我们如何使用它而言是“无聊的”。非常感谢所有评论和回答的人。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CR
{
class Program
{
static void Main(string[] args)
{
while (true)
{
int targetNumber = 20;
int steps = 13;
int[] route = null;
Boolean routeAcceptable = false;

// Continue choosing routes until we find one that is acceptable (doesn't average above or target win, but does exceed it at least once)
while(!routeAcceptable)
{
routeAcceptable = CalculateRoute(targetNumber, steps, out route) && route.Average() < targetNumber && route.Max() > targetNumber;
}

foreach (int i in route.Reverse())
{
Console.WriteLine(i);
}
Console.WriteLine("-----------------------");
Console.ReadLine();
}
}

static Boolean CalculateRoute(int targetNumber, int numSteps, out int[] route)
{
int maxValue = targetNumber * 16;
bool[,] reachable = new bool[numSteps + 1, maxValue];

// build up the map
reachable[0, 0] = true;
for (int step = 0; step < numSteps; step++)
{
for (int n = 0; n < maxValue; n++)
{
if (reachable[step, n])
{
foreach (int nextNum in ReachableNumbersFrom(n))
{
if (nextNum < maxValue && nextNum > 0)
{
reachable[step + 1, nextNum] = true;
}
}
}
}
}

// figure out how we got there
int[] routeTaken = new int[numSteps + 1];
int current = targetNumber;
for (int step = numSteps; step >= 0; step--)
{
routeTaken[step] = current;
bool good = false;

// Randomize the reachable numbers enumeration to make the route 'interesting'
foreach (int prev in RandomizedIEnumerbale(ReachableNumbersFromReverse(current)))
{
if (prev < targetNumber * 8)
{
if (reachable[step, prev])
{
current = prev;
good = true;

// Avoid hitting the same number twice, again to make the route 'interesting'
for (int c = numSteps; c >= 0; c--)
{
reachable[c, prev] = false;
}
break;
}
}
}

if (!good)
{
route = routeTaken;
return false;
}
}

route = routeTaken;
return true;
}

static IEnumerable<int> ReachableNumbersFrom(int n)
{
// additions
for (int i = 1; i <= 15; i++)
{
yield return n + i;
}

// mults/divides
yield return n / 2;
yield return n / 4;
yield return n * 2;
yield return n * 4;
}

static IEnumerable<int> ReachableNumbersFromReverse(int n)
{
// additions
for (int i = 1; i <= 15; i++)
{
if (n - i >= 0)
yield return n - i;
}

// mults/divides
if (n % 2 == 0)
yield return n / 2;
if (n % 4 == 0)
yield return n / 4;
yield return n * 2;
yield return n * 4;
}

static IEnumerable<int> RandomizedIEnumerbale(IEnumerable<int> enumerbale)
{
Random random = new Random(System.DateTime.Now.Millisecond);
return (
from r in
(
from num in enumerbale
select new { Num = num, Order = random.Next() }
)
orderby r.Order
select r.Num
);
}
}
}

最佳答案

我会使用动态规划。首先,构建一个 map ,显示每个步骤可以到达哪些数字,然后回溯以找出您如何到达那里:

void CalculateRoute(int targetNumber, int numSteps)
{
int maxValue = targetNumber * 16;
bool[,] reachable = new bool[numSteps + 1, maxValue];

// build up the map
reachable[0, 0] = true;
for (int step = 0; step < numSteps; step++)
{
for (int n = 0; n < maxValue; n++)
{
if (reachable[step, n])
{
foreach (int nextNum in ReachableNumbersFrom(n))
{
if (nextNum < maxValue && nextNum >= 0)
reachable[step + 1, nextNum] = true;
}
}
}
}

// figure out how we got there
int current = targetNumber;
for (int step = numSteps; step >= 0; step--)
{
Console.WriteLine(current);

bool good = false;
foreach (int prev in ReachableNumbersFromReverse(current))
{
if (reachable[step, prev])
{
current = prev;
good = true;
break;
}
}

if (!good)
{
Console.WriteLine("Unable to proceed");
break;
}
}
}

IEnumerable<int> ReachableNumbersFrom(int n)
{
// additions
for (int i = 1; i <= 15; i++)
yield return n + i;

// mults/divides
yield return n / 2;
yield return n / 4;
yield return n * 2;
yield return n * 4;
}

IEnumerable<int> ReachableNumbersFromReverse(int n)
{
// additions
for (int i = 1; i <= 15; i++)
yield return n - i;

// mults/divides
if (n % 2 == 0)
yield return n / 2;
if (n % 4 == 0)
yield return n / 4;
yield return n * 2;
yield return n * 4;
}

关于仅使用加法、除法和乘法以固定数量的步骤达到数字的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5009720/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com