#include <stdio.h>

/* Prototype Descriptions */
int  compute_type(int);
void read_input(int *,int *,int *,int *,int *,int *);
void reduces_on(int,  int a[]);
void reduces_off(int, int a[]);
void show_lamps(int,  int a[]);


/*********************************************************** 
 * 
 *   MAIN PROGRAM
 * 
 ***********************************************************/
main (int argc, char *argv[])
{
   int Nlamps, Nops, On1, On2, Off1, Off2;
   char *input_name;
   int aux;

   /* Contains all the possible combinations 
    * (the first combination is not used)
    *
    *   Combination   Type1  Type2  Type3  Type4
    *   ========================================  
    *        0          ------ not used ------
    *        1          1      1      1      1
    *        2          1      1      0      0
    *        3          0      0      1      1
    *        4          0      0      0      0
    *        5          1      0      1      0
    *        6          1      0      0      1
    *        7          0      1      1      0
    *        8          0      1      0      1
    */
   int combination[9];

   /* Initialization */
   On1 = On2 = Off1 = Off2 = -1;
   Nlamps = Nops  = 0;
   for(aux=0; aux < 9; aux++) combination[aux]=1;

   /* Reads input file */
   read_input(&Nlamps, &Nops, &On1, &On2, &Off1, &Off2);
    
   /* Discards possible combinations based on the number of movements */
   switch (Nops) {
      case 1: combination[1]=0;
              combination[6]=0;
              combination[7]=0;
              combination[8]=0;
              break;
      case 2: combination[5]=0;
              break;
   }

   /* Discards combinations based on the lamps one is sure to be on */
   if (On1 != -1) reduces_on(compute_type(On1),combination);
   if (On2 != -1) reduces_on(compute_type(On2),combination); 

   /* Discards combinations based on the lamps one is sure to be off */
   if (Off1 != -1) reduces_off(compute_type(Off1),combination);
   if (Off2 != -1) reduces_off(compute_type(Off2),combination);    
    
   /* Prints all possible combinations into a file */
   show_lamps(Nlamps, combination);
}       

/************************************************************** 
 * 
 * DISCARDS POSSIBLE COMBINATIONS BASED ON A LAMP THAT IS ON
 * 
 **************************************************************/ 
void reduces_on(int type, int combination[]) {
   switch (type) {
     case 1: combination[3]=0;
             combination[4]=0;
             combination[7]=0;
             combination[8]=0;
             break;
     case 2: combination[3]=0;
             combination[4]=0;
             combination[5]=0;
             combination[6]=0;
             break;
     case 3: combination[2]=0;
             combination[4]=0;
             combination[6]=0;
             combination[8]=0;
             break;
     case 4: combination[2]=0;
             combination[4]=0;
             combination[5]=0;
             combination[7]=0;
             break;
   }
}
  

/************************************************************** 
 * 
 * DISCARDS POSSIBLE COMBINATIONS BASED ON A LAMP THAT IS OFF
 * 
 **************************************************************/ 
void reduces_off(int type, int combination[]) {
   switch (type) {
     case 1: combination[1]=0;
             combination[2]=0;
             combination[5]=0;
             combination[6]=0;
             break;
     case 2: combination[1]=0;
             combination[2]=0;
             combination[7]=0;
             combination[8]=0;
             break;
     case 3: combination[1]=0;
             combination[3]=0;
             combination[5]=0;
             combination[7]=0;
             break;
     case 4: combination[1]=0;
             combination[3]=0;
             combination[6]=0;
             combination[8]=0;
             break;
   }
}

/************************************************************** 
 * 
 * COMPUTES DE TYPE OF A LAMP (arg N):
 * 
 *  Type 1 -> even and is not multiple of 3N+1
 *  Type 2 -> even and is multiple of 3N+1
 *  Type 3 -> odd  and is not multiple of 3N+1
 *  Type 4 -> odd  and is multiple of 3N+1
 * 
 **************************************************************/ 
int compute_type(int N)
{
   if ((N % 2) == 0) {
       if ((N % 3) != 1) return 1; else return 2;               
     } else {
       if ((N % 3) != 1) return 3; else return 4;               
   }
}

/************************************************************** 
 * 
 * READS IMPUT FILE
 * 
 **************************************************************/ 
void read_input (int *Nlamps,int *Nops,
                 int *On1,int *On2,int *Off1,  int *Off2) 
{
   FILE *input_fp;
                        
   /* Opens input file */
   input_fp = fopen("PARTY.IN", "r");

   /* Reads the number of lamps and the number of operations)*/
   fscanf(input_fp, "%d %d", Nlamps, Nops);
        
   /* Reads the lamps one is sure to be ON */
   fscanf(input_fp, "%d", On1);
   if (*On1 != -1) { 
      fscanf(input_fp, "%d -1", On2);
   }
        
   /* Reads the lamps one is sure to be ON */
   fscanf(input_fp, "%d", Off1);
   if (*Off1 != -1) fscanf(input_fp, "%d", Off2);
}



/************************************************************** 
 * 
 * Prints all possible combinations to file "MyOutput" 
 * 
 **************************************************************/ 
void show_lamps(int Nlamps, int combination[])
{
   FILE *output_fp;
   int aux, i, type_i;

   /*
    *   Combination   Type1  Type2  Type3  Type4
    *   ========================================  
    *        0          ------ not used ------
    *        1          1      1      1      1
    *        2          1      1      0      0
    *        3          0      0      1      1
    *        4          0      0      0      0
    *        5          1      0      1      0
    *        6          1      0      0      1
    *        7          0      1      1      0
    *        8          0      1      0      1
    */        
   static int comb_definition[9][5] = { {0, 0, 0, 0, 0}, 
                                        {0, 1, 1, 1, 1},
                                        {0, 1, 1, 0, 0},
                                        {0, 0, 0, 1, 1},
                                        {0, 0, 0, 0, 0},
                                        {0, 1, 0, 1, 0},
                                        {0, 1, 0, 0, 1},
                                       {0, 0, 1, 1, 0},
                                        {0, 0, 1, 0, 1} };
 
   /* Opens input file */
   output_fp = fopen("PARTY.OUT", "w");
     
   for (aux=1; aux<9; aux++) {
      if (combination[aux]) {
         for (i=1; i<Nlamps+1; i=i+1) {
            type_i = compute_type(i);
            fprintf(output_fp,"%d",comb_definition[aux][type_i]);
         }
         fprintf(output_fp,"\n");
      }
   }
}

