From c2b2da271ba3c8a73f3b687e2b69b9e95bc5e6bf Mon Sep 17 00:00:00 2001
From: chylex <contact@chylex.com>
Date: Mon, 5 Dec 2022 03:21:16 +0100
Subject: [PATCH] Refactor 2017 code

---
 2017/01/main.sql          |  6 +++---
 2017/02/main.sql          | 19 +++++++------------
 2017/utils/procedures.sql | 14 ++++++++++++--
 3 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/2017/01/main.sql b/2017/01/main.sql
index e66d4ce..22c2503 100644
--- a/2017/01/main.sql
+++ b/2017/01/main.sql
@@ -1,4 +1,4 @@
-CALL aoc_text_file('01');
+CALL aoc_load_file_lines('01');
 
 CREATE TABLE "01.characters" AS
 	SELECT r.row - 1 AS index, r.character
@@ -9,7 +9,7 @@ CREATE UNIQUE INDEX "01.characters.index" ON "01.characters" (index);
 
 UPDATE "01.output"
 SET result = (
-	SELECT SUM(a.character::INTEGER) AS result
+	SELECT SUM(a.character::INT) AS result
 	FROM "01.characters" a
 	INNER JOIN "01.characters" b ON a.index = (b.index + 1) % (SELECT MAX(index) + 1 FROM "01.characters")
 	WHERE a.character = b.character
@@ -18,7 +18,7 @@ WHERE part = 1;
 
 UPDATE "01.output"
 SET result = (
-	SELECT SUM(a.character::INTEGER) AS result
+	SELECT SUM(a.character::INT) AS result
 	FROM "01.characters" a
 	INNER JOIN "01.characters" b ON a.index = (b.index + (SELECT (MAX(index) + 1) / 2 FROM "01.characters")) % (SELECT MAX(index) + 1 FROM "01.characters")
 	WHERE a.character = b.character
diff --git a/2017/02/main.sql b/2017/02/main.sql
index f72194f..dee7a78 100644
--- a/2017/02/main.sql
+++ b/2017/02/main.sql
@@ -1,24 +1,19 @@
-CALL aoc_text_file('02');
+CALL aoc_load_file_lines('02');
+CALL aoc_input_extract_cells('02', '\t', 'INT');
 
 UPDATE "02.output" SET result = (
 	SELECT SUM(row.difference)
 	FROM (
-		SELECT MAX(cell::INTEGER) - MIN(cell::INTEGER) AS difference
-		FROM "02.input"
-		CROSS JOIN REGEXP_SPLIT_TO_TABLE(input, '\t') cell
-		GROUP BY input
+		SELECT MAX(value::INT) - MIN(value::INT) AS difference
+		FROM "02.input.cells"
+		GROUP BY row
 	) row
 ) WHERE part = 1;
 
-CREATE TABLE "02.cells" AS
-	SELECT input.row, cell.col, cell.value::INTEGER
-	FROM (SELECT ROW_NUMBER() OVER () AS row, input AS line FROM "02.input") input
-	CROSS JOIN REGEXP_SPLIT_TO_TABLE(input.line, '\t') WITH ORDINALITY AS cell(value, col);
-
 UPDATE "02.output" SET result = (
 	SELECT SUM(a.value / b.value)
-	FROM "02.cells" a
-	INNER JOIN "02.cells" b ON a.row = b.row AND a.value != b.value AND a.value % b.value = 0
+	FROM "02.input.cells" a
+	INNER JOIN "02.input.cells" b ON a.row = b.row AND a.value != b.value AND a.value % b.value = 0
 ) WHERE part = 2;
 
 SELECT aoc_results('02');
diff --git a/2017/utils/procedures.sql b/2017/utils/procedures.sql
index 90f9b12..4128dfa 100644
--- a/2017/utils/procedures.sql
+++ b/2017/utils/procedures.sql
@@ -32,14 +32,24 @@ CREATE OR REPLACE FUNCTION aoc_results(day TEXT)
 AS
 $$
 BEGIN
-	RETURN QUERY EXECUTE FORMAT('SELECT CONCAT(''Part '', part, '' : '', result) FROM %I WHERE result IS NOT NULL ORDER BY part', day || '.output');
+	RETURN QUERY EXECUTE FORMAT('SELECT result FROM %I ORDER BY part', day || '.output');
 END
 $$ LANGUAGE plpgsql;
 
-CREATE OR REPLACE PROCEDURE aoc_text_file(day TEXT) AS
+CREATE OR REPLACE PROCEDURE aoc_load_file_lines(day TEXT) AS
 $$
 BEGIN
 	CALL aoc_setup_tables(day, 'input TEXT');
 	EXECUTE FORMAT('COPY %I FROM ''/aoc/%s/input.txt'' WITH DELIMITER E''\1''', day || '.input', day);
 END
 $$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE PROCEDURE aoc_input_extract_cells(day TEXT, delimiter TEXT, value_type TEXT) AS
+$$
+BEGIN
+	EXECUTE FORMAT('CREATE TABLE %I AS
+		SELECT input.row, cell.col, cell.value::%s
+		FROM (SELECT ROW_NUMBER() OVER () AS row, input AS line FROM %I) input
+		CROSS JOIN REGEXP_SPLIT_TO_TABLE(input.line, %L) WITH ORDINALITY AS cell(value, col)', day || '.input.cells', value_type, day || '.input', delimiter);
+END
+$$ LANGUAGE plpgsql;