디지털 논리 회로-시험 문제


14

시험에서 해결하지 못한 질문이 있습니다.

나는 4 비트 수와 수익을 수신하는 디지털 논리 회로를 구축 할 필요가 true숫자 인 경우 0, 7또는 14. 하나의 XOR게이트 (2 입력), 하나 NOR(3 입력), 하나 NAND(2 입력) 및 하나의 3 대 8 디코더 만 있습니다.

나는 그 질문을 해결할 수 없다고 생각합니다. 그렇게 할 수있는 조합을 찾지 못했습니다. 어떻게 해결할 수 있습니까?


1
힌트 : 4 비트와 3-8 디코더가 주어지면 비트 중 하나를 다르게 처리해야합니다.
브라이언 드럼 몬드

2
@BrianDrummond이지만 이미 알고 있으며 여전히 해결하지 못했습니다. 내가 시도한 모든 솔루션에는 하나의 OR 게이트가 누락되었다고 생각합니다. 문제를 해결할 수있는 주어진 게이트와 같은 조합을 찾을 수 없습니다 ... 유형 당 하나의 게이트 만 있습니다 ...
nrofis

3
@BrianDrummond : 존재한다고 생각되는 솔루션에 대한 설명을 게시하면 확인할 수 있습니다. 솔루션이 존재하지 않는다고 말하기는 어렵지만 솔루션이 유효한지 쉽게 확인할 수 있습니다.
pasaba por aqui

2
@ Ido Kessler ... 귀하의 솔루션에 흥미가 있었고 귀하의 증거가 올바른 경우 삭제하여 죄송합니다. 지금까지 아무도 해결책이없는 것 같습니다. 아마도 알고리즘에 대한 설명을 포함하면 답이 향상 될 것입니다. 그것이 정확하고 버그가 없다고 얼마나 확신하십니까?
Tut

3
@ jalalipop, 나는 어제했다. Ido Kessler와 pasaba por aqui는 옳았다. 교수는 그 질문이 잘못되었고 NAND는 NOR 여야한다고 말했다 ....
nrofis

답변:


24

나는 그의 가능한 모든 조합을 시도 C #에서 알고리즘 작성 Nor 3->1 Xor 2->1 Nand 2->1Decoder 3->8.

7 시간 동안 7 시간 동안 2 시간 동안 실행 한 후 42 False를 반환했습니다 . 나는이 알고리즘이 가능한 모든 조합을 확인하기 때문에 질문에 답이 없다는 것을 증명한다고 생각합니다. :)

나는 그것을 설명하도록 요청 받았으므로 다음 부분은 코드의 부분에 대한 설명입니다. TL; DR- 마지막에 코드를 건너 뛸 수 있습니다 . :)


입력 라인에 대해 이야기 해 봅시다. 0 또는 1 상태이며 가능한 각 입력 (0 ~ 15)에 대해 서로 다른 값을 갖습니다.

첫 번째 줄의 경우 다음과 같습니다 : 0 1 0 1 1 ... 두 번째는 : 0 1 1 0 0 1 1 ... 세 번째 : 0 0 1 1 1 1 .... 이진과 같습니다 계산 ... 당신은 아이디어를 얻었다 : P

그래서 각 상태의 각 줄을 나타내는 객체를 만들었습니다.

class BitLine{
    bool[] IsActiveWhenInputIs = new bool[16];
}

bitLine.IsActiveWhenInputIs [5]는 입력이 5 일 때 라인이 활성화되었는지 여부를 리턴합니다.

이것은 입력 줄을 모두 만드는 코드입니다.

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
    }
}

상수 "0"입력 또는 "1"입력을 제공하기 위해 "always true"및 "always false"비트 라인도 작성합니다.

for (int i = 0; i < 16; i++){
    bitLineList[4].IsActiveWhenInputIs[i] = false;
    bitLineList[5].IsActiveWhenInputIs[i] = true;
}

알다시피, 우리가 찾고있는 것은 실제로 특정 비트 라인입니다. 입력은 0, 7, 14 일 때 참입니다.

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)
}

이것은 실제로 간단하게 만들었습니다. 실제로 찾고있는 것은 inputBitLine에서이 neededBitLine을 "위조"하는 방법입니다 (이것은 출력을 원하는 것을 프로그램에 표현하는 방법입니다).

우리가 갈 방법 지금이다 : 우리가 같은 우리의 비트 라인에 대한 몇 가지 논리적 인 요소를 사용할 때마다 Xor, Nor, Nand또는 심지어 Decoder, 우리가 실제로 새로운 비트 라인을 만드는이 \이야. 가능한 모든 입력에서 각 라인의 값을 0에서 15까지 알고 있으므로 가능한 모든 입력에서 새로운 bitLine 값을 계산할 수 있습니다!

Nand Nor와 Xor는 모두 간단합니다.

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]);
    }
}

가능한 각 입력에 대해 새 BitLine의 작동 방식을 나타냅니다.

디코더를 다루는 것은 약간 까다 롭지 만 아이디어는 "입력의 비트가 이진수로 숫자 x를 나타내는 경우 x 번째 출력 비트 라인은 true이고 나머지는 모두 false입니다. 이 함수는 비트 라인 배열을 가져오고 배열에 8 개의 새로운 비트 라인을 추가합니다.

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);
        }
    }
}

이제 기본 요소가 모두 갖추어져 있으므로 알고리즘에 대해 이야기 해 보겠습니다.

우리는 재귀 알고리즘을 각 깊이에서 현재 사용 가능한 비트 라인에서 다른 요소 (nor \ nand \ xor \ decoder)를 사용하려고 시도한 다음 요소를 다음 재귀 깊이에 사용할 수 없도록 설정하려고합니다. 맨 아래에 도착하고 사용할 요소가 더 이상 없을 때마다 원하는 비트 라인이 있는지 확인합니다.

이 코드는 현재 라인 그룹에 찾고있는 라인이 포함되어 있는지 주어진 시간에 확인합니다.

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 CheckEquals(BitLine other)
{
    for (var i = 0; i < 16; i++)
    {
        if (this.IsActiveWhenInputIs[i] != other.IsActiveWhenInputIs[i])
        {
            return false;
        }
    }
    return true;
}

자, 이제 주요 부분에서는 이것이 주요 알고리즘입니다.

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;
    }
}

이 함수는 사용 가능한 bitLine 목록, 목록 길이, 각 요소가 현재 사용 가능한지 (xor / nor / nand / decoder) 여부를 나타내는 부울 및 검색중인 bitLine을 나타내는 bitLine을 수신합니다.

각 단계에서 사용할 요소가 더 있는지 확인합니다. 그렇지 않은 경우 필요한 비트 라인을 보관할지 여부를 확인합니다.

여전히 더 많은 요소가있는 경우 각 요소에 대해 해당 요소를 사용하여 새 bitLine을 작성하고 그 후 다음 재귀 깊이를 호출하는 함수를 호출합니다.

다음 처리기 함수는 모두 매우 간단하며 "사용 가능한 비트 라인에서 2 \ 3을 선택하고 관련 요소를 사용하여 결합합니다. 그런 다음 재귀의 다음 깊이를 호출합니다. 이번에는 포함되지 않습니다. 이 요소! ".

그것들은 기능입니다 :

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;
}

그리고 이것은 우리가 찾고자하는 필요한 라인으로이 함수를 호출하는 것입니다. 전기 부품의 가능한 모든 조합을 검사하여 결국 단일 라인이 될 수있는 방식으로 이들을 결합 할 수 있는지 확인합니다. 필요한 값으로 출력됩니다.

* 항상 동일한 목록을 사용하므로 항상 새 비트 라인 인스턴스를 만들 필요가 없습니다. 그런 이유로 200 버퍼를 제공합니다.


이것은 완전한 프로그램입니다 :

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();
        }
    }
}

이번에는 그것이 올바른 설명이기를 바랍니다 : P


6
이러한 종류의 솔버 작동 방식에 대한 높은 수준의 설명을 포함 할 수 있습니다. 주석 처리되지 않은이 코드 덤프를 읽는 것이 즉시 명확하지 않습니다.
Dave Tweed

2
이것은 흥미로운 솔루션이며 알고리즘에 대한 설명을 제공 할 수 있기를 바랍니다. 방법을 입증하기 위해 유사한 테스트 사례를 수행 했습니까? (BTW, 미묘한 Douglas Adams 참조를 좋아합니다)
Tut

2
x == 2, x == 3, x == 4, ..., x == 11과 같이 확인할 수있는 테스트 사례 로이 알고리즘을 사용해 보았습니다. 실행하는 데 시간이 오래 걸리므로 x % 3 == 0 및 x % 5 == 0도 불가능할 수 있으며 두 가지 모두에 대한 답변을 찾을 수 없습니다. 그러나 알고리즘은 내가 직접 솔루션을 찾은 위의 모든 경우에 true를 반환했습니다.
Ido Kessler

3
+1! @IdoKessler 2 비트 입력 NOR로 2 비트 입력 NAND를 변경하고 소프트웨어가 솔루션을 제공하는지 확인할 수 있습니까? 실제로 NAND 대신 해당 게이트를 사용하면 솔루션이 있습니다.
next-hack

3
@ next-hack 2 비트 NOR을 사용하도록 변경하면 True를 반환했습니다.
Ido Kessler

8

이것은 가장 확실한 해결책을 버리는 대답이 아닙니다.

1248

24

(...도 아니다 {엑스=0,엑스=,엑스=6}) 낸드 (2 xor 4)

148

그러나 이전 표현의 단순화는 다음과 같습니다.

(엑스=0 또는 엑스= 또는 엑스=6) 또는 (2=4)

그것은 예상 한 것이 아닙니다 :

(엑스=0 또는 엑스= 또는 엑스=6)  (2=4)

이런 이유로, 나는 그 질문에 오류가있을 가능성이 있다고 생각한다.


2
어쩌면 그것은 사실이지만, 나는 더 이상 대답을 찾지 못했습니다.
nrofis

2
+1. 나는 당신이 옳다고 믿으며 NAND는 NOR이어야합니다.
Brian Drummond

2

귀하의 질문에 대한 올바른 답변은 항상 true를 반환하는 모든 회로입니다. 입력 번호가 0, 7 또는 14 인 경우에도 true를 리턴하므로

입력 번호가 0, 7 또는 14이면 true를 출력하는 회로를 명시 적으로 질문해야한다고 생각합니다. 그렇지 않으면 false를 출력합니다.


2
와우, 나는 그런 대답을 기대하지 않았습니다. 입력이 0, 7 또는 14 인 경우에만 회로가 true를 반환해야합니다.
nrofis

1
정확히 그렇게
Agustin Tena

2
사양을주의 깊게 살펴보면 +1입니다. 이것은 고객으로부터 그러한 사양을 얻을 때 나쁜 엔지니어링입니다. 이 경우 정답은 고객에게 사양 관련 문제를 지적하고 실제로 원하는 것을 확인하는 것입니다. 그러나 시험 문제의 경우 즉시 사용 가능한 사고 방식을 보여 주며 매우 간단한 답변을 정확하게 제공합니다.
Olin Lathrop

-3

할 수 있습니다. 힌트로 가운데 두 비트는 이러한 모든 비트 패턴에 대해 동일하므로 xoring하면 0을 생성하고 다른 두 비트로 디코더에 입력 할 수 있습니다. 나머지 게이트는 정확한 단일 비트 출력을 제공하기 위해 세 개의 디코더 출력에 적용됩니다.


이미 그랬어 나는 문제를 해결하는 어떤 조합도 찾지 못했습니다 ...
nrofis

xor를 사용하여 디코더의 4 비트를 3 비트로 줄입니다. 디코더는 3 개의 매칭 패턴에 대해 1 인 3 개의 출력을 가질 것이다. 낸드 게이트를 인버터로 사용하지 마십시오.
John

4
@John ... 솔루션은 6 개의 제품 용어 (간체 화되지 않음)를 산출하며 그 중 3 개는 유효하지 않습니다. 다시 말해, 솔루션이 0, 7 또는 14에 대해 true를 반환하지만; 1, 6 또는 8에 대해서도 true를 반환합니다.
Tut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.