Solutions for 2022, as well as 2015-2018 and 2019 up to day 11

This commit is contained in:
Chris Alge 2023-03-12 15:20:02 +01:00
commit 1895197c49
722 changed files with 375457 additions and 0 deletions

View file

@ -0,0 +1,8 @@
[package]
name = "day12_hill_climbing_algorithm"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -0,0 +1,29 @@
You try contacting the Elves using your handheld device, but the river you're following must be too low to get a decent signal.
You ask the device for a heightmap of the surrounding area (your puzzle input). The heightmap shows the local area from above broken into a grid; the elevation of each square of the grid is given by a single lowercase letter, where a is the lowest elevation, b is the next-lowest, and so on up to the highest elevation, z.
Also included on the heightmap are marks for your current position (S) and the location that should get the best signal (E). Your current position (S) has elevation a, and the location that should get the best signal (E) has elevation z.
You'd like to reach E, but to save energy, you should do it in as few steps as possible. During each step, you can move exactly one square up, down, left, or right. To avoid needing to get out your climbing gear, the elevation of the destination square can be at most one higher than the elevation of your current square; that is, if your current elevation is m, you could step to elevation n, but not to elevation o. (This also means that the elevation of the destination square can be much lower than the elevation of your current square.)
For example:
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi
Here, you start in the top-left corner; your goal is near the middle. You could start by moving down or right, but eventually you'll need to head toward the e at the bottom. From there, you can spiral around to the goal:
v..v<<<<
>v.vv<<^
.>vv>E^^
..v>>>^^
..>>>>>^
In the above diagram, the symbols indicate whether the path exits each square moving up (^), down (v), left (<), or right (>). The location that should get the best signal is still E, and . marks unvisited squares.
This path reaches the goal in 31 steps, the fewest possible.
What is the fewest steps required to move from your current position to the location that should get the best signal?

View file

@ -0,0 +1,41 @@
abccccccccccccccccaaccccccccccccccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa
abcccccccccccccaaaaaccccccccccccccccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaa
abccccccccccccccaaaaaccccccccccccccaaaaacccaaaaaacccccaaccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaa
abccccccccccccccaaaaacccccccccaacccaaaaacccaaaaaaaccccaaaacaacaaccccccccccccccccccccccccaaaccccaaaccccccccccccaaaa
abcccccccccccccaaaaacccccccaaaaaccaaaaaacccaaaaaaaacaaaaaacaaaaaccccccccccccccccccccccccaaacccaaaaccccccccccccaaac
abccccccaacaaaccccaaccccccccaaaaacaaaaaaccaaaacaaaacaaaaaccaaaaaaccccccccccccccccccccccccaaaaaaaacccccccccccccaacc
abccccccaaaaaaccccccccccccccaaaaacaaaaaaccaaaaccaaaacaaaaacaaaaaacccccccccccccccccccccccaaaaaaaaaccccccccccccccccc
abccccccaaaaaacccccccccccccaaaaaccccaaccccaacccccaaccaacaacaaaaaccccccccccccccccccccccccccaaakkkkllllcccaaaccccccc
abccccccaaaaaaacccccccccccccccaaccccaacccccccccccccccccccccccaaaccccccaaaacccccccccjjjjkkkkkkkkkkllllccccaacaccccc
abcccccaaaaaaaacccccaaccccccccccccccaaaaaaccccccccccccccccccaaccccccccaaaaccccccccjjjjjkkkkkkkkkppllllcccaaaaacccc
abcccccaaaaaaaaccaaaacccccccccccccccaaaaaccccccccccccccccaacaaccccccccaaaacccccccjjjjjjjkkkkkppppppplllccaaaaacccc
abccccccccaaaccccaaaaaacccccccccccaaaaaaaccccccccccccccccaaaaacccccccccaacccccccjjjjoooooooppppppppplllcccaaaccccc
abccccccccaaccccccaaaaaccccaacccccaaaaaaaaccccaaacccccccccaaaaaaacccccccccccccccjjjooooooooppppuuppppllcccaaaccccc
abccccccaacccccccaaaaacccccaaaccaaaaaaaaaaccaaaaaaccccccaaaaaaaaaacaaaccccccccccjjjoooouuuoopuuuuupppllcccaaaccccc
abacccccaaccccccccccaacccccaaaaaaaccaaaaaaccaaaaaaccccccaaaaaccaaaaaaaccccaaccccjjoootuuuuuuuuuuuuvpqlllcccccccccc
abaccaaaaaaaacccccccccccccccaaaaaaccaacccccccaaaaacccccccacaaaccaaaaaaccaaaacaccjjooottuuuuuuuxyuvvqqljjccddcccccc
abcccaaaaaaaaccccccccccccaaaaaaaaacaacaaccccaaaaaccccccccccaaaaaaaaaacccaaaaaacciijootttxxxuuxyyyvvqqjjjjdddcccccc
abcccccaaaaccccaaacccccccaaaaaaaaacaaaaaccccaaaaaccccccccccccaaaaaaaaacccaaaaccciiinntttxxxxxxyyvvqqqqjjjddddccccc
abccccaaaaaccccaaaaacccccaaaaaaaaaaaaaaaaccccccccccccccccccccaaaaaaaaaaccaaaaccciiinntttxxxxxxyyvvvqqqqjjjdddccccc
abccccaaaaaaccaaaaaccccccccaaaaaaaaaaaaaacccccccccccccccccccccccaaacaaacaacaaccciiinnnttxxxxxyyyvvvvqqqqjjjdddcccc
SbccccaaccaaccaaaaacccccccccaaaaaaaaaaaaacccccccccccccccccccccccaaacccccccccccciiinnntttxxxEzzyyyyvvvqqqjjjdddcccc
abcccccccccccccaaaaacccccccaaaaaaaaacaaaccccccccccccccccccccccccaaccccccccccccciiinnnttxxxxyyyyyyyyvvvqqqjjjdddccc
abcccccccccccccaaccccccccccaaaaaaaaccccccccccccccccccccccccccccccccccccccccccciiinnntttxxyyyyyyyyyvvvvqqqjjjdddccc
abccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccciiinntttxxxwwwyyywwvvvvrqqjjjjdddccc
abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccciinnntttxwwwwwyyywwvvvrrrqkkkeddcccc
abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccchhnnntttsswwswwyywwrrrrrrkkkkeeecccc
abcccccccccccccccccccccccccccaaaaaacccccccccccccccccccaccccccccccccaaacccccccchhhnmmssssssswwwwwwrrrkkkkkeeeeecccc
abcccccccccccccccccccccccccccccaaacccccccccccccccccccaaccccccccccaaaaaacccccaahhhmmmmmsssssswwwwrrrkkkkkeeeeeccccc
abaacccccccccccccaccccccccccccccccccccccccccccccccaaaaacaacccccccaaaaaacaaaaaahhhhmmmmmmmmssswwwrrkkkkeeeeeacccccc
abacccccccccccccaaaaaaaaccccccccaaacccccccaaccccccaaaaaaaacccccccaaaaaacaaaaaaahhhhmmmmmmmmsssrrrrkkkeeeeeaacccccc
abaaaccccaaccccccaaaaaacccccccccaaacccaacaaaccccccccaaaacccccccccaaaaacccaaaaaaahhhhhhhmmmmlsssrrllkfeeeeaaaaacccc
abaaaccaaaaccccccaaaaaacccccccccaaaaaaaaaaaaaacccccaaaaacccccccccaaaaacccaaaaaaachhhhhgggmllsssrrllkffeaaaaaaacccc
abaacccaaaaaacccaaaaaaaacccccaaaaaaaaaaaaaaaaacccccaacaaacccccccccccccccaaaaaacccccchggggglllllllllfffaaaaaaaacccc
abaaccccaaaacccaaaaaaaaaaccccaaaaaaaaacaaaaaaaccaccaccaaacccccccccccccccaaaaaacccccccccgggglllllllffffaaaaaacccccc
abcccccaaaaacccaaaaaaaaaacccccaaaaaaaccaaaaacccaaaccccccccccccccccccccccccccaacccccccccagggglllllffffccccaaacccccc
abcccccaacaaccccccaaaaacaccaacccaaaaaaaaaaaaaccaaacccccccccccccccccccccccccccccccccccccaagggggffffffcccccccccccccc
abcccccccccccaaaaaaaaacccccaaccaaaaaaaccaaaaacaaaaccccccccccccccccccccccccccccccccccccaaaacgggfffffccccccccccccccc
abcccccccccccaaaaacaacccaaaaaaaaaaccaacccaaaaaaaacccaaccccccccccccccccccccccccccccccccccccccggfffccccccccccccaaaca
abccccccccccaaaaaaccccccaaaaaaaaacccccccccaaaaaaaaaaaacccccccccccccaaaccccccccccccccccccccccaaaccccccccccccccaaaaa
abccccccccccaaaaaaccccccccaaaacccccccccccccaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccaaaccccccccccccccaaaa
abcccccccccccaaaaacccccccaaaaaaccccccccccaaaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccccccccccccccccccaaaaa

View file

@ -0,0 +1,271 @@
use std::u8;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct Coordinate {
x: u8,
y: u8,
}
impl Coordinate {
pub fn from(x: u8, y: u8) -> Self {
Self {
x,
y,
}
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Position {
height: u8,
coordinate: Coordinate,
max: Coordinate,
}
impl Position {
/// Constructs a Position from its components.
///
/// Parameters:
/// - height: The elevation at this position. Assumed to be within 0..=25.
/// - coordinate: The Coordinates of this position.
/// - max: The South-Eastern-most Coordinate of the map. This is stored here, so the map does
/// not have to be queried for its dimensions at every neighbour lookup. Anything south or east
/// of this Coordinate will not be considered part of the map.
pub fn from(height: u8, coordinate: Coordinate, max: Coordinate) -> Self {
Self {
height,
coordinate,
max,
}
}
/// Returns this Position's coordinate component
pub fn coordinate(&self) -> Coordinate {
self.coordinate
}
/// Returns this Position's height component
pub fn height(&self) -> u8 {
self.height
}
/// Finds all direct neighbours of this Position in the 4 cardinal directions as a Vector of
/// Coordinates. This will not return any Coordinates outside the grid. The order of
/// Coordinates in the result is always
///
/// 1. Western neighbour,
/// 2. Northern neighbour,
/// 3. Southern neighbour,
/// 4. Eastern neighbour,
///
/// skipping any that would be outside the grid.
///
/// # Examples
/// ```
/// use day12_hill_climbing_algorithm::*;
/// let this_position = Position::from(0, Coordinate::from(2, 1), Coordinate::from(2, 1));
///
/// assert_eq!(this_position.neighbours(), vec![
/// Coordinate::from(1, 1),
/// Coordinate::from(2, 0),
/// ]);
/// ```
pub fn neighbours(&self) -> Vec<Coordinate> {
let mut out = Vec::new();
if self.coordinate.x > 0 {
out.push(Coordinate { x: self.coordinate.x - 1, y: self.coordinate.y });
}
if self.coordinate.y > 0 {
out.push(Coordinate { x: self.coordinate.x, y: self.coordinate.y - 1 });
}
if self.coordinate.y < self.max.y {
out.push(Coordinate { x: self.coordinate.x, y: self.coordinate.y + 1 });
}
if self.coordinate.x < self.max.x {
out.push(Coordinate { x: self.coordinate.x + 1, y: self.coordinate.y });
}
out
}
/// Finds all direct neighbours of this Position, that can reach it directly, meaning their heigth is no
/// more than one unit below the height of this cell.
///
/// Parameters:
/// - self: This Position
/// - grid: A 2D-Array of the map, where each element denotes the height at the coordinate
/// represented by its indices.
///
/// Returns:
/// A Vector of all Coordinates that can reach this Position directly. The order is always
/// West, North, South, East, skipping any that would be outside the grid or can't reach this
/// Position directly.
///
/// # Examples
/// ```
/// use day12_hill_climbing_algorithm::*;
/// let this_position = Position::from(2, Coordinate::from(2, 1), Coordinate::from(2, 2));
/// let grid = vec![
/// vec![0, 4, 0],
/// vec![1, 3, 2],
/// vec![2, 3, 1],
/// ];
///
/// assert_eq!(this_position.reverse_reachable_neighbours(&grid), vec![
/// Coordinate::from(1, 1), // The western neighbour can reach us because they are heigher than us.
/// Coordinate::from(2, 2), // The southern neighbour can reach us because they are only 1 below us.
/// // But the northern neighbour can't reach us because they are more than 1 below us.
/// ]);
/// ```
pub fn reverse_reachable_neighbours(&self, grid: &[Vec<u8>]) -> Vec<Coordinate> {
self.neighbours()
.iter()
.filter(|neighbour| grid[neighbour.y as usize][neighbour.x as usize]>=self.height.saturating_sub(1))
.copied()
.collect()
}
}
/// For a given destination, returns all starting positions in the grid that can reach the
/// destination as a 2D-vector where the first dimension represents the distance to the destination.
/// So `result[0]` will be a vector that only contains the destination itself (0 steps removed from
/// it), `result[1]` will contain all its direct neighbours that can reach it, and so on. Generally
/// `result[n]` will contain any Position that needs exactly n steps to reach the destination on its
/// shortest path.
///
/// Parameters:
/// - destination: The `Position` the network is centered on. The distances will be in relation to
/// this.
/// - grid: The complete map as a 2D-Array, where each element represents the height at the
/// Position denoted by its indices.
///
/// Returns:
/// A 2D-Vector containing all `Position` that can reach the destination in any way. The index of
/// its first dimension equals the distance from that Position to the destination, meaning all
/// Positions in `result[n]` are exactly `n` steps away from the destination on their shortest
/// path. The index of the second dimension has no inherent meaning.
///
/// # Examples
/// ```
/// use day12_hill_climbing_algorithm::*;
/// let max = Coordinate::from(2, 2);
/// let this_position = Position::from(4, max, max);
/// let grid = vec![
/// vec![0, 4, 0],
/// vec![1, 4, 3],
/// vec![2, 3, 4],
/// ];
///
/// assert_eq!(get_network_to(this_position, &grid), vec![
/// vec![ this_position ],
/// vec![
/// Position::from(3, Coordinate::from(1, 2), max),
/// Position::from(3, Coordinate::from(2, 1), max), ],
/// vec![
/// Position::from(2, Coordinate::from(0, 2), max),
/// Position::from(4, Coordinate::from(1, 1), max), ],
/// vec![
/// Position::from(1, Coordinate::from(0, 1), max),
/// Position::from(4, Coordinate::from(1, 0), max), ],
/// vec![
/// Position::from(0, Coordinate::from(0, 0), max), ],
/// ]);
/// ```
pub fn get_network_to(destination: Position, grid: &[Vec<u8>]) -> Vec<Vec<Position>> {
let mut network = vec![vec![destination]];
loop {
let last_distance = &network[network.len()-1];
let mut new_this_distance = Vec::new();
last_distance.iter().for_each(|last_position| {
last_position.reverse_reachable_neighbours(grid).iter().for_each(|neighbour| {
let neighbour_position = Position {
coordinate: *neighbour,
height: grid[neighbour.y as usize][neighbour.x as usize],
max: destination.max,
};
if !network.iter().flatten().any(|position| position == &neighbour_position) && !new_this_distance.contains(&neighbour_position) {
new_this_distance.push(neighbour_position);
}
});
});
if new_this_distance.is_empty() {
break;
}
network.push(new_this_distance);
}
network
}
/// Converts a String-encoded map into the grid representation and finds the starting point, ending
/// point and the last represented point of the grid.
///
/// Parameters:
/// - map: A str representing the grid. This is assumed to be written in a recangular fassion (so
/// all lines are of equal length and no positions are empty), where the line number indicates the
/// North-South component of a coordinate and the position inside the line (or its column)
/// indicates the East-West component. The first character is assumed to be the North-Western-most
/// point of the grid. Each character is assumed to represent:
/// - the elevation at this coordinate, indicated by a lowercase letter, whose position in the
/// English alphabet denotes the elevation (a=0, b=1, c=2, ... z=25), or
/// - the starting position, indicated by an uppercase S, and assumed to be at elevation 0, or
/// - the end position, indicated by an uppercase E, and assumed to be at elevation 25.
///
/// Returns:
/// - grid: A 2D-Vector of u8, containing the same elevation data as `map`, but in a numerical format.
/// The layout is the same as in map, so `grid[y][x]` will be the elevation indicated by the x'th
/// character in line y (both 0-indexed) of map.
/// - start: The Coordinate of the last character marked with an uppercase S in the map. It is
/// assumed to have elevation 0.
/// - end: The Coordinate of the last character marked with an uppercase E in the map. It is
/// assumed to have elevation 25.
/// - max: The Coordinate of the last character in the last line of map. This is used to
/// determine the extent of the map.
///
/// # Panics
///
/// This panics if map contains lines of different length.
///
/// # Examples
/// ```
/// use day12_hill_climbing_algorithm::*;
/// let map = "Sabqponm\nabcryxxl\naccszExk\nacctuvwj\nabdefghi";
/// let (grid, start, end, max) = parse(map);
/// assert_eq!(grid, vec![
/// vec![0, 0, 1, 16, 15, 14, 13, 12],
/// vec![0, 1, 2, 17, 24, 23, 23, 11],
/// vec![0, 2, 2, 18, 25, 25, 23, 10],
/// vec![0, 2, 2, 19, 20, 21, 22, 9],
/// vec![0, 1, 3, 4, 5, 6, 7, 8],
/// ]);
/// assert_eq!(start, Coordinate::from(0, 0));
/// assert_eq!(end, Coordinate::from(5, 2));
/// assert_eq!(max, Coordinate::from(7, 4));
/// ```
///
pub fn parse(map: &str) -> (Vec<Vec<u8>>, Coordinate, Coordinate, Coordinate) {
let mut grid = Vec::new();
let mut start = Coordinate { x: 0, y: 0, };
let mut end = Coordinate { x: 0, y: 0, };
for row in 0..map.lines().count() {
let mut this_row = Vec::new();
for charcode in map.lines().nth(row).unwrap().bytes() {
match charcode {
b'S' => { start = Coordinate { x: this_row.len() as u8, y: row as u8, }; this_row.push(0); },
b'E' => { end = Coordinate { x: this_row.len() as u8, y: row as u8, }; this_row.push(25); },
c => this_row.push(c - b'a'),
}
}
grid.push(this_row);
}
let max = Coordinate {
x: grid[0].len() as u8 - 1,
y: grid.len() as u8 - 1,
};
grid.iter().enumerate().for_each(|(idx, row)| {
if row.len() != max.x as usize + 1 {
panic!("Tried to parse a non-rectangular map. Row {idx} has {} characters, but row 0 has {}.", row.len(), max.x + 1);
}
});
(grid, start, end, max)
}

View file

@ -0,0 +1,67 @@
use std::fs;
use day12_hill_climbing_algorithm::*;
/// Reads the file at the given path from the file system and returns its contents as a String.
fn read_file(path: &str) -> String {
fs::read_to_string(path)
.expect("File not Found")
}
fn get_length<F>(dest_network: &[Vec<Position>], start_condition: F) -> usize where
F: Fn(&Position) -> bool + Copy {
dest_network.iter()
.enumerate()
.find(|(_length, positions)| positions.iter().any(start_condition))
.unwrap()
.0
}
fn main() {
//let map = read_file("sample_input");
let map = read_file("input");
let (grid, start, end, max) = parse(&map);
let end_position = Position::from(25, end, max);
let dest_network = get_network_to(end_position, &grid);
let start_finish_length = get_length(&dest_network, |position| position.coordinate() == start);
println!("We can get from start to end in {} steps.", start_finish_length);
let shortest_scenic = get_length(&dest_network, |position| position.height() == 0);
println!("The shortest scenic route is {} steps long.", shortest_scenic);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sample_input_matches_challenge() {
let map = read_file("tests/sample_input");
let (grid, start, end, max) = parse(&map);
let end_position = Position::from(25, end, max);
let dest_network = get_network_to(end_position, &grid);
let start_finish_length = get_length(&dest_network, |position| position.coordinate() == start);
assert_eq!(start_finish_length, 31);
let shortest_scenic = get_length(&dest_network, |position| position.height() == 0);
assert_eq!(shortest_scenic, 29)
}
#[test]
fn challenge_input_matches_solution() {
let map = read_file("tests/input");
let (grid, start, end, max) = parse(&map);
let end_position = Position::from(25, end, max);
let dest_network = get_network_to(end_position, &grid);
let start_finish_length = get_length(&dest_network, |position| position.coordinate() == start);
assert_eq!(start_finish_length, 425);
let shortest_scenic = get_length(&dest_network, |position| position.height() == 0);
assert_eq!(shortest_scenic, 418)
}
}

View file

@ -0,0 +1,41 @@
abccccccccccccccccaaccccccccccccccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa
abcccccccccccccaaaaaccccccccccccccccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaaa
abccccccccccccccaaaaaccccccccccccccaaaaacccaaaaaacccccaaccccccccccccccccccccccccccccccccccccccccccccccccccccccaaaa
abccccccccccccccaaaaacccccccccaacccaaaaacccaaaaaaaccccaaaacaacaaccccccccccccccccccccccccaaaccccaaaccccccccccccaaaa
abcccccccccccccaaaaacccccccaaaaaccaaaaaacccaaaaaaaacaaaaaacaaaaaccccccccccccccccccccccccaaacccaaaaccccccccccccaaac
abccccccaacaaaccccaaccccccccaaaaacaaaaaaccaaaacaaaacaaaaaccaaaaaaccccccccccccccccccccccccaaaaaaaacccccccccccccaacc
abccccccaaaaaaccccccccccccccaaaaacaaaaaaccaaaaccaaaacaaaaacaaaaaacccccccccccccccccccccccaaaaaaaaaccccccccccccccccc
abccccccaaaaaacccccccccccccaaaaaccccaaccccaacccccaaccaacaacaaaaaccccccccccccccccccccccccccaaakkkkllllcccaaaccccccc
abccccccaaaaaaacccccccccccccccaaccccaacccccccccccccccccccccccaaaccccccaaaacccccccccjjjjkkkkkkkkkkllllccccaacaccccc
abcccccaaaaaaaacccccaaccccccccccccccaaaaaaccccccccccccccccccaaccccccccaaaaccccccccjjjjjkkkkkkkkkppllllcccaaaaacccc
abcccccaaaaaaaaccaaaacccccccccccccccaaaaaccccccccccccccccaacaaccccccccaaaacccccccjjjjjjjkkkkkppppppplllccaaaaacccc
abccccccccaaaccccaaaaaacccccccccccaaaaaaaccccccccccccccccaaaaacccccccccaacccccccjjjjoooooooppppppppplllcccaaaccccc
abccccccccaaccccccaaaaaccccaacccccaaaaaaaaccccaaacccccccccaaaaaaacccccccccccccccjjjooooooooppppuuppppllcccaaaccccc
abccccccaacccccccaaaaacccccaaaccaaaaaaaaaaccaaaaaaccccccaaaaaaaaaacaaaccccccccccjjjoooouuuoopuuuuupppllcccaaaccccc
abacccccaaccccccccccaacccccaaaaaaaccaaaaaaccaaaaaaccccccaaaaaccaaaaaaaccccaaccccjjoootuuuuuuuuuuuuvpqlllcccccccccc
abaccaaaaaaaacccccccccccccccaaaaaaccaacccccccaaaaacccccccacaaaccaaaaaaccaaaacaccjjooottuuuuuuuxyuvvqqljjccddcccccc
abcccaaaaaaaaccccccccccccaaaaaaaaacaacaaccccaaaaaccccccccccaaaaaaaaaacccaaaaaacciijootttxxxuuxyyyvvqqjjjjdddcccccc
abcccccaaaaccccaaacccccccaaaaaaaaacaaaaaccccaaaaaccccccccccccaaaaaaaaacccaaaaccciiinntttxxxxxxyyvvqqqqjjjddddccccc
abccccaaaaaccccaaaaacccccaaaaaaaaaaaaaaaaccccccccccccccccccccaaaaaaaaaaccaaaaccciiinntttxxxxxxyyvvvqqqqjjjdddccccc
abccccaaaaaaccaaaaaccccccccaaaaaaaaaaaaaacccccccccccccccccccccccaaacaaacaacaaccciiinnnttxxxxxyyyvvvvqqqqjjjdddcccc
SbccccaaccaaccaaaaacccccccccaaaaaaaaaaaaacccccccccccccccccccccccaaacccccccccccciiinnntttxxxEzzyyyyvvvqqqjjjdddcccc
abcccccccccccccaaaaacccccccaaaaaaaaacaaaccccccccccccccccccccccccaaccccccccccccciiinnnttxxxxyyyyyyyyvvvqqqjjjdddccc
abcccccccccccccaaccccccccccaaaaaaaaccccccccccccccccccccccccccccccccccccccccccciiinnntttxxyyyyyyyyyvvvvqqqjjjdddccc
abccccccccccccccccccccccccaaaaaaaacccccccccccccccccccccccccccccccccccccccccccciiinntttxxxwwwyyywwvvvvrqqjjjjdddccc
abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccciinnntttxwwwwwyyywwvvvrrrqkkkeddcccc
abcccccccccccccccccccccccccccaaaaaaccccccccccccccccccccccccccccccccccccccccccchhnnntttsswwswwyywwrrrrrrkkkkeeecccc
abcccccccccccccccccccccccccccaaaaaacccccccccccccccccccaccccccccccccaaacccccccchhhnmmssssssswwwwwwrrrkkkkkeeeeecccc
abcccccccccccccccccccccccccccccaaacccccccccccccccccccaaccccccccccaaaaaacccccaahhhmmmmmsssssswwwwrrrkkkkkeeeeeccccc
abaacccccccccccccaccccccccccccccccccccccccccccccccaaaaacaacccccccaaaaaacaaaaaahhhhmmmmmmmmssswwwrrkkkkeeeeeacccccc
abacccccccccccccaaaaaaaaccccccccaaacccccccaaccccccaaaaaaaacccccccaaaaaacaaaaaaahhhhmmmmmmmmsssrrrrkkkeeeeeaacccccc
abaaaccccaaccccccaaaaaacccccccccaaacccaacaaaccccccccaaaacccccccccaaaaacccaaaaaaahhhhhhhmmmmlsssrrllkfeeeeaaaaacccc
abaaaccaaaaccccccaaaaaacccccccccaaaaaaaaaaaaaacccccaaaaacccccccccaaaaacccaaaaaaachhhhhgggmllsssrrllkffeaaaaaaacccc
abaacccaaaaaacccaaaaaaaacccccaaaaaaaaaaaaaaaaacccccaacaaacccccccccccccccaaaaaacccccchggggglllllllllfffaaaaaaaacccc
abaaccccaaaacccaaaaaaaaaaccccaaaaaaaaacaaaaaaaccaccaccaaacccccccccccccccaaaaaacccccccccgggglllllllffffaaaaaacccccc
abcccccaaaaacccaaaaaaaaaacccccaaaaaaaccaaaaacccaaaccccccccccccccccccccccccccaacccccccccagggglllllffffccccaaacccccc
abcccccaacaaccccccaaaaacaccaacccaaaaaaaaaaaaaccaaacccccccccccccccccccccccccccccccccccccaagggggffffffcccccccccccccc
abcccccccccccaaaaaaaaacccccaaccaaaaaaaccaaaaacaaaaccccccccccccccccccccccccccccccccccccaaaacgggfffffccccccccccccccc
abcccccccccccaaaaacaacccaaaaaaaaaaccaacccaaaaaaaacccaaccccccccccccccccccccccccccccccccccccccggfffccccccccccccaaaca
abccccccccccaaaaaaccccccaaaaaaaaacccccccccaaaaaaaaaaaacccccccccccccaaaccccccccccccccccccccccaaaccccccccccccccaaaaa
abccccccccccaaaaaaccccccccaaaacccccccccccccaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccaaaccccccccccccccaaaa
abcccccccccccaaaaacccccccaaaaaaccccccccccaaaaaaaaaaaaaaccccccccccccaaaaccccccccccccccccccccccccccccccccccccccaaaaa

View file

@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi