class Signal {
    int t;
    boolean b;
    Signal next;
    Signal( int t0, boolean b0, Signal next0 ){
        t = t0;
        b = b0;
        next = next0;
    }
    // Q4
    Signal( boolean b0 ){
	b = b0; // default init: t=0; next=null
    }
}

class Simu {
    // Q3
    static void ppb( boolean b ){
        System.out.print( b ? "1" : "0" );
    }
    static void displayDebug( Signal f ){
        while( f != null ){
            System.out.println( f.t + "|=>" + f.b );
            f = f.next;
        }
        System.out.println( );
    }
    
    // Q5
    static void display( int n, Signal f ){
        Signal ff = f;
        boolean bb = f.b;
        for( int i = 0; i <= n; i ++ ){
            if( ff != null && i == ff.t ){
                bb = ff.b;
                ff = ff.next;
            }
            ppb( bb );
        }
        System.out.println( );
    }
    
    // Q6
    static boolean checkSignal(Signal f){
        if( f == null || f.t != 0 )
            return false;
        while( f.next != null ){
            if (f.t >= f.next.t)
                return false;
            f = f.next;
         }
        return true;
    }
    
    // Q7
    static Signal arrayToSignal( boolean[] a ){
        int n = a.length;
        boolean cv = a[n-1];
        Signal f = null;
        for( int i = 1; i <= n; i++ ){
            int ii = n - i;
            if( a[ii] != cv ){
                f = new Signal( ii + 1, cv, f );
                cv = a[ii];
            }
        }
        return new Signal( 0, a[0], f );
    }
    
    // Q8
    static boolean getVal( Signal f, int i ){
        boolean b = f.b;
        while( f != null ){
            if( i < f.t )
                return b;
            else {
                b = f.b;
                f = f.next;
            }
        }
        return b;
    }
    
    // Q9
    static Signal simplify_aux( boolean b, Signal f ){
        if( f == null )
            return null;
        else if( f.b == b )
            return simplify_aux( b, f.next );
        else return new Signal( f.t, f.b, simplify_aux( f.b, f.next ) );
    }
    static Signal simplify( Signal f ){
        return new Signal( 0, f.b, simplify_aux( f.b, f.next ) );
    }
    
    // Q10
    static Signal opNot( Signal f ){
        if( f == null ) return null;
        else return new Signal( f.t, !f.b, opNot( f.next ) );
    }
    
    // Q11
    static Signal opDelay_aux( Signal f ){
        if( f == null ) return null;
        else return new Signal( f.t + 1, f.b, opDelay_aux( f.next ) );
    }
    static Signal opDelay( Signal f ){
	if( f.b ){
	    return new Signal( 0, false, opDelay_aux( f ) );
	} else {
	    Signal s = opDelay_aux( f );
	    s.t = 0;
	    return s;
	}
    }

    // Q12
    static Signal opAnd( Signal f0, Signal f1 ){
        Signal rres = new Signal( 0, f0.b && f1.b, null );
        Signal res = rres;
        boolean b0 = f0.b;
        boolean b1 = f1.b;
        f0 = f0.next;
        f1 = f1.next;
        while( f0 != null || f1 != null ){
            if( f0 == null ){ // f1 != null
                res.next = new Signal( f1.t, b0 && f1.b, null );
                b1 = f1.b;
                f1 = f1.next;
            } else if( f1 == null ){ // f0 != null
                res.next = new Signal( f0.t, b1 && f0.b, null );
                b0 = f0.b;
                f0 = f0.next;
            } else if( f0.t == f1.t ){
                res.next = new Signal( f0.t, f0.b && f1.b, null );
                b0 = f0.b;
                b1 = f1.b;
                f0 = f0.next;
                f1 = f1.next;
            } else if( f0.t < f1.t ){
                res.next = new Signal( f0.t, f0.b && b1, null );
                b0 = f0.b;
                f0 = f0.next;
            } else { // f0.t > f1.t
                res.next = new Signal( f1.t, f1.b && b0, null );
                b1 = f1.b;
                f1 = f1.next;
            }
            res = res.next;
        }
        return simplify( rres );
    }
    
    // Q13
    static Signal opOr( Signal f0, Signal f1 ){
        return opNot( opAnd( opNot( f0 ), opNot( f1 ) ) );
    }
    
    public static void main( String[] args ){
	// Q2
	Signal s0 = new Signal(0,false,new Signal(1,true,new Signal(4,false,null)));
	Signal s1 = new Signal(0,true,new Signal(1,false,new Signal(4,true,new Signal(5,false,null))));
        Signal s2 = new Signal(0,true,new Signal(2,false,new Signal(4,true,null)));
    }
}

