rm moved files
This commit is contained in:
parent
9d19b8a230
commit
d6ee3239c8
|
@ -1,5 +1,3 @@
|
|||
data
|
||||
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
|
@ -14,3 +12,6 @@ Cargo.lock
|
|||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# Related to Advent of Code
|
||||
input.txt
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "part2"
|
||||
name = "calories"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
//! Read a file containing sets of number
|
||||
//! Compute the max of the sum of each set
|
||||
//! Print the result
|
||||
//!
|
||||
//! # Example
|
||||
//! cargo run -- ../input.txt # Execute the program with the input file
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
|
||||
let mut max = 0;
|
||||
let mut current = 0;
|
||||
for line in contents.lines() {
|
||||
// Check if line is empty
|
||||
if line.is_empty() {
|
||||
if current > max {
|
||||
max = current;
|
||||
}
|
||||
current = 0;
|
||||
} else {
|
||||
let number: i32 = line.parse().unwrap();
|
||||
current += number;
|
||||
}
|
||||
}
|
||||
println!("Max: {}", max);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "part1"
|
||||
name = "snacks"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
//! Read a file containing sets of number
|
||||
//! Get the three maximum sum of the sets
|
||||
//! Print the sum of the three maximum
|
||||
//!
|
||||
//! # Example
|
||||
//! cargo run -- ../input.txt # Execute the program with the input file
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
let mut current = 0;
|
||||
let mut current_maximums = [0; 3]; // Store the three maximums
|
||||
for line in contents.lines() {
|
||||
// Check if line is empty
|
||||
if line.is_empty() {
|
||||
// Check if current is greater than the minimum of the maximums
|
||||
if current > *current_maximums.iter().min().unwrap() {
|
||||
// Replace each value of the maximums by the current value if it is greater
|
||||
// And keep the maximums sorted with previous maximums kept
|
||||
for i in 0..3 {
|
||||
if current > current_maximums[i] {
|
||||
current_maximums[i] = current;
|
||||
current_maximums.sort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
current = 0;
|
||||
} else {
|
||||
let number: i32 = line.parse().unwrap();
|
||||
current += number;
|
||||
}
|
||||
}
|
||||
println!("Max: {}", current_maximums.iter().sum::<i32>());
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
A Y
|
||||
B X
|
||||
C Z
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "guess-rock-paper-scissors"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,17 @@
|
|||
//! # Guess the Rock Paper Scissors Game
|
||||
//! We get the other player choice and wether to win or lose
|
||||
//! we replace the game result with our player chose
|
||||
//! and print the result
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
mod rps;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
rps::guess_game(&contents);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
/// Guess what the other player will play
|
||||
/// Accordinhg to the result
|
||||
/// and the first player choice
|
||||
/// 'X' means lose
|
||||
/// 'Y' means draw
|
||||
/// 'Z' means win
|
||||
///
|
||||
/// 'A' means Rock
|
||||
/// 'B' means Paper
|
||||
/// 'C' means Scissors
|
||||
fn guess(player: char, result: char) -> char {
|
||||
let available_moves = "ABC";
|
||||
let available_results = "XYZ";
|
||||
let move_index = available_moves.find(player).unwrap();
|
||||
let result_index = available_results.find(result).unwrap();
|
||||
let new_move_index = (move_index + result_index) % 3;
|
||||
available_moves.chars().nth(new_move_index).unwrap()
|
||||
}
|
||||
|
||||
pub fn guess_game(content: &str) {
|
||||
for line in content.lines() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "rock-paper-scissors"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,19 @@
|
|||
//! # Read a file containing a set of 'Rock Paper Scissors' play
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```bash
|
||||
//! cargo run -- ../input.txt # Execute the program with the input file
|
||||
//! ```
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
mod rps;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
println!("{}", rps::compute_game_score(&contents));
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//! # Compute score given by a specific play of 'Rock Paper Scissors'
|
||||
//!
|
||||
//! For instance:
|
||||
//!
|
||||
//! ```text
|
||||
//! A Y
|
||||
//! B X
|
||||
//! C Z
|
||||
//! ```
|
||||
//! Where A is what the other player plays, Y is what the second player plays on the first round
|
||||
//!
|
||||
//! A corresponds to Rock, B to Paper, C to Scissors.
|
||||
//!
|
||||
//! Similarly Y corresponds to Rock, X to Paper, Z to Scissors.
|
||||
//!
|
||||
//! Scissors beats Paper, Paper beats Rock, Rock beats Scissors
|
||||
//!
|
||||
//! - A Win gives 6 points
|
||||
//! - A Draw gives 3 points
|
||||
//! - A Lose gives 0 points
|
||||
//!
|
||||
//! - Playing Rock gives 1 points
|
||||
//! - Playing Paper gives 2 points
|
||||
//! - Playing Scissors gives 3 points
|
||||
//!
|
||||
|
||||
/// Compute the score of a game round
|
||||
pub fn compute_score(other_player: char, second_player: char) -> u32 {
|
||||
let mut score = 0;
|
||||
let other_available_moves = "ABC";
|
||||
let my_available_moves = "XYZ";
|
||||
let other_move_index = other_available_moves.find(other_player).unwrap();
|
||||
let moves_points = [1, 2, 3];
|
||||
let move_point_index = my_available_moves.find(second_player).unwrap();
|
||||
// println!("Move point index: {}", move_point_index);
|
||||
let move_point = moves_points[move_point_index];
|
||||
score += move_point;
|
||||
let my_move_index = my_available_moves.find(second_player).unwrap();
|
||||
let has_won = my_move_index == (other_move_index + 1) % 3;
|
||||
if has_won {
|
||||
score += 6;
|
||||
} else if other_move_index == my_move_index {
|
||||
score += 3;
|
||||
}
|
||||
// else score += 0;
|
||||
score
|
||||
}
|
||||
|
||||
/// Compute the score of a game
|
||||
pub fn compute_game_score(game: &str) -> u32 {
|
||||
let mut score = 0;
|
||||
for line in game.lines() {
|
||||
let parts = line.split_whitespace();
|
||||
let other_player = parts.clone().nth(0).unwrap().chars().nth(0).unwrap();
|
||||
let second_player = parts.clone().nth(1).unwrap().chars().nth(0).unwrap();
|
||||
// print!("{} vs {} ", other_player, second_player);
|
||||
score += compute_score(other_player, second_player);
|
||||
}
|
||||
score
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_compute_score() {
|
||||
assert_eq!(compute_score('A', 'Y'), 2+6);
|
||||
// TODO add more tests
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compute_game_score() {
|
||||
let game = "A Y";
|
||||
assert_eq!(compute_game_score(game), 2+6);
|
||||
// TODO add more tests
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "trebuchet"
|
||||
name = "rucksack"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<h2>--- Day 3: Rucksack Reorganization ---</h2><p>One Elf has the important job of loading all of the <a href="https://en.wikipedia.org/wiki/Rucksack" target="_blank">rucksacks</a> with supplies for the <span title="Where there's jungle, there's hijinxs.">jungle</span> journey. Unfortunately, that Elf didn't quite follow the packing instructions, and so a few items now need to be rearranged.</p>
|
||||
<p>Each rucksack has two large <em>compartments</em>. All items of a given type are meant to go into exactly one of the two compartments. The Elf that did the packing failed to follow this rule for exactly one item type per rucksack.</p>
|
||||
<p>The Elves have made a list of all of the items currently in each rucksack (your puzzle input), but they need your help finding the errors. Every item type is identified by a single lowercase or uppercase letter (that is, <code>a</code> and <code>A</code> refer to different types of items).</p>
|
||||
<p>The list of items for each rucksack is given as characters all on a single line. A given rucksack always has the same number of items in each of its two compartments, so the first half of the characters represent items in the first compartment, while the second half of the characters represent items in the second compartment.</p>
|
||||
<p>For example, suppose you have the following list of contents from six rucksacks:</p>
|
||||
<pre><code>vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
</code></pre>
|
||||
<ul>
|
||||
<li>The first rucksack contains the items <code>vJrwpWtwJgWrhcsFMMfFFhFp</code>, which means its first compartment contains the items <code>vJrwpWtwJgWr</code>, while the second compartment contains the items <code>hcsFMMfFFhFp</code>. The only item type that appears in both compartments is lowercase <code><em>p</em></code>.</li>
|
||||
<li>The second rucksack's compartments contain <code>jqHRNqRjqzjGDLGL</code> and <code>rsFMfFZSrLrFZsSL</code>. The only item type that appears in both compartments is uppercase <code><em>L</em></code>.</li>
|
||||
<li>The third rucksack's compartments contain <code>PmmdzqPrV</code> and <code>vPwwTWBwg</code>; the only common item type is uppercase <code><em>P</em></code>.</li>
|
||||
<li>The fourth rucksack's compartments only share item type <code><em>v</em></code>.</li>
|
||||
<li>The fifth rucksack's compartments only share item type <code><em>t</em></code>.</li>
|
||||
<li>The sixth rucksack's compartments only share item type <code><em>s</em></code>.</li>
|
||||
</ul>
|
||||
<p>To help prioritize item rearrangement, every item type can be converted to a <em>priority</em>:</p>
|
||||
<ul>
|
||||
<li>Lowercase item types <code>a</code> through <code>z</code> have priorities 1 through 26.</li>
|
||||
<li>Uppercase item types <code>A</code> through <code>Z</code> have priorities 27 through 52.</li>
|
||||
</ul>
|
||||
<p>In the above example, the priority of the item type that appears in both compartments of each rucksack is 16 (<code>p</code>), 38 (<code>L</code>), 42 (<code>P</code>), 22 (<code>v</code>), 20 (<code>t</code>), and 19 (<code>s</code>); the sum of these is <code><em>157</em></code>.</p>
|
||||
<p>Find the item type that appears in both compartments of each rucksack. <em>What is the sum of the priorities of those item types?</em>
|
|
@ -0,0 +1,23 @@
|
|||
//! # Rucksack Reorganizatio
|
||||
//!
|
||||
//! Read a file containing a list of items in a set of rucksacks
|
||||
//! compute the sum of priorities of items that are in both compartiments
|
||||
//! where each sack is divided into two equally sized compartiments
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```bash
|
||||
//! cargo run -- ../input.txt # Execute the program with the input file
|
||||
//! ```
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
mod rucksack;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
println!("{}", rucksack::sum_priorities_items_both_compartiments(&contents));
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
/// lowercase `a` to `z` have priorities 1 to 26, uppercase `A` through `Z` have priority 27 through 52.
|
||||
fn priority(item: char) -> u32 {
|
||||
let value: u32;
|
||||
if item.is_lowercase() {
|
||||
value = item as u32 - 96;
|
||||
} else {
|
||||
value = item as u32 - 64 + 26;
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
pub fn sum_priorities_items_both_compartiments(sacks: &str) -> u32 {
|
||||
let mut sum: u32 = 0;
|
||||
for sack in sacks.lines() {
|
||||
let middle_index: usize = sack.len() / 2;
|
||||
let first_compartiment: &str = &sack[..middle_index];
|
||||
let second_compartiment: &str = &sack[middle_index..];
|
||||
for item in first_compartiment.chars() {
|
||||
if second_compartiment.contains(item) {
|
||||
sum += priority(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_priority() {
|
||||
assert_eq!(priority('a'), 1);
|
||||
assert_eq!(priority('z'), 26);
|
||||
assert_eq!(priority('A'), 27);
|
||||
assert_eq!(priority('Z'), 52);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sum_priorities_items_both_compartiments() {
|
||||
assert_eq!(sum_priorities_items_both_compartiments("aAa"), 1);
|
||||
assert_eq!(sum_priorities_items_both_compartiments("AbilABC"), 27);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "camp-cleanup"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,37 @@
|
|||
<h2>--- Day 4: Camp Cleanup ---</h2><p>Space needs to be cleared before the last supplies can be unloaded from the ships, and so several Elves have been assigned the job of cleaning up sections of the camp. Every section has a unique <em>ID number</em>, and each Elf is assigned a range of section IDs.</p>
|
||||
<p>However, as some of the Elves compare their section assignments with each other, they've noticed that many of the assignments <em>overlap</em>. To try to quickly find overlaps and reduce duplicated effort, the Elves pair up and make a <em>big list of the section assignments for each pair</em> (your puzzle input).</p>
|
||||
<p>For example, consider the following list of section assignment pairs:</p>
|
||||
<pre><code>2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
</code></pre>
|
||||
<p>For the first few pairs, this list means:</p>
|
||||
<ul>
|
||||
<li>Within the first pair of Elves, the first Elf was assigned sections <code>2-4</code> (sections <code>2</code>, <code>3</code>, and <code>4</code>), while the second Elf was assigned sections <code>6-8</code> (sections <code>6</code>, <code>7</code>, <code>8</code>).</li>
|
||||
<li>The Elves in the second pair were each assigned two sections.</li>
|
||||
<li>The Elves in the third pair were each assigned three sections: one got sections <code>5</code>, <code>6</code>, and <code>7</code>, while the other also got <code>7</code>, plus <code>8</code> and <code>9</code>.</li>
|
||||
</ul>
|
||||
<p>This example list uses single-digit section IDs to make it easier to draw; your actual list might contain larger numbers. Visually, these pairs of section assignments look like this:</p>
|
||||
<pre><code>.234..... 2-4
|
||||
.....678. 6-8
|
||||
|
||||
.23...... 2-3
|
||||
...45.... 4-5
|
||||
|
||||
....567.. 5-7
|
||||
......789 7-9
|
||||
|
||||
.2345678. 2-8
|
||||
..34567.. 3-7
|
||||
|
||||
.....6... 6-6
|
||||
...456... 4-6
|
||||
|
||||
.23456... 2-6
|
||||
...45678. 4-8
|
||||
</code></pre>
|
||||
<p>Some of the pairs have noticed that one of their assignments <em>fully contains</em> the other. For example, <code>2-8</code> fully contains <code>3-7</code>, and <code>6-6</code> is fully contained by <code>4-6</code>. In pairs where one assignment fully contains the other, one Elf in the pair would be exclusively cleaning sections their partner will already be cleaning, so these seem like the most in need of reconsideration. In this example, there are <code><em>2</em></code> such pairs.</p>
|
||||
<p><em>In how many assignment pairs does one range fully contain the other?</em></p>
|
|
@ -0,0 +1,30 @@
|
|||
//! Camp Cleanup
|
||||
//! ===========other_range
|
||||
|
||||
fn is_contained_in(one_range: [u32; 2], other_range: [u32; 2]) -> bool {
|
||||
(one_range[0] >= other_range[0] && one_range[1] <= other_range[1]) || (other_range[0] >= one_range[0] && other_range[1] <= one_range[1])
|
||||
}
|
||||
|
||||
pub fn count_lazy_elves(elf_pairs: &str) -> u32 {
|
||||
let mut lazy_elves_counter: u32 = 0;
|
||||
for elf_pair in elf_pairs.lines() {
|
||||
let pair_split = elf_pair.split(',');
|
||||
// Get each elves as a vector of 2 u32
|
||||
let one_elf: Vec<u32> = pair_split.clone()
|
||||
.nth(0)
|
||||
.unwrap()
|
||||
.split('-')
|
||||
.map(|s| s.parse().unwrap())
|
||||
.collect();
|
||||
let other_elf: Vec<u32> = pair_split.clone()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.split('-')
|
||||
.map(|s| s.parse().unwrap())
|
||||
.collect();
|
||||
if is_contained_in([one_elf[0], one_elf[1]], [other_elf[0], other_elf[1]]) {
|
||||
lazy_elves_counter += 1;
|
||||
}
|
||||
}
|
||||
lazy_elves_counter
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
//! Find Elves that can be lazy
|
||||
//!
|
||||
//! Lazy Elves are Elves whose given section ID range are completely contained
|
||||
//! by its pair mate section ID range.
|
||||
//!
|
||||
//! The input file is a list of Elf section ID ranges, a pair at a line
|
||||
//!
|
||||
//! ## Example
|
||||
//! ```bash
|
||||
//! cargo run -- ../input.txt # Execute the program with the input file
|
||||
//! ```
|
||||
|
||||
use std::fs;
|
||||
use std::env;
|
||||
|
||||
mod camp;
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let filename = &args[1];
|
||||
let contents: String = fs::read_to_string(filename)
|
||||
.expect("Something went wrong reading the file");
|
||||
println!("{}", camp::count_lazy_elves(&contents));
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
|
@ -0,0 +1,9 @@
|
|||
[D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "supply-stacks"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
queues = "1.1.0"
|
|
@ -0,0 +1,41 @@
|
|||
//! # Day 5: Supply Stacks
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
fn extract_crates_in_layer(layer: &str, piles_number: usize) -> Vec<char> {
|
||||
let mut crates: Vec<char> = Vec::with_capacity(piles_number);
|
||||
for i in 0..piles_number {
|
||||
let crate_name_idx: usize = i * 4 + 1;
|
||||
let crate_name: char = layer.chars().nth(crate_name_idx).unwrap();
|
||||
crates[i] = crate_name;
|
||||
}
|
||||
crates
|
||||
}
|
||||
|
||||
fn parse_crates_piles(entrepot: &str) -> Vec<VecDeque<char>> {
|
||||
let mut piles: Vec<VecDeque<char>> = Vec::new();
|
||||
let mut number_of_piles: usize = 0;
|
||||
let mut entrepot_layers = entrepot.lines();
|
||||
let last_line = entrepot_layers.nth_back(0);
|
||||
let piles_number: usize = (last_line.expect("reason").len() + 1) / 4 as usize;
|
||||
for pile_idx in 0..piles_number {
|
||||
piles[pile_idx] = VecDeque::new();
|
||||
}
|
||||
let j = 0;
|
||||
let number_of_layers: usize = entrepot_layers.clone().count();
|
||||
for layer in entrepot_layers {
|
||||
if j != number_of_layers - 1 {
|
||||
// Not the last line
|
||||
let crates = extract_crates_in_layer(layer, piles_number);
|
||||
// Enqueue below the pile
|
||||
for pile_idx in 0..crates.len() {
|
||||
piles[pile_idx].push_back(crates[pile_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
piles
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let input_file = "../data/sample.txt";
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "part2"
|
||||
version = "0.1.0"
|
|
@ -1,80 +0,0 @@
|
|||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
|
||||
// Extract all numbers, digits and letter written digits
|
||||
fn extract_numbers(line: &str) -> Vec<u32> {
|
||||
let written_digits: Vec<&str> = vec![
|
||||
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
];
|
||||
let mut max_tail_overlaps: HashMap<&str, u32> = HashMap::new();
|
||||
// Compute the size of the suffix of number i overlaping with prefix of number j:
|
||||
for suffix_number in &written_digits {
|
||||
max_tail_overlaps.insert(suffix_number.clone(), 0);
|
||||
for prefix_number in &written_digits {
|
||||
if suffix_number != prefix_number {
|
||||
let mut overlap: u32 = 0;
|
||||
for i in 0..(cmp::min(prefix_number.len(), suffix_number.len())) {
|
||||
if suffix_number.chars().nth_back(i) == prefix_number.chars().nth(i) {
|
||||
overlap += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if overlap > max_tail_overlaps[suffix_number] {
|
||||
max_tail_overlaps.insert(suffix_number, overlap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut numbers: Vec<u32> = Vec::new();
|
||||
let mut current_digit_word: String = "".to_owned();
|
||||
for character in line.chars() {
|
||||
if character.is_digit(10) {
|
||||
numbers.push(character.to_digit(10).unwrap());
|
||||
current_digit_word = "".to_owned(); // Reset writing word
|
||||
} else {
|
||||
current_digit_word.push(character);
|
||||
// Check for the presence of any of the digit words
|
||||
for (index, digit_writing) in written_digits.iter().enumerate() {
|
||||
let word_length = digit_writing.len();
|
||||
let positions: Vec<(usize, &str)> =
|
||||
current_digit_word.match_indices(digit_writing).collect();
|
||||
if positions.len() > 0 {
|
||||
let digit = index as u32 + 1;
|
||||
numbers.push(digit);
|
||||
let start_position = positions[0].0;
|
||||
let end_position =
|
||||
start_position + word_length - max_tail_overlaps[digit_writing] as usize;
|
||||
let current_digit_word_slice = ¤t_digit_word[end_position..];
|
||||
current_digit_word = current_digit_word_slice.to_owned();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numbers
|
||||
}
|
||||
|
||||
// Extract number including letters
|
||||
fn extract_number(line: &str) -> u32 {
|
||||
let numbers: Vec<u32> = extract_numbers(line);
|
||||
let first: u32 = numbers[0];
|
||||
let last: u32 = numbers[numbers.len() - 1];
|
||||
let number: u32 = first * 10 + last;
|
||||
number
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let input_filename: &str = "../data/input.txt";
|
||||
|
||||
let contents =
|
||||
fs::read_to_string(input_filename).expect("Should have been able to read the file");
|
||||
|
||||
let mut sum: u32 = 0;
|
||||
for line in contents.lines() {
|
||||
let number = extract_number(line);
|
||||
println!("{}\t{:?}", line, number);
|
||||
sum += number;
|
||||
}
|
||||
println!("{:?}", sum);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "trebuchet"
|
||||
version = "0.1.0"
|
|
@ -1,33 +0,0 @@
|
|||
use std::fs;
|
||||
|
||||
fn extract_number(line: &str) -> u32 {
|
||||
let mut has_digit: bool = false;
|
||||
let mut first: u32 = 0;
|
||||
let mut last: u32 = 0;
|
||||
for character in line.chars() {
|
||||
if character.is_digit(10) {
|
||||
if !has_digit {
|
||||
has_digit = true;
|
||||
first = character.to_digit(10).unwrap();
|
||||
}
|
||||
last = character.to_digit(10).unwrap();
|
||||
}
|
||||
}
|
||||
let number: u32 = first * 10 + last;
|
||||
number
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let input_filename: &str = "../data/input.txt";
|
||||
|
||||
let contents =
|
||||
fs::read_to_string(input_filename).expect("Should have been able to read the file");
|
||||
|
||||
let mut sum: u32 = 0;
|
||||
for line in contents.lines() {
|
||||
let number = extract_number(line);
|
||||
// println!("{:?}", number);
|
||||
sum += number;
|
||||
}
|
||||
println!("{:?}", sum);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
with open("data/input.txt", "r") as f:
|
||||
games = f.read()
|
||||
|
||||
limits = {
|
||||
"red": 12,
|
||||
"green": 13,
|
||||
"blue": 14
|
||||
}
|
||||
|
||||
s = 0
|
||||
|
||||
for game in games.split("\n")[:-1]:
|
||||
parts = game.split(":")
|
||||
head = parts[0]
|
||||
identifier = head.split(" ")[1]
|
||||
overflow = False
|
||||
for draw in parts[1].split(";"):
|
||||
draw = draw.strip()
|
||||
for count in draw.split(","):
|
||||
count = count.strip()
|
||||
count_parts = count.split(" ")
|
||||
color = count_parts[1]
|
||||
amount = int(count_parts[0])
|
||||
if amount > limits[color]:
|
||||
overflow = True
|
||||
break
|
||||
if overflow:
|
||||
break
|
||||
if not overflow:
|
||||
s += int(identifier)
|
||||
|
||||
print(s)
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
my $filename = '../data/input.txt';
|
||||
|
||||
open(FH, '<', $filename) or die $!;
|
||||
|
||||
sub possible_id {
|
||||
my $line = $_[0];
|
||||
my $reds = $_[1];
|
||||
my $greens = $_[2];
|
||||
my $blues = $_[3];
|
||||
my @colors = qw(red green blue);
|
||||
my @quantities = ($reds, $greens, $blues);
|
||||
# Extract the id and game draws
|
||||
my @game_parts = split /:/, $line, 2;
|
||||
my @id_parts = split / /, $game_parts[0], 2;
|
||||
my $id = $id_parts[1];
|
||||
my @game_plays = split /;/, $game_parts[1];
|
||||
foreach my $play (@game_plays) {
|
||||
my @color_counts = (0, 0, 0);
|
||||
my @play_draws = split /,/, $play;
|
||||
foreach my $draw (@play_draws) {
|
||||
my @draw_parts = split / /, $draw;
|
||||
my $color = $draw_parts[2];
|
||||
my $amount = int($draw_parts[1]);
|
||||
for ((0..2)) {
|
||||
my $idx = $_;
|
||||
my $limit_color = $colors[$idx];
|
||||
my $limit_amount = $quantities[$idx];
|
||||
if ($color eq $limit_color) {
|
||||
$color_counts[$idx] += $amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
# print join(", ", @color_counts) . "\n";
|
||||
for ((0..2)) {
|
||||
if ($quantities[$_] < $color_counts[$_]) {
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return int($id);
|
||||
}
|
||||
|
||||
my $reds_limit = 12;
|
||||
my $greens_limit = 13;
|
||||
my $blues_limit = 14;
|
||||
|
||||
my $sum = 0;
|
||||
while (<FH>) {
|
||||
# print $_;
|
||||
my $id = possible_id($_, $reds_limit, $greens_limit, $blues_limit);
|
||||
$sum += $id;
|
||||
# print $id . "\n";
|
||||
}
|
||||
|
||||
close(FH);
|
||||
|
||||
print $sum . "\n";
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
import numpy as np
|
||||
|
||||
with open("data/input.txt", "r") as f:
|
||||
games = f.read()
|
||||
|
||||
limits = {
|
||||
"red": 12,
|
||||
"green": 13,
|
||||
"blue": 14
|
||||
}
|
||||
|
||||
s = 0
|
||||
|
||||
for game in games.split("\n")[:-1]:
|
||||
parts = game.split(":")
|
||||
head = parts[0]
|
||||
identifier = head.split(" ")[1]
|
||||
max_counts = dict(red=0, green=0, blue=0)
|
||||
for draw in parts[1].split(";"):
|
||||
draw = draw.strip()
|
||||
for count in draw.split(","):
|
||||
count = count.strip()
|
||||
count_parts = count.split(" ")
|
||||
color = count_parts[1]
|
||||
amount = int(count_parts[0])
|
||||
if amount > max_counts[color]:
|
||||
max_counts[color] = amount
|
||||
s += np.prod(list(max_counts.values()))
|
||||
|
||||
print(s)
|
|
@ -1,47 +0,0 @@
|
|||
with open("data/input.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
table = [
|
||||
[item for item in row]
|
||||
for row in data.split("\n")
|
||||
]
|
||||
|
||||
symbols = "&~\"#'{([-|`_\\^`])}@)]=+}$£%*!§/:;,?<>"
|
||||
|
||||
|
||||
parts = []
|
||||
|
||||
positions = set()
|
||||
|
||||
for i in range(len(table)):
|
||||
for j in range(len(table[i])):
|
||||
letter = table[i][j]
|
||||
if letter in symbols:
|
||||
found = False
|
||||
for dx in [-1, 0, 1]:
|
||||
for dy in [-1, 0, 1]:
|
||||
y = i + dx
|
||||
x = j + dy
|
||||
if x >= 0 and x < len(table[i]) and y >= 0 and y <= len(table):
|
||||
number = ""
|
||||
digit = table[y][x]
|
||||
if digit != "." and digit.isdigit():
|
||||
number = digit
|
||||
found = True
|
||||
# Extend right
|
||||
shift = 1
|
||||
idx = x + shift
|
||||
while idx >= 0 and idx < len(table[y]) and table[y][idx] != "." and table[y][idx].isdigit():
|
||||
number = number + table[y][idx]
|
||||
idx += shift
|
||||
position = (y, idx)
|
||||
# Extend left
|
||||
shift = -1
|
||||
idx = x + shift
|
||||
while idx >= 0 and idx < len(table[y]) and table[y][idx] != "." and table[y][idx].isdigit():
|
||||
number = table[y][idx] + number
|
||||
idx += shift
|
||||
if position not in positions:
|
||||
positions.add(position)
|
||||
parts.append(int(number))
|
||||
print(sum(parts))
|
|
@ -1,51 +0,0 @@
|
|||
import numpy as np
|
||||
|
||||
with open("data/input.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
table = [
|
||||
[item for item in row]
|
||||
for row in data.split("\n")
|
||||
]
|
||||
|
||||
symbols = "&~\"#'{([-|`_\\^`])}@)]=+}$£%*!§/:;,?<>"
|
||||
|
||||
|
||||
gears = []
|
||||
|
||||
|
||||
for i in range(len(table)):
|
||||
for j in range(len(table[i])):
|
||||
letter = table[i][j]
|
||||
if letter == "*":
|
||||
gear_numbers = []
|
||||
positions = set()
|
||||
for dx in [-1, 0, 1]:
|
||||
for dy in [-1, 0, 1]:
|
||||
y = i + dx
|
||||
x = j + dy
|
||||
if x >= 0 and x < len(table[i]) and y >= 0 and y <= len(table):
|
||||
number = ""
|
||||
digit = table[y][x]
|
||||
if digit != "." and digit.isdigit():
|
||||
number = digit
|
||||
found = True
|
||||
# Extend right
|
||||
shift = 1
|
||||
idx = x + shift
|
||||
while idx >= 0 and idx < len(table[y]) and table[y][idx] != "." and table[y][idx].isdigit():
|
||||
number = number + table[y][idx]
|
||||
idx += shift
|
||||
position = (y, idx)
|
||||
# Extend left
|
||||
shift = -1
|
||||
idx = x + shift
|
||||
while idx >= 0 and idx < len(table[y]) and table[y][idx] != "." and table[y][idx].isdigit():
|
||||
number = table[y][idx] + number
|
||||
idx += shift
|
||||
if position not in positions:
|
||||
positions.add(position)
|
||||
gear_numbers.append(int(number))
|
||||
if len(gear_numbers) == 2:
|
||||
gears.append(np.prod(gear_numbers))
|
||||
print(sum(gears))
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/env perl
|
||||
use warnings;
|
||||
use strict;
|
||||
use List::Util;
|
||||
|
||||
my $filename = "./data/input.txt";
|
||||
|
||||
open(FH, '<', $filename) or die $!;
|
||||
|
||||
my $score = 0;
|
||||
while (<FH>) {
|
||||
my $card = $_;
|
||||
my $points = 0;
|
||||
my @parts = split /:/, $card;
|
||||
my @lists = split /\|/, $parts[1];
|
||||
my @winning = split ' ', $lists[0];
|
||||
my @numbers = split ' ', $lists[1];
|
||||
my @previous = ();
|
||||
foreach my $number (@numbers) {
|
||||
if ($number eq " ") {
|
||||
print $_;
|
||||
}
|
||||
if ((List::Util::any { $_ eq $number } @winning) && (List::Util::all { $_ ne $number } @previous)) {
|
||||
push(@previous, $number);
|
||||
if ($points == 0) {
|
||||
$points = 1;
|
||||
} else {
|
||||
$points *= 2;
|
||||
}
|
||||
# print $number . ", ";
|
||||
}
|
||||
}
|
||||
#if ($points == 0) {
|
||||
# print "no points" . "\n";
|
||||
#} else {
|
||||
# print $points . " points\n";
|
||||
#}
|
||||
$score += $points;
|
||||
}
|
||||
|
||||
print $score . "\n";
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import queue
|
||||
|
||||
with open("data/input.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
q = queue.Queue()
|
||||
|
||||
def winning_copies(card):
|
||||
lists = card.split(":")[1].split("|")
|
||||
winning = lists[0].split()
|
||||
numbers = lists[1].split()
|
||||
matching = 0
|
||||
for number in numbers:
|
||||
if number in winning:
|
||||
matching += 1
|
||||
return matching
|
||||
|
||||
cards = data.split("\n")
|
||||
cards.remove("")
|
||||
for i, card in enumerate(cards):
|
||||
q.put((i, card))
|
||||
|
||||
counter = 0
|
||||
while not q.empty():
|
||||
i, card = q.get()
|
||||
copies = winning_copies(card)
|
||||
if copies > 0:
|
||||
for j in range(1, copies+1):
|
||||
copy = cards[i+j]
|
||||
q.put((i+j, copy))
|
||||
counter += 1
|
||||
|
||||
print(counter)
|
|
@ -1,56 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# day 5 - Advent of Code 2023
|
||||
# part 1
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
with open("data/sample.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
parts = data.split("\n\n")
|
||||
|
||||
seeds = parts[0]
|
||||
seeds = seeds.split(": ")[1].split()
|
||||
seeds = list(map(int, seeds))
|
||||
|
||||
maps = [
|
||||
[
|
||||
[int(item) for item in values.split()]
|
||||
for values in themap.split("\n")[1:]
|
||||
if values != ""
|
||||
]
|
||||
for themap in parts[1:]
|
||||
]
|
||||
|
||||
|
||||
def recursive_min_descent(seed, maps):
|
||||
current = seed
|
||||
for submap in maps:
|
||||
for indication in submap:
|
||||
destination, source, size = indication
|
||||
return current
|
||||
|
||||
|
||||
"""
|
||||
soils = list(map(lambda seed: descent(seed, maps), seeds))
|
||||
|
||||
seeds = range(0, 99)
|
||||
|
||||
df = pd.DataFrame(
|
||||
dict(seed=seeds, soil=list(map(lambda seed: descent(seed, maps), seeds)))
|
||||
)
|
||||
|
||||
"""
|
||||
# Check that no map indication overlaps
|
||||
for submap in maps:
|
||||
for indication1 in submap:
|
||||
_, start1, range1 = indication1
|
||||
for indication2 in submap:
|
||||
if indication1 == indication2:
|
||||
continue
|
||||
_, start2, range2 = indication2
|
||||
if not (start2 > start1 + range1 or start1 > start2 + range2):
|
||||
print("overlap")
|
||||
|
||||
print(df)
|
|
@ -1,54 +0,0 @@
|
|||
use std::fs;
|
||||
|
||||
fn parse_steps(lines: std::str::Lines) -> Vec<Vec<Vec<u32>>> {
|
||||
let mut steps: Vec<Vec<Vec<u32>>> = Vec::new();
|
||||
let mut step: Vec<Vec<u32>> = Vec::new();
|
||||
for line in lines {
|
||||
if line.contains("-to-") {
|
||||
step = Vec::new();
|
||||
steps.push(step);
|
||||
} else if line != "" {
|
||||
let numbers: Vec<&str> = line.split(" ").collect();
|
||||
let numbers: Vec<u32> = numbers
|
||||
.iter()
|
||||
.map(|string| {
|
||||
let number: u32 = string.parse().unwrap();
|
||||
number
|
||||
})
|
||||
.collect();
|
||||
let n = steps.len();
|
||||
steps[n - 1].push(numbers);
|
||||
}
|
||||
}
|
||||
steps
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let filepath: &str = "../../data/sample.txt";
|
||||
|
||||
let contents = fs::read_to_string(filepath).expect("Should have been hable to read the file");
|
||||
|
||||
let mut lines = contents.lines();
|
||||
let seeds: Vec<&str> = lines
|
||||
.next()
|
||||
.unwrap()
|
||||
.split(": ")
|
||||
.nth(1)
|
||||
.expect("Should have a seed")
|
||||
.split(" ")
|
||||
.collect();
|
||||
let steps = parse_steps(lines);
|
||||
for step in steps {
|
||||
println!("{:?}", step);
|
||||
}
|
||||
let seeds: Vec<u32> = seeds
|
||||
.iter()
|
||||
.map(|string| {
|
||||
let number: u32 = string.trim().parse().unwrap();
|
||||
number
|
||||
})
|
||||
.collect();
|
||||
for seed in seeds {
|
||||
println!("{:?}", seed);
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
with open("data/input.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
data = data.split("\n")
|
||||
times = data[0].split(":")[1].split()
|
||||
distances = data[1].split(":")[1].split()
|
||||
|
||||
times = [int(i) for i in times]
|
||||
distances = [int(i) for i in distances]
|
||||
|
||||
# print(times)
|
||||
# print(distances)
|
||||
|
||||
product = 1
|
||||
|
||||
|
||||
def distance(pressed_duration, limit_duration):
|
||||
return pressed_duration * (limit_duration - pressed_duration)
|
||||
|
||||
|
||||
for time, dist in zip(times, distances):
|
||||
count = 0
|
||||
for i in range(0, time + 1):
|
||||
if distance(i, time) > dist:
|
||||
count += 1
|
||||
product *= count
|
||||
|
||||
print(product)
|
|
@ -1,28 +0,0 @@
|
|||
with open("data/sample.txt", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
data = data.split("\n")
|
||||
times = data[0].split(":")[1].replace(" ", "").split()
|
||||
distances = data[1].split(":")[1].replace(" ", "").split()
|
||||
|
||||
times = [int(i) for i in times]
|
||||
distances = [int(i) for i in distances]
|
||||
|
||||
# print(times)
|
||||
# print(distances)
|
||||
|
||||
product = 1
|
||||
|
||||
|
||||
def distance(pressed_duration, limit_duration):
|
||||
return pressed_duration * (limit_duration - pressed_duration)
|
||||
|
||||
|
||||
for time, dist in zip(times, distances):
|
||||
count = 0
|
||||
for i in range(0, time + 1):
|
||||
if distance(i, time) > dist:
|
||||
count += 1
|
||||
product *= count
|
||||
|
||||
print(product)
|
Loading…
Reference in New Issue