Cod sursa(job #1941806)

Utilizator cosminbxCosmin Banu cosminbx Data 27 martie 2017 16:36:55
Problema Fractal Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>

// shapes:
// A(0)   B(1)   C(2)   D(3)   A'(4)  B'(5)  C'(6)  D'(7)
// ---+   |  ^   +--+   +-->   <--+   ^  |   +--+   +---
//    |   |  |   |  |   |         |   |  |   |  |   |
// <--+   +_-+   |  v   +---   ---+   +--+   v  |   +-->

// index:
// 0 1
// 2 3

static const uint32_t shape_cost[8][4] = {
    { 0, 1, 3, 2}, // 0
    { 0, 3, 1, 2}, // 1
    { 1, 2, 0, 3}, // 2
    { 2, 3, 1, 0}, // 3
    { 3, 2, 0, 1}, // 4
    { 3, 0, 2, 1}, // 5
    { 2, 1, 3, 0}, // 6
    { 1, 0, 2, 3}, // 7
};

static const uint32_t next_shape[8][4] = {
    { 1, 0, 6, 0}, // 0
    { 0, 3, 1, 1}, // 1
    { 2, 2, 4, 7}, // 2
    { 3, 1, 3, 6}, // 3
    { 5, 4, 2, 4}, // 4
    { 4, 7, 5, 5}, // 5
    { 6, 6, 0, 3}, // 6
    { 7, 5, 7, 2}, // 7
};

uint32_t fractal(int s, uint32_t k, uint32_t x, uint32_t y) {
    uint32_t _2k = 1 << k;
    uint32_t _2k_1 = _2k >> 1;

    uint32_t xm = 0 < x && x <= _2k_1;
    uint32_t xM = _2k_1 < x && x <= _2k;
    uint32_t ym = 0 < y && y <= _2k_1;
    uint32_t yM = _2k_1 < y && y <= _2k;

    uint32_t i = 0;
    uint32_t _x = 0;
    uint32_t _y = 0;

    if (xm && ym) {
        i = 0;
        _x = x;
        _y = y;
    } else if (xM && ym) {
        i = 1;
        _x = x - _2k_1;
        _y = y;
    } else if (xm && yM) {
        i = 2;
        _x = x;
        _y = y - _2k_1;
    } else if (xM && yM) {
        i = 3;
        _x = x - _2k_1;
        _y = y - _2k_1;
    } else {
        exit(-1);
    }

    // shape cost of an entire square of dim 2^(k-1)
    uint32_t _2_2k_1 = 1 << (2*k - 2);

    if (k == 1)
        return shape_cost[s][i];

    return shape_cost[s][i] * _2_2k_1 + fractal(next_shape[s][i], k - 1, _x, _y);
}

int main(void) {
    FILE *fin = fopen("fractal.in", "r");
    if (fin == NULL) {
        return 1;
    }

    uint32_t k, x, y;
    fscanf(fin, "%" PRIu32, &k);
    fscanf(fin, "%" PRIu32, &x);
    fscanf(fin, "%" PRIu32, &y);

    fclose(fin);

    FILE *fout = fopen("fractal.out", "w");
    if (fout == NULL) {
        return 1;
    }
    // default shape 'B'(1)
    fprintf(fout, "%" PRIu32 "\n", fractal(1, k, x, y));
    fclose(fout);

    return 0;
}