package Aufgaben;

import java.io.*;
import java.util.Random;



class Senden implements Runnable
{
    Kabel kabel;
    boolean bstop = true;
    Senden(Kabel kabel)
    {
        this.kabel = kabel;
    }
   
    public void stop()
    {
        bstop = false;
    }
    public void run() 
    {
        
        
            for(int i=0;i<1;i++)
            {
                kabel.erzeugen_kodieren("101");
            }
            
        
    }
}

class Empfaengen implements Runnable
{
    Kabel kabel;
    Empfaengen(Kabel kabel)
    {
        this.kabel = kabel;
    }
    public void run() 
    {
        while(true)
        {
            kabel.emfaengen_korrigieren();
        }
    }
    
}

class Kabel
{
    private String datenSatz;
    private boolean bvoll = false;
    private int[]neu;
    int r;
    int t;
    
    public synchronized void erzeugen_kodieren( String datenSatz )
    {
        int m;
        
        if(bvoll)
        {
            try {wait();}
            catch(Exception e){}
        }
        
        int []alt = new int [datenSatz.length()];
        for(int i=0;i<datenSatz.length();i++)
        {
            alt[i] = Integer.parseInt(""+datenSatz.charAt(i));
        }
        m = datenSatz.length();
        
        for(int j=0;;j++)
        {
            if(m+j+1<Math.pow(2, j))
            {
                r = j;
                break;
            }
        }
        
        t = m+r;
        neu = new int[t+1];
        int t1 = 1;
        int t2 = 0;
        for(int i=1;i<=t;i++)
        {
            if(i==t1)
            {
                neu[i] = 0;
                t1 = t1*2;
            }
            else
            {
                neu[i] = alt[t2];
                t2 = t2+1;
            }
        }
        
        for(int i=t;i>0;i--)
        {
            boolean bool = false;
            for(int k=0;k<r;k++)
            {
                if(i==Math.pow(2, k));
                bool = true;
            }
            if(neu[i]==1&&bool==false)
            {
                int s = i;
                int k = r-1;
                
            do
            {
                
                if(s>Math.pow(2, k))
                {
                    neu[(int)Math.pow(2, k)] = neu[(int)Math.pow(2, k)]+1;
                    System.out.println(neu[(int)Math.pow(2, k)]);
                    s = s-(int)Math.pow(2, k);
                }
                else if(s==Math.pow(2, k))
                {
                    neu[(int)Math.pow(2, k)] = neu[(int)Math.pow(2, k)]+1;
                    break;
                }
                k--;
            }while(k>=0);
            }
            
        }
        
        for(int j=0;j<r;j++)
        {
            if(neu[(int)Math.pow(2, j)]%2==1)
            {
                neu[(int)Math.pow(2, j)] = 1;
            }
            else
            {
                neu[(int)Math.pow(2, j)] = 0;
            }
        }
    
        
      /*  Random random = new Random(System.currentTimeMillis());
        int x = Math.abs(random.nextInt( )) % t;
        if(neu[x] ==1)
        {
            neu[x] = 0;
        }
        else
        {
            neu[x] = 1;
        }*/
        
        bvoll = true;
        notify();
    }
        

    
    
   public synchronized void emfaengen_korrigieren()
    {
        int err = 0;
        int len = t+1;
        if(!bvoll)
        {
            try {wait();}
            catch(Exception e){}
        }
        for(int i=1;i<len;i++)
        System.out.print(neu[i]);
        
        for(int i=len-1;i>0;i--)
        {
            boolean bool = false;
            for(int tr=0;tr<r;tr++)
            {
                if(i==Math.pow(2, tr));
                bool = true;
            }
            if(neu[i]==1&&bool==false)
            {
                int s = i;
                int k = r-1;
            
            do
            {
                if(s>Math.pow(2, k))
                {
                    neu[(int)Math.pow(2, k)] = neu[(int)Math.pow(2, k)]+1;
                    s = s-(int)Math.pow(2, k);
                }
                else if(s==Math.pow(2, k))
                {
                    neu[(int)Math.pow(2, k)] = neu[(int)Math.pow(2, k)]+1;
                    break;
                }
                k--;
            }while(k>=0);
            }
        }
        
        for(int j=0;j<r;j++)
        {
            if(neu[(int)Math.pow(2, j)]%2==1)
            {
                err += (int)Math.pow(2, j);
            }
        }
        
        if(err ==0)
        {
            System.out.println("kein Fehler");
        }
        else if(neu[err-1]==0)
        {
            neu[err-1] = 1;
        }
        else
        {
            neu[err-1] = 0;
        }
        
        for(int i=1;i<len;i++)
        {
            boolean b = true;
            for(int j=0;j<r;j++)
            {
                if(i==Math.pow(2, j))
                b = false;
            }
            if(b==true)
            {
                System.out.print(neu[i]);
            }
        }
        
        bvoll = false;
        notify();
    }
    
}

public class Odd_Even_Protokoll {

    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        Kabel kabel = new Kabel();
        Senden s = new Senden(kabel);
        
        Empfaengen e = new Empfaengen(kabel);
        new Thread(s).start();
        new Thread(e).start();
    }

}