aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Gia Phong <mcsinyx@disroot.org>2021-12-05 15:18:59 +0700
committerNguyễn Gia Phong <mcsinyx@disroot.org>2021-12-05 15:18:59 +0700
commit85bd7ec1bd9cdc7ec53692fce5cae3118b7357a0 (patch)
tree1880d6822b4c1e6d978abb0dda073dd42755efad
parent48f468b9b8a3f909b60399e277405b9723b8643a (diff)
downloadcp-85bd7ec1bd9cdc7ec53692fce5cae3118b7357a0.tar.gz
[aoc] Add first five/fifth
-rw-r--r--README.md14
-rw-r--r--aoc/2021/01/part-one.py6
-rw-r--r--aoc/2021/01/part-two.py8
-rw-r--r--aoc/2021/02/part-one.zig25
-rw-r--r--aoc/2021/02/part-two.zig27
-rw-r--r--aoc/2021/03/part-one.zig19
-rw-r--r--aoc/2021/03/part-two.raku8
-rw-r--r--aoc/2021/04/part-one.zig48
-rw-r--r--aoc/2021/04/part-two.zig48
-rw-r--r--aoc/2021/05/part-one.zig46
-rw-r--r--aoc/2021/05/part-two.zig48
11 files changed, 291 insertions, 6 deletions
diff --git a/README.md b/README.md
index 4ba11ad..5fd359d 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ this README as well as commit messages are duolingo (anglais et vietnamien).
| Thư mục | Nguồn đề bài |
| ------------ | ------------------------------------------------------ |
| `2ndary` | Secondary school competitions |
+| `aoc` | [Advent of Code][5] |
| `coci` | [Giải Tin học Croatia mở rộng][0] |
| `codechef` | [Codechef][2] |
| `codeforces` | [Codeforces][3] |
@@ -19,11 +20,12 @@ this README as well as commit messages are duolingo (anglais et vietnamien).
| `toys` | Programs that don't deserve their own repo |
| `usth` | L'Université des Sciences et des Technologies de Hanoï |
-[0]: http://www.hsin.hr/coci/
-[1]: http://laptrinh.ntu.edu.vn/
-[2]: http://codechef.com/
-[3]: http://codeforces.com/
-[4]: https://www.reddit.com/r/dailyprogrammer
+[0]: https://hsin.hr/coci
+[1]: http://laptrinh.ntu.edu.vn
+[2]: https://codechef.com
+[3]: https://codeforces.com
+[4]: https://reddit.com/r/dailyprogrammer
+[5]: https://adventofcode.com
Ở mỗi thư mục con sẽ có tệp `README.md` ghi lại đề bài. Riêng `coci`, `ntu` và
`codeforces` sẽ chỉ có danh sách đường dẫn tới các đề bài. Đề bài sẽ được cập
@@ -44,7 +46,7 @@ Phiên bản các trình dịch sử dụng test:
| Raku | Rakudo 2018.12+ |
| Rust | Rust 2018+ |
| Scheme | GNU Guile 2.0.11+ |
-| Zig | Zig 0.7.1+ |
+| Zig | Zig 0.8.1+ |
SICP không chỉ dùng Guile để chạy Scheme mà còn sử dụng Racket (`#lang sicp`)
trong các chương 1, 2 và 3.
diff --git a/aoc/2021/01/part-one.py b/aoc/2021/01/part-one.py
new file mode 100644
index 0000000..db9a650
--- /dev/null
+++ b/aoc/2021/01/part-one.py
@@ -0,0 +1,6 @@
+from itertools import tee
+from sys import stdin
+
+old, new = tee(map(int, stdin.read().strip().split()))
+next(new)
+print(sum(o < n for o, n in zip(old, new)))
diff --git a/aoc/2021/01/part-two.py b/aoc/2021/01/part-two.py
new file mode 100644
index 0000000..c8b0ac9
--- /dev/null
+++ b/aoc/2021/01/part-two.py
@@ -0,0 +1,8 @@
+from itertools import tee
+from sys import stdin
+
+old, new = tee(map(int, stdin.read().strip().split()))
+next(new)
+next(new)
+next(new)
+print(sum(o < n for o, n in zip(old, new)))
diff --git a/aoc/2021/02/part-one.zig b/aoc/2021/02/part-one.zig
new file mode 100644
index 0000000..68335d7
--- /dev/null
+++ b/aoc/2021/02/part-one.zig
@@ -0,0 +1,25 @@
+const eql = std.mem.eql;
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+ var position = @as(usize, 0);
+ var depth = @as(usize, 0);
+ defer print("{}\n", .{ position * depth });
+
+ var input = tokenize(@embedFile("input"), "\n");
+ while (input.next()) |line| {
+ var command = tokenize(line, " ");
+ const direction = command.next().?;
+ const x = try parseUnsigned(usize, command.next().?, 10);
+ if (eql(u8, direction, "forward"))
+ position += x
+ else if (eql(u8, direction, "down"))
+ depth += x
+ else if (eql(u8, direction, "up"))
+ depth -= x
+ else unreachable;
+ }
+}
diff --git a/aoc/2021/02/part-two.zig b/aoc/2021/02/part-two.zig
new file mode 100644
index 0000000..f597db6
--- /dev/null
+++ b/aoc/2021/02/part-two.zig
@@ -0,0 +1,27 @@
+const eql = std.mem.eql;
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+ var position = @as(usize, 0);
+ var depth = @as(usize, 0);
+ defer print("{}\n", .{ position * depth });
+
+ var aim = @as(usize, 0);
+ var input = tokenize(@embedFile("input"), "\n");
+ while (input.next()) |line| {
+ var command = tokenize(line, " ");
+ const direction = command.next().?;
+ const x = try parseUnsigned(usize, command.next().?, 10);
+ if (eql(u8, direction, "forward")) {
+ position += x;
+ depth += aim * x;
+ } else if (eql(u8, direction, "down")) {
+ aim += x;
+ } else if (eql(u8, direction, "up")) {
+ aim -= x;
+ } else unreachable;
+ }
+}
diff --git a/aoc/2021/03/part-one.zig b/aoc/2021/03/part-one.zig
new file mode 100644
index 0000000..6088925
--- /dev/null
+++ b/aoc/2021/03/part-one.zig
@@ -0,0 +1,19 @@
+const print = @import("std").debug.print;
+
+const input = @embedFile("input");
+const mean = @splat(12, @as(u16, '0' * 1000 + 500));
+const pos = @Vector(12, u4){ 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+pub fn main() !void {
+ var sum = @splat(12, @as(u16, 0));
+ var i = @as(usize, 0);
+ while (i < input.len) : (i += 13) {
+ var j = @as(usize, 0);
+ while (j < 12) : (j += 1)
+ sum[j] += input[i + j];
+ }
+
+ const common = @bitCast(@Vector(12, u1), sum > mean);
+ const gamma = @reduce(.Add, @as(@Vector(12, u12), common) << pos);
+ print("{}\n", .{ @as(usize, gamma) * ~gamma });
+}
diff --git a/aoc/2021/03/part-two.raku b/aoc/2021/03/part-two.raku
new file mode 100644
index 0000000..71464a2
--- /dev/null
+++ b/aoc/2021/03/part-two.raku
@@ -0,0 +1,8 @@
+sub filter(&op, @report, $column=0) {
+ return parse-base @report[0].join, 2 unless @report.elems > 1;
+ my $common = ([+] map *[$column], @report) > (@report.elems - 1) div 2;
+ filter &op, (grep { op $_[$column], $common }, @report), $column + 1
+}
+
+my $input = map *.comb, words slurp 'input';
+put [*] map { filter $_, $input }, (&infix:<==>, &infix:<!=>)
diff --git a/aoc/2021/04/part-one.zig b/aoc/2021/04/part-one.zig
new file mode 100644
index 0000000..67dc4e0
--- /dev/null
+++ b/aoc/2021/04/part-one.zig
@@ -0,0 +1,48 @@
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+ var boards: [100][5]@Vector(5, u16) = undefined;
+ var input = tokenize(@embedFile("input"), "\n");
+ var order = tokenize(input.next().?, ",");
+ var i = @as(usize, 0);
+ while (i < 100) : (i += 1) {
+ var j = @as(usize, 0);
+ while (j < 5) : (j += 1) {
+ var row = tokenize(input.next().?, " ");
+ var k = @as(usize, 0);
+ while (k < 5) : (k += 1)
+ boards[i][j][k] = 1 + try parseUnsigned(u16, row.next().?, 10);
+ }
+ }
+
+ const result = loop: while (i > 0) : (i -= 1) {
+ const n = 1 + try parseUnsigned(u16, order.next().?, 10);
+ var j = @as(usize, 0);
+ while (j < 100) : (j += 1) {
+ var u = @as(usize, 0);
+ var k = @as(usize, 0);
+ while (k < 5) : (k += 1) {
+ var l = @as(usize, 0);
+ while (l < 5) : (l += 1) {
+ if (boards[j][k][l] == n)
+ boards[j][k][l] = 0
+ else if (boards[j][k][l] > 0)
+ u += 1;
+ }
+ }
+
+ const b = boards[j];
+ const sum = b[0] + b[1] + b[2] + b[3] + b[4];
+ const result = (@reduce(.Add, sum) - u) * (n - 1);
+ if (@reduce(.Min, sum) == 0)
+ break :loop result;
+ for (b) |v|
+ if (@reduce(.Max, v) == 0)
+ break :loop result;
+ }
+ } else unreachable;
+ print("{}\n", .{ result });
+}
diff --git a/aoc/2021/04/part-two.zig b/aoc/2021/04/part-two.zig
new file mode 100644
index 0000000..ffe2c05
--- /dev/null
+++ b/aoc/2021/04/part-two.zig
@@ -0,0 +1,48 @@
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+pub fn main() !void {
+ var boards: [100][5]@Vector(5, u16) = undefined;
+ var input = tokenize(@embedFile("input"), "\n");
+ var order = tokenize(input.next().?, ",");
+ var i = @as(usize, 0);
+ while (i < 100) : (i += 1) {
+ var j = @as(usize, 0);
+ while (j < 5) : (j += 1) {
+ var row = tokenize(input.next().?, " ");
+ var k = @as(usize, 0);
+ while (k < 5) : (k += 1)
+ boards[i][j][k] = 1 + try parseUnsigned(u16, row.next().?, 10);
+ }
+ }
+
+ var won = @splat(100, false);
+ while (i > 0) : (i -= 1) {
+ const n = 1 + try parseUnsigned(u16, order.next().?, 10);
+ var j = @as(usize, 0);
+ while (j < 100) : (j += 1) {
+ var u = @as(usize, 0);
+ var k = @as(usize, 0);
+ while (k < 5) : (k += 1) {
+ var l = @as(usize, 0);
+ while (l < 5) : (l += 1) {
+ if (boards[j][k][l] == n)
+ boards[j][k][l] = 0
+ else if (boards[j][k][l] > 0)
+ u += 1;
+ }
+ }
+
+ const b = boards[j];
+ const sum = b[0] + b[1] + b[2] + b[3] + b[4];
+ won[j] = for (b) |v| {
+ if (@reduce(.Max, v) == 0)
+ break true;
+ } else @reduce(.Min, sum) == 0;
+ if (@reduce(.And, won))
+ return print("{}\n", .{ (@reduce(.Add, sum) - u) * (n - 1) });
+ }
+ }
+}
diff --git a/aoc/2021/05/part-one.zig b/aoc/2021/05/part-one.zig
new file mode 100644
index 0000000..95ad5a8
--- /dev/null
+++ b/aoc/2021/05/part-one.zig
@@ -0,0 +1,46 @@
+const allocator = std.heap.page_allocator;
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const set = std.mem.set;
+const swap = std.mem.swap;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+inline fn index(x: usize, y: usize) usize {
+ return x * 1000 + y;
+}
+
+pub fn main() !void {
+ const diagram = try allocator.alloc(u16, 1_000_000);
+ defer allocator.free(diagram);
+ set(u16, diagram, 0);
+
+ var input = tokenize(@embedFile("input"), "\n");
+ while (input.next()) |line| {
+ var segment = tokenize(line, " -> ");
+ var point = tokenize(segment.next().?, ",");
+ var x1 = try parseUnsigned(usize, point.next().?, 10);
+ var y1 = try parseUnsigned(usize, point.next().?, 10);
+ point = tokenize(segment.next().?, ",");
+ var x2 = try parseUnsigned(usize, point.next().?, 10);
+ var y2 = try parseUnsigned(usize, point.next().?, 10);
+
+ if (x1 > x2)
+ swap(usize, &x1, &x2);
+ if (y1 > y2)
+ swap(usize, &y1, &y2);
+
+ if (x1 == x2) {
+ while (y1 <= y2) : (y1 += 1)
+ diagram[index(x1, y1)] += 1;
+ } else if (y1 == y2) {
+ while (x1 <= x2) : (x1 += 1)
+ diagram[index(x1, y1)] += 1;
+ }
+ }
+
+ var result: usize = 0;
+ for (diagram) |point|
+ result += @boolToInt(point > 1);
+ print("{}\n", .{ result });
+}
diff --git a/aoc/2021/05/part-two.zig b/aoc/2021/05/part-two.zig
new file mode 100644
index 0000000..2c7ed83
--- /dev/null
+++ b/aoc/2021/05/part-two.zig
@@ -0,0 +1,48 @@
+const allocator = std.heap.page_allocator;
+const parseUnsigned = std.fmt.parseUnsigned;
+const print = std.debug.print;
+const set = std.mem.set;
+const swap = std.mem.swap;
+const std = @import("std");
+const tokenize = std.mem.tokenize;
+
+inline fn index(x: usize, y: usize) usize {
+ return x * 1000 + y;
+}
+
+pub fn main() !void {
+ const diagram = try allocator.alloc(u16, 1_000_000);
+ defer allocator.free(diagram);
+ set(u16, diagram, 0);
+
+ var input = tokenize(@embedFile("input"), "\n");
+ while (input.next()) |line| {
+ var segment = tokenize(line, " -> ");
+ var point = tokenize(segment.next().?, ",");
+ var x1 = try parseUnsigned(usize, point.next().?, 10);
+ var y1 = try parseUnsigned(usize, point.next().?, 10);
+ point = tokenize(segment.next().?, ",");
+ var x2 = try parseUnsigned(usize, point.next().?, 10);
+ var y2 = try parseUnsigned(usize, point.next().?, 10);
+
+ if (x1 == x2) {
+ if (y1 > y2) swap(usize, &y1, &y2);
+ while (y1 <= y2) : (y1 += 1)
+ diagram[index(x1, y1)] += 1;
+ } else if (y1 == y2) {
+ if (x1 > x2) swap(usize, &x1, &x2);
+ while (x1 <= x2) : (x1 += 1)
+ diagram[index(x1, y1)] += 1;
+ } else while (true) {
+ diagram[index(x1, y1)] += 1;
+ if (x1 == x2 or y1 == y2) break;
+ if (x1 > x2) x1 -= 1 else x1 += 1;
+ if (y1 > y2) y1 -= 1 else y1 += 1;
+ }
+ }
+
+ var result: usize = 0;
+ for (diagram) |point|
+ result += @boolToInt(point > 1);
+ print("{}\n", .{ result });
+}