NANDロジックゲートを使用して16進数の7セグメントディスプレイを駆動


9

ユビキタス7セグメント数値表示では、このWikipedia .gifに示すように、16桁の16進数すべてを明確に表示できます。

この課題のエントリは、16進数の4ビットを7つのセグメントの入力に変換するNAND論理ゲートを使用して回路図を作成します。7セグメントディスプレイの入力には、通常次のようにラベルが付けられています。(このチャレンジでは、DP(小数点)は無視されます)

ここに画像の説明を入力してください

したがって、回路は次の真理値表に準拠する必要があります。

Hex   | Hex Input Bit | Output to Segment line:
digit |  3  2  1  0   |  A  B  C  D  E  F  G
------+---------------+-----------------------
   0  |  0  0  0  0   |  1  1  1  1  1  1  0
   1  |  0  0  0  1   |  0  1  1  0  0  0  0
   2  |  0  0  1  0   |  1  1  0  1  1  0  1
   3  |  0  0  1  1   |  1  1  1  1  0  0  1
   4  |  0  1  0  0   |  0  1  1  0  0  1  1
   5  |  0  1  0  1   |  1  0  1  1  0  1  1
   6  |  0  1  1  0   |  1  0  1  1  1  1  1
   7  |  0  1  1  1   |  1  1  1  0  0  0  0
   8  |  1  0  0  0   |  1  1  1  1  1  1  1
   9  |  1  0  0  1   |  1  1  1  1  0  1  1
   A  |  1  0  1  0   |  1  1  1  0  1  1  1
   b  |  1  0  1  1   |  0  0  1  1  1  1  1
   C  |  1  1  0  0   |  1  0  0  1  1  1  0
   d  |  1  1  0  1   |  0  1  1  1  1  0  1
   E  |  1  1  1  0   |  1  0  0  1  1  1  1
   F  |  1  1  1  1   |  1  0  0  0  1  1  1

この表は正確だと思いますが、エラーを見つけたらお知らせください。

スコアは、使用する2入力NANDゲートの数によって決まります(ゲートあたり1ポイント)。物事を簡略化するために、図でAND、OR、NOT、およびXORゲートを使用し、以下の対応するスコアを使用できます。

  • NOT: 1
  • AND: 2
  • OR: 3
  • XOR: 4

この課題は、回路図の描画に関するものであり、コーディングに関するものではないようです。また、ゲートあたりのポイント値は、任意の(おそらく意図的に)、および使用しているようだと+あなたはNANDが唯一の1である状態いないときに、3ポイントである
stokastic

@stokastic このサイトには他にも論理ゲートの課題がたくさんあるので、コミュニティに受け入れられるこのカテゴリの課題を想定しています。多くの人が同じ採点システムを使用しています。 NANDロジックは、このスコアリングシステムを非常によく説明しています。
デジタルトラウマ

けっこうだ。私はそれらのタグを見たことがありません。「プログラミングパズル」や「コードゴルフ」にはあまり適合しないようです。
2014

回路は分割できますか?言い換えれば、値を変数に保存して、後で呼び出すことができますか?
XNOR

@xnorあなたはこの種のことについて話していますか:codegolf.stackexchange.com/a/26235/11259?もしそうなら、答えはイエスです。
デジタルトラウマ

回答:


17

ドミノ-合計スコア:243 NAND

  • 使用されるOR:61(それぞれ3 NAND-> 183 NAND)

  • 使用されない:60(各1 NAND-> 60 NAND)

このソリューションはドミノにあり、マーティンビュトナーの2つのドミノ関連の質問(Domino DayDomino Circuitsのゴルフ)に答える過程で私が書いたソフトウェアのコレクションが必要でした。

Domino Circuitソルバーを変更することで、ORと最初の入力が常にTRUEであるIFNOTで構成されるドミノ回路(このファイルにはソルバー出力と回路スケルトンも含まれています)を作成できました(そのため、本質的にNOTです)。この答えに当てはまることあまりないので、真理値表のORとNOTの解決策を示します。

A: 1011011111101011
((-1 ifnot (2 or (1 or (-1 ifnot 0)))) or ((-1 ifnot ((-1 ifnot 1) or (-1 ifnot 2))) or ((-1 ifnot (3 or (-1 ifnot (0 or (-1 ifnot 1))))) or (-1 ifnot (0 or ((-1 ifnot 3) or (-1 ifnot (2 or 1))))))))
B: 1111100111100100
((-1 ifnot (3 or 1)) or ((-1 ifnot (3 or (2 or 0))) or (-1 ifnot ((-1 ifnot 3) or ((-1 ifnot (2 or (0 or (-1 ifnot 1)))) or (-1 ifnot ((-1 ifnot 0) or (-1 ifnot 2))))))))
C: 1101111111110100
((-1 ifnot (2 or (-1 ifnot 3))) or ((-1 ifnot (1 or (-1 ifnot 0))) or (-1 ifnot (0 or (-1 ifnot (3 or (1 or (-1 ifnot 2))))))))
D: 1011011011011110
((-1 ifnot (3 or (1 or 0))) or ((-1 ifnot (2 or ((-1 ifnot (3 or 0)) or (-1 ifnot (1 or 0))))) or (-1 ifnot ((-1 ifnot 2) or ((-1 ifnot (3 or 1)) or (-1 ifnot ((-1 ifnot 1) or (-1 ifnot 3))))))))
E: 1010001010111111
((-1 ifnot (3 or (-1 ifnot (2 or (-1 ifnot 1))))) or (-1 ifnot ((-1 ifnot 0) or (-1 ifnot (2 or 1)))))
F: 1000111011111011
((-1 ifnot (3 or (-1 ifnot 1))) or ((-1 ifnot (2 or (0 or (-1 ifnot (1 or (-1 ifnot 3)))))) or (-1 ifnot ((-1 ifnot 0) or (-1 ifnot (2 or (-1 ifnot 1)))))))
G: 0011111011110111
((-1 ifnot (2 or (0 or (-1 ifnot 1)))) or ((-1 ifnot (1 or (-1 ifnot (2 or 0)))) or (-1 ifnot ((-1 ifnot (3 or 2)) or (-1 ifnot (0 or (-1 ifnot 3)))))))

使用されるバイナリ演算はORおよびIFNOTのみであることに注意してください。ここでは、スコアリングの目的で、各IFNOTをNOTとしてカウントしています。

回路の最後に7セグメントディスプレイを追加し、それをドミノシミュレーター/ gifジェネレーターに送りました。結果のgif(「A」が表示されていることを示します)の生成には約2時間かかりました。最終的な回路のサイズは1141 * 517であるため、各「セル」は単一のピクセルで表されます。黒のセルは空で、灰色のセルには立っているドミノがあり、白のセルには倒れたドミノがあります。これは、何が起こっているのか実際には分からないことを意味し、それがまったく押しつぶされている場合には役に立ちません。Sparrは私の元のgif(650kB)のはるかに小さいバージョンを提供してくれたので、ここにあります!

アニメーション

以下は、上記の入力1010( 'A')のアニメーションの最後のフレームです。左端の入力、上部の電力線、ほとんどのスペースを占めるスイッチボード、スイッチボードの左側にある7つの個別のロジック(これらは上記の関数のドミノ表現です)、および右端は7セグメントディスプレイ自体です。これが実行されると、個々のセグメントがほぼ同時に点灯するため、一部のセグメントが点灯して他のセグメントが点灯するのを待っている間、それを長時間見ることはできません。

アニメーションの最後のフレーム

ここ(36MB)またはここ(650kB、Sparrの厚意による)の栄光の中でアニメーションを参照してください(小さいコピーははるかに小さいですが、私のブラウザは美しさを損なうフレームをスキップするように見えたので、オリジナルをそのままにしました)

7セグメントディスプレイの詳細はこちらで確認できます(「1」が表示されています)。


3
+1でドミノを使って7セグメントディスプレイを運転する超現実性!
デジタルトラウマ

それは素晴らしいです...誰かがこれを実際に試してみる必要があります
Beta Decay

11

30個のNAND

おそらくディスプレイ上のシンボルを変更することを除いて、この問題に対する簡単な解決策はないと確信していますが、それは別の別の問題になるでしょう。

たとえば、出力を表示するようにFPGAをプログラミングする場合など、これは実際に役立つことなので、Verilogコードを提供します。

ミニマリズムについて:もちろん、作るのは難しいものでした。7セグメントディスプレイは人間が数字を表示するかなりランダムな方法であり、結果としてかなりランダムな回路にもなるため、理解することはできません。そして、これらの最小限の回路で一般的であるように、その論理的な深さは、近接ソリューションの場合よりもいくらか高くなっています。これは、シリアルの方がパラレルよりも単純だからです。

伝送遅延は、シート上の各NANDゲートの下向きの位置によって示されます。

最小16進数の7セグメントディスプレイドライバー

Verilogコード:

// Hexadecimal 7-segment display driver
// Minimal at 30 NANDs
//
// By Kim Øyhus 2018 (c) into (CC BY-SA 3.0)
// This work is licensed under the Creative Commons Attribution 3.0
// Unported License. To view a copy of this license, visit
// https://creativecommons.org/licenses/by-sa/3.0/
//
// This is my entry to win this Programming Puzzle & Code Golf
// at Stack Exchange: 
// /codegolf/37648/drive-a-hexadecimal-7-segment-display-using-nand-logic-gates
//
// I am quite sure there are no simpler solutions to this problem,
// except perhaps by changing the symbols on the display,
// but that would be another and different problem.
//
// Since this is actually something useful to do, for instance when
// programming an FPGA to show output, I provide this Verilog code.
//
// As for the minimalism: Of course it was tricky to make.
// It is not comprehensible, since a 7-segment display is
// just a fairly random way of showing numbers, resulting
// in a circuit that is fairly random too.
// And as is typical for these minimal circuits, its logical depth
// is somewhat higher than for close solutions. I guess this is because
// serial is simpler than parallel.
//
// 4 bits of input "in_00?", and 7 bits of output,
// one bit per LED in the segment.
//   A
// F   B
//   G
// E   C
//   D

module display7 ( in_000, in_001, in_002, in_003,  G, F, E, D, C, B, A );
  input in_000, in_001, in_002, in_003;
  output G, F, E, D, C, B, A;
  wire wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017, wir018, wir019, wir020, wir021, wir022 ;

  nand gate000 ( wir000, in_000, in_002 );
  nand gate001 ( wir001, in_000, in_000 );
  nand gate002 ( wir002, wir000, in_001 );
  nand gate003 ( wir003, in_001, wir002 );
  nand gate004 ( wir004, wir000, wir002 );
  nand gate005 ( wir005, in_002, wir003 );
  nand gate006 ( wir006, in_003, wir001 );
  nand gate007 ( wir007, wir006, wir004 );
  nand gate008 ( wir008, in_003, wir005 );
  nand gate009 ( wir009, wir005, wir008 );
  nand gate010 ( wir010, in_003, wir008 );
  nand gate011 ( wir011, wir010, wir009 );
  nand gate012 ( wir012, wir010, wir007 );
  nand gate013 ( wir013, wir001, wir011 );
  nand gate014 ( wir014, wir003, wir004 );
  nand gate015 (      G, wir011, wir014 );
  nand gate016 ( wir015, in_003, wir014 );
  nand gate017 ( wir016, wir015, wir013 );
  nand gate018 (      C, wir016, wir012 );
  nand gate019 ( wir017, wir016, wir007 );
  nand gate020 ( wir018, wir003, wir012 );
  nand gate021 ( wir019, wir017, in_003 );
  nand gate022 (      F, wir011, wir017 );
  nand gate023 (      D, wir018, wir017 );
  nand gate024 (      B, wir012,      F );
  nand gate025 ( wir020, wir004, wir018 );
  nand gate026 ( wir021, wir001,      D );
  nand gate027 (      E, wir019, wir021 );
  nand gate028 ( wir022,      D, wir019 );
  nand gate029 (      A, wir020, wir022 );
endmodule

キム・オイフス


これは本当に印象的なソリューションです!なぜ30を超えることができないと確信しているのですか?37はすでに「かなり減少」しているように見えました。
Alex Meiburg

ありがとう。私はこのソリューションを超えて検索しましたが、ソリューション自体を見つけるよりもはるかに多くの時間を費やしましたが、そこには何もありませんでした。私がより良いものを逃した確率は非常に小さいです。これは統計的な議論です。
KimOyhus

7

NOTに〜を使用し、NANDにNを使用して、コンピューター出力(出力間で用語を共有せずに)は、共有せずに82個のNANDを持つソリューションを見つけます。共有用語を手動で探すと、NANDは54に減少し、共有を含むコンピューター検索では、さらに37のNANDに減少します。この方法は確実に網羅的ではないため、最小値はさらに低くなる可能性があります。

上記のテーブルを再作成するプログラムは次のとおりです。各ラインには、その出力のNANDSのラベルが付いています。

#include <stdio.h>

int N(int x, int y) { return 1 & ~(x & y); }

void main(void)
{
    int i0, i1, i2, i3;
    for (i3 = 0; i3 <= 1; i3++) {
    for (i2 = 0; i2 <= 1; i2++) {
    for (i1 = 0; i1 <= 1; i1++) {
    for (i0 = 0; i0 <= 1; i0++) {
            printf("%d %d %d %d : %d %d %d %d %d %d %d\n", i3, i2, i1, i0,
    /* 14 */        N(N(N(i3, N(i2, i1)), N(N(i2, i0), ~i1)), N(N(i2, N(i3, N(i3, i0))), N(i0, N(i3, N(i3, i1))))),
    /* 12 */        N(N(N(i3, i0), N(i2, N(i1, i0))), N(~i1, N(N(i3, i0), N(~i3, N(i2, i0))))),
    /* 10 */        N(N(i0, N(i3, i1)), N(N(i3, i2), N(i1, N(i1, N(~i3, ~i2))))),
    /* 16 */        N(N(N(i2, i1), N(N(i3, i0), N(i2, i0))), N(N(i0, N(i1, ~i2)), N(N(i3, i2), N(N(i3, i1), N(i2, N(i2, i1)))))),
    /*  7 */        N(N(i3, i2), N(N(i2, N(i2, i1)), N(i0, N(i3, i1)))),
    /* 11 */        N(N(i3, N(i2, N(i3, i1))), N(N(i1, N(i2, N(i2, i0))), N(i0, N(i2, ~i3)))),
    /* 12 */        N(N(i3, i0), ~N(N(i1, N(i2, i0)), N(N(i3, i2), N(~i3, N(i2, N(i2, i1)))))) );
    } } } }
}

そしてここに出力があります:

0 0 0 0 : 1 1 1 1 1 1 0
0 0 0 1 : 0 1 1 0 0 0 0
0 0 1 0 : 1 1 0 1 1 0 1
0 0 1 1 : 1 1 1 1 0 0 1
0 1 0 0 : 0 1 1 0 0 1 1
0 1 0 1 : 1 0 1 1 0 1 1
0 1 1 0 : 1 0 1 1 1 1 1
0 1 1 1 : 1 1 1 0 0 0 0
1 0 0 0 : 1 1 1 1 1 1 1
1 0 0 1 : 1 1 1 1 0 1 1
1 0 1 0 : 1 1 1 0 1 1 1
1 0 1 1 : 0 0 1 1 1 1 1
1 1 0 0 : 1 0 0 1 1 1 0
1 1 0 1 : 0 1 1 1 1 0 1
1 1 1 0 : 1 0 0 1 1 1 1
1 1 1 1 : 1 0 0 0 1 1 1

そして、これは同等の方程式であり、54 NANDに到達するための項を共有しています。

    /* 1 */ int z1 = 1 - i1;
    /* 1 */ int z2 = 1 - i2;
    /* 1 */ int z3 = 1 - i3;

    /* 1 */ int n_i2_i0 = N(i2, i0);
    /* 1 */ int n_i2_i1 = N(i2, i1);
    /* 1 */ int n_i3_i0 = N(i3, i0);
    /* 1 */ int n_i3_i1 = N(i3, i1);
    /* 1 */ int n_i3_i2 = N(i3, i2);

    /* 1 */ int n_i0_n_i3_i1 = N(i0, n_i3_i1);
    /* 1 */ int n_i2_n_i2_i1 = N(i2, n_i2_i1);

            printf("%d %d %d %d : %d %d %d %d %d %d %d\n", i3, i2, i1, i0,
    /* 9 */ N(N(N(i3, n_i2_i1), N(n_i2_i0, z1)), N(N(i2, N(i3, n_i3_i0)), N(i0, N(i3, n_i3_i1)))),
    /* 7 */ N(N(n_i3_i0, N(i2, N(i1, i0))), N(z1, N(n_i3_i0, N(z3, n_i2_i0)))),
    /* 5 */ N(n_i0_n_i3_i1, N(n_i3_i2, N(i1, N(i1, N(z3, z2))))),
    /* 8 */ N(N(n_i2_i1, N(n_i3_i0, n_i2_i0)), N(N(i0, N(i1, z2)), N(n_i3_i2, N(n_i3_i1, n_i2_n_i2_i1)))),
    /* 2 */ N(n_i3_i2, N(n_i2_n_i2_i1, n_i0_n_i3_i1)),
    /* 8 */ N(N(i3, N(i2, n_i3_i1)), N(N(i1, N(i2, n_i2_i0)), N(i0, N(i2, z3)))),
    /* 6 */ N(n_i3_i0, ~N(N(i1, n_i2_i0), N(n_i3_i2, N(z3, n_i2_n_i2_i1)))) );

そして、これが37 NANDソリューションです。

    x0fff =  N(i3, i2);
    x33ff =  N(i3, i1);
    x55ff =  N(i3, i0);
    x0f0f =  not(i2);
    x3f3f =  N(i2, i1);
    x5f5f =  N(i2, i0);
    xcfcf =  N(i2, x3f3f);
    xf3f3 =  N(i1, x0f0f);
    x5d5d =  N(i0, xf3f3);
    xaaa0 =  N(x55ff, x5f5f);
    xfc30 =  N(x33ff, xcfcf);
    xd5df =  N(x3f3f, xaaa0);
    xf3cf =  N(x0fff, xfc30);
    xaeb2 =  N(x5d5d, xf3cf);
    x7b6d =  N(xd5df, xaeb2);
    xb7b3 =  N(i1, x7b6d);
    xf55f =  N(x0fff, xaaa0);
    xcea0 =  N(x33ff, xf55f);
    x795f =  N(xb7b3, xcea0);
    xd7ed =  N(xaeb2, x795f);
    xfaf0 =  N(x55ff, x0f0f);
    xae92 =  N(x55ff, x7b6d);
    xdd6d =  N(x33ff, xae92);
    x279f =  N(xfaf0, xdd6d);
    xaf0f =  N(i2, x55ff);
    x50ff =  N(i3, xaf0f);
    xef4c =  N(xb7b3, x50ff);
    x1cb3 =  N(xf3cf, xef4c);
    xef7c =  N(xf3cf, x1cb3);
    xfb73 =  N(i1, x279f);
    x2c9e =  N(xd7ed, xfb73);
    xdf71 =  N(xf3cf, x2c9e);
    xdd55 =  N(i0, x33ff);
    xf08e =  N(x0fff, xdf71);
    x2ffb =  N(xdd55, xf08e);
    x32ba =  N(xcfcf, xdd55);
    xfd45 =  N(x0fff, x32ba);

    printf("%d %d %d %d : %d %d %d %d %d %d %d\n", i3, i2, i1, i0,
            xd7ed, x279f, x2ffb, x7b6d, xfd45, xdf71, xef7c);
    } } } }

2
「37 NAND」の誇り高いヘッダーが必要です。あなたの投稿はそれなしでは控えめすぎます。
KimOyhus、2018年

4

NAND 197個

これは私の最初の論理ゲートの挑戦なのでです。それはあまりゴルフされておらず、最小の解決策ではないかもしれません。ここでは回路分割を使用していません。

A = OR(AND(d, NOT(AND(a, XOR(c, b)))), AND(NOT(d), NOT(AND(NOT(b), XOR(a, c)))))
B = AND(OR(OR(NOT(c), AND(NOT(d), NOT(XOR(b, a)))), AND(d, a)), NOT(AND(AND(d, b), a)))
C = OR(AND(NOT(c), NOT(AND(AND(NOT(d), b), NOT(a)))), AND(c, OR(NOT(d), AND(AND(d, NOT(b)), a))))
D = AND(OR(OR(OR(a, c), AND(AND(NOT(d), NOT(c)), NOT(a))), AND(AND(d, NOT(c)), NOT(b))), NOT(OR(AND(AND(NOT(d), NOT(b)), XOR(c, a)), AND(AND(c, b), a))))
E = OR(AND(NOT(a), NOT(AND(AND(NOT(d), c), NOT(b)))), AND(d, NOT(AND(AND(NOT(c), NOT(b)), a))))
F = AND(OR(OR(d, c), AND(NOT(b), NOT(a))), NOT(AND(AND(c, a), XOR(d, b))))
G = AND(OR(OR(d, c), b), NOT(OR(AND(AND(NOT(d), c), AND(b, a)), AND(AND(d, c), AND(NOT(b), NOT(a))))))
  • 36個のNOTを使用、36個のNAND
  • 41個のANDを使用、84個のNAND
  • 19個のORを使用、57個のNAND
  • 5 XOR使用、20 NAND

私が正しい場合、私のスコアは197です。


この課題の間に、ゲートをテストするための簡単なJavaScriptコードを作成しました。

function NOT(a){return !a}function AND(a,b){return a&b}function OR(a,b){return a|b}function XOR(a,b){return a^b}
for(d=0;d<=1;d++){for(c=0;c<=1;c++){for(b=0;b<=1;b++){for(a=0;a<=1;a++){console.log(""+d+c+b+a,
    // Enter your gate here
    // OR(AND(d, NOT(AND(a, XOR(c, b)))), AND(NOT(d), NOT(AND(NOT(b), XOR(a, c)))))
)}}}}

ゲートをコピーして変更し、ブラウザのコンソールまたはNode.js REPLに貼り付けます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.