1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
%{
#include <err.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/* Shut up the compiler */
int fileno(FILE *);
struct Instr {
enum {
HLF,
INC,
JIE,
JIO,
JMP,
TPL
} type;
enum {
A,
B
} reg;
int imm;
};
int i = 0;
struct Instr *program;
#ifdef PART2
unsigned long long registers[2] = {1, 0};
#else
unsigned long long registers[2];
#endif
%}
%x ARGS
%%
hlf { program[i].type = HLF; BEGIN(ARGS); }
inc { program[i].type = INC; BEGIN(ARGS); }
jie { program[i].type = JIE; BEGIN(ARGS); }
jio { program[i].type = JIO; BEGIN(ARGS); }
jmp { program[i].type = JMP; BEGIN(ARGS); }
tpl { program[i].type = TPL; BEGIN(ARGS); }
<ARGS>[ab] { program[i].reg = *yytext - 'a'; }
<ARGS>[+\-][0-9]+ { program[i].imm = atoi(yytext); }
<ARGS>[ ,]+ { ; }
<ARGS>\n { i++; BEGIN(INITIAL); }
%%
static unsigned long long
execute(void)
{
for (i = 0; i < PROGLEN; i++) {
switch (program[i].type) {
case HLF:
registers[program[i].reg] /= 2;
break;
case INC:
registers[program[i].reg]++;
break;
case JIE:
if (!(registers[program[i].reg] & 1))
i += program[i].imm - 1;
break;
case JIO:
if (registers[program[i].reg] == 1)
i += program[i].imm - 1;
break;
case JMP:
i += program[i].imm - 1;
break;
case TPL:
registers[program[i].reg] *= 3;
break;
}
}
return registers[B];
}
int
main(void)
{
FILE *fp;
if (!(program = calloc(PROGLEN, sizeof(struct Instr))))
err(EXIT_FAILURE, "calloc");
if (!(fp = fopen("input", "r")))
err(EXIT_FAILURE, "fopen");
yyrestart(fp);
yylex();
fclose(fp);
printf("%llu\n", execute());
return EXIT_SUCCESS;
}
|