Skip to content

Instantly share code, notes, and snippets.

@sadache
Created February 2, 2010 13:44
Show Gist options
  • Save sadache/292671 to your computer and use it in GitHub Desktop.
Save sadache/292671 to your computer and use it in GitHub Desktop.
namespace TTest
{
using CircularList;
using WithCompus = Char;
//using RobotState = Tuple<IEnumerable<char>, Position>;
class Program
{
static void Main(string[] args)
{
WithCompus meWithCompusToNorth = 'N';
var initial=new RobotState(meWithCompusToNorth, new Position(1, 2));
Console.WriteLine(initial.Do(new List<char> { 'L','M','L','M','L','M','L','M','M' },new Position(5,5)).Item2.Y);
}
}
public class RobotState : Tuple<char, Position>
{
public RobotState(WithCompus compus, Position position) : base(compus, position) { }
public RobotState Advance()
{
switch (this.Item1){
case 'N': return new RobotState(Item1,Item2.Advance(onY:1));
case 'S': return new RobotState(Item1,Item2.Advance(onY:-1));
case 'E': return new RobotState(Item1, Item2.Advance(onX: 1));
case 'W': return new RobotState(Item1, Item2.Advance(onX: -1));
default: return this;
}
}
public RobotState TurnRight(){
return new RobotState(this.Item1.TurnClockwise(), Item2);
}
public RobotState TurnLeft()
{
return new RobotState(this.Item1.TurnCounterClockwise(), Item2);
}
}
public struct Position{
public readonly int X,Y;
public Position(int x, int y){ this.X = x; this.Y = y; }
public Position Advance(int onX=0,int onY=0){ return new Position(X + onX, Y + onY); }
}
}
namespace CircularList
{
using TWTest;
public static class CompusExtensions
{
static List<char?> directionsClockwise = new List<char?> { 'N', 'E', 'S', 'W' };
static public char TurnClockwise(this char direction)
{
return directionsClockwise.ElementAtOrDefault(directionsClockwise.IndexOf(direction) + 1) ?? directionsClockwise.First().Value;
}
static public char TurnCounterClockwise(this char direction)
{
return directionsClockwise.ElementAtOrDefault(directionsClockwise.IndexOf(direction) -1) ?? directionsClockwise.Last().Value;
}
}
static public class RobotStateExtensions
{
static public RobotState Do(this RobotState state,char command)
{
switch (command)
{
case 'M': return state.Advance();
case 'R': return state.TurnRight();
case 'L': return state.TurnLeft();
default: return state; //do nothing on unknown command, you can log here...
}
}
static public RobotState InBoundsOrNull(this RobotState state, Position bounds)
{
return (state.Item2.X > bounds.X || state.Item2.Y > bounds.Y) || (state.Item2.X <0 || state.Item2.Y <0) ? null : state;
}
static public RobotState Do(this RobotState initialState, IEnumerable<char> commands,Position bounds)
{
return commands.Aggregate(initialState, (s, command) => s.Do(command).InBoundsOrNull(bounds) ?? s);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment