Created
June 28, 2015 13:06
-
-
Save orzFly/6da4cef22e9d286ad5e3 to your computer and use it in GitHub Desktop.
Bulls and Cows Solver
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.Collections.Generic; | |
using System.Text; | |
namespace _4DigitalSolver | |
{ | |
public class PermutationAndCombination<T> | |
{ | |
/// <summary> | |
/// 交换两个变量 | |
/// </summary> | |
/// <param name="a">变量1</param> | |
/// <param name="b">变量2</param> | |
public static void Swap(ref T a, ref T b) | |
{ | |
T temp = a; | |
a = b; | |
b = temp; | |
} | |
/// <summary> | |
/// 递归算法求数组的组合(私有成员) | |
/// </summary> | |
/// <param name="list">返回的范型</param> | |
/// <param name="t">所求数组</param> | |
/// <param name="n">辅助变量</param> | |
/// <param name="m">辅助变量</param> | |
/// <param name="b">辅助数组</param> | |
/// <param name="M">辅助变量M</param> | |
private static void GetCombination(ref List<T[]> list, T[] t, int n, int m, int[] b, int M) | |
{ | |
for (int i = n; i >= m; i--) | |
{ | |
b[m - 1] = i - 1; | |
if (m > 1) | |
{ | |
GetCombination(ref list, t, i - 1, m - 1, b, M); | |
} | |
else | |
{ | |
if (list == null) | |
{ | |
list = new List<T[]>(); | |
} | |
T[] temp = new T[M]; | |
for (int j = 0; j < b.Length; j++) | |
{ | |
temp[j] = t[b[j]]; | |
} | |
list.Add(temp); | |
} | |
} | |
} | |
/// <summary> | |
/// 递归算法求排列(私有成员) | |
/// </summary> | |
/// <param name="list">返回的列表</param> | |
/// <param name="t">所求数组</param> | |
/// <param name="startIndex">起始标号</param> | |
/// <param name="endIndex">结束标号</param> | |
private static void GetPermutation(ref List<T[]> list, T[] t, int startIndex, int endIndex) | |
{ | |
if (startIndex == endIndex) | |
{ | |
if (list == null) | |
{ | |
list = new List<T[]>(); | |
} | |
T[] temp = new T[t.Length]; | |
t.CopyTo(temp, 0); | |
list.Add(temp); | |
} | |
else | |
{ | |
for (int i = startIndex; i <= endIndex; i++) | |
{ | |
Swap(ref t[startIndex], ref t[i]); | |
GetPermutation(ref list, t, startIndex + 1, endIndex); | |
Swap(ref t[startIndex], ref t[i]); | |
} | |
} | |
} | |
/// <summary> | |
/// 求从起始标号到结束标号的排列,其余元素不变 | |
/// </summary> | |
/// <param name="t">所求数组</param> | |
/// <param name="startIndex">起始标号</param> | |
/// <param name="endIndex">结束标号</param> | |
/// <returns>从起始标号到结束标号排列的范型</returns> | |
public static List<T[]> GetPermutation(T[] t, int startIndex, int endIndex) | |
{ | |
if (startIndex < 0 || endIndex > t.Length - 1) | |
{ | |
return null; | |
} | |
List<T[]> list = new List<T[]>(); | |
GetPermutation(ref list, t, startIndex, endIndex); | |
return list; | |
} | |
/// <summary> | |
/// 返回数组所有元素的全排列 | |
/// </summary> | |
/// <param name="t">所求数组</param> | |
/// <returns>全排列的范型</returns> | |
public static List<T[]> GetPermutation(T[] t) | |
{ | |
return GetPermutation(t, 0, t.Length - 1); | |
} | |
/// <summary> | |
/// 求数组中n个元素的排列 | |
/// </summary> | |
/// <param name="t">所求数组</param> | |
/// <param name="n">元素个数</param> | |
/// <returns>数组中n个元素的排列</returns> | |
public static List<T[]> GetPermutation(T[] t, int n) | |
{ | |
if (n > t.Length) | |
{ | |
return null; | |
} | |
List<T[]> list = new List<T[]>(); | |
List<T[]> c = GetCombination(t, n); | |
for (int i = 0; i < c.Count; i++) | |
{ | |
List<T[]> l = new List<T[]>(); | |
GetPermutation(ref l, c[i], 0, n - 1); | |
list.AddRange(l); | |
} | |
return list; | |
} | |
/// <summary> | |
/// 求数组中n个元素的组合 | |
/// </summary> | |
/// <param name="t">所求数组</param> | |
/// <param name="n">元素个数</param> | |
/// <returns>数组中n个元素的组合的范型</returns> | |
public static List<T[]> GetCombination(T[] t, int n) | |
{ | |
if (t.Length < n) | |
{ | |
return null; | |
} | |
int[] temp = new int[n]; | |
List<T[]> list = new List<T[]>(); | |
GetCombination(ref list, t, t.Length, n, temp, n); | |
return list; | |
} | |
} | |
} |
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.Collections.Generic; | |
using System.Text; | |
namespace _4DigitalSolver | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Solver s = new Solver(4); | |
while(s.Answers.Count > 1) | |
{ | |
string i, a, b; | |
Console.Write("Input="); | |
i = Console.ReadLine(); | |
Console.Write("A="); | |
a = Console.ReadLine(); | |
Console.Write("B="); | |
b = Console.ReadLine(); | |
try | |
{ | |
s.Filter(new Solver.Guess(i, int.Parse(a), int.Parse(b))); | |
} | |
catch (Exception e) { } | |
Console.WriteLine("{0} remaining: {1}", s.Answers.Count, String.Join(", ", new List<string>(s.Answers).ToArray())); | |
} | |
Console.ReadKey(); | |
} | |
} | |
} |
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.Collections.Generic; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
namespace _4DigitalSolver | |
{ | |
class Solver | |
{ | |
public struct Guess | |
{ | |
static Regex Duplicate = new Regex(@"(.).*\1"); | |
public string Value; | |
public int A; public int B; | |
public Guess(string value, int a, int b) { Value = value; A = a; B = b; } | |
public Guess(string Answer, string Input) | |
{ | |
if (Answer.Length != Input.Length) throw new ArgumentException("Misalign"); | |
Value = Input; | |
if (Answer == Input) | |
{ | |
A = Value.Length; | |
B = 0; | |
return; | |
} | |
if (Duplicate.Match(Input).Success) throw new ArgumentException("Dup"); | |
A = 0; B = 0; | |
for (int i = 0; i < Answer.Length; i++) | |
{ | |
int p = Answer.IndexOf(Input[i]); | |
if (p == i) A++; | |
else if (p != -1) B++; | |
} | |
} | |
} | |
List<string> answers; | |
List<Guess> guesses = new List<Guess>(); | |
int length; | |
public Solver(): this(4) {} | |
public Solver(int length) | |
{ | |
this.length = length; | |
InitAnswer(); | |
} | |
private void InitAnswer() { | |
answers = new List<string>(); | |
var comb = new List<int[]>(PermutationAndCombination<int>.GetCombination(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, length)); | |
foreach(var c in comb) { | |
var p = PermutationAndCombination<int>.GetPermutation(c); | |
answers.AddRange(p.ConvertAll((i) => string.Join("", Array.ConvertAll(i, (j) => j.ToString())))); | |
} | |
} | |
public void Filter(Guess guess) | |
{ | |
guesses.Add(guess); | |
answers.RemoveAll((string ans) => | |
{ | |
if (ans == guess.Value) return true; | |
Guess g = new Guess(guess.Value, ans); | |
return !(g.A == guess.A && g.B == guess.B); | |
}); | |
} | |
public System.Collections.ObjectModel.ReadOnlyCollection<string> Answers { get { return answers.AsReadOnly(); } } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment