Last active
May 12, 2022 10:09
-
-
Save quangnle/6aa7a0b363c4d6ea128d30d9f7b54ab5 to your computer and use it in GitHub Desktop.
padlock riddle
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; | |
/// <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