Cod sursa(job #995907)

Utilizator Xavierpana emil Xavier Data 10 septembrie 2013 14:51:18
Problema Fractal Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 4.28 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Made by Pana Emil

#define N 4

// Direction: 0=anticlockwise, 1=clockwise
// Orientation: 0=up, 1=left, 2=down, 3=right
// Count: number of steps to find the searched point
// Perimeter = array of coordonates anti clockwise
void dei(int* perimeter, int x, int y, int orientation, int direction, int* count)
{
    int i;
    
    for(i = 0; i < N; i++)
    {
        //printf("%d\n", perimeter[i]);
    }
    
    if(perimeter[0] == perimeter[2] && perimeter[1] == perimeter[3])
    {
        //printf("\nam ajuns la x=%d, y=%d", x, y);
    } else {
        //printf("\n\n");
        
        int midX = (perimeter[0] + perimeter[2]) / 2;
        int midY = (perimeter[1] + perimeter[3]) / 2;
        
        // The number of steps to count for every dial
        int steps = (perimeter[2] - perimeter[0] + 1) * (perimeter[3] - perimeter[1] + 1) / 4;
        
        //printf("steps = %d\n", steps);
        
        int cadran = 0;
        
        if(x <= midX)
        {
            perimeter[2] = midX;
        } else {
            cadran = 2;
            
            perimeter[0] = midX + 1;
        }
        
        if(y <= midY)
        {
            if(cadran == 2){
                cadran = 3;
            }
            perimeter[3] = midY;
        } else {
            if(cadran == 0) {
                cadran = 1;
            }
            perimeter[1] = midY + 1;
        }
        
        //printf("cadran %d\n", cadran);
        
        // Compute the dials where I change direction
        int leftCadran;
        int rightCadran;
        switch(orientation)
        {
            case 0:
                leftCadran = 0;
                rightCadran = 3;
            break;
                
            case 1:
                leftCadran = 1;
                rightCadran = 0;
            break;
            
            case 2:
                leftCadran = 2;
                rightCadran = 1;
            break;
            
            case 3:
                leftCadran = 3;
                rightCadran = 2;
            break;
        }
        
        // Counting the number of steps
        if(direction == 0)
        {
            i = leftCadran;
            while(i != rightCadran && i != cadran)
            {
                *count += steps;
                i = (i+1) % N;
            }
        } else
        {
            i = rightCadran;
            while(i != leftCadran && i != cadran)
            {
                *count += steps;
                i = (i-1);
                if(i < 0)
                {
                    i += N;
                }
            }
        }
        
        //printf("count=%d\n", *count);
        
        // Change direction in function of dial
        if(cadran == leftCadran || cadran == rightCadran)
        {
            direction = 1 - direction;
        }
        
        // Orientation: 0=up, 1=left, 2=down, 3=right
        
        // Change the orientation in function to dial
        if(cadran == leftCadran) {
            orientation = (orientation + 1) % N;
        }
        
        if(cadran == rightCadran) {
            orientation = (orientation - 1) % N;
        }
        
        // For negative modulus
        if(orientation < 0)
        {
            orientation += N;
        }
        
        //printf("direction %d\n", direction);
        //printf("orientation %d\n", orientation);
        
        dei(perimeter, x, y, orientation, direction, count);
    }
}

// x = column, y = line
int main()
{
   FILE* input = fopen("fractal.in", "r");
   FILE* output = fopen("fractal.out", "w");
   
   int k, x, y;
   
   fscanf(input, "%d %d %d", &k, &x, &y);
   
   x--;
   y--;
   
   //printf("%d %d %d\n\n", k, x, y);
   
   int* perimeter = (int*) malloc(N * sizeof(int));
   
   // left x1
   perimeter[0] = 0;
   // top y1
   perimeter[1] = 0;
   // right x2
   perimeter[2] = pow(2, k) - 1;
   // bottom y2
   perimeter[3] = pow(2, k) - 1;
   
   int w = 0;
   int* count = &w;
   
   // Up and anticlockwise
   dei(perimeter, x, y, 0, 0, count);
   
   fprintf(output, "%d", *count);
   
   fclose(input);
   fclose(output);
   
   return 0;
}