summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--2020/day16.c55
-rw-r--r--2020/day16.pl30
2 files changed, 55 insertions, 30 deletions
diff --git a/2020/day16.c b/2020/day16.c
new file mode 100644
index 0000000..6b3d29e
--- /dev/null
+++ b/2020/day16.c
@@ -0,0 +1,55 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+static struct Rule {
+	char name[32];
+	int a[2];
+	int b[2];
+} rules[32];
+static int nrules;
+struct Ticket {
+	int fields[32];
+};
+static bool parse(struct Ticket *ticket) {
+	for (int i = 0; i < nrules; ++i) {
+		if (scanf("%d,", &ticket->fields[i]) < 1) return false;
+	}
+	scanf("\n");
+	return true;
+}
+static bool check(const struct Rule *rule, int field) {
+	return (field >= rule->a[0] && field <= rule->a[1])
+		|| (field >= rule->b[0] && field <= rule->b[1]);
+}
+int main(void) {
+	for (;;) {
+		struct Rule rule;
+		scanf("%[^:]: ", rule.name);
+		if (!strcmp(rule.name, "your ticket")) break;
+		scanf(
+			"%d-%d or %d-%d\n",
+			&rule.a[0], &rule.a[1], &rule.b[0], &rule.b[1]
+		);
+		rules[nrules++] = rule;
+	}
+	struct Ticket mine;
+	parse(&mine);
+	scanf("nearby tickets:\n");
+	struct Ticket nearby[256];
+	int len;
+	for (len = 0; parse(&nearby[len]); ++len);
+	int error = 0;
+	for (int i = 0; i < len; ++i) {
+		for (int j = 0; j < nrules; ++j) {
+			bool valid = false;
+			for (int r = 0; r < nrules; ++r) {
+				if (!check(&rules[r], nearby[i].fields[j])) continue;
+				valid = true;
+				break;
+			}
+			if (!valid) error += nearby[i].fields[j];
+		}
+	}
+	printf("%d\n", error);
+}
diff --git a/2020/day16.pl b/2020/day16.pl
deleted file mode 100644
index 8ebe521..0000000
--- a/2020/day16.pl
+++ /dev/null
@@ -1,30 +0,0 @@
-use strict;
-use warnings;
-
-my (%rules, @ticket, @nearby);
-while (<>) {
-	chomp;
-	if (/([^:]+): (\d+)-(\d+) or (\d+)-(\d+)/) {
-		$rules{$1} = [$2, $3, $4, $5];
-	} elsif (/your ticket:/) {
-		<>;
-		chomp;
-		@ticket = split ',';
-	} elsif (/^[\d,]+$/) {
-		my @fields = split ',';
-		push @nearby, \@fields;
-	}
-}
-
-my $error = 0;
-foreach my $t (@nearby) {
-	foreach my $f (@$t) {
-		my $valid = 0;
-		foreach my $r (values %rules) {
-			$valid = 1 if $f >= $$r[0] && $f <= $$r[1];
-			$valid = 1 if $f >= $$r[2] && $f <= $$r[3];
-		}
-		$error += $f unless $valid;
-	}
-}
-print "$error\n";