Commits vergleichen

..

4 Commits

Autor SHA1 Nachricht Datum
1ff9286276 solved day 9 and deduplicated some code 2024-12-09 10:57:41 +01:00
9d807bbc75 moved kartesian and euclidian systems to theis own modules.
no breaking api change
2024-12-08 11:14:33 +01:00
8e7e46f47f updated old solutions
* splitspace is now parsing
* added  some examples(04 is syntetic)
2024-12-08 02:04:16 +01:00
61c433eab7 updated day one to reflext api changes 2024-12-08 01:44:21 +01:00
16 geänderte Dateien mit 684 neuen und 335 gelöschten Zeilen

6
examples/2024/01.txt Normale Datei
Datei anzeigen

@ -0,0 +1,6 @@
3 4
4 3
2 5
1 3
3 9
3 3

6
examples/2024/02.txt Normale Datei
Datei anzeigen

@ -0,0 +1,6 @@
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9

17
examples/2024/04.txt Normale Datei
Datei anzeigen

@ -0,0 +1,17 @@
S.MX
.A.M
S.MA
M.MS
.A..
S.S.
S.S.
.A..
M.M.
M.SS
.A.A
M.SM
SAMX
....
M...
AA..
S.S.

10
examples/2024/06.txt Normale Datei
Datei anzeigen

@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

1
examples/2024/09.txt Normale Datei
Datei anzeigen

@ -0,0 +1 @@
2333133121414131402

Datei anzeigen

@ -1,4 +1,4 @@
use advent_of_code::strings::{get_numbers, get_string_numbers};
use advent_of_code::strings::{convert_to_array, get_numbers, get_string_numbers};
#[allow(unused_imports)]
use advent_of_code::{include_data, include_example};
@ -7,7 +7,8 @@ include_data!(DATAb 2023 01b);
fn main() {
let mut sum: u32 = 0;
for coordinates in DATAa.split('\n').map(get_numbers) {
for coordinates in convert_to_array::<_, _, '\n'>(DATAa, get_numbers::<u32>) {
if coordinates.len() == 0 {
continue;
}

Datei anzeigen

@ -1,9 +1,18 @@
use advent_of_code::strings::{convert_to_array, parsenumber, splitspace};
use advent_of_code::strings::{convert_to_array, parsenumber};
#[allow(unused_imports)]
use advent_of_code::{include_data, include_example};
include_data!(DATA 2024 01);
pub fn splitspace(input: &str) -> (u32, u32) {
println!("{}", input);
let mut output = input.split_ascii_whitespace();
(
parsenumber(output.next().unwrap()),
parsenumber(output.next().unwrap()),
)
}
fn distance(leftlist: &Vec<u32>, rightlist: &Vec<u32>) -> u32 {
let mut distance = 0;
for i in 0..leftlist.len() {
@ -38,8 +47,8 @@ fn main() {
let mut leftlist = Vec::<u32>::with_capacity(1000);
let mut rightlist = Vec::<u32>::with_capacity(1000);
for (left, right) in convert_to_array::<_, _, '\n'>(DATA, splitspace) {
leftlist.push(parsenumber(left));
rightlist.push(parsenumber(right));
leftlist.push(left);
rightlist.push(right);
}
leftlist.sort();
rightlist.sort();

Datei anzeigen

@ -101,7 +101,7 @@ fn safe(record: Vec<u32>) -> bool {
}
fn main() {
let numbers = convert_to_array::<_,_,'\n'>(DATA, get_numbers);
let numbers = convert_to_array::<_, _, '\n'>(DATA, get_numbers);
let mut safe_reports = 0;
let mut safe_with_dampener = 0;
for report in numbers {

Datei anzeigen

@ -31,8 +31,8 @@ fn main() {
("do()", _) => parse = true,
("don't()", _) => parse = false,
(_, true) => {
let a = parsenumber(capture.name("i").unwrap().as_str());
let b = parsenumber(capture.name("j").unwrap().as_str());
let a = parsenumber::<u32>(capture.name("i").unwrap().as_str());
let b = parsenumber::<u32>(capture.name("j").unwrap().as_str());
sum += a * b
}
(_, _) => {}

Datei anzeigen

@ -1,78 +1,220 @@
#[allow(unused_variables)]
use std::ops::RangeInclusive;
use std::ops::Neg;
#[allow(unused_variables)]
#[allow(unused_imports)]
use advent_of_code::{include_data, include_example};
use advent_of_code::{
matrix,
strings::{convert_to_array, line_to_char},
};
include_data!(DATA 2024 04);
include_example!(DATA 2024 04);
#[derive(Debug, Clone)]
enum Direction {
Forward(usize, usize),
Backward(usize, usize),
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
struct TextPos {
startx: usize,
starty: usize,
endx: usize,
endy: usize,
length: usize,
}
impl Direction {
fn iter(&self) -> RangeInclusive<usize> {
let (from, to) = match self {
Direction::Forward(from, to) => (from, to),
Direction::Backward(to, from) => (from, to),
};
*from..=*to
#[inline]
fn dist(a: (usize, usize), b: (usize, usize)) -> (i32, i32) {
(a.0 as i32 - b.0 as i32, a.1 as i32 - b.1 as i32)
}
#[inline]
fn dist_abs(a: (usize, usize), b: (usize, usize)) -> (usize, usize) {
let t = dist(a, b);
(t.0.abs() as usize, t.1.abs() as usize)
}
impl TextPos {
const fn center(self) -> (usize, usize) {
(
self.startx.saturating_add(self.endx).div_ceil(2),
self.starty.saturating_add(self.endy).div_ceil(2),
)
}
fn crossing(self, other: &&Self) -> bool {
if self.length != other.length && self.length != 3 {
todo!()
}
if self.center() != other.center() {
return false;
}
true
}
}
fn main() {
let table: Vec<Vec<char>> = DATA
.split('\n')
.map(|line| line.chars().collect())
.collect();
let length = table[0].len();
let mut xmas;
let mut amount = 0;
let directions = [
Direction::Forward(0, length - 1),
Direction::Backward(0, length - 1),
#[test]
fn test_crossing() {
let cases = [
(
TextPos {
startx: 0,
starty: 0,
endx: 2,
endy: 2,
length: 3,
},
TextPos {
startx: 0,
starty: 0,
endx: 2,
endy: 2,
length: 3,
},
true,
),
(
TextPos {
startx: 1,
starty: 0,
endx: 1,
endy: 2,
length: 3,
},
TextPos {
startx: 0,
starty: 1,
endx: 2,
endy: 1,
length: 3,
},
true,
),
(
TextPos {
startx: 0,
starty: 0,
endx: 2,
endy: 0,
length: 3,
},
TextPos {
startx: 1,
starty: 0,
endx: 2,
endy: 0,
length: 3,
},
false,
),
];
for r in directions.clone() {
for c in directions.clone() {
println!("Horizontal: {:?}, vertical: {:?}", r.clone(), c.clone());
for row in r.iter() {
xmas = 0;
for column in c.iter() {
println!(
"Row {}, Column {}, dir {:?} {:?}",
row,
column,
r.clone(),
c.clone()
);
match (xmas, table[row][column]) {
(_x, 'X') => {
xmas = 1;
//println!("Found X, previous was {}", _x)
}
(1, 'M') => {
xmas = 2;
//println!("Found XM")
}
(2, 'A') => {
xmas = 3;
//println!("Found XMA")
}
(3, 'S') => {
xmas = 0;
amount += 1;
//println!("found XMAS in {}:{}", row, column);
}
(_x, _ch) => {
xmas = 0;
//println!("Reset, was {}({})", _x, _ch)
for case in cases {
assert_eq!(case.0.crossing(&&case.1), case.2)
}
}
fn valid(x: usize, y: i32, max: usize) -> Option<usize> {
let tmp = if y < 0 {
x.checked_sub(y.neg() as usize)
} else {
x.checked_add(y as usize)
};
if let Some(xi) = tmp {
if xi < max {
return Some(xi);
}
}
None
}
fn validxy(
x: usize,
y: usize,
modx: i32,
mody: i32,
heigth: usize,
length: usize,
) -> Option<(usize, usize)> {
if let Some(xi) = valid(x, modx, length) {
if let Some(yi) = valid(y, mody, heigth) {
return Some((xi, yi));
}
}
None
}
fn find_text(data: Vec<Vec<char>>, length: usize, heigth: usize, text: &str) -> (usize, usize) {
let first: char = text.chars().nth(0).unwrap();
let mut amount = 0;
let mut found;
let mut character;
let mut chars;
let mut coords = Vec::new();
let mut currentpos;
for row in 0..heigth {
for column in 0..length {
let char = data[row][column];
if char != first {
continue;
}
for (x, y) in matrix(false, true, true) {
if x == y && y == 0 {
continue;
}
found = 1;
chars = text.chars();
chars.next();
loop {
character = chars.next();
if character == None {
amount += 1;
currentpos = TextPos {
startx: row,
starty: column,
endx: (row as i32 + x * found) as usize,
endy: (column as i32 + y * found) as usize,
length: text.len(),
};
coords.push(currentpos);
break;
}
if let Some((posmodx, posmody)) =
validxy(row, column, x * found, y * found, length, heigth)
{
if data[posmodx][posmody] == character.unwrap() {
found += 1;
} else {
break;
}
} else {
break;
}
}
}
}
}
println!("There are {} XMAS in text", amount);
let mut xtexts = Vec::new();
for node in coords.clone() {
for o in coords.iter().filter(|other| node.crossing(other)) {
let other = *o;
if node == other {
continue;
}
let x = (node.min(other), node.max(other));
if !xtexts.contains(&x) {
xtexts.push(x);
}
}
}
println!("{:?}", xtexts);
(amount, xtexts.len())
}
fn main() {
let table = convert_to_array(DATA, line_to_char);
let length = table[0].len();
let (amount, _) = find_text(table.clone(), length, table.len(), "XMAS");
println!("There are {} XMAS in text", amount);
let (amount, amount_cross) = find_text(table.clone(), length, table.len(), "MAS");
println!(
"There are {} MAS in text, are {} crossed",
amount, amount_cross
);
}

149
src/bin/2024/09.rs Normale Datei
Datei anzeigen

@ -0,0 +1,149 @@
use advent_of_code::strings::char_to_num;
#[allow(unused_imports)]
use advent_of_code_macros::{include_data, include_example};
include_data!(DATA 2024 09);
type Disk = Vec<Option<u64>>;
fn print_disk(disk: Disk, columns: bool) {
if columns {
for i in 1..=disk.len() {
print!("{:02}", i);
}
println!()
}
for block in disk {
match block {
None => print!(" "),
Some(x) => print!("{} ", x),
}
}
println!(";")
}
fn layout_to_disk(layout: Vec<u64>) -> Disk {
let mut disk = Vec::new();
let mut space = false;
let mut block;
let mut blockid = 0;
for blocksize in layout {
block = if space {
None
} else {
blockid += 1;
Some(blockid - 1)
};
for _ in 0..blocksize {
disk.push(block);
}
space = !space;
}
disk
}
fn calculate_checksum(disk: Disk) -> u64 {
let iter = disk.iter();
let mut checksum = 0;
let mut position = 0;
for block in iter {
if block.is_some() {
checksum += block.unwrap() * position;
}
position += 1;
}
checksum
}
fn compact_blocks(disk: &mut Disk) {
let mut lastblock = disk.len() - 1;
let mut block = 0;
loop {
if disk[block].is_none() {
if disk[lastblock].is_some() {
disk[block] = disk[lastblock];
disk[lastblock] = None;
block += 1;
}
lastblock -= 1;
} else {
block += 1
}
if lastblock <= block {
break;
}
}
}
fn move_blocks(disk: &mut Disk, file_start: usize, length: usize, new_start: usize) {
for i in 0..=length {
disk[new_start + i] = disk[file_start - length + i];
disk[file_start - length + i] = None;
}
}
fn compact_files(disk: &mut Disk) {
let mut length;
let mut fileid;
let mut spaceblock;
let mut block;
let mut endblock = disk.len();
//print_disk(disk.clone(), true);
loop {
endblock -= 1;
if endblock == 0 {
break;
}
if disk[endblock].is_some() {
fileid = disk[endblock];
length = 0;
while disk[endblock - length] == fileid {
if endblock - length - 1 == 0 {
break;
}
length += 1;
}
if length == 0 {
break;
}
length -= 1;
block = 0;
loop {
if block + length >= disk.len() || block + length >= endblock {
endblock -= length;
break;
}
spaceblock = disk.get(block..=block + length).unwrap();
if spaceblock.iter().all(Option::is_none) {
move_blocks(disk, endblock, length, block);
break;
}
block += 1;
}
}
//print_disk(disk.clone(), false);
}
}
fn main() {
let mut layout = Vec::with_capacity(DATA.len());
for char in DATA.chars() {
layout.push(char_to_num(char));
}
let raw_disk = layout_to_disk(layout);
println!("Layout parsed");
let mut block_disk = raw_disk.clone();
let mut file_disk = raw_disk.clone();
compact_blocks(&mut block_disk);
let mut cksum = calculate_checksum(block_disk);
println!(
"Checksum for the blockcompacted disk is: {}",
cksum
);
compact_files(&mut file_disk);
cksum = calculate_checksum(file_disk);
println!(
"Checksum for the filecompacted disk is: {}",
cksum,
);
}

Datei anzeigen

@ -0,0 +1,63 @@
use num::*;
use std::ops::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Euclidian<T>
where
T: Integer,
{
pub x: T,
pub y: T,
pub z: T,
}
impl<T: Integer> Add for Euclidian<T> {
fn add(self, rhs: Self) -> Self::Output {
Euclidian {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
type Output = Euclidian<T>;
}
impl<T: Integer + AddAssign> AddAssign for Euclidian<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
self.z += rhs.z;
}
}
impl<T: Integer> Sub for Euclidian<T> {
fn sub(self, rhs: Self) -> Self::Output {
Euclidian {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
type Output = Euclidian<T>;
}
impl<T: Integer + SubAssign> SubAssign for Euclidian<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
self.z -= rhs.z;
}
}
impl<T: Integer> Euclidian<T> {
pub const fn new(x: T, y: T, z: T) -> Self {
Self { x: x, y: y, z: z }
}
}
#[cfg(test)]
mod test {
use super::*;
}

Datei anzeigen

@ -0,0 +1,189 @@
use num::*;
use std::ops::*;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct Kartesian<T>
where
T: Integer,
{
pub x: T,
pub y: T,
}
impl<T: Integer> Add for Kartesian<T> {
fn add(self, rhs: Self) -> Self::Output {
Kartesian {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
type Output = Kartesian<T>;
}
impl<T: Integer + AddAssign> AddAssign for Kartesian<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<T: Integer> Sub for Kartesian<T> {
fn sub(self, rhs: Self) -> Self::Output {
Kartesian {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
type Output = Kartesian<T>;
}
impl<T: Integer + SubAssign> SubAssign for Kartesian<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<T: Integer> Kartesian<T> {
pub const fn new(x: T, y: T) -> Self {
Self { x: x, y: y }
}
}
impl<T: Integer + CheckedAdd + Default> Kartesian<T> {
pub fn checked_add_max(self, rhs: Kartesian<T>, max: Kartesian<T>) -> Option<Kartesian<T>> {
let mut new = Kartesian::default();
new.x = match self.x.checked_add(&rhs.x) {
None => return None,
Some(x) => {
if x < T::default() || x >= max.x {
return None;
}
x
}
};
new.y = match self.y.checked_add(&rhs.y) {
None => return None,
Some(y) => {
if y < T::default() || y >= max.y {
return None;
}
y
}
};
Some(new)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum KartesianDirection {
TopLeft,
Top,
TopRight,
Left,
None,
Right,
BottomLeft,
Bottom,
BottomRight,
}
impl KartesianDirection {
pub fn vector<T: Signed + Integer + Zero + From<i8>>(self) -> Kartesian<T> {
const BELOW: i8 = -1;
const ON: i8 = 0;
const UPPER: i8 = 1;
Kartesian::<T> {
x: match self {
Self::TopLeft | Self::Top | Self::TopRight => BELOW.into(),
Self::Left | Self::None | Self::Right => ON.into(),
Self::BottomLeft | Self::Bottom | Self::BottomRight => UPPER.into(),
},
y: match self {
Self::TopLeft | Self::Left | Self::BottomLeft => BELOW.into(),
Self::Top | Self::None | Self::Bottom => ON.into(),
Self::TopRight | Self::Right | Self::BottomRight => UPPER.into(),
},
}
}
pub fn clockwise(self, diagonal: bool) -> KartesianDirection {
match (self, diagonal) {
(KartesianDirection::TopLeft, _) => Self::Top,
(KartesianDirection::Top, true) => Self::TopRight,
(KartesianDirection::Top, false) => Self::Right,
(KartesianDirection::TopRight, _) => Self::Right,
(KartesianDirection::Left, true) => Self::TopLeft,
(KartesianDirection::Left, false) => Self::Top,
(KartesianDirection::None, _) => Self::None,
(KartesianDirection::Right, true) => Self::BottomRight,
(KartesianDirection::Right, false) => Self::Bottom,
(KartesianDirection::BottomLeft, _) => Self::Left,
(KartesianDirection::Bottom, true) => Self::BottomLeft,
(KartesianDirection::Bottom, false) => Self::Left,
(KartesianDirection::BottomRight, _) => Self::Bottom,
}
}
pub fn anticlockwise(self, diagonal: bool) -> KartesianDirection {
match (self, diagonal) {
(KartesianDirection::TopLeft, _) => Self::Left,
(KartesianDirection::Top, true) => Self::TopLeft,
(KartesianDirection::Top, false) => Self::Left,
(KartesianDirection::TopRight, _) => Self::Top,
(KartesianDirection::Left, true) => Self::BottomLeft,
(KartesianDirection::Left, false) => Self::Bottom,
(KartesianDirection::None, _) => Self::None,
(KartesianDirection::Right, true) => Self::TopRight,
(KartesianDirection::Right, false) => Self::Top,
(KartesianDirection::BottomLeft, _) => Self::Bottom,
(KartesianDirection::Bottom, true) => Self::BottomRight,
(KartesianDirection::Bottom, false) => Self::Right,
(KartesianDirection::BottomRight, _) => Self::Right,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_clockwise() {
let mut current = KartesianDirection::Top;
let clock = [
KartesianDirection::Top,
KartesianDirection::TopRight,
KartesianDirection::Right,
KartesianDirection::BottomRight,
KartesianDirection::Bottom,
KartesianDirection::BottomLeft,
KartesianDirection::Left,
KartesianDirection::TopLeft,
];
for hand in clock {
assert_eq!(current, hand);
current = current.clockwise(true);
}
}
#[test]
fn test_anticlockwise() {
let mut current = KartesianDirection::Top;
let clock = [
KartesianDirection::Top,
KartesianDirection::TopLeft,
KartesianDirection::Left,
KartesianDirection::BottomLeft,
KartesianDirection::Bottom,
KartesianDirection::BottomRight,
KartesianDirection::Right,
KartesianDirection::TopRight,
];
for hand in clock {
assert_eq!(current, hand);
current = current.anticlockwise(true);
}
}
}

Datei anzeigen

@ -0,0 +1,4 @@
mod euclidian;
mod kartesian;
pub use euclidian::*;
pub use kartesian::*;

Datei anzeigen

@ -2,8 +2,10 @@ use std::ops::{Add, AddAssign, DivAssign, Sub, SubAssign};
use num::*;
mod coordinate_systems;
pub mod strings;
pub use advent_of_code_macros::*;
pub use coordinate_systems::*;
pub type Table = Vec<Vec<char>>;
@ -29,244 +31,6 @@ pub fn matrix(zero: bool, diag: bool, non_diag: bool) -> Vec<(i32, i32)> {
d
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
pub struct Kartesian<T>
where
T: Integer,
{
pub x: T,
pub y: T,
}
impl<T: Integer> Add for Kartesian<T> {
fn add(self, rhs: Self) -> Self::Output {
Kartesian {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
type Output = Kartesian<T>;
}
impl<T: Integer + AddAssign> AddAssign for Kartesian<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
}
}
impl<T: Integer> Sub for Kartesian<T> {
fn sub(self, rhs: Self) -> Self::Output {
Kartesian {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
type Output = Kartesian<T>;
}
impl<T: Integer + SubAssign> SubAssign for Kartesian<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
}
}
impl<T: Integer> Kartesian<T> {
pub const fn new(x: T, y: T) -> Self {
Self { x: x, y: y }
}
}
impl<T: Integer + CheckedAdd + Default> Kartesian<T> {
pub fn checked_add_max(self, rhs: Kartesian<T>, max: Kartesian<T>) -> Option<Kartesian<T>> {
let mut new = Kartesian::default();
new.x = match self.x.checked_add(&rhs.x) {
None => return None,
Some(x) => {
if x < T::default() || x >= max.x {
return None;
}
x
}
};
new.y = match self.y.checked_add(&rhs.y) {
None => return None,
Some(y) => {
if y < T::default() || y >= max.y {
return None;
}
y
}
};
Some(new)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Euclidian<T>
where
T: Integer,
{
pub x: T,
pub y: T,
pub z: T,
}
impl<T: Integer> Add for Euclidian<T> {
fn add(self, rhs: Self) -> Self::Output {
Euclidian {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
type Output = Euclidian<T>;
}
impl<T: Integer + AddAssign> AddAssign for Euclidian<T> {
fn add_assign(&mut self, rhs: Self) {
self.x += rhs.x;
self.y += rhs.y;
self.z += rhs.z;
}
}
impl<T: Integer> Sub for Euclidian<T> {
fn sub(self, rhs: Self) -> Self::Output {
Euclidian {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
}
}
type Output = Euclidian<T>;
}
impl<T: Integer + SubAssign> SubAssign for Euclidian<T> {
fn sub_assign(&mut self, rhs: Self) {
self.x -= rhs.x;
self.y -= rhs.y;
self.z -= rhs.z;
}
}
impl<T: Integer> Euclidian<T> {
pub const fn new(x: T, y: T, z: T) -> Self {
Self { x: x, y: y, z: z }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum KartesianDirection {
TopLeft,
Top,
TopRight,
Left,
None,
Right,
BottomLeft,
Bottom,
BottomRight,
}
impl KartesianDirection {
pub fn vector<T: Signed + Integer + Zero + From<i8>>(self) -> Kartesian<T> {
const BELOW: i8 = -1;
const ON: i8 = 0;
const UPPER: i8 = 1;
Kartesian::<T> {
x: match self {
Self::TopLeft | Self::Top | Self::TopRight => BELOW.into(),
Self::Left | Self::None | Self::Right => ON.into(),
Self::BottomLeft | Self::Bottom | Self::BottomRight => UPPER.into(),
},
y: match self {
Self::TopLeft | Self::Left | Self::BottomLeft => BELOW.into(),
Self::Top | Self::None | Self::Bottom => ON.into(),
Self::TopRight | Self::Right | Self::BottomRight => UPPER.into(),
},
}
}
pub fn clockwise(self, diagonal: bool) -> KartesianDirection {
match (self, diagonal) {
(KartesianDirection::TopLeft, _) => Self::Top,
(KartesianDirection::Top, true) => Self::TopRight,
(KartesianDirection::Top, false) => Self::Right,
(KartesianDirection::TopRight, _) => Self::Right,
(KartesianDirection::Left, true) => Self::TopLeft,
(KartesianDirection::Left, false) => Self::Top,
(KartesianDirection::None, _) => Self::None,
(KartesianDirection::Right, true) => Self::BottomRight,
(KartesianDirection::Right, false) => Self::Bottom,
(KartesianDirection::BottomLeft, _) => Self::Left,
(KartesianDirection::Bottom, true) => Self::BottomLeft,
(KartesianDirection::Bottom, false) => Self::Left,
(KartesianDirection::BottomRight, _) => Self::Bottom,
}
}
pub fn anticlockwise(self, diagonal: bool) -> KartesianDirection {
match (self, diagonal) {
(KartesianDirection::TopLeft, _) => Self::Left,
(KartesianDirection::Top, true) => Self::TopLeft,
(KartesianDirection::Top, false) => Self::Left,
(KartesianDirection::TopRight, _) => Self::Top,
(KartesianDirection::Left, true) => Self::BottomLeft,
(KartesianDirection::Left, false) => Self::Bottom,
(KartesianDirection::None, _) => Self::None,
(KartesianDirection::Right, true) => Self::TopRight,
(KartesianDirection::Right, false) => Self::Top,
(KartesianDirection::BottomLeft, _) => Self::Bottom,
(KartesianDirection::Bottom, true) => Self::BottomRight,
(KartesianDirection::Bottom, false) => Self::Right,
(KartesianDirection::BottomRight, _) => Self::Right,
}
}
}
#[test]
fn test_clockwise() {
let mut current = KartesianDirection::Top;
let clock = [
KartesianDirection::Top,
KartesianDirection::TopRight,
KartesianDirection::Right,
KartesianDirection::BottomRight,
KartesianDirection::Bottom,
KartesianDirection::BottomLeft,
KartesianDirection::Left,
KartesianDirection::TopLeft,
];
for hand in clock {
assert_eq!(current, hand);
current = current.clockwise(true);
}
}
#[test]
fn test_anticlockwise() {
let mut current = KartesianDirection::Top;
let clock = [
KartesianDirection::Top,
KartesianDirection::TopLeft,
KartesianDirection::Left,
KartesianDirection::BottomLeft,
KartesianDirection::Bottom,
KartesianDirection::BottomRight,
KartesianDirection::Right,
KartesianDirection::TopRight,
];
for hand in clock {
assert_eq!(current, hand);
current = current.anticlockwise(true);
}
}
pub fn numberlength<T: Integer + DivAssign + From<u32> + Copy>(n: T) -> u32 {
let divider = T::from(10);
let mut num = n;

Datei anzeigen

@ -1,9 +1,21 @@
use num::{pow::Pow, Integer};
use std::ops::AddAssign;
pub fn splitspace(input: &str) -> (&str, &str) {
let mut output = input.split_ascii_whitespace();
(output.next().unwrap().trim(), output.next().unwrap().trim())
#[inline]
pub fn char_to_num<T: Integer + From<u32>>(c: char) -> T {
match c {
'1' => T::from(1),
'2' => T::from(2),
'3' => T::from(3),
'4' => T::from(4),
'5' => T::from(5),
'6' => T::from(6),
'7' => T::from(7),
'8' => T::from(8),
'9' => T::from(9),
'0' => T::from(0),
_ => unreachable!(),
}
}
pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + Copy>(
@ -14,19 +26,7 @@ pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + C
let mut output: T = T::from(0);
let mut mul: u32 = 0;
for c in input.chars().rev() {
let i: T = match c {
'1' => T::from(1),
'2' => T::from(2),
'3' => T::from(3),
'4' => T::from(4),
'5' => T::from(5),
'6' => T::from(6),
'7' => T::from(7),
'8' => T::from(8),
'9' => T::from(9),
'0' => T::from(0),
_ => unreachable!(),
};
let i: T = char_to_num(c);
if mul > MAX_POWER {
return output;
}
@ -39,19 +39,7 @@ pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + C
pub fn get_numbers<T: Integer + From<u32>>(input: &str) -> Vec<T> {
let mut numbers = Vec::new();
for char in input.chars() {
match char {
'1' => numbers.push(T::from(1)),
'2' => numbers.push(T::from(2)),
'3' => numbers.push(T::from(3)),
'4' => numbers.push(T::from(4)),
'5' => numbers.push(T::from(5)),
'6' => numbers.push(T::from(6)),
'7' => numbers.push(T::from(7)),
'8' => numbers.push(T::from(8)),
'9' => numbers.push(T::from(9)),
'0' => numbers.push(T::from(0)),
_ => unimplemented!(),
}
numbers.push(char_to_num(char));
}
numbers
}