Skip to content

Instantly share code, notes, and snippets.

@aboo
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aboo/64d409f583188c0c1d9d to your computer and use it in GitHub Desktop.
Save aboo/64d409f583188c0c1d9d to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
namespace SnakeAndLaddersSolution
{
public class SnakeAndLadder
{
private struct Jump
{
public int Start;
public int End;
}
private const int TOP = 100;
private const int STEP_SIZE = 6;
private int _minDiceCount = int.MaxValue;
private readonly List<Jump> _jumps = new List<Jump>();
public bool OptionalJump { get; set; }
public void AddJump(int start, int end)
{
_jumps.Add(new Jump { Start = start, End = end });
}
public int Solve()
{
var path = new Stack<int>();
path.Push(1); //start from square 1
return FindMinimumDice(path, 0);
}
private int FindMinimumDice(Stack<int> path, int diceCount)
{
if (diceCount >= _minDiceCount)
{
//too long. we've already found a shortest path.
//drop going deeper
return -1;
}
var currentSquare = path.Peek();
var diceCounts = new List<int>();
int newDiceCount;
var ignoreNormalJump = false;
for (var i = 0; i <= STEP_SIZE; i++)
{
var newSquare = currentSquare + i;
if (newSquare == TOP)
{
//got there
var totalDiceCount = diceCount + (i == 0 ? 0 : 1);
_minDiceCount = Math.Min(_minDiceCount, totalDiceCount); //register the shortest path
return totalDiceCount;
}
if (_jumps.All(j => j.Start != newSquare)) continue; //only process jumps
var jump = _jumps.First(j => j.Start == newSquare);
if (path.Contains(jump.End))
continue; //already been here
path.Push(jump.Start);
path.Push(jump.End);
newDiceCount = FindMinimumDice(path, diceCount + (i == 0 ? 0 : 1));
path.Pop();
path.Pop();
if (newDiceCount != -1)
diceCounts.Add(newDiceCount);
if (i == 0 && !OptionalJump) //the current squre is a jump that should be taken
{
ignoreNormalJump = true;
break;
}
}
if (!ignoreNormalJump)
{
var longestJump = 0;
for (var i = STEP_SIZE; i > 0; i--)
{
if (_jumps.All(j => j.Start != currentSquare + i))
{
longestJump = currentSquare + i;
break;
}
}
if (longestJump != 0)
{
path.Push(longestJump);
newDiceCount = FindMinimumDice(path, diceCount + 1);
path.Pop();
if (newDiceCount != -1)
diceCounts.Add(newDiceCount);
}
}
return !diceCounts.Any() ? -1 : diceCounts.Min();
}
}
class Program
{
static void Main(string[] args)
{
var sal = new SnakeAndLadder();
//set OptionalJump to true if the jump is optional
//sal.OptionalJump = true;
sal.AddJump(2,51);
sal.AddJump(60,40);
Console.WriteLine(sal.Solve());
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment