Advent of Code

Diff
Login

Diff

Differences From Artifact [3996de5fa9]:

To Artifact [8ba34621fd]:


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
        case 5: return (unsigned)(r[1] & 0xFFFFFFFF);
        case 6: return (unsigned)(r[2] & 0xFFFFFFFF);
    }
}

static unsigned instruction(unsigned ip, unsigned opcode, unsigned operand,
                            unsigned long long r[3],
                            char *out, size_t *outlen) {
    unsigned nextip = ip + 2;
    switch (opcode) {
        default: case 3: if (r[0]) { nextip = operand; } break;
        case 0: r[0] = r[0] / (1 << combo(operand, r)); break;
        case 1: r[1] = r[1] ^ operand; break;
        case 2: r[1] = combo(operand, r) % 8; break;
        case 4: r[1] = r[1] ^ r[2]; break;
        case 5: if (*outlen) { out[*outlen] = ','; *outlen += 1; }
                out[*outlen] = combo(operand, r) % 8 + '0';
                *outlen += 1;
                break;
        case 6: r[1] = r[0] / (1 << combo(operand, r)); break;
        case 7: r[2] = r[0] / (1 << combo(operand, r)); break;
    }
    return nextip;
}







|







<
|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72
        case 5: return (unsigned)(r[1] & 0xFFFFFFFF);
        case 6: return (unsigned)(r[2] & 0xFFFFFFFF);
    }
}

static unsigned instruction(unsigned ip, unsigned opcode, unsigned operand,
                            unsigned long long r[3],
                            unsigned *out, size_t *outlen) {
    unsigned nextip = ip + 2;
    switch (opcode) {
        default: case 3: if (r[0]) { nextip = operand; } break;
        case 0: r[0] = r[0] / (1 << combo(operand, r)); break;
        case 1: r[1] = r[1] ^ operand; break;
        case 2: r[1] = combo(operand, r) % 8; break;
        case 4: r[1] = r[1] ^ r[2]; break;

        case 5: out[*outlen] = combo(operand, r) % 8;
                *outlen += 1;
                break;
        case 6: r[1] = r[0] / (1 << combo(operand, r)); break;
        case 7: r[2] = r[0] / (1 << combo(operand, r)); break;
    }
    return nextip;
}
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99





























100
101
102
103
104
105
106
    unsigned p[100] = {0}, np = 0;
    while (dta && *dta) {
        unsigned v = strtoul(dta, &err, 10);
        p[np++] = v;
        if (*err == 0) dta = NULL;
        else dta = err + 1; // skip comma
    }
    char output[1000];
    size_t outlen = 0;
    unsigned ip = 0;
    while (ip + 1 < np) {
        ip = instruction(ip, p[ip], p[ip+1], reg, output, &outlen);
    }
    output[outlen] = 0;
    printf("Program's output is {%s}\n", output);





























}

/* === aoc202409 =======================================================
   WOW! input consists of a 20,000 long string of numbers!
   Make an array of blocks, each with either -1 or the fileid
   For Part Two: make an array of blocks with the encoded value of
(fileid * 10) + length, or, when empty, the negative length







|





<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    unsigned p[100] = {0}, np = 0;
    while (dta && *dta) {
        unsigned v = strtoul(dta, &err, 10);
        p[np++] = v;
        if (*err == 0) dta = NULL;
        else dta = err + 1; // skip comma
    }
    unsigned output[100];
    size_t outlen = 0;
    unsigned ip = 0;
    while (ip + 1 < np) {
        ip = instruction(ip, p[ip], p[ip+1], reg, output, &outlen);
    }

    printf("Program's output is {");
    for (unsigned k = 0; k < outlen; k++) {
        if (k) putchar(',');
        putchar((int)output[k] + '0');
    }
    printf("}\n");

    printf("Program is          (%u", p[0]);
    for (unsigned k = 1; k < np; k++) {
        if (k) putchar(',');
        putchar((int)p[k] + '0');
    }
    printf(")\n");

    reg[3] = 202322936867370;
#if 0
    // I'm not happy with my "solution".
    // It wasn't the program who found it.
    // I found it by studying closer and closer attempts

    // first I noticed that the program work 3 bits at a time,
    // so, to generate a sequence with 16 numbers it needs 48 bits

    // I then simply calculated the output with each 3-bit value one-by-one
    // until I had the whole thing

    // someday, maybe, I'll try to write a proper recursive solution
#else
    printf("Start with A = %llu to get the quine.\n", reg[3]);
#endif
}

/* === aoc202409 =======================================================
   WOW! input consists of a 20,000 long string of numbers!
   Make an array of blocks, each with either -1 or the fileid
   For Part Two: make an array of blocks with the encoded value of
(fileid * 10) + length, or, when empty, the negative length