Created
February 2, 2010 13:44
-
-
Save sadache/292671 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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