-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday25-postgresql.jl
95 lines (81 loc) · 2.37 KB
/
day25-postgresql.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
95
using FunSQL
using LibPQ
using DBInterface
# Make LibPQ compatible with DBInterface.
DBInterface.connect(::Type{LibPQ.Connection}, args...; kws...) =
LibPQ.Connection(args...; kws...)
DBInterface.prepare(conn::LibPQ.Connection, args...; kws...) =
LibPQ.prepare(conn, args...; kws...)
DBInterface.execute(conn::Union{LibPQ.Connection, LibPQ.Statement}, args...; kws...) =
LibPQ.execute(conn, args...; kws...)
const var"funsql_%" = FunSQL.Fun."%"
const funsql_as_bigint = FunSQL.Fun."(?::bigint)"
const funsql_string_to_table = FunSQL.Fun.string_to_table
const funsql_substr = FunSQL.Fun.substr
@funsql begin
parse_requirements() =
from(
string_to_table(:input, "\n"),
columns = [snafu])
from_snafu_step() =
begin
filter(snafu != "")
define(
ch => substr(snafu, 1, 1),
snafu => substr(snafu, 2))
define(
digit =>
ch == "2" ? 2 :
ch == "1" ? 1 :
ch == "0" ? 0 :
ch == "-" ? -1 :
ch == "=" ? -2 : missing)
define(
value => value * 5 + digit)
end
to_snafu_step() =
begin
filter(value != 0)
define(
digit => (value + 2) % 5 - 2)
define(
ch =>
digit == 2 ? "2" :
digit == 1 ? "1" :
digit == 0 ? "0" :
digit == -1 ? "-" :
digit == -2 ? "=" : missing)
define(
snafu => concat(ch, snafu),
value => (value - digit) / 5)
end
solve_part1() =
begin
parse_requirements()
define(value => as_bigint(0))
iterate(from_snafu_step())
filter(snafu == "")
group()
define(
value => sum(value),
snafu => "")
iterate(to_snafu_step())
filter(value == 0)
select(part1 => snafu)
end
solve_part2() =
select(part2 => missing)
solve_all() =
solve_part1().cross_join(solve_part2())
const q = solve_all()
end # @funsql
if isempty(ARGS)
println(FunSQL.render(q, dialect = :postgresql))
else
const db = DBInterface.connect(FunSQL.DB{LibPQ.Connection}, "")
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