C
C#•7mo ago
BenMcLean

Turtle moving question

Given this test here:
public void TurtleTest()
{
static ushort expected(ushort startX, ushort startY, ushort newY, bool yFirst = false)
{
ushort x = startX,
y = startY;
while (y != newY)
{
if (yFirst && x - startX < y - startY
|| !yFirst && x - startX <= y - startY)
x++;
else
y++;
}
return x;
}
static ushort actual(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY);
for (ushort startX = 0; startX < 9; startX++)
for (ushort startY = 0; startY < 9; startY++)
for (ushort newY = startY; newY < startY + 9; newY++)
{
Assert.Equal(
expected: expected(startX, startY, newY, false),
actual: actual(startX, startY, newY, false));
Assert.Equal(
expected: expected(startX, startY, newY, true),
actual: actual(startX, startY, newY, true));
}
}
public void TurtleTest()
{
static ushort expected(ushort startX, ushort startY, ushort newY, bool yFirst = false)
{
ushort x = startX,
y = startY;
while (y != newY)
{
if (yFirst && x - startX < y - startY
|| !yFirst && x - startX <= y - startY)
x++;
else
y++;
}
return x;
}
static ushort actual(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY);
for (ushort startX = 0; startX < 9; startX++)
for (ushort startY = 0; startY < 9; startY++)
for (ushort newY = startY; newY < startY + 9; newY++)
{
Assert.Equal(
expected: expected(startX, startY, newY, false),
actual: actual(startX, startY, newY, false));
Assert.Equal(
expected: expected(startX, startY, newY, true),
actual: actual(startX, startY, newY, true));
}
}
How do I rewrite the actual method to always give the same output as the expected method?
1 Reply
BenMcLean
BenMcLean•7mo ago
Some context: I have a math question which I am having trouble coming up with good words for. First, see this method here:
static ushort getX(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY);
static ushort getX(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY);
Given an X and Y starting position and the assumption that we're drawing a line which goes diagonally in an x+, y+ direction and we know the new y value, this method should calculate the new x value. But there's a catch. We can't actually move diagonally in making this line. We can only move cardinally, so to get there, we move in a zigzag pattern, either y first or x first. From knowing the answer to whether we're moving y first or x first, (in the yFirst parameter) I should be able to return the first or smaller new x value which is in the column of the specified new y value. This seems like a dumb question because the answer should be obvious but somehow my brain just isn't intuiting what it should be. I'm guessing it would add one or subtract one based on the value of the yFirst variable. One possibility would be to pre-calculate a giant lookup table of all the possible results but I mean, the goal is to make actual be a formula. ChatGPT suggests (ushort)(startX + Math.Max(0, Math.Min(newY - startY, yFirst ? 1 : 0))) That didn't work. I believe Tommy Ettinger has found the solution:
static ushort actual(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY - (((startY != newY) && yFirst) ? 1 : 0));
static ushort actual(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY - (((startY != newY) && yFirst) ? 1 : 0));
So what I ended up with in the end was:
static ushort getX(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY - (yFirst && startY != newY ? 1 : 0));
static ushort getY(ushort startX, ushort startY, ushort newX, bool yFirst = false) => (ushort)(startY + newX - startX - (yFirst || startX == newX ? 0 : 1));
static ushort getX(ushort startX, ushort startY, ushort newY, bool yFirst = false) => (ushort)(startX + newY - startY - (yFirst && startY != newY ? 1 : 0));
static ushort getY(ushort startX, ushort startY, ushort newX, bool yFirst = false) => (ushort)(startY + newX - startX - (yFirst || startX == newX ? 0 : 1));
(that was awkward phrasing but I had to say "what I ended up with in the end was" to avoid saying, "the final solution was" 😉 )