Created
February 1, 2012 20:50
-
-
Save xfire/1719228 to your computer and use it in GitHub Desktop.
knight move for c# from LYAHFGG inclusive the composing of monadic functions
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
using System; | |
using System.Linq; | |
using System.Text; | |
using System.Collections.Generic; | |
namespace KnightsMove | |
{ | |
public static class KnightsMoveMain | |
{ | |
static string Show<T>(this IEnumerable<T> xs) { return "[" + string.Join(", ", xs) + "]"; } | |
class Pos : Tuple<int, int> | |
{ | |
public Pos(int a, int b) : base(a, b) {} | |
} | |
static IEnumerable<Pos> KnightMove(Pos pos) | |
{ | |
var range = Enumerable.Range(1, 8); | |
var x = pos.Item1; | |
var y = pos.Item2; | |
return from xs in new List<Pos>() | |
{ new Pos(x + 1, y + 2), new Pos(x + 1, y - 2), | |
new Pos(x - 1, y + 2), new Pos(x - 1, y - 2), | |
new Pos(x + 2, y + 1), new Pos(x + 2, y - 1), | |
new Pos(x - 2, y + 1), new Pos(x - 2, y - 1), | |
} | |
where range.Contains(xs.Item1) && range.Contains(xs.Item2) | |
orderby xs | |
select xs; | |
} | |
static IEnumerable<Pos> In3(Pos pos) | |
{ | |
// return KnightMove(pos).SelectMany(KnightMove).SelectMany(KnightMove); | |
return from first in KnightMove(pos) | |
from second in KnightMove(first) | |
from third in KnightMove(second) | |
select third; | |
} | |
static bool CanReachIn3(Pos f, Pos t) | |
{ | |
return In3(f).Contains(t); | |
} | |
// ---------------------------------------------------------------------------------------------------- | |
static Func<A, IEnumerable<C>> Compose<A, B, C>(this Func<A, IEnumerable<B>> f, Func<B, IEnumerable<C>> g) | |
{ | |
return a => f(a).SelectMany(b => g(b)); | |
} | |
static IEnumerable<Func<T, TR>> Repeat<T, TR>(this Func<T, TR> f) | |
{ | |
while(true) { | |
yield return f; | |
} | |
} | |
static IEnumerable<Func<T, TR>> Replicate<T, TR>(this Func<T, TR> f, int n) | |
{ | |
return f.Repeat().Take(n); | |
} | |
static IEnumerable<T> ToList<T>(this T value) | |
{ | |
return new List<T>() { value }; | |
} | |
static IEnumerable<Pos> InN(Pos pos, int n) | |
{ | |
var fs = Replicate<Pos, IEnumerable<Pos>>(KnightMove, n).Aggregate(Compose); | |
return pos.ToList().SelectMany(fs); | |
} | |
static bool CanReachInN(int n, Pos f, Pos t) | |
{ | |
return InN(f, n).Contains(t); | |
} | |
public static void Main() | |
{ | |
Console.WriteLine("expected: [(4, 1), (4, 3), (5, 4), (7, 4), (8, 1), (8, 3)]"); | |
Console.WriteLine(" 1: " + KnightMove(new Pos(6, 2)).Show()); | |
Console.WriteLine(""); | |
Console.WriteLine("expected: [(6, 2), (7, 3)]"); | |
Console.WriteLine(" 1: " + KnightMove(new Pos(8, 1)).Show()); | |
Console.WriteLine(""); | |
Console.WriteLine(" can reach in 3 from (6, 2) to (6, 1): " + CanReachIn3(new Pos(6, 2), new Pos(6, 1))); | |
Console.WriteLine("can reach in N(=3) from (6, 2) to (6, 1): " + CanReachInN(3, new Pos(6, 2), new Pos(6, 1))); | |
Console.WriteLine(""); | |
Console.WriteLine(" can reach in 3 from (6, 2) to (7, 3): " + CanReachIn3(new Pos(6, 2), new Pos(7, 3))); | |
Console.WriteLine("can reach in N(=3) from (6, 2) to (7, 3): " + CanReachInN(3, new Pos(6, 2), new Pos(7, 3))); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment