LINQで非決定性計算
Haskellやっぱ難しいよ。難しいって。 - テンポラリ
↑前にhaskellでやってたのをC# + LINQでやってみた。
前は意味わかんなかったけど、今なら読めるしかけるなぁ。
public void f1() { var result = from baker in Enumerable.Range(1, 5) from cooper in Enumerable.Range(1, 5) from fletcher in Enumerable.Range(1, 5) from miller in Enumerable.Range(1, 5) from smith in Enumerable.Range(1, 5) where !new[] { baker, cooper, fletcher, miller, smith }.Dup() && baker != 5 && cooper != 1 && fletcher != 1 && fletcher != 5 && miller > cooper && Math.Abs(smith - fletcher) != 1 && Math.Abs(fletcher - cooper) != 1 select new { baker = baker, cooper = cooper, fletcher = fletcher, miller = miller, smith = smith }; result.ToList().ForEach( r => Console.WriteLine( "baker:{0} cooper:{1} fletcher:{2} miller:{3} smith:{4}", r.baker, r.cooper, r.fletcher, r.miller, r.smith)); } ユーティリティがコレ public static class Util { public static bool Dup(this int[] values) { return values.Distinct().Count() != values.Length; } } メソッドで書くとこんな感じ? public void f2() { var result = Enumerable.Range(1, 5).SelectMany( baker => Enumerable.Range(1, 5).SelectMany( cooper => Enumerable.Range(1, 5).SelectMany( fletcher => Enumerable.Range(1, 5).SelectMany( miller => Enumerable.Range(1, 5).SelectMany( smith => Enumerable.Repeat(new { baker = baker, cooper = cooper, fletcher = fletcher, miller = miller, smith = smith }, 1)))))).Where( r => !new[] { r.baker, r.cooper, r.fletcher, r.miller, r.smith }.Dup() && r.baker != 5 && r.cooper != 1 && r.fletcher != 1 && r.fletcher != 5 && r.miller > r.cooper && Math.Abs(r.smith - r.fletcher) != 1 && Math.Abs(r.fletcher - r.cooper) != 1); result.ToList().ForEach( r => Console.WriteLine( "baker:{0} cooper:{1} fletcher:{2} miller:{3} smith:{4}", r.baker, r.cooper, r.fletcher, r.miller, r.smith)); }