commit a5b5bcfc3bdc7e933cabf64d87e4060e0b3e6265 Author: shoofle Date: Sat Dec 9 23:43:09 2023 -0500 added all the stuff diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..162238c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/*.input diff --git a/__pycache__/aoc_01.cpython-311.pyc b/__pycache__/aoc_01.cpython-311.pyc new file mode 100644 index 0000000..fa4b124 Binary files /dev/null and b/__pycache__/aoc_01.cpython-311.pyc differ diff --git a/__pycache__/aoc_02.cpython-311.pyc b/__pycache__/aoc_02.cpython-311.pyc new file mode 100644 index 0000000..01169b0 Binary files /dev/null and b/__pycache__/aoc_02.cpython-311.pyc differ diff --git a/__pycache__/aoc_05.cpython-311.pyc b/__pycache__/aoc_05.cpython-311.pyc new file mode 100644 index 0000000..4c4828e Binary files /dev/null and b/__pycache__/aoc_05.cpython-311.pyc differ diff --git a/aoc_01.py b/aoc_01.py new file mode 100644 index 0000000..c604b19 --- /dev/null +++ b/aoc_01.py @@ -0,0 +1,22 @@ +#!python3 +import re + +digits = "one two three four five six seven eight nine".split(" ") + +nums_of_digits = dict((b, str(a+1)) for (a, b) in enumerate(digits)) +or_of_digits = "|".join(digits) +first_re = re.compile("\D*?(\d|" + or_of_digits + ").*") +second_re = re.compile(".*(\d|" + or_of_digits + ")\D*?") + +with open("input01d", "r") as f: + s = 0 + for line in f.readlines(): + first = first_re.match(line).group(1) + second = second_re.match(line).group(1) + if first in digits: + first = nums_of_digits[first] + if second in digits: + second = nums_of_digits[second] + s += int(first + second) + print(s) + diff --git a/aoc_02.py b/aoc_02.py new file mode 100755 index 0000000..09ef6b0 --- /dev/null +++ b/aoc_02.py @@ -0,0 +1,53 @@ +#!python3 +import re + +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take the list of games") +parser.add_argument("red_max", help="how many reds are available", type=int) +parser.add_argument("green_max", help="how many greens are available", type=int) +parser.add_argument("blue_max", help="how many blues are available", type=int) +args = parser.parse_args() + +line_re = re.compile("Game (\d+):(.*)") +red_re = re.compile(".*?(\d+) red.*") +green_re = re.compile(".*?(\d+) green.*") +blue_re = re.compile(".*?(\d+) blue.*") + +def game_from_line(string): + m = line_re.match(string) + game_number = int(m.group(1)) + game_strings = m.group(2).split(";") + games = [] + for g in game_strings: + reds = red_re.match(g) + reds = int(reds.group(1)) if reds else 0 + + greens = green_re.match(g) + greens = int(greens.group(1)) if greens else 0 + + blues = blue_re.match(g) + blues = int(blues.group(1)) if blues else 0 + + games.append((reds, greens, blues)) + + return (game_number, games) + +all_games = [] +with open(args.filename, "r") as f: + for l in f.readlines(): + all_games.append(game_from_line(l)) + +for l in all_games: + print(l) + +answer = 0 +for l in all_games: + answer += l[0] + for (r, g, b) in l[1]: + if r > args.red_max or g > args.green_max or b > args.blue_max: + answer -= l[0] + break + + +print(answer) \ No newline at end of file diff --git a/aoc_02b.py b/aoc_02b.py new file mode 100755 index 0000000..56765a5 --- /dev/null +++ b/aoc_02b.py @@ -0,0 +1,43 @@ +#!python3 +import re + +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take the list of games") +args = parser.parse_args() + +line_re = re.compile("Game (\d+):(.*)") +red_re = re.compile(".*?(\d+) red.*") +green_re = re.compile(".*?(\d+) green.*") +blue_re = re.compile(".*?(\d+) blue.*") + +def game_from_line(string): + m = line_re.match(string) + game_number = int(m.group(1)) + game_strings = m.group(2).split(";") + games = [] + for g in game_strings: + reds = red_re.match(g) + reds = int(reds.group(1)) if reds else 0 + + greens = green_re.match(g) + greens = int(greens.group(1)) if greens else 0 + + blues = blue_re.match(g) + blues = int(blues.group(1)) if blues else 0 + + games.append((reds, greens, blues)) + + return (game_number, games) + +all_games = [] +with open(args.filename, "r") as f: + for l in f.readlines(): + all_games.append(game_from_line(l)) + +answer = 0 +for l in all_games: + r, g, b = map(max, zip(*l[1])) + answer += r*g*b + +print(answer) \ No newline at end of file diff --git a/aoc_03.py b/aoc_03.py new file mode 100644 index 0000000..f70ca71 --- /dev/null +++ b/aoc_03.py @@ -0,0 +1,138 @@ +#!python3 + + + +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take the list of games") +args = parser.parse_args() + +parts = [] +notparts = [] +gearsum = 0 + + +def check_neighbors(nbrs): + for n in nbrs: + if n not in ".0123456789\n": + return True + +def neighbors(x, y, ls): + out = [] + for dx in range(-1,2): + for dy in range(-1,2): + if dx == 0 and dy == 0: + continue + if y+dy < 0 or y+dy >= len(ls): + continue + if x+dx < 0 or x+dx >= len(ls[y+dy]): + continue + out.append(ls[y+dy][x+dx]) + return out + +def numerical_neighbors(x, y, ls): + out = set() + for dx in range(-1, 2): + for dy in range(-1, 2): + if dx == 0 and dy == 0: + continue + if y+dy < 0 or y+dy >= len(ls): + continue + if x+dx < 0 or x+dx >= len(ls[y+dy]): + continue + + + if ls[y+dy][x+dx] in "0123456789": + out |= {(x+dx,y+dy, ls[y+dy][x+dx])} + + return out + +def get_number(x,y, lines): + """assumes (x,y) is the coordinates of a digit in lines""" + while x-1 >= 0 and lines[y][x-1] in "0123456789": + x = x-1 + start = (x,y) + + number = "" + coords = set() + while lines[y][x] in "0123456789": + number += lines[y][x] + coords |= {(x,y)} + x += 1 + if x >= len(lines[y]): break + + return (number, frozenset(coords)) + + + + +with open(args.filename, "r") as file: + lines = file.readlines() + for y, l in enumerate(lines): + number = "" + nbrs = [] + for x, c in enumerate(l): + if c == "\n": print("HEYYYY") + if c in "0123456789": + number = number + c + nbrs.extend(neighbors(x,y,lines)) + if c not in "0123456789\n" and number != "": + if check_neighbors(nbrs): + #print("found a number:", number, "".join(nbrs), " and accepted it") + parts.append(int(number)) + else: + #print("found a number:", number, "".join(nbrs), " and rejected it") + notparts.append(int(number)) + number = "" + nbrs = [] + if c not in "0123456789": + continue + if number != "": + if check_neighbors(nbrs): + print("found a number:", number, "".join(nbrs), " and accepted it") + parts.append(int(number)) + else: + print("found a number:", number, "".join(nbrs), " and rejected it") + notparts.append(int(number)) + number = "" + nbrs = [] + + + gearsum = 0 + for y, l in enumerate(lines): + for x, c in enumerate(l): + if c == "*": + print("found a gear at ", x, " ", y) + gear_nums = [] + gear_coordsets = set() + # we found a gear + neighbors = numerical_neighbors(x,y,lines) + print("the gear had neighbors ", neighbors) + for xa, ya, neighboring_number in neighbors: + number, coords = get_number(xa, ya, lines) + print("found a neighbor ", number, " at coords ", coords) + if coords in gear_coordsets: + print("rejecting that neighbor because we already got it") + # we've already got this number. mvoe alnog + continue + else: + print("adding it to gear cordsets", gear_coordsets) + gear_nums.append(number) + gear_coordsets |= {coords} + print("which corresponded to numbers", gear_nums) + + if len(gear_nums) == 2: + gearsum += int(gear_nums[0])*int(gear_nums[1]) + + + +print("accepted:") +print(parts) +print("rejected:") +print(notparts) + +print("sum of parts are:", sum(parts)) +print("sum of unique parts are: ", sum(set(parts))) +print("gear sum is: ", gearsum) + + diff --git a/aoc_04.py b/aoc_04.py new file mode 100644 index 0000000..6e02376 --- /dev/null +++ b/aoc_04.py @@ -0,0 +1,42 @@ +#!python3 + +import re +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take data") +args = parser.parse_args() + +points = 0 +with open(args.filename, "r") as f: + for l in f.readlines(): + secondhalf = l.split(":")[1] + winning = set(secondhalf.split("|")[0].split()) + ours = set(secondhalf.split("|")[1].split()) + print(winning & ours) + points += 2 ** (len(winning & ours) - 1) if winning & ours else 0 + +print(points) + + +line_re = re.compile("Card([ ]+\d+):(.*)\|(.*)") +with open(args.filename, "r") as f: + lines = f.readlines() + games = [] + for l in lines: + games.append(1) + print("starting ouot we have:") + print(games) + for l in lines: + print(l) + line = line_re.match(l) + current_game_number = int(line.group(1)) + winning = set(line.group(2).split()) + ours = set(line.group(3).split()) + wins = len(winning & ours) + + next_several = range(current_game_number, current_game_number+wins) + for i in next_several: + if i < len(games): + games[i] += games[current_game_number-1] + +print(sum(games)) diff --git a/aoc_05.py b/aoc_05.py new file mode 100755 index 0000000..daafa6e --- /dev/null +++ b/aoc_05.py @@ -0,0 +1,57 @@ +import re +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take data") +args = parser.parse_args() + + + +seeds = [] + +maps = [] # list of map lists +with open(args.filename, "r") as f: + seeds_re = re.compile("seeds: ((\d| )*)") + new_map_re = re.compile("(.*?) map:") + map_data_re = re.compile("\d+ \d+ \d+") + + current_map = [] + for l in f.readlines(): + if seeds_re.match(l): + seeds = list(map(int, seeds_re.match(l).group(1).split())) + + if new_map_re.match(l): + if current_map: + maps.append(current_map) + current_map = [] + + if map_data_re.match(l): + current_map.append(list(map(int, map_data_re.match(l).group(0).split()))) + + if current_map: maps.append(current_map) + +print("seeds: ", seeds) +print("maps are: ") +for x in maps: print(x) + +def mapit(the_map, number): + for destination_start, origin_start, length in the_map: + offset = number - origin_start + + if offset < length and offset >= 0: + return destination_start + offset + + return number + +def consecutive_maps(all_maps, number): + output = [] + output.append(number) + for the_map in all_maps: + number = mapit(the_map, number) + output.append(number) + + return output + +consec_maps = [consecutive_maps(maps, s) for s in seeds] +for s in consec_maps: print(s) + +print(list(sorted(consec_maps, key=lambda x: x[-1]))) \ No newline at end of file diff --git a/aoc_05c.py b/aoc_05c.py new file mode 100644 index 0000000..2cfd01f --- /dev/null +++ b/aoc_05c.py @@ -0,0 +1,66 @@ +import re +import argparse +parser = argparse.ArgumentParser() +parser.add_argument("filename", help="the file from which to take data") +args = parser.parse_args() + + + +seeds = [] + +maps = [] # list of map lists +with open(args.filename, "r") as f: + seeds_re = re.compile("seeds: ((\d| )*)") + new_map_re = re.compile("(.*?) map:") + map_data_re = re.compile("\d+ \d+ \d+") + + current_map = [] + for l in f.readlines(): + if seeds_re.match(l): + seeds = list(map(int, seeds_re.match(l).group(1).split())) + + if new_map_re.match(l): + if current_map: + maps.append(current_map) + current_map = [] + + if map_data_re.match(l): + current_map.append(list(map(int, map_data_re.match(l).group(0).split()))) + + if current_map: maps.append(current_map) + +print("seeds: ", seeds) +print("maps are: ") +for x in maps: print(x) + +def mapit(the_map, number): + for destination_start, origin_start, length in the_map: + offset = number - origin_start + + if offset < length and offset >= 0: + return destination_start + offset + + return number + +def consecutive_maps(all_maps, number): + output = [] + output.append(number) + for the_map in all_maps: + number = mapit(the_map, number) + output.append(number) + + return output + +consec_maps = [consecutive_maps(maps, s) for s in seeds] +for s in consec_maps: print(s) + +print("things sorted ", list(sorted(consec_maps, key=lambda x: x[-1]))) + +best = 9999999999999999 +for i in range(0,len(seeds),2): + for x in range(seeds[i], seeds[i]+seeds[i+1]): + candidate = consecutive_maps(maps, x) + if candidate[-1] < best: + best = candidate[-1] + +print(best) \ No newline at end of file diff --git a/day06/aoc b/day06/aoc new file mode 100755 index 0000000..4057128 Binary files /dev/null and b/day06/aoc differ diff --git a/day06/aoc.rs b/day06/aoc.rs new file mode 100644 index 0000000..fc3c89e --- /dev/null +++ b/day06/aoc.rs @@ -0,0 +1,73 @@ +use std::fs; +use std::env; +use std::iter::zip; + +fn main() { + println!("Hello world!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + // get time lineaswords and distance line as words + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let mut contents = binding.lines(); + + let times = contents.next() + .expect("should have a line of times"); + let distances = contents.next() + .expect("should have aline of distances"); + + let pairs = zip( + times.split_whitespace(), + distances.split_whitespace()).skip(1); + // skip the first (label) + + let mut product = 1; + for (time_s, distance_s) in pairs { + let time: u128 = time_s.parse().unwrap(); + let distance: u128 = distance_s.parse().unwrap(); + println!("{} ms, {} meters", time, distance); + + let winning_strats = win(time, distance); + println!("there are {} ways to win", winning_strats); + + product = product * winning_strats; + } + + println!("product of winning strats is {}", product); + + let time_s = String::from( + times.replace(" ","").rsplit(':').next() + .expect("we should have a time") + ); + let distance_s = String::from( + distances.replace(" ","").rsplit(':').next() + .expect("we should have a distance") + ); + println!("the big race is {} milliseconds and {} meters", + time_s, + distance_s); + + let time: u128 = time_s.parse().unwrap(); + let distance: u128 = distance_s.parse().unwrap(); + + println!("{} ms, {} meters", time, distance); + println!("{} wins", win(time,distance)); +} + +fn win(time: u128, distance: u128) -> u128 { + let mut num_wins = 0; + for delay in 0..time { + if delay * (time - delay) > distance { + num_wins = num_wins + 1; + } + } + + return num_wins; +} \ No newline at end of file diff --git a/day07/aoc b/day07/aoc new file mode 100755 index 0000000..cd4f296 Binary files /dev/null and b/day07/aoc differ diff --git a/day07/aoc.rs b/day07/aoc.rs new file mode 100644 index 0000000..bcda941 --- /dev/null +++ b/day07/aoc.rs @@ -0,0 +1,123 @@ +use std::iter::*; +use std::cmp::*; +use std::collections::HashMap; +use std::fs; +use std::env; + + +type Hand = [usize;5]; + +fn main() { + let card_value: HashMap = zip([ '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J','Q', 'K', 'A'], 0..13).collect(); + + println!("Hello, AoC day 7!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + // get time lineaswords and distance line as words + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let contents = binding.lines(); + + let mut hands: Vec<(Hand, u32)> = Vec::new(); + + for line in contents { + if !line.is_empty() { + hands.push(parse(line, &card_value)); + } + } + + hands.sort_unstable_by(|(ha, _), (hb, _)| hand_compare(*ha, *hb)); + + let mut sum = 0; + for (index, (_hand, bet)) in hands.iter().enumerate() { + let score = ((index as u32) + 1) * bet; + sum += score; + } + + println!("total scores was: {}", sum); +} + +fn parse(line: &str, dictionary: &HashMap) -> (Hand, u32) { + let (hand, value) = line.split_once(" ").expect("expected a line to have the format 'AAAAA ###'"); + let mut m: [usize;5] = [0;5]; + + for (i, character) in hand.chars().enumerate() { + m[i] = *dictionary.get(&character).expect(&format!("expected a card in {}", line)); + } + + let val:u32 = value.parse().unwrap(); + println!("{:?} for {}", m, val); + return (m, val); +} + +fn rank(hand: Hand) -> u32 { + let mut a = [0; 13]; + for letter in hand { + a[letter] += 1; + } + + let mut fives = 0; + let mut fours = 0; + let mut threes = 0; + let mut twos = 0; + let mut _ones = 0; + + for number in a { + match number { + 5 => fives += 1, + 4 => fours += 1, + 3 => threes += 1, + 2 => twos += 1, + 1 => _ones += 1, + _ => () + } + } + + if fives > 0 { + return 6; + } + if fours > 0 { + return 5; + } + if threes == 1 && twos == 1 { + return 4; + } + if threes == 1 { + return 3; + } + if twos == 2 { + return 2; + } + if twos == 1 { + return 1; + } + + return 0; +} + + +fn hand_compare(a: Hand, b: Hand) -> Ordering { + let bs_a = rank(a); + let bs_b = rank(b); + + if bs_a > bs_b { + return Ordering::Greater; + } else if bs_a < bs_b { + return Ordering::Less; + } + + if a > b { + return Ordering::Greater; + } else if a < b { + return Ordering::Less; + } + + return Ordering::Equal; +} \ No newline at end of file diff --git a/day07/boc b/day07/boc new file mode 100755 index 0000000..40fd84c Binary files /dev/null and b/day07/boc differ diff --git a/day07/boc.rs b/day07/boc.rs new file mode 100644 index 0000000..4bc2654 --- /dev/null +++ b/day07/boc.rs @@ -0,0 +1,149 @@ +use std::iter::*; +use std::cmp::*; +use std::collections::HashMap; +use std::fs; +use std::env; + + +type Hand = [usize;5]; + +fn main() { + let card_value: HashMap = zip(['J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A'], 0..13).collect(); + + println!("Hello, AoC day 7!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let contents = binding.lines(); + + let mut hands: Vec<(Hand, u32)> = Vec::new(); + + for line in contents { + if !line.is_empty() { + hands.push(parse(line, &card_value)); + } + } + + hands.sort_by(|(ha, _), (hb, _)| hand_compare(*ha, *hb)); + + println!("and now, the sorted:"); + for (hand, value) in hands.iter() { + let ran = match rank(*hand) { + 6 => "five of a kind", + 5 => "four of a kind", + 4 => "full house", + 3 => "three of a kind", + 2 => "two pair", + 1 => "one pair", + 0 => "card high", + _ => "mystery to us all" + }; + println!("{:?}, which is a {}, for {}", hand, ran, value); + } + + let mut sum = 0; + for (index, (_hand, bet)) in hands.iter().enumerate() { + let score = ((index as u32) + 1) * bet; + sum += score; + } + + println!("total scores was: {}", sum); +} + +fn parse(line: &str, dictionary: &HashMap) -> (Hand, u32) { + let (hand, value) = line.split_once(" ").expect("expected a line to have the format 'AAAAA ###'"); + let mut m: [usize;5] = [0;5]; + + for (i, character) in hand.chars().enumerate() { + m[i] = *dictionary.get(&character).expect(&format!("expected a card in {}", line)); + } + + return (m, value.parse().unwrap()); +} + +fn rank(hand: Hand) -> u32 { + let mut a = [0; 13]; + for letter in hand { + a[letter] += 1; + } + + let mut fives = 0; + let mut fours = 0; + let mut threes = 0; + let mut twos = 0; + let mut _ones = 0; + + for number in &a[1..] { + + match number { + 5 => fives += 1, + 4 => fours += 1, + 3 => threes += 1, + 2 => twos += 1, + 1 => _ones += 1, + _ => () + } + } + + if (fives > 0) || + ((fours == 1) && (a[0] == 1)) || + ((threes == 1) && (a[0] == 2)) || + ((twos == 1) && (a[0] == 3)) || + (a[0] == 4) || + (a[0] == 5) { + return 6; + } + if (fours > 0) || + ((threes == 1) && (a[0] == 1)) || + ((twos == 1) && (a[0] == 2)) || + (a[0] == 3) || + (a[0] == 4) { + return 5; + } + if (threes == 1 && twos == 1) || + ((twos == 2) && (a[0] == 1)) { + return 4; + } + if (threes == 1) || + ((twos == 1) && (a[0] == 1)) || + (a[0] == 2) { + return 3; + } + if twos == 2 { + return 2; + } + if (twos == 1) || + (a[0] == 1) { + return 1; + } + + return 0; +} + + +fn hand_compare(a: Hand, b: Hand) -> Ordering { + let bs_a = rank(a); + let bs_b = rank(b); + + if bs_a > bs_b { + return Ordering::Greater; + } else if bs_a < bs_b { + return Ordering::Less; + } + + if a > b { + return Ordering::Greater; + } else if a < b { + return Ordering::Less; + } + + return Ordering::Equal; +} \ No newline at end of file diff --git a/day08/.gitignore b/day08/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/day08/.gitignore @@ -0,0 +1 @@ +/target diff --git a/day08/Cargo.lock b/day08/Cargo.lock new file mode 100644 index 0000000..d2d4331 --- /dev/null +++ b/day08/Cargo.lock @@ -0,0 +1,54 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "day08" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" diff --git a/day08/Cargo.toml b/day08/Cargo.toml new file mode 100644 index 0000000..66b9abc --- /dev/null +++ b/day08/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day08" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +regex = "1.10.2" diff --git a/day08/src/main.rs b/day08/src/main.rs new file mode 100644 index 0000000..6b121ff --- /dev/null +++ b/day08/src/main.rs @@ -0,0 +1,78 @@ +use std::fs; +use std::env; +use regex::Regex; +use std::collections::HashMap; + +//type Choice = (&str, &str); + +fn main() { + println!("Hello AoC day 8!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + // get time lineaswords and distance line as words + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let mut contents = binding.lines(); + + let directions = contents.next().expect("There has to be a first line...").to_string(); + let re = Regex::new(r"(\w\w\w) = \((\w\w\w), (\w\w\w)\)").unwrap(); + + let mut our_map = HashMap::new(); + let mut feet = Vec::new(); + + for line in contents { + let Some(capture) = re.captures(line) else { continue }; + match re.captures(line) { + Some(capture) => { + let this = capture[1].to_string(); + if this.chars().nth(2) == Some('A') { + feet.push(this.to_string()); + } + let those = (capture[2].to_string(), capture[3].to_string()); + our_map.insert(this, those); + () + }, + None => () + } + } + println!("our directions list is {}", directions); + //println!("{:?}", our_map); + + println!("starting at {feet:?}"); + let mut z_lengths = Vec::new(); + //let mut z_cycles = Vec::new(); + let mut count = 0; + + + while !finished(&feet) { + let mut iter = directions.chars(); + for i in 0..feet.len() { + let (left, right) = our_map.get(&feet[i]).expect("we should stay on the map."); + match iter.next() { + Some('L') => {feet[i] = left.to_string();}, + Some('R') => {feet[i] = right.to_string();}, + _ => {iter = directions.chars();} + } + } + count += 1; + + z_lengths.push(count); + } + println!("we walked {count} steps!"); + //println!("the cycle lengths were {z_cycles:?}") +} + +fn finished(spot: &Vec ) -> bool { + let mut output = true; + for foot in spot { + output = output && (foot.chars().nth(2) == Some('Z')) + } + return output; +} diff --git a/day08/src/main2.rs b/day08/src/main2.rs new file mode 100644 index 0000000..469b495 --- /dev/null +++ b/day08/src/main2.rs @@ -0,0 +1,86 @@ +use std::fs; +use std::env; +use regex::Regex; +use std::collections::HashMap; + +//type Choice = (&str, &str); + +fn main() { + println!("Hello AoC day 8!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + // get time lineaswords and distance line as words + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let mut contents = binding.lines(); + + let directions = contents.next().expect("There has to be a first line...").to_string(); + let re = Regex::new(r"(\w\w\w) = \((\w\w\w), (\w\w\w)\)").unwrap(); + + let mut our_map = HashMap::new(); + let mut feet = Vec::new(); + + for line in contents { + let Some(capture) = re.captures(line) else { continue }; + match re.captures(line) { + Some(capture) => { + let this = capture[1].to_string(); + if this.chars().nth(2) == Some('A') { + feet.push(this.to_string()); + } + let those = (capture[2].to_string(), capture[3].to_string()); + our_map.insert(this, those); + () + }, + None => () + } + } + println!("our directions list is {}", directions); + //println!("{:?}", our_map); + + println!("starting at {feet:?}"); + let mut z_lengths = Vec::new(); + //let mut z_cycles = Vec::new(); + + for foot in feet { + let mut here = &foot; + let mut iter = directions.chars(); + let mut count = 0; + + while here.chars().nth(2) != Some('Z') { + let (left, right) = our_map.get(here).expect("we should stay on the map."); + match iter.next() { + Some('L') => { + here = left; + count += 1; + }, + Some('R') => { + here = right; + count += 1; + }, + _ => { + iter = directions.chars(); + } + } + } + + z_lengths.push(count); + } + println!("we walked {z_lengths:?} steps!"); + //println!("the cycle lengths were {z_cycles:?}") +} + +fn finished(spot: &Vec ) -> bool { + let mut output = true; + for foot in spot { + output = output && (foot.chars().nth(2) == Some('Z')) + } + return output; +} diff --git a/day09/.gitignore b/day09/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/day09/.gitignore @@ -0,0 +1 @@ +/target diff --git a/day09/Cargo.lock b/day09/Cargo.lock new file mode 100644 index 0000000..8aa567a --- /dev/null +++ b/day09/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day09" +version = "0.1.0" diff --git a/day09/Cargo.toml b/day09/Cargo.toml new file mode 100644 index 0000000..15d9cf9 --- /dev/null +++ b/day09/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day09" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day09/src/main.rs b/day09/src/main.rs new file mode 100644 index 0000000..542a8fa --- /dev/null +++ b/day09/src/main.rs @@ -0,0 +1,77 @@ +use std::iter::*; +use std::fs; +use std::env; + +fn main() { + println!("Hello, AoC day 9!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + // get time lineaswords and distance line as words + let binding = fs::read_to_string(file_path) + .expect("Should have been able to read the file"); + let contents = binding.lines(); + + let mut sum_of_nexts = 0; + let mut sum_of_prevs = 0; + + for line in contents { + let nums: Vec = line.split_whitespace().map(|x| x.parse::().expect("ran into an unparseable number")).collect(); + println!("{nums:?}"); + + let mut stack: Vec> = Vec::new(); + stack.push(nums); + + while !all_zero(&(stack.last().expect("we should have at least one set of values. in the list"))) { + let mut diffs = Vec::new(); + let object = stack.pop().expect("our stack of values for differencing should have at least one list in it"); + + for i in 0..(object.len() - 1) { + diffs.push(object[i+1] - object[i]); + } + println!("{diffs:?}"); + + stack.push(object); + stack.push(diffs); + } + + stack.reverse(); + + let mut difference = 0; + + for s in &stack { + let start = s.last().expect("we shoulld always have values in our stack of difference lists"); + difference = start + difference; + } + + println!("the next value should be {difference}"); + sum_of_nexts += difference; + + + difference = 0; + + for s in &stack { + let first = s.first().expect("we shoulld always have values in our stack of difference lists"); + difference = first - difference; + } + println!("the previous value should be {difference}"); + sum_of_prevs += difference; + } + + println!("the sum of next values is {sum_of_nexts}"); + println!("the sum of previous values is {sum_of_prevs}"); +} + +fn all_zero(slice: &[i64]) -> bool { + for s in slice { + if *s != 0 { return false; } + } + + return true; +}