[ create a new paste ] login | about

Link: http://codepad.org/ZMxogzk3    [ raw code | fork ]

C, pasted on Aug 10:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

struct { int x, y; } const co[] = {
    {62, -67}, {  4, -71}, {-86,  71}, {-25, -53}, {-23, 70},
    {46, -34}, {-92, -62}, {-15,  89}, {100,  42}, { -4, 43},
    {21,  59}, { 86, -25}, { 93, -52}, {-41, -48}, {-45, 76},
    {85, -43}, {-69,  64}, {-50, -32}, { 48, -15}, {-14, 38}
};

#define N (sizeof(co) / sizeof(co[0]))

typedef uint16_t Sint;
typedef struct { Sint min, max; } MinMax;

uint32_t dist[N][N];
MinMax cache[N + (N << (N - 1))];
MinMax* pos[1 << N];
size_t masks[1 << N];

void calc_mask(const size_t mask) {
    MinMax *out = pos[mask];
    for (size_t i = N; i--; ) {
        if (!(mask & (1U << i)))
            continue;
        const size_t m = mask & ~(1U << i);
        MinMax *in = pos[m];
        MinMax r = {UINT16_MAX, 0};

        for (size_t j = N; j--; ) {
            if (!(m & (1U << j)))
                continue;
            const uint32_t d = dist[i][j];
            MinMax sub = *in;
            in++;

            sub.max += d;
            if (sub.max > r.max)
                r.max = sub.max;
            sub.min += d;
            if (sub.min < r.min)
                r.min = sub.min;
        }

        *out = r;
        out++;
    }
}

int main() {
    for (size_t i = 0; i < N; i++)
        for (size_t j = 0; j < i; j++)
            dist[i][j] = dist[j][i] =
                abs(co[i].x - co[j].x) + abs(co[i].y - co[j].y);

    {
        size_t *ptr = &masks[0];
        for (size_t i = 0; i < (1 << N); i++) {
            const size_t m = masks[i];
            for (size_t j = 1 << (N - 1); j != 0; j >>= 1) {
                if (!(j & m) && !pos[j | m]) {
                    pos[j | m] = &cache[0];
                    *ptr = j | m;
                    ptr++;
                }
            }
        }
    }

    {
        MinMax *p = &cache[0] + N;
        for (size_t i = 0; i < (1 << N); i++) {
            const size_t m = masks[i];
            pos[m] = p;
            for (size_t j = 1 << (N - 1); j != 0; j >>= 1)
                if ((j & m))
                    p++;
        }
    }

    for (size_t i = N; i < (1 << N); i++)
        calc_mask(masks[i]);

    const MinMax *p = pos[(1 << N) - 1];
    Sint min = UINT16_MAX;
    Sint max = 0;
    for (size_t i = 0; i < N; i++) {
        if (p[i].max > max)
            max = p[i].max;
        if (p[i].min < min)
            min = p[i].min;
    }
    printf("%d %d\n", min, max);

    return 0;
}


Create a new paste based on this one


Comments: