Related
So I have a method which returns an array of the factors of a number
Tools.cs
public static long[] GetFactors(long number)
{
long range = number / 2;
long potentialFactors = 2;
long[] factors = new long[range + 1];
factors[0] = 1;
factors[range] = number;
for (long i = 1; i < range; i++)
{
if (number % potentialFactors == 0)
{
factors[i] = potentialFactors;
potentialFactors++;
} else
{
potentialFactors++;
}
}
Console.WriteLine($"here are the factors for the number {number}:\n"+string.Join("\n", factors));
return factors;
}
program.cs
static void Main(string[] args)
{
Tools.GetFactors(24);
Console.ReadLine();
}
But when I run my code, this appears:
here are the factors for the number 24:
1
2
3
4
0
6
0
8
0
0
0
12
24
How can I stop 0 from appearing, should I rewrite the "for" loop, or is there a way to remove 0 from the array?
You are allocating a fixed size array and setting the element to non-zero only when it is a factor.
You should instead use a var factors = new List<long>(); and call factors.Add(potentialFactor); to only store those numbers which are valid factors.
This code is using List instead of Array and also there are some other changes.
public static List<long> GetFactors(long number)
{
long range = number / 2;
List<long> factors = new List<long>() { 1 };
for (long i = 2; i <= range; i++)
{
if (number % i == 0)
{
factors.Add(i);
}
}
factors.Add(number);
Console.WriteLine($"here are the factors for the number {number}:\n" + string.Join("\n", factors));
return factors;
}
I agree a list is better when you dont know before hand how many factors you will gote. But if you really want to use an Array. You can loop throught this array, find the 0's one by one and them swith Left the numbers. Like so :
// Extension Method of array
public static void RemoveAllZeros(this long[] array) // O(N^2)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
// Grab the index override value and continue swift left
for (int j = i; j < array.Length - 1; j++)
{
array[j] = array[j + 1];
}
}
}
}
OR using a bit of LINQ and List :p :
// Extension Method of array
public static void RemoveAllZeros(this long[] numbers)
{
int zeroPst = numbers.ToList().IndexOf(0);
if (zeroPst == -1)
return;
for (int i = zeroPst; i < numbers.Length - 1; i++)
{
numbers[i] = numbers[i + 1];
}
numbers.RemoveAllZeros(); //Recursion, carefull
}
So the code that I wrote, is for the number of occurrence. Suppose in the sample part which is mentioned, if I give an input Array of {2,1,1,1,3}, it will give me the count of Number 2 occurrence as 1. Now, I'm struggling to write the code in a manner so that it gives me the count only if it's continuous from left to right. Suppose, if my array is {1,1,1,2,0}, only then it will give me the total occurrence of 1 as 3, but not if it's {1,0,1,2,1} or {0,0,1,1,1} or {1,1,2,2,1}
static void Evaluate_V5B(int[] window, int[] PayCombos,)
{
int[] Counters1 = new int[3];
for (int index0 = 0; index0 < 5; index0++)
{
Console.Write("{0} ", window[index0]);
int symbol = window[index0];
Counters1[symbol]++;
}
Console.WriteLine();
for (int indexJ = 0; indexJ < Counters1.Length; indexJ++)
{
Console.WriteLine("{0}", Counters1[indexJ]);
}
}
This will take the 1st element in the array and return continuous occurrences from left to right. If that element found anywhere else it will return 0 as count:
static void Evaluate(int[] array)
{
var count = 1;
var first = array[0];
for (int i = 1; i < array.Length; i++)
{
if(array[i] == first)
{
count++;
}
else{
for (int j = i + 1; j < array.Length; j++)
{
if(first == array[j]) {
count = 0;
break;
}
}
break;
}
}
Console.WriteLine($"Count of Number {first} occurrence is {count}");
}
This function will find the number of continuous occurrences of a specific number num in the array nums, if it is the first number.
static int ContinuousOccurrences(int[] nums, int num)
{
if (nums[0] == num)
{
int continuousOccurrences =
nums.TakeWhile(x => x == num).Count();
int totalOccurrences =
nums.Where(x => x == num).Count();
if(continuousOccurrences == totalOccurrences)
{
return continuousOccurrences;
}
else
{
return 0;
}
}
return 0;
}
If you want to know the number of continuous occurrences of the first number, call the function this way:
ContinuousOccurrences(nums, nums[0])
I'm trying to sort a text file using a merge sort. I keep getting an index out of range exception when I try to run it though. I'll Specify the areas where the exception occurs.
class Program
{
static public void DoMerge(int[] numbers, int left, int mid, int right)
{
int[] temp = new int[25];
int i, left_end, num_elements, tmp_pos;
left_end = (mid - 1);
tmp_pos = left;
num_elements = (right - left + 1);
while ((left <= left_end) && (mid <= right))
{
if (numbers[left] <= numbers[mid])
temp[tmp_pos++] = numbers[left++];
else
temp[tmp_pos++] = numbers[mid++];
}
while (left <= left_end)
temp[tmp_pos++] = numbers[left++];
while (mid <= right)
The above part is fine but below I get one exception.
temp[tmp_pos++] = numbers[mid++];
The next few lines are fine.
for (i = 0; i < num_elements; i++)
{
numbers[right] = temp[right];
right--;
}
}
static public void MergeSort_Recursive(int[] numbers, int left, int right)
{
int mid;
if (right > left)
{
mid = (right + left) / 2;
The next few lines all give me exceptions as well.
MergeSort_Recursive(numbers, left, mid);
MergeSort_Recursive(numbers, (mid + 1), right);
DoMerge(numbers, left, (mid + 1), right);
As far as I've seen the rest is fine, but I'll add it just so you guys can see.
}
}
static void Main(string[] args)
{
string fileNumbers = File.ReadAllText("sort(5).txt");
string[] intNumbers = fileNumbers.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int[] numbers = new int[intNumbers.Length];
int len = 999;
//for (int n = 0; n < intNumbers.Length; n++)
//{
// numbers[n] = int.Parse(intNumbers[n]);
//}
Console.WriteLine("MergeSort: ");
MergeSort_Recursive(numbers, 0, len - 1);
for (int i = 0; i < 1; i++)
Console.WriteLine(numbers[i]);
Console.Read();
}
}
The text file I'm trying to read has 500 numbers, highest number being 999, the smallest is 6, the numbers are pretty random and I have to sort them.
P.S. I know what an Out of Range Exception is and I know what causes it, hence the reason why I'm asking why my code is throwing the exception.
Your sorting code looks to be mostly fine. I ran it on a small array and it sorted correctly.
There are two problems in your code that are causing your out of range exceptions.
The first problem is that you are setting len to 999.
You mentioned that the file contains 500 numbers, but it would be best to just set len to numbers.Length.
static void Main(string[] args)
{
string fileNumbers = File.ReadAllText("sort(5).txt");
string[] intNumbers = fileNumbers.Split(new char[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int[] numbers = new int[intNumbers.Length];
int len = numbers.Length;
for (int n = 0; n < intNumbers.Length; n++)
{
numbers[n] = int.Parse(intNumbers[n]);
}
Console.WriteLine("MergeSort: ");
MergeSort_Recursive(numbers, 0, len - 1);
for (int i = 0; i < numbers.Length; i++)
Console.WriteLine(numbers[i]);
//Console.Read(); //Not sure what this is for....
}
The second problem is when you create your temp array, you are creating it with a length of 25.
This will fix that part:
int[] temp = new int[numbers.Length];
Note that a better approach would be to create your temp array in your main function, and pass it as a parameter to MergeSort_Recursive() and DoMerge(), so that you don't have to create a new array on each merge operation.
I have this array of integers:-
int[] numbers = new int[] { 10, 20, 30, 40 };
I am trying to create an array which will have first element, last element, second element, second-last element and so on..
So, my resulting output will be:-
int[] result = {10,40,20,30};
This was my approach, in one loop start from first and go till the middle & in second loop start from last and get to the middle and select items accordingly, but I totally messed it up. Here is my attempted code:-
private static IEnumerable<int> OrderedArray(int[] numbers)
{
bool takeFirst = true;
if (takeFirst)
{
takeFirst = false;
for (int i = 0; i < numbers.Length / 2; i++)
{
yield return numbers[i];
}
}
else
{
takeFirst = true;
for (int j = numbers.Length; j < numbers.Length / 2; j--)
{
yield return numbers[j];
}
}
}
Need Help.
You might try this:
int[] result = numbers.Zip(numbers.Reverse(), (n1,n2) => new[] {n1, n2})
.SelectMany(x =>x)
.Take(numbers.Length)
.ToArray();
Explanation: This approach basically pairs up the elements of the original collection with the elements of its reverse ordered collection (using Zip). So you get a collection of pairs like [first, last], [second, second from last], etc.
It then flattens those collection of pairs into a single collection (using SelectMany). So the collection becomes [first, last, second, second from last,...].
Finally, we limit the number of elements to the length of the original array (n). Since we are iterating through twice as many elements (normal and reverse), it works out that iterating through n elements allow us to stop in the middle of the collection.
As a different approach, this is a modification on your existing method:
private static IEnumerable<int> OrderedArray(int[] numbers)
{
var count = (numbers.Length + 1) / 2;
for (int i = 0; i < count; i++)
{
yield return numbers[i];
int reverseIdx = numbers.Length - 1 - i;
if(i != reverseIdx)
yield return numbers[reverseIdx];
}
}
ok,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var length = source.Count;
var limit = length / 2;
for (var i = 0; i < limit; i++)
{
yield return source[i];
yield return source[length - i - 1];
}
if (length % 2 > 0)
{
yield return source[limit];
}
}
}
Which you could use like this,
var result = numbers.EndToEnd().ToArray();
more optimally,
public static class Extensions
{
public static IEnumerable<T> EndToEnd<T>(this IReadOnlyList<T> source)
{
var c = source.Count;
for (int i = 0, f = 0, l = c - 1; i < c; i++, f++, l--)
{
yield return source[f];
if (++i == c)
{
break;
}
yield return source[l];
}
}
}
no divide or modulus required.
With a simple for;
int len = numbers.Length;
int[] result = new int[len];
for (int i = 0, f = 0, l = len - 1; i < len; f++, l--)
{
result[i++] = numbers[f];
if (f != l)
result[i++] = numbers[l];
}
Based on Selman22's now deleted answer:
int[] numbers = new int[] { 10, 20, 30, 40 };
int[] result = numbers
.Select((x,idx) => idx % 2 == 0
? numbers[idx/2]
: numbers[numbers.Length - 1 -idx/2])
.ToArray();
result.Dump();
(The last line is LinqPad's way of outputting the results)
Or in less LINQy form as suggested by Jeppe Stig Nielsen
var result = new int[numbers.Length];
for (var idx = 0; idx < result.Length; idx++) {
result[idx] = idx % 2 == 0 ? numbers[idx/2] : numbers[numbers.Length - 1 -idx/2];
}
The principle is that you have two sequences, one for even elements (in the result) and one for odd. The even numbers count the first half of the array and the odds count the second half from the back.
The only modification to Selman's code is adding the /2 to the indexes to keep it counting one by one in the right half while the output index (which is what idx basically is in this case) counts on.
Came up with this
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 10, 20, 30, 40, 50, 60, 70};
List<int> numbers2 = new List<int>();
int counter1 = 0;
int counter2 = numbers.Count - 1;
int remainder = numbers.Count % 2 == 0 ? 1: 0;
while (counter1-1 < counter2)
{
if (counter1 + counter2 % 2 == remainder)
{
numbers2.Add(numbers[counter1]);
counter1++;
}
else
{
numbers2.Add(numbers[counter2]);
counter2--;
}
}
string s = "";
for(int a = 0; a< numbers2.Count;a++)
s+=numbers2[a] + " ";
Console.Write(s);
Console.ReadLine();
}
This late answer steals a lot from the existing answers!
The idea is to allocate the entire result array at once (since its length is known). Then fill out all even-indexed members first, from one end of source. And finally fill out odd-numbered entries from the back end of source.
public static TElement[] EndToEnd<TElement>(this IReadOnlyList<TElement> source)
{
var count = source.Count;
var result = new TElement[count];
for (var i = 0; i < (count + 1) / 2; i++)
result[2 * i] = source[i];
for (var i = 1; i <= count / 2; i++)
result[2 * i - 1] = source[count - i];
return result;
}
Came up with this
public int[] OrderedArray(int[] numbers)
{
int[] final = new int[numbers.Length];
var limit=numbers.Length;
int last = numbers.Length - 1;
var finalCounter = 0;
for (int i = 0; finalCounter < numbers.Length; i++)
{
final[finalCounter] = numbers[i];
final[((finalCounter + 1) >= limit ? limit - 1 : (finalCounter + 1))] = numbers[last];
finalCounter += 2;
last--;
}
return final;
}
I'm working on an algorithm to find a set of non intersected paths in a grid for a
given pairs of points..
Like this for these pairs:
(9,4) and (12,13)
The output should be something like this:
9,10,11,7,3,4
13,14,15,16,12
and print "Blocked" if it can't route all paths
First I searched for an already made algorithm to find all simple paths between 2
points in a graph or a grid. and I found this one by #Casey Watson and #svick here..
It works really well but for small graphs only.
I converted it to C#.NET and enhanced it a little bit to be able to find paths of
maximum length X. and build on it my total algorithm.
The one I built works fine in small graphs..
Here is routes 9 pairs in a 8x8 grid..
but it takes a huge time in larger ones like the 16x16 or even the final one I intended to do which is a 3D model of 16x16x2
Like this
The algorithm was developed to be a depth first search RECURSIVE algorithm, but it
took a huge time to return value to the user. so I decided to convert it to loops instead of the recursive calls so that I can benefit from yield return feature in .NET
but still it didn't help any better.
The loops version of the algorithm find a route for a pair of points in less than a second but the recursive one took more than 90 seconds.
when I tried with 2 pairs, the loops version took around 342 seconds but the recursive one took around 200..
So I can't know which is faster..!? the recursive or the loops one..
I really want to know the best way to do this..
Note : the first digit in the number of the node determine the layer (Starts at 1)..
Here is the code
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace AlgorithmTest
{
struct Connection
{
public int FirstNode;
public int SecondNode;
public Connection(int N1,int N2)
{
FirstNode = N1;
SecondNode = N2;
}
}
enum Algorithm
{ Recursion, Loops }
public class Search
{
private const int MAX = 15;
private const int Width = 16;
private const int Length = 16;
private const int Height = 2;
private static void Main(string[] args)
{
var graph = new Graph();
var str = new int[Height,Length, Width];
var level = ((int)Math.Pow(10, (Length * Width).ToString().Length) >= 100) ? (int)Math.Pow(10, (Length * Width).ToString().Length) : 100;
for (var i = 0; i < Height; i++)
{
int num = 0;
for (var j = 0; j < Length; j++)
for (var k = 0; k < Width; k++)
{
str[i, j, k] = ++num + level;
}
level += level;
}
for (var i = 0; i < Height; i++)
{
for (var j = 0; j < Length; j++)
{
for (var k = 0; k < Width; k++)
{
if (i < Height - 1) graph.addEdge(str[i, j, k], str[i + 1, j, k]);
if (i > 0) graph.addEdge(str[i, j, k], str[i - 1, j, k]);
if (k < Width - 1) graph.addEdge(str[i, j, k], str[i, j, k + 1]);
if (k > 0) graph.addEdge(str[i, j, k], str[i, j, k - 1]);
if (j < Length - 1) graph.addEdge(str[i, j, k], str[i, j + 1, k]);
if (j > 0) graph.addEdge(str[i, j, k], str[i, j - 1, k]);
}
}
}
var wt = new Stopwatch();
wt.Start();
var connectedNodes = new List<Connection>()
{
new Connection(1030, 1005),
// new Connection(1002, 1044),
// new Connection(1015, 1064),
// new Connection(1041, 1038),
// new Connection(1009, 1027),
// new Connection(1025, 1018),
// new Connection(1037, 1054),
// new Connection(1049, 1060),
// new Connection(1008, 1031),
// new Connection(1001, 1035),
};
wt.Start();
Console.WriteLine("Using Loops:");
Console.WriteLine();
var allPaths = new Search().FindAllPaths(connectedNodes, graph, MAX, Algorithm.Loops);
wt.Stop();
foreach (var path in allPaths)
{
PrintPath(path);
}
Console.WriteLine("Total Seconds: " + wt.Elapsed.TotalSeconds + ", Number of paths: " + allPaths.Count());
Console.WriteLine("***************************************************************************************************");
Console.WriteLine("Using Recursion:");
Console.WriteLine();
wt.Reset();
wt.Start();
allPaths = new Search().FindAllPaths(connectedNodes, graph, MAX, Algorithm.Recursion);
wt.Stop();
foreach (var path in allPaths)
{
PrintPath(path);
}
Console.WriteLine("Total Seconds: " + wt.Elapsed.TotalSeconds + ", Number of paths: " + allPaths.Count());
Console.WriteLine();
}
private IEnumerable<List<int>> FindAllPaths(List<Connection> connectedNodes, Graph graph, int max, Algorithm algorithm)
{
var paths=new Stack<List<int>>();
var blocked=new List<int>();
for (var i = 0; i < connectedNodes.Count; i++)
{
if (!blocked.Contains(connectedNodes[i].FirstNode)) blocked.Add(connectedNodes[i].FirstNode);
if (!blocked.Contains(connectedNodes[i].SecondNode)) blocked.Add(connectedNodes[i].SecondNode);
}
if (algorithm == Algorithm.Recursion)
{
if (FindAllPaths(connectedNodes, 0, max, graph, paths, blocked))
{
Console.WriteLine("BLOCKED");
return new List<List<int>>();
}
}
else if(algorithm==Algorithm.Loops)
{
if (!FindAllPaths2(connectedNodes, 0, max, graph, paths, blocked))
{
Console.WriteLine("BLOCKED");
return new List<List<int>>();
}
}
return paths;
}
private static bool FindAllPaths(List<Connection> connectedNodes,int order,int max, Graph graph, Stack<List<int>> allPaths, List<int> blocked)
{
if (order >= connectedNodes.Count) return false;
var paths = SearchForPaths(graph, connectedNodes[order].FirstNode, connectedNodes[order].SecondNode, max, blocked);
if (paths.Count == 0) return true;
int i;
for (i = 0; i < paths.Count; i++)
{
var path = paths[i];
allPaths.Push(path);
blocked.AddRange(path);
if (!FindAllPaths(connectedNodes, order + 1,max, graph, allPaths, blocked)) break;
allPaths.Pop();
foreach (var j in path)
{
blocked.RemoveAll(num => num==j);
}
paths.RemoveAll(list => IsListsSimilar(list,path));
i--;
}
if (i == paths.Count) return true;
return false;
}
private static bool IsListsSimilar(List<int> L1,List<int> L2)
{
if (L2.Count > L1.Count) return false;
for (int i = 0; i < L2.Count - 1; i++)
{
if (L1[i] != L2[i]) return false;
}
return true;
}
private static List<List<int>> SearchForPaths(Graph graph, int start, int end, int max, List<int> blocked)
{
blocked.Remove(start);
blocked.Remove(end);
var nodePaths = new List<List<int>>();
var visited = new LinkedList<int>();
visited.AddLast(start);
DepthFirstSearch(graph, visited, end, max, blocked, nodePaths);
nodePaths = nodePaths.OrderBy(list => list.Count).ToList();
return nodePaths;
}
private static void DepthFirstSearch(Graph graph, LinkedList<int> visited, int end, int max, List<int> blocked, List<List<int>> paths)
{
var nodes = graph.adjacentNodes(visited.Last.Value);
// examine adjacent nodes
var nodeCount = blocked.Count;
for (int i = 0; i < nodeCount; i++)
{
if (visited.Contains(blocked[i])) return;
}
if (visited.Count > max) return;
nodeCount = nodes.Count;
for (var i = 0; i < nodeCount; i++)
{
if (visited.Contains(nodes[i]) || nodes[i] != end) continue;
visited.AddLast(nodes[i]);
{
paths.Add(new List<int>(visited));
}
visited.RemoveLast();
break;
}
nodeCount = nodes.Count;
for (var i = 0; i < nodeCount; i++)
{
if (visited.Contains(nodes[i]) || nodes[i] == end) continue;
visited.AddLast(nodes[i]);
DepthFirstSearch(graph, visited, end, max, blocked, paths);
visited.RemoveLast();
}
}
private static bool FindAllPaths2(List<Connection> connectedNodes, int order, int max, Graph graph, Stack<List<int>> allPaths, List<int> blocked)
{
if (order >= connectedNodes.Count) return false;
foreach (var path in SearchForPaths2(graph, connectedNodes[order].FirstNode, connectedNodes[order].SecondNode, max, blocked))
{
allPaths.Push(path);
blocked.AddRange(path);
if (!FindAllPaths2(connectedNodes, order + 1, max, graph, allPaths, blocked)) break;
allPaths.Pop();
foreach (var j in path)
{
blocked.RemoveAll(num => num == j);
}
}
return true;
}
private static IEnumerable<List<int>> SearchForPaths2(Graph graph, int start, int end, int max, List<int> blocked)
{
blocked.Remove(start);
blocked.Remove(end);
var visited = new LinkedList<int>();
visited.AddLast(start);
foreach (var VARIABLE in DepthFirstSearch(graph, visited, end, max, blocked))
{
yield return VARIABLE;
}
}
private static IEnumerable<List<int>> DepthFirstSearch(Graph graph, LinkedList<int> visited, int end, int max, List<int> blocked)
{
var nodes = graph.adjacentNodes(visited.Last.Value);
var nodeCount = blocked.Count;
for (int i = 0; i < nodeCount; i++)
{
if (visited.Contains(blocked[i])) yield break;
}
if (visited.Count > max) yield break;
nodeCount = nodes.Count;
for (var i = 0; i < nodeCount; i++)
{
if (visited.Contains(nodes[i]) || nodes[i] != end) continue;
visited.AddLast(nodes[i]);
yield return (new List<int>(visited));
visited.RemoveLast();
break;
}
nodeCount = nodes.Count;
for (var i = 0; i < nodeCount; i++)
{
if (visited.Contains(nodes[i]) || nodes[i] == end) continue;
visited.AddLast(nodes[i]);
foreach (var P in DepthFirstSearch(graph, visited, end, max, blocked))
{
yield return P;
}
visited.RemoveLast();
}
}
private static void PrintPath(List<int> visited)
{
for (int i = 0; i < visited.Count()-1; i++)
{
Console.Write(visited[i]);
Console.Write(" --> ");
}
Console.Write(visited[visited.Count() - 1]);
Console.WriteLine();
Console.WriteLine();
}
}
public class Graph
{
private readonly Dictionary<int, HashSet<int>> map = new Dictionary<int, HashSet<int>>();
public void addEdge(int node1, int node2)
{
HashSet<int> adjacent = null;
map.TryGetValue(node1, out adjacent);
if (adjacent == null)
{
adjacent = new HashSet<int>();
map.Add(node1, adjacent);
}
adjacent.Add(node2);
}
public List<int> adjacentNodes(int last)
{
HashSet<int> adjacent = null;
map.TryGetValue(last, out adjacent);
if (adjacent == null)
{
return new List<int>();
}
return new List<int>(adjacent);
}
}
}
I think the answer lies in how you have numbered the nodes in your grid. For a simple 2-dimensional grid, 4 nodes by 4, you would number them : 00, 01, 02, 03, 10, 11, 12 ... 30, 31, 32, 33. Think of them as composite number strings (not decimal values) acting as dimension-based node addresses.
In a 3-dimensional grid, they would be numbered 000, 001, 002, etc. up to 330, 331, 332, 333.
If you want to find all routes between two points 10 and 22 you can quickly calculate their distance by adding the dimensional differences: 1y is one away from 2y, and x0 is two away from x2. Therefore the node distance is 3, you will need to travel over 3 edges (connecting 4 nodes in total) to reach the destination.
The solution space (the only nodes that could ever be involved in a solution route) can be enumerated by creating a set of embedded FOR/NEXT loops, one for each dimension. In this case, the start and end values of 10 and 22 would produce: 10, 11, 12, 20, 21 and 22.
Now comes the clever bit. You can precompute (prepare) a table of 'forwarding' connections between the nodes in your array. Node 10 connects to 20 and 11 (both 1 dimensional difference away). From that you can generate a sequence of valid pathways from 10 to 22 by adding one to a dimension difference in which ever direction you plan to move (in a 2-D array you only get to choose one of two ways. In 3-D you get three choices).
Each answer should be the shortest possible distance. The computation time for this approach should be milliseconds. On a steam powered ZX81!