C # 'da bu olası her kombinasyonu deneyen bir algoritma yazdım Nor 3->1
Xor 2->1
Nand 2->1
ve Decoder 3->8
.
7½ milyon yıl 2 saat çalıştırdıktan sonra 42 False geri döndü . İnanıyorum ki, bu algoritma olası her kombinasyonu kontrol ettiği için sorunun cevabı olmadığını kanıtlıyor. :)
Bunu açıklamam istendi, bu yüzden bir sonraki kısım, kod bölümlerinin bir kısmı, bir kısmı. TL; DR - en sonunda koda atlayabilirsiniz :)
Girdi satırları hakkında konuşalım, 0 veya 1 durumları var ve olası girişlerin (0 ila 15) her biri için farklı değerler tutuyorlar:
ilk satır için şu şekilde görünür: 0 1 0 1 0 1 ... İkincisi: 0 0 1 1 0 0 1 1 ... üçüncü: 0 0 0 0 1 1 1 .... gibi ikili sayıyor ... fikri anladınız: P
Bu yüzden her eyaletindeki her satırı temsil eden bir nesne yarattım:
class BitLine{
bool[] IsActiveWhenInputIs = new bool[16];
}
Dediği gibi bitLine.IsActiveWhenInputIs [5] giriş 5 iken hattın aktif olup olmadığını döndürür.
Bu, girdi satırlarını tamamen oluşturan bir koddur:
var bitLineList = new BitLine[6]; // initialize new array of bitLines
for (int i = 0; i < 6; i++) bitLineList [i] = new BitLine(); // initialize each bitLine
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 4; j++)
{
int checker = 1 << j; // check whether the j-th bit is activated in the binary representation of the number.
bitLineList[j].IsActiveWhenInputIs[i] = ((checker & i) != 0); // if it's active, the AND result will be none zero, and so the return value will be true - which is what we need :D
}
}
Sabit "0" giriş veya "1" giriş sağlamak için "her zaman doğru" ve "her zaman yanlış" bit çizgileri de oluşturacağız.
for (int i = 0; i < 16; i++){
bitLineList[4].IsActiveWhenInputIs[i] = false;
bitLineList[5].IsActiveWhenInputIs[i] = true;
}
Şimdi fark ederseniz, aradığımız aslında belirli bir bitLine'dir, giriş 0, 7, 14 olduğunda doğrudur. Bunu sınıfımızda temsil edelim:
var neededBitLine = new BitLine();
for (int i = 0; i < 16; i++){
neededBitLine.IsActiveWhenInputIs[i] = ((i % 7) == 0); // be true for any number that is devideble by 7 (0,7,14)
}
Bu işleri gerçekten basitleştirdi: aradığımız şey, bu bitBitLine'ı girdi bit satırından "taklit etmenin" bir yoludur (bu benim programım için çıktımın olmasını istediğim şeyi temsil ediyorum).
Biz gitmek ne kadar şimdi, şudur: biz gibi bizim bitLines bazı mantıksal eleman her kullandığınızda Xor
, Nor
, Nand
hatta Decoder
, aslında yeni bir bitLine yaratıyor \ s. Olası her girişteki her bir satırın değerini 0 ila 15 arasında biliyoruz, böylece yeni bitLine \ s değerini olası her girişte de hesaplayabiliriz!
Nand Nor ve Xor'un hepsi açıktır:
void Xor(BitLine b1, BitLine b2, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = b1.IsActiveWhenInputIs[i] != b2.IsActiveWhenInputIs[i];
}
}
void Nand(BitLine b1, BitLine b2, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = !(b1.IsActiveWhenInputIs[i] && b2.IsActiveWhenInputIs[i]);
}
}
void Nor(BitLine b1, BitLine b2, BitLine b3, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = !(b1.IsActiveWhenInputIs[i] || b2.IsActiveWhenInputIs[i] || b3.IsActiveWhenInputIs[i]);
}
}
Olası her giriş için, yeni BitLine'ın nasıl davranacağını temsil eder.
Kod çözücüyü kullanmak biraz zordur, ancak fikir "girişteki bitler ikilikteki x sayısını temsil ediyorsa, x-çıkış çıkış bit çizgisi doğru olurken, diğerleri yanlış olacaktır. işlevinde, bu bir dizi bitline alır ve diziye 8 yeni bitline ekler.
void Decoder(BitLine b1, BitLine b2, BitLine b3, List<BitLine> lines, int listOriginalLength)
{
for (int optionNumber = 0; optionNumber < 8; optionNumber++)
{
for (var i = 0; i < 16; i++)
{
int sum = 0;
if (b1.IsActiveWhenInputIs[i]) sum += 4;
if (b2.IsActiveWhenInputIs[i]) sum += 2;
if (b3.IsActiveWhenInputIs[i]) sum += 1;
lines[listOriginalLength+optionNumber].IsActiveWhenInputIs[i] = (sum == optionNumber);
}
}
}
Şimdi tüm temel unsurlarımız var, bu yüzden algoritma hakkında konuşalım:
Yinelenen bir algoritma yapacağız, her derinlikte şu anda mevcut olan bit satırlarında başka bir öğe (ne de \ nand \ xor \ dekoder) kullanmaya çalışacak ve ardından öğeyi bir sonraki özyinelemeli derinlik için kullanılamayacak şekilde ayarlayacağız. Ne zaman dibe vardığımızda ve kullanacak başka elementimiz olmadığında, aradığımız şey olan bir bit çizgisine sahip olup olmadığımızı kontrol edeceğiz.
Bu kod, geçerli satır grubunun aradığımız satırı içerip içermediğini herhangi bir zamanda kontrol eder:
bool CheckIfSolutionExist(List<BitLine> lines, int linesLength BitLine neededLine)
{
for(int i = 0; i<linesLength; i++){
if (lines[i].CheckEquals(neededLine))
{
return true;
}
}
return false;
}
İki satırın eşit olup olmadığını kontrol etmek için kullandığı işlev budur:
bool CheckEquals(BitLine other)
{
for (var i = 0; i < 16; i++)
{
if (this.IsActiveWhenInputIs[i] != other.IsActiveWhenInputIs[i])
{
return false;
}
}
return true;
}
Tamam, şimdi ana bölüm için bu ana algoritma:
bool Solve(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if ((!nand) && (!nor) && (!xor) && (!decoder))
{
return CheckIfSolutionExist(lines, listLength, neededLine);
}
else
{
if (HandleNand(lines, nand, nor, xor, decoder, neededLine,listLength))
{
return true;
}
if (HandleNor(lines, nand, nor, xor, decoder, neededLine,listLength))
{
return true;
}
if (HandleXor(lines, nand, nor, xor, decoder, neededLine,listLength))
{
return true;
}
if (HandleDecoder(lines, nand, nor, xor, decoder, neededLine,listLength))
{
return true;
}
return false;
}
}
Bu işlev, kullanılabilir bitLines'ın bir listesini, liste uzunluğunu, her bir öğenin o anda kullanılabilir olup olmadığını gösteren bir boole (xor / nor / nand / decoder) ve aradığımız bitLine'i temsil eden bir bitLine alır.
Her aşamada, kullanılacak daha fazla unsurumuz olup olmadığını kontrol eder, eğer değilse - gerekli bit çizgimizi arşivleyip arşivlemediğimizi kontrol eder.
Hala daha fazla öğemiz varsa, bu nedenle her öğe için bu öğeleri kullanarak yeni bitLines oluşturma ve daha sonra bir sonraki yinelenen derinliği çağırmayı gerektiren bir işlevi çağırır.
Bir sonraki işleyici işlevlerinin hepsi oldukça basittir, kullanılabilir bit çizgilerinden "2 \ 3 seçin ve ilgili öğeyi kullanarak birleştirin. Sonra özyinelemenin bir sonraki derinliğini çağırın, sadece bu sefer bu eleman! "
bunlar fonksiyonlar:
bool HandleNand(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (nand)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
BitLine.Nand(lines[i], lines[j],lines[listLength]);
if (Solve(lines,listLength+1, false, nor, xor, decoder, neededLine))
{
return true;
}
}
}
}
return false;
}
bool HandleXor(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (xor)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
BitLine.Xor(lines[i], lines[j],lines[listLength]);
if (Solve(lines,listLength+1, nand, nor, false, decoder, neededLine))
{
return true;
}
}
}
}
return false;
}
bool HandleNor(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (nor)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
for (int k = j; k < listLength; k++)
{
BitLine.Nor(lines[i], lines[j], lines[k],lines[listLength]);
if (Solve(lines,listLength+1, nand, false, xor, decoder, neededLine))
{
return true;
}
}
}
}
}
return false;
}
bool HandleDecoder(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (decoder)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
for (int k = j; k < listLength; k++)
{
BitLine.Decoder(lines[i], lines[j], lines[k],lines,listLength);
if (Solve(lines,listLength+8, nand, nor, xor, false, neededLine))
{
return true;
}
}
}
}
}
return false;
}
Ve işte bu, sadece bu işlevi aradığımız hatla çağırıyoruz ve onları tek bir hat olacak şekilde birleştirmenin mümkün olup olmadığını kontrol etmek için elektrik parçalarının olası her kombinasyonunu kontrol ediyor. gerekli değerlerle çıktılanır.
* her zaman aynı listeyi kullandığımı fark ettim, bu yüzden her zaman yeni bitlines örnekleri oluşturmam gerekmeyecek. Bu nedenle 200 tamponlu veriyorum.
Bu tam program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
public class BitLine
{
public bool[] IsActiveWhenInputIs = new bool[16];
public static void Xor(BitLine b1, BitLine b2, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = b1.IsActiveWhenInputIs[i] != b2.IsActiveWhenInputIs[i];
}
}
public static void Nand(BitLine b1, BitLine b2, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = !(b1.IsActiveWhenInputIs[i] && b2.IsActiveWhenInputIs[i]);
}
}
public static void Nor(BitLine b1, BitLine b2, BitLine b3, BitLine outputBitLine)
{
for (var i = 0; i < 16; i++)
{
outputBitLine.IsActiveWhenInputIs[i] = !(b1.IsActiveWhenInputIs[i] || b2.IsActiveWhenInputIs[i] || b3.IsActiveWhenInputIs[i]);
}
}
public static void Decoder(BitLine b1, BitLine b2, BitLine b3, List<BitLine> lines, int listOriginalLength)
{
for (int optionNumber = 0; optionNumber < 8; optionNumber++)
{
for (var i = 0; i < 16; i++)
{
int sum = 0;
if (b1.IsActiveWhenInputIs[i]) sum += 4;
if (b2.IsActiveWhenInputIs[i]) sum += 2;
if (b3.IsActiveWhenInputIs[i]) sum += 1;
lines[listOriginalLength + optionNumber].IsActiveWhenInputIs[i] = (sum == optionNumber);
}
}
}
public bool CheckEquals(BitLine other)
{
for (var i = 0; i < 16; i++)
{
if (this.IsActiveWhenInputIs[i] != other.IsActiveWhenInputIs[i])
{
return false;
}
}
return true;
}
}
public class Solver
{
bool CheckIfSolutionExist(List<BitLine> lines, int linesLength, BitLine neededLine)
{
for (int i = 0; i < linesLength; i++)
{
if (lines[i].CheckEquals(neededLine))
{
return true;
}
}
return false;
}
bool HandleNand(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (nand)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
BitLine.Nand(lines[i], lines[j], lines[listLength]);
if (Solve(lines, listLength + 1, false, nor, xor, decoder, neededLine))
{
return true;
}
}
}
}
return false;
}
bool HandleXor(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (xor)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
BitLine.Xor(lines[i], lines[j], lines[listLength]);
if (Solve(lines, listLength + 1, nand, nor, false, decoder, neededLine))
{
return true;
}
}
}
}
return false;
}
bool HandleNor(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (nor)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
for (int k = j; k < listLength; k++)
{
BitLine.Nor(lines[i], lines[j], lines[k], lines[listLength]);
if (Solve(lines, listLength + 1, nand, false, xor, decoder, neededLine))
{
return true;
}
}
}
}
}
return false;
}
bool HandleDecoder(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if (decoder)
{
for (int i = 0; i < listLength; i++)
{
for (int j = i; j < listLength; j++)
{
for (int k = j; k < listLength; k++)
{
BitLine.Decoder(lines[i], lines[j], lines[k], lines, listLength);
if (Solve(lines, listLength + 8, nand, nor, xor, false, neededLine))
{
return true;
}
}
}
}
}
return false;
}
public bool Solve(List<BitLine> lines, int listLength, bool nand, bool nor, bool xor, bool decoder, BitLine neededLine)
{
if ((!nand) && (!nor) && (!xor) && (!decoder))
{
return CheckIfSolutionExist(lines, listLength, neededLine);
}
else
{
if (HandleNand(lines, listLength, nand, nor, xor, decoder, neededLine))
{
return true;
}
if (HandleNor(lines, listLength, nand, nor, xor, decoder, neededLine))
{
return true;
}
if (HandleXor(lines, listLength, nand, nor, xor, decoder, neededLine))
{
return true;
}
if (HandleDecoder(lines, listLength, nand, nor, xor, decoder, neededLine))
{
return true;
}
return false;
}
}
}
class Program
{
public static void Main(string[] args)
{
List<BitLine> list = new List<BitLine>();
var bitLineList = new BitLine[200];
for (int i = 0; i < 200; i++) bitLineList[i] = new BitLine();
// set input bit:
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 4; j++)
{
int checker = 1 << j;
bitLineList[j].IsActiveWhenInputIs[i] = ((checker & i) != 0);
}
}
// set zero and one constant bits:
for (int i = 0; i < 16; i++)
{
bitLineList[4].IsActiveWhenInputIs[i] = false;
bitLineList[5].IsActiveWhenInputIs[i] = true;
}
list.AddRange(bitLineList);
var neededBitLine = new BitLine();
for (int i = 0; i < 16; i++)
{
neededBitLine.IsActiveWhenInputIs[i] = (i%7==0); // be true for any number that is devideble by 7 (0,7,14)
}
var solver = new Solver();
Console.WriteLine(solver.Solve(list, 6, true, true, true, true, neededBitLine));
Console.ReadKey();
}
}
}
Umarım bu sefer geçerli bir açıklamadır: P