aboutsummaryrefslogtreecommitdiff
path: root/2022
diff options
context:
space:
mode:
Diffstat (limited to '2022')
-rw-r--r--2022/01/a.rs8
-rw-r--r--2022/01/b.rs9
-rw-r--r--2022/01/common.rs18
-rw-r--r--2022/02/a.rs13
-rw-r--r--2022/02/b.rs13
-rw-r--r--2022/02/common.rs10
-rw-r--r--2022/03/a.rs26
-rw-r--r--2022/03/b.rs29
-rw-r--r--2022/03/common.rs7
-rw-r--r--2022/04/a.rs7
-rw-r--r--2022/04/b.rs8
-rw-r--r--2022/04/common.rs20
-rw-r--r--2022/05/a.rs17
-rw-r--r--2022/05/b.rs20
-rw-r--r--2022/05/common.rs73
-rw-r--r--2022/06/a.rs9
-rw-r--r--2022/06/b.rs9
-rw-r--r--2022/06/common.rs20
-rw-r--r--2022/07/a.rs12
-rw-r--r--2022/07/b.rs13
-rw-r--r--2022/07/common.rs130
-rw-r--r--2022/08/a.rs42
-rw-r--r--2022/08/b.rs47
-rw-r--r--2022/08/common.rs13
-rw-r--r--2022/09/a.rs6
-rw-r--r--2022/09/b.rs6
-rw-r--r--2022/09/common.rs46
-rw-r--r--2022/README.md12
-rwxr-xr-x2022/run.sh12
29 files changed, 655 insertions, 0 deletions
diff --git a/2022/01/a.rs b/2022/01/a.rs
new file mode 100644
index 0000000..77e57e4
--- /dev/null
+++ b/2022/01/a.rs
@@ -0,0 +1,8 @@
1mod common;
2use common::*;
3
4fn main() {
5 let e = get_elves_from_stdin();
6 let m: i64 = e.iter().map(|a| a.iter().sum()).max().unwrap();
7 println!("{m}");
8}
diff --git a/2022/01/b.rs b/2022/01/b.rs
new file mode 100644
index 0000000..ca0b324
--- /dev/null
+++ b/2022/01/b.rs
@@ -0,0 +1,9 @@
1mod common;
2use common::*;
3
4fn main() {
5 let e = get_elves_from_stdin();
6 let mut w = e.iter().map(|a| a.iter().sum()).collect::<Vec<i64>>();
7 w.sort_by(|a, b| b.cmp(a));
8 println!("{}", w[0] + w[1] + w[2]);
9}
diff --git a/2022/01/common.rs b/2022/01/common.rs
new file mode 100644
index 0000000..8ed8b49
--- /dev/null
+++ b/2022/01/common.rs
@@ -0,0 +1,18 @@
1pub fn get_elves_from_stdin() -> Vec<Vec<i64>> {
2 let mut e = Vec::<Vec::<i64>>::new();
3 e.push(Vec::<i64>::new());
4 let mut line = String::new();
5 loop {
6 match std::io::stdin().read_line(&mut line).unwrap() {
7 0 => break,
8 1 => e.push(Vec::<i64>::new()),
9 _ => {
10 let n = line.trim().parse::<i64>().unwrap();
11 let last = e.len() - 1;
12 e[last].push(n);
13 }
14 }
15 line.clear();
16 }
17 e
18}
diff --git a/2022/02/a.rs b/2022/02/a.rs
new file mode 100644
index 0000000..1a49a6b
--- /dev/null
+++ b/2022/02/a.rs
@@ -0,0 +1,13 @@
1mod common;
2use common::*;
3
4pub fn main() {
5 let play_score = |s: &[u8]| (s[2] as i64) - ('X' as i64) + 1;
6 let win_score = |s: &[u8]| {
7 let other = s[0] as i64 - ('A' as i64);
8 let me = s[2] as i64 - ('X' as i64);
9 3 * ((me - other + 4) % 3)
10 };
11 let score = get_score(play_score, win_score);
12 println!("{score}");
13}
diff --git a/2022/02/b.rs b/2022/02/b.rs
new file mode 100644
index 0000000..9f2b580
--- /dev/null
+++ b/2022/02/b.rs
@@ -0,0 +1,13 @@
1mod common;
2use common::*;
3
4pub fn main() {
5 let play_score = |s: &[u8]| {
6 let other = s[0] as i64 - ('A' as i64);
7 let w = s[2] as i64 - ('X' as i64);
8 (other + w + 2) % 3 + 1
9 };
10 let win_score = |s: &[u8]| 3 * ((s[2] as i64) - ('X' as i64));
11 let score = get_score(play_score, win_score);
12 println!("{score}");
13}
diff --git a/2022/02/common.rs b/2022/02/common.rs
new file mode 100644
index 0000000..04581cf
--- /dev/null
+++ b/2022/02/common.rs
@@ -0,0 +1,10 @@
1pub fn get_score(play_score: fn(&[u8]) -> i64, win_score: fn(&[u8]) -> i64) -> i64 {
2 let mut score = 0;
3 let mut line = String::new();
4 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
5 let l = line.as_bytes();
6 score += play_score(l) + win_score(l);
7 line.clear();
8 }
9 score
10}
diff --git a/2022/03/a.rs b/2022/03/a.rs
new file mode 100644
index 0000000..568546c
--- /dev/null
+++ b/2022/03/a.rs
@@ -0,0 +1,26 @@
1mod common;
2use common::*;
3
4fn get_rep_val(rucksack: &[u8]) -> i64 {
5 let mut seen = [false; 256];
6 let mid = rucksack.len()/2;
7 for i in 0..mid {
8 seen[rucksack[i] as usize] = true;
9 }
10 for i in mid..rucksack.len() {
11 if seen[rucksack[i] as usize] {
12 return value(rucksack[i] as char);
13 }
14 }
15 panic!("Could not find repeated char");
16}
17
18fn main() {
19 let mut sum = 0;
20 let mut line = String::new();
21 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
22 sum += get_rep_val(line.as_bytes());
23 line.clear();
24 }
25 println!("{sum}");
26}
diff --git a/2022/03/b.rs b/2022/03/b.rs
new file mode 100644
index 0000000..89da764
--- /dev/null
+++ b/2022/03/b.rs
@@ -0,0 +1,29 @@
1mod common;
2use common::*;
3
4fn get_rep_val(e: &[String; 3]) -> i64 {
5 let mut seen = [[false; 256]; 2];
6 for i in 0..2 {
7 for c in e[i].chars() {
8 seen[i][c as usize] = true;
9 }
10 }
11 for c in e[2].chars() {
12 if seen[0][c as usize] && seen[1][c as usize] {
13 return value(c);
14 }
15 }
16 panic!("Could not find repeated char");
17}
18
19fn main() {
20 let mut sum = 0;
21 let mut lines: [String; 3] = Default::default();
22 while std::io::stdin().read_line(&mut lines[0]).unwrap() > 0 {
23 let _ = std::io::stdin().read_line(&mut lines[1]);
24 let _ = std::io::stdin().read_line(&mut lines[2]);
25 sum += get_rep_val(&lines);
26 for l in &mut lines { l.clear(); }
27 }
28 println!("{sum}");
29}
diff --git a/2022/03/common.rs b/2022/03/common.rs
new file mode 100644
index 0000000..cf323f5
--- /dev/null
+++ b/2022/03/common.rs
@@ -0,0 +1,7 @@
1pub fn value(c: char) -> i64 {
2 match c {
3 'a'..='z' => (c as i64) - ('a' as i64) + 1,
4 'A'..='Z' => (c as i64) - ('A' as i64) + 27,
5 _ => panic!("Error: unexpected character '{}'", c)
6 }
7}
diff --git a/2022/04/a.rs b/2022/04/a.rs
new file mode 100644
index 0000000..d69821a
--- /dev/null
+++ b/2022/04/a.rs
@@ -0,0 +1,7 @@
1mod common;
2use common::*;
3
4fn main() {
5 let contained = |a: (i64, i64), b: (i64, i64)| a.0 >= b.0 && a.1 <= b.1;
6 println!("{}", count(|a, b| contained(a, b) || contained(b, a)));
7}
diff --git a/2022/04/b.rs b/2022/04/b.rs
new file mode 100644
index 0000000..2affb65
--- /dev/null
+++ b/2022/04/b.rs
@@ -0,0 +1,8 @@
1mod common;
2use common::*;
3
4fn main() {
5 let overlap = |a: (i64, i64), b: (i64, i64)|
6 (a.0 >= b.0 && a.0 <= b.1) || (b.0 >= a.0 && b.0 <= a.1);
7 println!("{}", count(overlap));
8}
diff --git a/2022/04/common.rs b/2022/04/common.rs
new file mode 100644
index 0000000..92c32f1
--- /dev/null
+++ b/2022/04/common.rs
@@ -0,0 +1,20 @@
1fn get_ints(line: &str) -> ((i64, i64), (i64, i64)) {
2 let i = line.find('-').unwrap();
3 let j = line.find(',').unwrap();
4 let k = line[j..].find('-').unwrap() + j;
5 ((line[..i].parse().unwrap(), line[i+1..j].parse().unwrap()),
6 (line[j+1..k].parse().unwrap(), line[k+1..line.len()-1].parse().unwrap()))
7}
8
9pub fn count<F: Fn((i64, i64), (i64, i64)) -> bool>(condition: F) -> i64 {
10 let mut line = String::new();
11 let mut sum = 0;
12 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
13 let (a, b) = get_ints(&line);
14 if condition(a, b) {
15 sum += 1;
16 }
17 line.clear();
18 }
19 sum
20}
diff --git a/2022/05/a.rs b/2022/05/a.rs
new file mode 100644
index 0000000..ae0e937
--- /dev/null
+++ b/2022/05/a.rs
@@ -0,0 +1,17 @@
1mod common;
2use common::*;
3
4fn apply_move(grid: &mut Vec::<Vec::<char>>, line: &str) {
5 let (n, from, to) = read_move(&line);
6
7 for _ in 0..n {
8 let x = grid[from-1].pop().unwrap();
9 grid[to-1].push(x);
10 }
11}
12
13fn main() {
14 let mut grid = get_grid_from_stdin();
15 apply_moves_from_stdin(&mut grid, apply_move);
16 print_top(&grid);
17}
diff --git a/2022/05/b.rs b/2022/05/b.rs
new file mode 100644
index 0000000..824ee5e
--- /dev/null
+++ b/2022/05/b.rs
@@ -0,0 +1,20 @@
1mod common;
2use common::*;
3
4fn apply_move(grid: &mut Vec::<Vec::<char>>, line: &str) {
5 let (n, from, to) = read_move(&line);
6
7 let first_moved = grid[from-1].len()-n;
8 let len = grid[from-1].len();
9 for i in first_moved..len {
10 let x = grid[from-1][i];
11 grid[to-1].push(x);
12 }
13 grid[from-1].drain(first_moved..len);
14}
15
16fn main() {
17 let mut grid = get_grid_from_stdin();
18 apply_moves_from_stdin(&mut grid, apply_move);
19 print_top(&grid);
20}
diff --git a/2022/05/common.rs b/2022/05/common.rs
new file mode 100644
index 0000000..1725f09
--- /dev/null
+++ b/2022/05/common.rs
@@ -0,0 +1,73 @@
1pub type Grid = Vec<Vec<char>>;
2
3fn read_rows() -> Vec<Vec<char>> {
4 let mut rows = Vec::<Vec::<char>>::new();
5 let mut line = String::new();
6 loop {
7 let mut row = Vec::<char>::new();
8
9 std::io::stdin().read_line(&mut line).unwrap();
10 let line_chars = line.as_bytes();
11 if line_chars[1] == '1' as u8 {
12 let _ = std::io::stdin().read_line(&mut line);
13 break;
14 }
15
16 let mut i = 0;
17 while i < line_chars.len() {
18 row.push(line_chars[i+1] as char);
19 i += 4;
20 }
21
22 rows.push(row);
23 line.clear();
24 }
25
26 rows
27}
28
29fn rows_to_grid(rows: &Vec<Vec<char>>) -> Grid {
30 let mut grid = vec![Vec::<char>::new(); rows[0].len()];
31 for row in rows.iter().rev() {
32 for i in 0..row.len() {
33 if row[i] != ' ' {
34 grid[i].push(row[i]);
35 }
36 }
37 }
38 grid
39}
40
41fn next_usize(line: &str, s: usize) -> (usize, usize) {
42 let i = line[s..].find(|c: char| c.is_digit(10)).unwrap() + s;
43 let j = line[i..].find(|c: char| c.is_whitespace()).unwrap() + i;
44 (line[i..j].parse::<usize>().unwrap(), j)
45}
46
47pub fn read_move(line: &str) -> (usize, usize, usize) {
48 let (n, i) = next_usize(line, 0);
49 let (from, i) = next_usize(line, i);
50 let (to, _) = next_usize(line, i);
51
52 (n, from, to)
53}
54
55pub fn get_grid_from_stdin() -> Grid {
56 rows_to_grid(&read_rows())
57}
58
59pub fn apply_moves_from_stdin<F: Fn(&mut Grid, &str) -> ()>(grid: &mut Grid, apply_move: F) {
60 let mut line = String::new();
61 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
62 apply_move(grid, &line);
63 line.clear();
64 }
65}
66
67pub fn print_top(grid: &Grid) {
68 for column in grid {
69 let c = match column.last() { Some(d) => d, None => &'_' };
70 print!("{}", c);
71 }
72 println!();
73}
diff --git a/2022/06/a.rs b/2022/06/a.rs
new file mode 100644
index 0000000..996f9a5
--- /dev/null
+++ b/2022/06/a.rs
@@ -0,0 +1,9 @@
1mod common;
2use common::*;
3
4fn main() {
5 let mut line = String::new();
6 std::io::stdin().read_line(&mut line).unwrap();
7 let i = first_index_n_distinct(line.as_bytes(), 4) + 1;
8 println!("{i}");
9}
diff --git a/2022/06/b.rs b/2022/06/b.rs
new file mode 100644
index 0000000..78d2703
--- /dev/null
+++ b/2022/06/b.rs
@@ -0,0 +1,9 @@
1mod common;
2use common::*;
3
4fn main() {
5 let mut line = String::new();
6 std::io::stdin().read_line(&mut line).unwrap();
7 let i = first_index_n_distinct(line.as_bytes(), 14) + 1;
8 println!("{i}");
9}
diff --git a/2022/06/common.rs b/2022/06/common.rs
new file mode 100644
index 0000000..ed5360c
--- /dev/null
+++ b/2022/06/common.rs
@@ -0,0 +1,20 @@
1fn all_distinct<T: PartialEq>(a: &[T]) -> bool {
2 for i in 0..a.len() {
3 for j in i+1..a.len() {
4 if a[i] == a[j] {
5 return false;
6 }
7 }
8 }
9 return true;
10}
11
12pub fn first_index_n_distinct(a: &[u8], n: usize) -> usize {
13 assert!(n > 0, "{} must be greater than 0", n);
14 for i in 0..a.len()-n+1 {
15 if all_distinct(&a[i..i+n]) {
16 return i+n-1;
17 }
18 }
19 panic!("Cannot find {} distinct in a row", n);
20}
diff --git a/2022/07/a.rs b/2022/07/a.rs
new file mode 100644
index 0000000..a0d9a1a
--- /dev/null
+++ b/2022/07/a.rs
@@ -0,0 +1,12 @@
1mod common;
2use common::*;
3
4fn main() {
5 let fs = FileSystem::build_from_stdin();
6 let sum: usize = fs.iter()
7 .filter(|f| matches!(f.kind, FileType::Directory(_)))
8 .map(|f| f.real_size(&fs))
9 .filter(|s| *s <= 100000)
10 .sum();
11 println!("{sum}");
12}
diff --git a/2022/07/b.rs b/2022/07/b.rs
new file mode 100644
index 0000000..92bedc7
--- /dev/null
+++ b/2022/07/b.rs
@@ -0,0 +1,13 @@
1mod common;
2use common::*;
3
4fn main() {
5 let fs = FileSystem::build_from_stdin();
6 let remaining = 70000000 - fs[0].real_size(&fs);
7 let ds: usize = fs.iter()
8 .filter(|f| matches!(f.kind, FileType::Directory(_)))
9 .map(|f| f.real_size(&fs))
10 .filter(|s| *s + remaining >= 30000000)
11 .min().unwrap();
12 println!("{ds}");
13}
diff --git a/2022/07/common.rs b/2022/07/common.rs
new file mode 100644
index 0000000..675bf29
--- /dev/null
+++ b/2022/07/common.rs
@@ -0,0 +1,130 @@
1use std::ops;
2
3pub enum FileType {
4 File(usize),
5 Directory(Vec<usize>)
6}
7
8pub struct File {
9 pub kind: FileType,
10 name: String
11}
12
13impl File {
14 pub fn real_size(&self, fs: &FileSystem) -> usize {
15 match &self.kind {
16 FileType::File(s) => *s,
17 FileType::Directory(c) =>
18 c.iter().map(|x: &usize| fs[*x].real_size(&fs)).sum()
19 }
20 }
21}
22
23pub struct FileSystem {
24 files: Vec<File>
25}
26
27impl FileSystem {
28 fn new() -> Self {
29 Self {
30 files: vec![File {
31 kind: FileType::Directory(Vec::<usize>::new()),
32 name: String::from("/")
33 }]
34 }
35 }
36
37 pub fn build_from_stdin() -> Self {
38 let mut fs = FileSystem::new();
39 let mut path = Path::new();
40 let mut line = String::new();
41 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
42 if &line[..5] == "$ cd " {
43 exec_cd(&line[5..], &mut path, &fs);
44 } else if &line[..3] == "dir" {
45 fs.add_dir(&line[4..line.len()-1], path.last());
46 } else if line.as_bytes()[0] != '$' as u8 {
47 let i = line.find(' ').unwrap();
48 let size = line[0..i].parse::<usize>().unwrap();
49 fs.add_file(&line[i+1..line.len()-1], size, path.last());
50 }
51 line.clear();
52 }
53 fs
54 }
55
56 fn make_parent(&mut self, id: usize, parent: usize) {
57 let p = &mut self.files[parent];
58 if let FileType::Directory(v) = &mut p.kind {
59 v.push(id);
60 } else {
61 panic!("Parent is not a directory");
62 }
63 }
64
65 fn add_dir(&mut self, name: &str, parent: usize) {
66 let id = self.files.len();
67 self.files.push(
68 File {
69 kind: FileType::Directory(Vec::<usize>::new()),
70 name: String::from(name)
71 }
72 );
73 self.make_parent(id, parent);
74 }
75
76 fn add_file(&mut self, name: &str, size: usize, parent: usize) {
77 let id = self.files.len();
78 self.files.push(
79 File {
80 kind: FileType::File(size),
81 name: String::from(name)
82 }
83 );
84 self.make_parent(id, parent);
85 }
86
87 pub fn iter(&self) -> impl Iterator<Item = &File>{
88 self.files.iter()
89 }
90}
91
92impl ops::Index<usize> for FileSystem {
93 type Output = File;
94 fn index(&self, i: usize) -> &File {
95 &self.files[i]
96 }
97}
98
99struct Path {
100 stack: Vec<usize>
101}
102
103impl Path {
104 fn new() -> Self { Self { stack: vec![0] } } // 0 is the id of "/"
105 fn last(&self) -> usize { *self.stack.last().unwrap() }
106 fn clear(&mut self) { self.stack.drain(1..); }
107 fn pop(&mut self) { self.stack.pop(); }
108 fn push(&mut self, dir_id: usize) { self.stack.push(dir_id); }
109}
110
111fn exec_cd(line: &str, path: &mut Path, fs: &FileSystem) {
112 if line.as_bytes()[0] == '/' as u8 {
113 path.clear();
114 } else if &line[..2] == ".." {
115 path.pop();
116 } else {
117 let current_dir = &fs[path.last()];
118 if let FileType::Directory(children) = &current_dir.kind {
119 for c in children {
120 if fs[*c].name == &line[..line.len()-1] {
121 path.push(*c);
122 return;
123 }
124 }
125 } else {
126 panic!("Non-directory in path");
127 }
128 panic!("Directory not found in current path");
129 }
130}
diff --git a/2022/08/a.rs b/2022/08/a.rs
new file mode 100644
index 0000000..b145486
--- /dev/null
+++ b/2022/08/a.rs
@@ -0,0 +1,42 @@
1use std::cmp::max;
2mod common;
3use common::*;
4
5fn mark_visible(grid: &mut Grid) {
6 let update = |elem: &mut (i8, bool), m: &mut i8| {
7 elem.1 = elem.1 || elem.0 > *m;
8 *m = max(*m, elem.0);
9 };
10
11 for row in &mut *grid {
12 // From left
13 let mut m = -1;
14 for t in &mut *row { update(t, &mut m); }
15
16 // From right
17 let mut m = -1;
18 for t in &mut row.iter_mut().rev() { update(t, &mut m); }
19 }
20
21 for j in 0..grid[0].len() {
22 // From top
23 let mut m = -1;
24 for i in 0..grid.len() { update(&mut grid[i][j], &mut m); }
25
26 // From bottom
27 let mut m = -1;
28 for i in (0..grid.len()).rev() { update(&mut grid[i][j], &mut m); }
29 }
30}
31
32fn count_visible(grid: &Grid) -> usize {
33 grid.iter()
34 .map(|row| row.iter().filter(|c| c.1).count())
35 .sum()
36}
37
38fn main() {
39 let mut grid = read_grid_from_stdin();
40 mark_visible(&mut grid);
41 println!("{}", count_visible(&grid));
42}
diff --git a/2022/08/b.rs b/2022/08/b.rs
new file mode 100644
index 0000000..5f7bce8
--- /dev/null
+++ b/2022/08/b.rs
@@ -0,0 +1,47 @@
1use std::cmp::max;
2mod common;
3use common::*;
4
5fn count_visible_from(grid: &Grid, i0: usize, j0: usize) -> usize {
6 let x = grid[i0][j0].0;
7 let mut top = 0;
8 for i in (0..i0).rev() {
9 top += 1;
10 if grid[i][j0].0 >= x { break; }
11 }
12
13 let mut bottom = 0;
14 for i in i0+1..grid.len() {
15 bottom += 1;
16 if grid[i][j0].0 >= x { break; }
17 }
18
19 let mut left = 0;
20 for j in (0..j0).rev() {
21 left += 1;
22 if grid[i0][j].0 >= x { break; }
23 }
24
25 let mut right = 0;
26 for j in j0+1..grid[0].len() {
27 right += 1;
28 if grid[i0][j].0 >= x { break; }
29 }
30
31 top * bottom * left * right
32}
33
34fn max_view_factor(grid: &Grid) -> usize {
35 let mut m = 0;
36 for i in 0..grid.len() {
37 for j in 0..grid[0].len() {
38 m = max(m, count_visible_from(grid, i, j));
39 }
40 }
41 m
42}
43
44fn main() {
45 let grid = read_grid_from_stdin();
46 println!("{}", max_view_factor(&grid));
47}
diff --git a/2022/08/common.rs b/2022/08/common.rs
new file mode 100644
index 0000000..45fbf10
--- /dev/null
+++ b/2022/08/common.rs
@@ -0,0 +1,13 @@
1pub type Grid = Vec<Vec<(i8, bool)>>;
2
3pub fn read_grid_from_stdin() -> Grid {
4 let mut grid = Vec::<Vec<(i8, bool)>>::new();
5 let mut line = String::new();
6 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
7 let row = line[..line.len()-1].as_bytes().iter()
8 .map(|b| ((*b as i8) - ('0' as i8), false)).collect();
9 grid.push(row);
10 line.clear();
11 }
12 grid
13}
diff --git a/2022/09/a.rs b/2022/09/a.rs
new file mode 100644
index 0000000..0fc6278
--- /dev/null
+++ b/2022/09/a.rs
@@ -0,0 +1,6 @@
1mod common;
2use common::*;
3
4fn main() {
5 println!("{}", simulate(2).len());
6}
diff --git a/2022/09/b.rs b/2022/09/b.rs
new file mode 100644
index 0000000..1d43500
--- /dev/null
+++ b/2022/09/b.rs
@@ -0,0 +1,6 @@
1mod common;
2use common::*;
3
4fn main() {
5 println!("{}", simulate(10).len());
6}
diff --git a/2022/09/common.rs b/2022/09/common.rs
new file mode 100644
index 0000000..45048da
--- /dev/null
+++ b/2022/09/common.rs
@@ -0,0 +1,46 @@
1use std::collections::HashSet;
2
3fn get_dir(c: char) -> (i64, i64) {
4 match c {
5 'R' => (1, 0),
6 'L' => (-1, 0),
7 'U' => (0, 1),
8 'D' => (0, -1),
9 _ => panic!("Unexpected char")
10 }
11}
12
13fn follow(lead: (i64, i64), trail: (i64, i64)) -> (i64, i64) {
14 let max1 = |x: i64| x / (2 - (x%2).abs());
15 let d = (max1(lead.0 - trail.0), max1(lead.1 - trail.1));
16 (trail.0 + d.0, trail.1 + d.1)
17}
18
19fn step(r: &mut Vec<(i64, i64)>, d: (i64, i64)) {
20 r[0] = (r[0].0 + d.0, r[0].1 + d.1);
21 for i in 1..r.len() {
22 if (r[i].0 - r[i-1].0).abs() > 1 || (r[i].1 - r[i-1].1).abs() > 1 {
23 r[i] = follow(r[i-1], r[i]);
24 } else {
25 break;
26 }
27 }
28}
29
30pub fn simulate(n: usize) -> HashSet<(i64, i64)> {
31 let mut r = vec![(0, 0); n];
32 let mut visited = HashSet::<(i64, i64)>::new();
33 visited.insert(r[n-1]);
34
35 let mut line = String::new();
36 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
37 let dir = get_dir(line.chars().nth(0).unwrap());
38 let l = line[2..line.len()-1].parse::<usize>().unwrap();
39 for _ in 0..l {
40 step(&mut r, dir);
41 visited.insert(r[n-1]);
42 }
43 line.clear();
44 }
45 visited
46}
diff --git a/2022/README.md b/2022/README.md
new file mode 100644
index 0000000..1e134bd
--- /dev/null
+++ b/2022/README.md
@@ -0,0 +1,12 @@
1# Advent of Code 2022
2
3I did not solve these problems in 2022, but in 2025, as a playground
4to learn Rust.
5
6## Usage
7
8To run this code you'll need the `rustc` compiler (no `cargo`).
9
10From this folder run: `./run.sh day part`, for example `./run.sh 03 a`.
11Input is read from standard input; paste your input in the terminal or
12read it from a file with e.g. `<input.txt`.
diff --git a/2022/run.sh b/2022/run.sh
new file mode 100755
index 0000000..56e1177
--- /dev/null
+++ b/2022/run.sh
@@ -0,0 +1,12 @@
1#!/bin/sh
2
3usage() {
4 echo "Usage: $0 day part"
5 echo "Example: $0 07 b"
6}
7
8[ -n "$1" ] && [ -n "$2" ] || (usage; exit 1)
9[ -d "$1" ] || (echo "Directory $1 does not exist"; exit 1)
10[ -f "$1/$2.rs" ] || (echo "File $1/$2.rs does not exist"; exit 2)
11
12rustc "$1/$2.rs" -o "$1/$2.out" && time "./$1/$2.out"

Generated with cgit - Back to sebastiano.tronto.net