HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Algorithm for fewest moves in 1's, 10's, 100's, etc

Submitted by: @import:stackexchange-cs··
0
Viewed 0 times
movesalgorithmfewest100foretc

Problem

I'm building a math application (not homework) and I want to build a component that allows players to drag-and-drop 1's, 10's, 100's, etc to complete problems and a bonus reward if they do it in the fewest moves possible--How can I calculate this? e.g.

50 + X = 96


where X is a randomly generated integer and the player is modifying X during play. So, the player needs to make X=46, but starts at 121. For example,

if X is initially 121, and player needs to get to 46


player thinks, "cool, i'll just subtract 75"

remove 7x 10's, remove 5x 1's - 12 moves


but it turns out, there's a faster way to do it:

remove 1x 100's, add 2x 10's, add 5x 1's - 8 moves


Is there an existing algorithm for this? It would be helpful to calculate this for anything up to 10,000 where I can calculate the minimum number of moves required.

Solution

You can construct a graph with vertices $0,1,2,3,4,\dots,10000$, two vertices are adjacent if you can construct a number with a single operation from another one. A single operation is either adding or subtracting $1,10,100,1000,\dots$. For example,$N(46) = \{45, 47, 36, 56, 146, 1046,\dots\}$. Then the minimum number of operations required to construct a number $x$ is the shortest path from $x$ to 0. Since graph is undirected, you can run a single one to all algorithm (Dijkstra,BFS) and obtain all distances from 0 to any other vertex. Also the graph is pretty sparse, hence Dijsktra with heap will nail it. An implementation might no need to construct the whole graph, since neighborhoods are small and easily computable on the fly.

EDIT:
if you take Dijkstra code from Geeks, you can construct graph as

for(int v1 = 0; v1 < V; ++v1)
   for(int v2 = v1+1; v2 < V; ++v2)
      if(v2 - v1 == 1 || v2 - v1 == 10 || v2 - v1 == 100)
         g.addEdge(v1,v2,1);
 g.shortestPath(46); // gives 8 to 121

Code Snippets

for(int v1 = 0; v1 < V; ++v1)
   for(int v2 = v1+1; v2 < V; ++v2)
      if(v2 - v1 == 1 || v2 - v1 == 10 || v2 - v1 == 100)
         g.addEdge(v1,v2,1);
 g.shortestPath(46); // gives 8 to 121

Context

StackExchange Computer Science Q#109951, answer score: 2

Revisions (0)

No revisions yet.