-
Notifications
You must be signed in to change notification settings - Fork 0
/
day10-sqlite.jl
94 lines (80 loc) · 2.31 KB
/
day10-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
86
87
88
89
90
91
92
93
94
using FunSQL
using SQLite
const funsql_as_integer = FunSQL.Fun."CAST(? AS INTEGER)"
const funsql_group_concat = FunSQL.Agg.group_concat
const funsql_instr = FunSQL.Fun.instr
const funsql_mod = FunSQL.Fun.mod
const funsql_substr = FunSQL.Fun.substr
@funsql begin
split_first(text, sep = "\n") =
instr($text, $sep) > 0 ? substr($text, 1, instr($text, $sep) - 1) : $text
split_rest(text, sep = "\n") =
instr($text, $sep) > 0 ? substr($text, instr($text, $sep) + $(length(sep))) : ""
addx(line) =
as_integer(substr($line, 6))
split_one_instruction() =
begin
filter(rest != "")
define(
ip => ip + 1,
line => split_first(rest),
addx => addx(split_first(rest)),
rest => split_rest(rest))
end
split_instructions(text) =
begin
define(
ip => 0,
rest => $text)
split_one_instruction()
iterate(split_one_instruction())
end
expand_cycles() =
begin
split_instructions(:input)
left_join(from((; tick = [0, 1])), on = line != "noop")
partition(
order_by = [ip, tick],
frame = (mode = rows, start = -Inf, finish = -1))
define(
cycle => 1 + coalesce(count(), 0),
x => 1 + sum(addx * tick))
end
solve_part1() =
begin
from(cycles)
filter(mod(cycle + 20, 40) == 0)
group()
define(part1 => sum(x * cycle))
end
solve_part2() =
begin
from(cycles)
define(
row => 1 + (cycle - 1) / 40,
col => 1 + mod(cycle - 1, 40))
define(pixel => between(col, x, x + 2) ? "#" : ".")
order(row, col)
group(row)
define(line => group_concat(pixel, ""))
order(row)
group()
define(part2 => group_concat(line, "\n"))
end
solve_all() =
begin
solve_part1().cross_join(solve_part2())
with(cycles => expand_cycles())
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:\n$(output.part1)\n[$file] part2:\n$(output.part2)")
end
end