So I was attempting to design a logic circuit where each starting state had one and only one solve state for X inputs. This way my original design could be used with a programmable start state (Needs to be programmable so you can reset it!).
However I've failed -_-. The best circuit I've had time to come up with has two solutions for each starting state. Also sadly they are always the same two solutions so this is useless!
Now it is DEFINITELY possible to build this, I just can't remember my Higher Tech studies notes from 12 years ago well enough to do so.
ANYWAY I decided to "cheat" and come up with a less elegant solution.
- Relatively easy to add in more levers later.
- As the number of levers used increases the lock gets more and more complex and takes up more and more space.
In my previous lock each switch (using a four lever example here for simplicities sake) moves a minecart over a pressure plate which either toggles
For ease of discussion we will call each of these a "Pin". You must activate Pin 1 then 2 then 3 then 4. In other words the order is fixed.
To make this order programmable all I had to do was make each Pin have four routes and control these routes to make sure that each pin takes a different route from the other three.
You can add more route combinations to make more solutions possible. For a four "pin" lock you could have 16 different solutions but you'd spend quite some time getting the routing set-up to make sure you never had two "pins" taking the same route.
Well to my mind it feels like I've just designed a way of efficiently turning one lock into four locks, as you have to add routing for each extra programmable solution you want.
The true solution is to be able to take any combination of start order and have only one unique output for a series of logic. Then you can make it programmable by simply changing what the start input is.
I've written some c# code for testing solutions if anyone wants to see what they can come up with. This is a lazy approach though, the best way to do it is with paper, pen and an understanding of logic circuits. (From memory you draw a line for each input then add a series of logic gates until you get each desired output and then simplify your design by grouping things together into NAND gates)
private void ButtonRunTest_Click(object sender, RoutedEventArgs e)
{
List<Tuple<bool,bool,bool,bool>> inputs = new List<Tuple<bool, bool, bool, bool>>();
inputs.Add(new Tuple<bool, bool, bool, bool>(true,true,true,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,true,true,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,true,false,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,true,false,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,false,true,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,false,true,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,false,false,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(true,false,false,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,true,true,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,true,true,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,true,false,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,true,false,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,false,true,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,false,true,false));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,false,false,true));
inputs.Add(new Tuple<bool, bool, bool, bool>(false,false,false,false));
List<string> combinations = new List<string>();
//combinations.Add("A");
//combinations.Add("AB");
//combinations.Add("ABC");
//combinations.Add("ACB");
//combinations.Add("AC");
//combinations.Add("ACB");
//combinations.Add("AD");
//combinations.Add("ADB");
//combinations.Add("ADC");
//combinations.Add("B");
//combinations.Add("BA");
//combinations.Add("BAC");
//combinations.Add("BCA");
//combinations.Add("BC");
//combinations.Add("BCA");
//combinations.Add("AD");
//combinations.Add("BDA");
//combinations.Add("BDC");
//combinations.Add("C");
//combinations.Add("CA");
//combinations.Add("CAB");
//combinations.Add("CBA");
//combinations.Add("CB");
//combinations.Add("CBA");
//combinations.Add("CD");
//combinations.Add("CDA");
//combinations.Add("CDB");
//combinations.Add("D");
//combinations.Add("DA");
//combinations.Add("DAB");
//combinations.Add("DB");
//combinations.Add("DBA");
//combinations.Add("DBC");
//combinations.Add("DC");
//combinations.Add("DCA");
//combinations.Add("DCB");
combinations.Add("ABCD");
combinations.Add("ABDC");
combinations.Add("ACBD");
combinations.Add("ACDB");
combinations.Add("ADBC");
combinations.Add("ADCB");
combinations.Add("BACD");
combinations.Add("BADC");
combinations.Add("BCAD");
combinations.Add("BCDA");
combinations.Add("BDAC");
combinations.Add("BDCA");
combinations.Add("CABD");
combinations.Add("CADB");
combinations.Add("CBAD");
combinations.Add("CBDA");
combinations.Add("CDAB");
combinations.Add("CDBA");
combinations.Add("DABC");
combinations.Add("DACB");
combinations.Add("DBAC");
combinations.Add("DBCA");
combinations.Add("DCAB");
combinations.Add("DCBA");
WriteFiles(combinations, inputs);
}
private void WriteFiles(List<string> combinations, List<Tuple<bool,bool,bool,bool>> inputs)
{
List<string> solutions = new List<string>();
for (int i = 0; i < inputs.Count; i++)
{
bool a = inputs[i].Item1;
bool b = inputs[i].Item2;
bool c = inputs[i].Item3;
bool d = inputs[i].Item4;
string curKey = inputs[i].Item1.ToString() + inputs[i].Item2.ToString() + inputs[i].Item3.ToString() + inputs[i].Item4.ToString();
foreach (var curCombo in combinations)
{
var curOrder = curCombo.Trim().ToUpper().ToCharArray();
foreach (var x in curOrder)
{
if (x.Equals('A')) SwitchA();
else if (x.Equals('B')) SwitchB();
else if (x.Equals('C')) SwitchC();
else if (x.Equals('D')) SwitchD();
else throw new NotSupportedException("Char was: " + x);
}
if (a && b && c && d)
{
solutions.Add(curKey + ": " + curCombo);
}
}
}
StreamWriter fileWriter = new StreamWriter("c:\\TMP\\logictest.txt");
foreach (string x in solutions)
{
fileWriter.WriteLine(x);
}
fileWriter.Close();
}
private void SwitchA(out bool a, out bool b, out bool c, out bool d)
{
a = true;
b = false;
c = false;
d = false;
}
private void SwitchB(out bool b, out bool c, out bool d)
{
b = true;
c = false;
d = false;
}
private void SwitchC(out bool c, out bool d)
{
c = true;
d = false;
}
private void SwitchD(out bool d)
{
d = true;
}