88 lines
2.6 KiB
Markdown
88 lines
2.6 KiB
Markdown
|
---
|
||
|
permalink: "/{{ year }}/{{ month }}/{{ day }}/select-solution-from-aoc-where-year-2022"
|
||
|
title: "SELECT solution FROM aoc WHERE year = 2022"
|
||
|
published_date: "2022-12-09 11:20:00 +0100"
|
||
|
layout: post.liquid
|
||
|
data:
|
||
|
route: blog
|
||
|
---
|
||
|
|
||
|
Every year [Advent of Code][aoc] happens.
|
||
|
Every year I'm not super enthusiastic to actually solve those challenges.
|
||
|
Every year I still start (and then maybe stop after some days).
|
||
|
|
||
|
2022 was similar.
|
||
|
I don't have a new programming language to learn and I still write enough code day-by-day that more coding is not really necessary.
|
||
|
But yet sometimes it can be kind of nice to have a small challenge with a clear solution to go for
|
||
|
and so I set myself some rules and went ahead.
|
||
|
|
||
|
## My own rules
|
||
|
|
||
|
* Solve it in SQL.
|
||
|
* I started to run that in [BigQuery], but moved to [SQLite].
|
||
|
* Only the SQL the system provides. How far can I take this?
|
||
|
* It was easier on BigQuery with its large base of functionality, including string procesing, arrays, structs, ...
|
||
|
* On SQLite initially I tried to avoid any custom functionality, I later relaxed this rule: [SQLean] is okay occasionally.
|
||
|
* Once (so far) I used Python to preprocess the data. SQL is just really not good at text processing.
|
||
|
* Getting the solution once is good enough.
|
||
|
* The code can be ugly, messy and inefficient.
|
||
|
* I don't write tests.
|
||
|
* I do test. Just manually against the test input.
|
||
|
* No persistent data.
|
||
|
* It's all in-memory tables, CTEs, temporary views and a bunch of `SELECT`.
|
||
|
* Learn some arcane SQL features.
|
||
|
* Did you know SQL can recurse and select over windows? I do now!
|
||
|
|
||
|
These are my rules. I break them when I feel like it.
|
||
|
|
||
|
[AoC]: https://adventofcode.com/
|
||
|
[bigquery]: https://cloud.google.com/bigquery/
|
||
|
[sqlite]: https://sqlite.org/
|
||
|
[sqlean]: https://github.com/nalgeon/sqlean
|
||
|
|
||
|
## Sneak peek of day 1
|
||
|
|
||
|
`SELECT solution FROM aoc WHERE year = 2022 AND day = 1;`
|
||
|
|
||
|
I plan to release my solutions publicly, but I haven't yet.
|
||
|
So for now you get my solution to day 1:
|
||
|
|
||
|
```sql
|
||
|
CREATE TABLE data(raw);
|
||
|
.import input01.txt data
|
||
|
WITH
|
||
|
groups AS (
|
||
|
SELECT rowid, ROW_NUMBER() OVER (ORDER BY rowid) cat FROM data WHERE raw = ''
|
||
|
),
|
||
|
elves AS (
|
||
|
SELECT
|
||
|
COALESCE(
|
||
|
(SELECT cat FROM groups WHERE data.rowid < groups.rowid LIMIT 1),
|
||
|
(SELECT cat + 1 FROM groups ORDER BY cat DESC LIMIT 1)
|
||
|
) AS elf,
|
||
|
raw as calories
|
||
|
FROM data WHERE raw != ''
|
||
|
),
|
||
|
part1 AS (
|
||
|
SELECT
|
||
|
elf,
|
||
|
SUM(calories) AS total_calories
|
||
|
FROM elves
|
||
|
GROUP BY 1
|
||
|
ORDER BY 2 DESC
|
||
|
)
|
||
|
|
||
|
--SELECT * FROM part1;
|
||
|
SELECT SUM(total_calories) as best_3 FROM (
|
||
|
SELECT * FROM part1 LIMIT 3
|
||
|
);
|
||
|
```
|
||
|
|
||
|
Runnable as:
|
||
|
|
||
|
```
|
||
|
sqlite3 < aoc01.sql
|
||
|
```
|
||
|
|
||
|
(Oh, another rule: It needs to run as `sqlite3 < script.sql`)
|