Skip to content

Instantly share code, notes, and snippets.

@quangnle
Last active May 12, 2022 10:09
Show Gist options
  • Save quangnle/6aa7a0b363c4d6ea128d30d9f7b54ab5 to your computer and use it in GitHub Desktop.
Save quangnle/6aa7a0b363c4d6ea128d30d9f7b54ab5 to your computer and use it in GitHub Desktop.
padlock riddle
using System;
using System.Collections.Generic;
/// <summary>
///Gargamel is an evil notorious witch. He has a chest full of treasures that he had plundered from the Smurf.
///One day, the Smurfs sneaked into the Gargamel's mansion and stole the chest.
///However, this chest was locked with a three-digit padlock and the Smurfs cannot break the chest.
///Finally, they found a recipe that engraved on the chest tobe the clue for the pasword:
/// (i) 1,4,7 - one digit is right but in the wrong place
/// (ii) 1,8,9 - one digit is right and in the correct place
/// (iii) 9,6,4 - two digits are right but both are in the wrong place
/// (iv) 5,2,3 - all are wrong digits
/// (v) 2,8,6 - one digit is right but in the wrong place
/// Can you help the Smurfs?
/// </summary>
///
namespace PadlockRiddle
{
class Program
{
static void Main(string[] args)
{
RuleEngine engine = new RuleEngine();
engine.UpdateRule(new ROneRightWrongPlace(1, 4, 7));
engine.UpdateRule(new ROneRightInPlace(1, 8, 9));
engine.UpdateRule(new RTwoRightsWrongPlace(9, 6, 4));
engine.UpdateRule(new RAllWrong(5, 2, 3));
engine.UpdateRule(new ROneRightWrongPlace(2, 8, 6));
//another case testing (remember to remove +1 when checking)
//engine.UpdateRule(new ROneRightInPlace(6, 8, 2));
//engine.UpdateRule(new ROneRightWrongPlace(6, 1, 4));
//engine.UpdateRule(new RTwoRightsWrongPlace(2, 0, 6));
//engine.UpdateRule(new RAllWrong(7, 3, 8));
//engine.UpdateRule(new ROneRightWrongPlace(7, 8, 0));
// generate all possibilities for 3 digits
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
for (int k = 0; k < 9; k++)
{
// validate input
if (i!=j && j!=k && i!= k)
{
// checking...
var solution = engine.Check(i+1, j+1, k+1);
if(solution == true)
{
Console.Write("Solution is: {0} {1} {2}",i+1,j+1,k+1);
}
}
}
}
}
Console.Read();
}
}
class RuleEngine
{
private List<Rule> _lstRules;
internal RuleEngine()
{
_lstRules = new List<Rule>();
}
internal void UpdateRule(Rule rule)
{
_lstRules.Add(rule);
}
// check if an input is matched
internal bool Check(int a, int b, int c)
{
// check all rules in the rule list
for (int i = 0; i < _lstRules.Count; i++)
{
if (!_lstRules[i].Match(a, b, c)) return false;
}
return true;
}
}
internal abstract class Rule
{
protected int _a, _b, _c;
internal Rule(int a, int b, int c)
{
this._a = a;
this._b = b;
this._c = c;
}
/// <summary>
/// this indicates x is unmatched with any digits of the solution
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
internal bool IsWrong(int x)
{
return x != _a && x != _b && x != _c;
}
/// <summary>
/// this indicates x is one of the digits in the solution but in the wrong place
/// </summary>
/// <param name="x"></param>
/// <param name="pos"></param>
/// <returns></returns>
internal bool IsRightButWrongPlace(int x, int pos)
{
return ((pos == 1 && x != _a) && (x == _b || x == _c)) ||
((pos == 2 && x != _b) && (x == _a || x == _c)) ||
((pos == 3 && x != _c) && (x == _a || x == _b));
}
/// <summary>
/// this indicates x is correct digit and in the right place
/// </summary>
/// <param name="x">ongoing checked value</param>
/// <param name="pos">position (1 or 2 or 3)</param>
/// <returns></returns>
internal bool IsRightInPlace(int x, int pos)
{
return (pos == 1 && x == _a) || (pos == 2 && x == _b) || (pos == 3 && x == _c);
}
internal abstract bool Match(int a, int b, int c);
}
/// <summary>
/// for rule 1 and 5
/// </summary>
internal class ROneRightWrongPlace : Rule
{
internal ROneRightWrongPlace(int a, int b, int c): base(a, b, c) { }
internal override bool Match(int a, int b, int c)
{
return (IsRightButWrongPlace(a, 1) && IsWrong(b) && IsWrong(c)) ||
(IsRightButWrongPlace(b, 2) && IsWrong(a) && IsWrong(c)) ||
(IsRightButWrongPlace(c, 3) && IsWrong(b) && IsWrong(a));
}
}
/// <summary>
/// for rule 3
/// </summary>
internal class RTwoRightsWrongPlace : Rule
{
internal RTwoRightsWrongPlace(int a, int b, int c): base(a, b, c) { }
internal override bool Match(int a, int b, int c)
{
return (IsRightButWrongPlace(a, 1) && IsRightButWrongPlace(b, 2) && IsWrong(c)) ||
(IsRightButWrongPlace(a, 1) && IsRightButWrongPlace(c, 3) && IsWrong(b)) ||
(IsRightButWrongPlace(b, 2) && IsRightButWrongPlace(c, 3) && IsWrong(a));
}
}
/// <summary>
/// for rule 2
/// </summary>
internal class ROneRightInPlace : Rule
{
internal ROneRightInPlace(int a, int b, int c): base(a, b, c) { }
internal override bool Match(int a, int b, int c)
{
return (IsRightInPlace(a, 1) && IsWrong(b) && IsWrong(c)) ||
(IsRightInPlace(b, 2) && IsWrong(a) && IsWrong(c)) ||
(IsRightInPlace(c, 3) && IsWrong(b) && IsWrong(a));
}
}
/// <summary>
/// for rule 4
/// </summary>
internal class RAllWrong : Rule
{
internal RAllWrong(int a, int b, int c): base(a, b, c) { }
internal override bool Match(int a, int b, int c)
{
return IsWrong(a) && IsWrong(b) && IsWrong(c);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment