-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday02-sqlite.jl
85 lines (69 loc) · 1.95 KB
/
day02-sqlite.jl
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
using FunSQL
using SQLite
const funsql_instr = FunSQL.Fun.instr
const funsql_substr = FunSQL.Fun.substr
function funsql_score_by_line(score_table)
cases = FunSQL.SQLNode[]
for i = 1:3
for j = 1:3
line = "$('A'+i-1) $('X'+j-1)"
push!(cases, FunSQL.Get(:line) .== line, score_table[i, j])
end
end
FunSQL.Fun(:case, cases...)
end
# Scores indexed by [opponent move, my move].
const scores_part1 = [(1+3) (2+6) (3+0); (1+0) (2+3) (3+6); (1+6) (2+0) (3+3)]
# Scores indexed by [opponent move, outcome].
const scores_part2 = [(3+0) (1+3) (2+6); (1+0) (2+3) (3+6); (2+0) (3+3) (1+6)]
@funsql begin
split_line(text) =
instr($text, "\n") > 0 ? substr($text, 1, instr($text, "\n") - 1) : $text
split_rest(text) =
instr($text, "\n") > 0 ? substr($text, instr($text, "\n") + 1) : ""
split_lines_one_step() =
begin
filter(rest != "")
define(
line => split_line(rest),
rest => split_rest(rest))
end
split_lines(text) =
begin
define(rest => $text)
split_lines_one_step()
iterate(split_lines_one_step())
end
parse_guide() =
split_lines(:input)
solve_part1() =
begin
from(guide)
define(score => score_by_line($scores_part1))
group()
define(part1 => sum(score))
end
solve_part2() =
begin
from(guide)
define(score => score_by_line($scores_part2))
group()
define(part2 => sum(score))
end
solve_all() =
begin
solve_part1().cross_join(solve_part2())
with(guide => parse_guide())
end
const q = solve_all()
end # @funsql
if isempty(ARGS)
println(FunSQL.render(q, dialect = :sqlite))
else
const db = DBInterface.connect(FunSQL.DB{SQLite.DB})
for file in ARGS
input = read(file, String)
output = first(DBInterface.execute(db, q, input = input))
println("[$file] part1: $(output.part1), part2: $(output.part2)")
end
end