/* ----------------------------------------------------------
    基本情報 平成14年秋 午後 問8
 ---------------------------------------------------------- */

/* 入出力用信号線 */
class Wire {
    private boolean value;
    public boolean getValue() { return value; }
    public void setValue( boolean value ) { this.value = value; }
}

/* ゲートを表す抽象クラス */
abstract class Gate {
    protected Wire[] input;
    protected Wire output;

    /* コンストラクタ
     *   nInputs : 入力信号線の数
     */
    public Gate( int nInputs ) {
    input = new Wire[nInputs];
    for ( int i=0; i < nInputs ; i++ ) { input[i] = new Wire(); }
    output = new Wire();
    }

    /* 他ゲートの入力へ自ゲートの出力を接続
     *   otherGate : 他ゲート
     *   nthInput  : 接続する入力信号線のインデックス
     */
    public void connectOutputTo( Gate otherGate, int nthInput ) {
    try {
        otherGate.input[nthInput] = output;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    }

    public Wire getInput( int n ) { return input[n]; }
    public Wire getOutput() { return output; }
    abstract public void tick(); //回路を作動
}

/* NOT */
class NotGate extends Gate {
    public NotGate() { super(1); }
    public void tick() {
    output.setValue( !input[0].getValue() );
    }
}

/* AND */
class AndGate extends Gate {
    public AndGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() && input[1].getValue() );
    }
}

/* ----------------------------------------------------------
    以下 宿題メール裏版 2004/05/19分 エンベデッドの為に追加
 ---------------------------------------------------------- */

/* OR */
class OrGate extends Gate {
    public OrGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() || input[1].getValue() );
    }
}

/* XOR */
class XorGate extends Gate {
    public XorGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() ^ input[1].getValue() );
    }
}

/* Buffer */
class BufferGate extends Gate {
    public BufferGate() { super(1); }
    /* バッファ回路はノイズ対策と思われるので
     * 簡単のため入力をそのまま出力する
     */
    public void tick() { output.setValue( input[0].getValue() ); }
}

/* ----------------------------------------------------------

 ┬──┐　　　　┬─＼　　　　　┤┌─＼　　　　│＼
 │　　├─　　　│　　)─ 　　　││　　)─ 　　┤　＞─
 ┴──┘　　　　┴─／　　　　　┤└─／　　　　│／
 AND 回路　　　　 OR 回路　　　　XOR 回路　　　　バッファ回路

 入力信号 A
   　───●──┬─＼
 入力信号 B│　　│g0  ) ──┐
 　　───┼●─┴─／　　　└┤┌─＼　g3  │＼　出力信号 C
 　　　　　││　　　　　　　　││g2  ) ○─┤g4>○───
 　　　　　│└─┬─＼　　　┌┤└─／　    │／  g5
 　　　　　│　　│g1  ) ──┘
 　　　　　└──┴─／

 ---------------------------------------------------------- */

/* 上記回路のテスト */
public class LogicalCircuitTest {
    public static void main( String[] args ) {

    /* 入力信号A: inputs[][0], 入力信号B: inputs[][1] */
    boolean[][] inputs = {
        { true, true },
        { true, false },
        { false, true },
        { false, false }
    };
    boolean inputA, inputB;

    Gate[] gates = new Gate[6];

    for ( int i=0 ; i < inputs.length ; i++ ) {
        inputA = inputs[i][0];
        inputB = inputs[i][1];

        gates[0] = new OrGate();     //g0 : or
        gates[1] = new OrGate();     //g1 : or
        gates[2] = new XorGate();    //g2 : xor
        gates[3] = new NotGate();    //g3 : not
        gates[4] = new BufferGate(); //g4 : buffer
        gates[5] = new NotGate();    //g5 : not

        /* 各ゲートを接続 */
        gates[0].connectOutputTo( gates[2], 0 ); // g0 --> g2
        gates[1].connectOutputTo( gates[2], 1 ); // g1 --> g2
        gates[2].connectOutputTo( gates[3], 0 );
        gates[3].connectOutputTo( gates[4], 0 );
        gates[4].connectOutputTo( gates[5], 0 );

        /* g0, g1 に入力 */
        gates[0].getInput(0).setValue( inputA );
        gates[0].getInput(1).setValue( inputB );
        gates[1].getInput(0).setValue( inputA );
        gates[1].getInput(1).setValue( inputB );

        /* 回路作動 */
        for ( int j=0 ; j < gates.length ; j++ ) { gates[j].tick(); }

        System.out.println( "A : " + inputA + "\t" +
                "B : " + inputB + "\t" +
                "result : " + gates[5].getOutput().getValue() );
    }
    }
}



/* ========================================================================

上記のリストに修正を加えたものを添付します。

*** ここから ***

/* ----------------------------------------------------------
    基本情報 平成14年秋 午後 問8
 ---------------------------------------------------------- */

/* 入出力用信号線 */
class Wire {
    private boolean value;
    public boolean getValue() { return value; }
    public void setValue( boolean value ) { this.value = value; }
}

/* ゲートを表す抽象クラス */
abstract class Gate {
    protected Wire[] input;
    protected Wire output;

    /* コンストラクタ
     *   nInputs : 入力信号線の数
     */
    public Gate( int nInputs ) {
    input = new Wire[nInputs];
    for ( int i=0; i < nInputs ; i++ ) { input[i] = new Wire(); }
    output = new Wire();
    }

    /* 他ゲートの入力へ自ゲートの出力を接続
     *   otherGate : 他ゲート
     *   nthInput  : 接続する入力信号線のインデックス
     */
    public void connectOutputTo( Gate otherGate, int nthInput ) {
    try {
        otherGate.input[nthInput] = output;
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    }

    public Wire getInput( int n ) { return input[n]; }
    public Wire getOutput() { return output; }
    abstract public void tick(); //回路を作動
}

/* NOT */
class NotGate extends Gate {
    public NotGate() { super(1); }
    public void tick() {
    output.setValue( !input[0].getValue() );
    }
}

/* AND */
class AndGate extends Gate {
    public AndGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() && input[1].getValue() );
    }
}

/* ----------------------------------------------------------
    以下 宿題メール裏版 2004/05/19分 エンベデッドの為に追加
 ---------------------------------------------------------- */

/* OR */
class OrGate extends Gate {
    public OrGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() || input[1].getValue() );
    }
}

/* XOR */
class XorGate extends Gate {
    public XorGate() { super(2); }
    public void tick() {
    output.setValue( input[0].getValue() ^ input[1].getValue() );
    }
}

/* Buffer */
class BufferGate extends Gate {
    public BufferGate() { super(1); }
    /* バッファ回路はノイズ対策と思われるので
     * 簡単のため入力をそのまま出力する
     */
    public void tick() { output.setValue( input[0].getValue() ); }
}

/* ----------------------------------------------------------

 ┬──┐　　　　┬─＼　　　　　┤┌─＼　　　　│＼
 │　　├─　　　│　　)─ 　　　││　　)─ 　　┤　＞─
 ┴──┘　　　　┴─／　　　　　┤└─／　　　　│／
 AND 回路　　　　 OR 回路　　　　XOR 回路　　　　バッファ回路

 入力信号 A
   　───●──┬──┐g1
 入力信号 B│　　│g0  │○─┐
 　　───┼●─┴──┘　　└┤┌─＼　g4  │＼　出力信号 C
 　　　　　││　　　　　　　　││g3  ) ○─┤g5>○───
 　　　　　│└─┬─＼　　　┌┤└─／　    │／  g6
 　　　　　│　　│g2  ) ──┘
 　　　　　└──┴─／

 ---------------------------------------------------------- */

/* 上記回路のテスト */
public class LogicalCircuitTest {
    public static void main( String[] args ) {

    /* 入力信号A: inputs[][0], 入力信号B: inputs[][1] */
    boolean[][] inputs = {
        { true, true },
        { true, false },
        { false, true },
        { false, false }
    };
    boolean inputA, inputB;

    Gate[] gates = new Gate[7];

    for ( int i=0 ; i < inputs.length ; i++ ) {
        inputA = inputs[i][0];
        inputB = inputs[i][1];

        gates[0] = new AndGate();    //g0 : and
        gates[1] = new NotGate();    //g1 : not
        gates[2] = new OrGate();     //g2 : or
        gates[3] = new XorGate();    //g3 : xor
        gates[4] = new NotGate();    //g4 : not
        gates[5] = new BufferGate(); //g5 : buffer
        gates[6] = new NotGate();    //g6 : not

        /* 各ゲートを接続 */
        gates[0].connectOutputTo( gates[1], 0 ); // g0 --> g1
        gates[1].connectOutputTo( gates[3], 0 ); // g1 --> g3
        gates[2].connectOutputTo( gates[3], 1 ); // g2 --> g3
        gates[3].connectOutputTo( gates[4], 0 );
        gates[4].connectOutputTo( gates[5], 0 );
        gates[5].connectOutputTo( gates[6], 0 );

        /* g0, g1 に入力 */
        gates[0].getInput(0).setValue( inputA );
        gates[0].getInput(1).setValue( inputB );
        gates[2].getInput(0).setValue( inputA );
        gates[2].getInput(1).setValue( inputB );

        /* 回路作動 */
        for ( int j=0 ; j < gates.length ; j++ ) { gates[j].tick(); }

        System.out.println( "A : " + inputA + "\t" +
                "B : " + inputB + "\t" +
                "result : " + gates[6].getOutput().getValue() );
    }
    }
}

*** ここまで ***
*/

