読売新聞社の入社試験問題より。A~Eの発言から順位を導き出す(ただし1人だけ嘘つきがいる)。
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
namespace KomaUniv
{
static class Ex
{
public static IEnumerable<IList<T>> Permutation<T>(
this IList<T> source, int count)
{
return PermutationRec(source, count, new List<int>(),
Enumerable.Range(0, source.Count).ToList());
}
private static IEnumerable<IList<T>> PermutationRec<T>(
IList<T> source, int count, List<int> indices, List<int> candidates)
{
if (count == indices.Count)
{
yield return indices.Select(x => source[x]).ToArray();
yield break;
}
for (var i = 0; i < candidates.Count; i++)
{
var v = candidates[i];
candidates.RemoveAt(i);
indices.Add(v);
foreach (var l in PermutationRec(source, count, indices, candidates))
yield return l;
indices.RemoveAt(indices.Count - 1);
candidates.Insert(i, v);
}
}
public static Func<T, bool> And<T>(this Func<T, bool> p1, Func<T, bool> p2)
{
return x => p1(x) && p2(x);
}
public static Func<T, bool> Or<T>(this Func<T, bool> p1, Func<T, bool> p2)
{
return x => p1(x) || p2(x);
}
public static Func<T, bool> Not<T>(this Func<T, bool> p)
{
return x => !p(x);
}
}
class Program
{
static void Main(string[] args)
{
var all = new[] { 1, 2, 3, 4, 5 }
.Permutation(5)
.Select(x => new { A = x[0], B = x[1], C = x[2], D = x[3], E = x[4] });
var a = Predicate(all, x => x.C < x.A && x.D < x.A);
var b = Predicate(all, x => x.D < x.B && x.B < x.A);
var c = Predicate(all, x => x.C < x.D && 2 < x.C);
var d = Predicate(all, x => x.C < x.D && x.D < x.B);
var e = Predicate(all, x => x.E == 1);
var result = all.Where(
((a.Not()).And(b).And(c).And(d).And(e))
.Or(a.And(b.Not()).And(c).And(d).And(e))
.Or(a.And(b).And(c.Not()).And(d).And(e))
.Or(a.And(b).And(c).And(d.Not()).And(e))
.Or(a.And(b).And(c).And(d).And(e.Not()))
).First();
Console.WriteLine(result.ToString());
}
static Func<T, bool> Predicate<T>(IEnumerable<T> dummy, Func<T, bool> pred)
{
return pred;
}
}
}