aboutsummaryrefslogtreecommitdiff
path: root/2015/23/puzzles.l
blob: 6793126c410757ea52df81db8a1ceae8ad00903b (plain) (blame)
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;
}