Compare commits
3 Commits
de7ee8f0f6
...
bd91fcb60c
Author | SHA1 | Date | |
---|---|---|---|
bd91fcb60c | |||
33615b015f | |||
b7a1f05b1e |
82
Cargo.lock
generated
82
Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
@ -70,6 +70,8 @@ dependencies = [
|
|||||||
"colored",
|
"colored",
|
||||||
"grid",
|
"grid",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"misc",
|
||||||
|
"nom",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
@ -144,9 +146,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colored"
|
name = "colored"
|
||||||
version = "2.1.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@ -154,9 +156,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.5"
|
version = "0.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
@ -173,9 +175,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.20"
|
version = "0.8.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
@ -287,6 +289,29 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "misc"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
@ -549,22 +574,23 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.59.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm",
|
||||||
@ -573,45 +599,51 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.48.5"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
|
edition = "2021"
|
||||||
name = "aoc2024"
|
name = "aoc2024"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aoc-runner = "0.3.0"
|
aoc-runner = "0.3.0"
|
||||||
@ -10,8 +10,10 @@ atoi = "2.0.0"
|
|||||||
bitflags = "2.6.0"
|
bitflags = "2.6.0"
|
||||||
cached = "0.54.0"
|
cached = "0.54.0"
|
||||||
colored = "2.1.0"
|
colored = "2.1.0"
|
||||||
grid = { version = "0.1.0", path = "utils/grid" }
|
grid = {version = "0.1.0", path = "utils/grid"}
|
||||||
itertools = "0.13.0"
|
itertools = "0.13.0"
|
||||||
|
misc = {path = "utils/misc"}
|
||||||
|
nom = "7.1.3"
|
||||||
rayon = "1.10.0"
|
rayon = "1.10.0"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
rustc-hash = "2.1.0"
|
rustc-hash = "2.1.0"
|
||||||
|
161
src/day14.rs
161
src/day14.rs
@ -1,12 +1,27 @@
|
|||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::aoc;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use grid::{AsCoord2d, Coord2d, Grid};
|
use grid::{AsCoord2d, Coord2d, Grid};
|
||||||
|
use misc::CustomWrapped;
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::digit1,
|
||||||
|
combinator::{map_res, opt, recognize},
|
||||||
|
sequence::{preceded, separated_pair},
|
||||||
|
IResult,
|
||||||
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::str::FromStr;
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
|
type Coord = (CustomWrapped<i64>, CustomWrapped<i64>);
|
||||||
struct Robot {
|
struct Robot {
|
||||||
pos: Coord2d,
|
pos: Coord,
|
||||||
vel: Coord2d,
|
vel: (i64, i64),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Robots {
|
||||||
|
robots: Vec<Robot>,
|
||||||
|
width: i64,
|
||||||
|
height: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@ -17,52 +32,37 @@ enum Quadrant {
|
|||||||
SE = 3,
|
SE = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Robot {
|
fn nom_i64(input: &str) -> IResult<&str, i64> {
|
||||||
type Err = Box<dyn std::error::Error>;
|
let (i, number) = map_res(recognize(preceded(opt(tag("-")), digit1)), |s| i64::from_str(s))(input)?;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
Ok((i, number))
|
||||||
let re = Regex::new(r"p=(\d+),(\d+) v=([+-]?\d+),([+-]?\d+)").unwrap();
|
}
|
||||||
match re.captures(s) {
|
fn nom_i64_pair(input: &str) -> IResult<&str, (i64, i64)> {
|
||||||
Some(c) => Ok(Self {
|
let (i, pair) = separated_pair(nom_i64, tag(","), nom_i64)(input)?;
|
||||||
pos: (
|
Ok((i, pair))
|
||||||
c.get(1).unwrap().as_str().parse::<i64>().unwrap(),
|
|
||||||
c.get(2).unwrap().as_str().parse().unwrap(),
|
|
||||||
)
|
|
||||||
.to_coord(),
|
|
||||||
vel: (
|
|
||||||
c.get(3).unwrap().as_str().parse::<i64>().unwrap(),
|
|
||||||
c.get(4).unwrap().as_str().parse().unwrap(),
|
|
||||||
)
|
|
||||||
.to_coord(),
|
|
||||||
}),
|
|
||||||
None => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Robot {
|
impl Robot {
|
||||||
fn step(&mut self, bounds: (i64, i64)) {
|
fn from_str(s: &str, bounds: (i64, i64)) -> Self {
|
||||||
let mut candidate_new_pos = ((self.pos.x() + self.vel.x()), (self.pos.y() + self.vel.y()));
|
let (s, pos) = preceded(tag("p="), nom_i64_pair)(s).unwrap();
|
||||||
if candidate_new_pos.0 < 0 {
|
let (_, vel) = preceded(tag(" v="), nom_i64_pair)(s).unwrap();
|
||||||
// if pos goes negative, add the upper bound
|
Self {
|
||||||
candidate_new_pos.0 += bounds.0;
|
pos: (CustomWrapped::new(pos.0, bounds.0), CustomWrapped::new(pos.1, bounds.1)),
|
||||||
|
vel,
|
||||||
}
|
}
|
||||||
if candidate_new_pos.1 < 0 {
|
}
|
||||||
candidate_new_pos.1 += bounds.1;
|
fn step(&mut self, count: i64) {
|
||||||
}
|
self.pos.0 += self.vel.x() * count;
|
||||||
candidate_new_pos.0 %= bounds.0;
|
self.pos.1 += self.vel.y() * count;
|
||||||
candidate_new_pos.1 %= bounds.1;
|
|
||||||
|
|
||||||
self.pos = candidate_new_pos.to_coord();
|
|
||||||
}
|
}
|
||||||
fn quad(&self, bounds: (i64, i64)) -> Option<Quadrant> {
|
fn quad(&self, bounds: (i64, i64)) -> Option<Quadrant> {
|
||||||
let splits = (bounds.0 / 2, bounds.1 / 2);
|
let splits = (bounds.0 / 2, bounds.1 / 2);
|
||||||
if self.pos.x() < splits.0 && self.pos.y() < splits.1 {
|
if self.pos.0 < splits.0 && self.pos.1 < splits.1 {
|
||||||
Some(Quadrant::NW)
|
Some(Quadrant::NW)
|
||||||
} else if self.pos.x() > splits.0 && self.pos.y() < splits.1 {
|
} else if self.pos.0 > splits.0 && self.pos.1 < splits.1 {
|
||||||
Some(Quadrant::NE)
|
Some(Quadrant::NE)
|
||||||
} else if self.pos.x() < splits.0 && self.pos.y() > splits.1 {
|
} else if self.pos.0 < splits.0 && self.pos.1 > splits.1 {
|
||||||
Some(Quadrant::SW)
|
Some(Quadrant::SW)
|
||||||
} else if self.pos.x() > splits.0 && self.pos.y() > splits.1 {
|
} else if self.pos.0 > splits.0 && self.pos.1 > splits.1 {
|
||||||
Some(Quadrant::SE)
|
Some(Quadrant::SE)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -70,49 +70,58 @@ impl Robot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
impl Robots {
|
||||||
fn display(robots: &Vec<Robot>, bounds: (i64, i64)) {
|
fn from_vec(robots: Vec<Robot>, width: i64, height: i64) -> Self {
|
||||||
let grid = as_grid(robots, bounds);
|
Self { robots, width, height }
|
||||||
for row in 0..grid.height() {
|
}
|
||||||
for col in 0..grid.width() {
|
fn as_grid(&self) -> Grid<usize> {
|
||||||
print!(
|
let mut grid = Grid::with_shape(self.width as usize, self.height as usize, 0usize);
|
||||||
"{}",
|
for r in &self.robots {
|
||||||
if *grid.get(&(col, row)).unwrap() != 0 {
|
grid.increment(&(r.pos.0.val, r.pos.1.val), 1usize);
|
||||||
"█".green()
|
}
|
||||||
} else {
|
grid
|
||||||
" ".color(colored::Color::Black)
|
}
|
||||||
}
|
fn count_quads(&self) -> [u64; 4] {
|
||||||
);
|
let mut counts = [0; 4];
|
||||||
|
for r in &self.robots {
|
||||||
|
if let Some(q) = r.quad((self.width, self.height)) {
|
||||||
|
counts[q as usize] += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
counts
|
||||||
|
}
|
||||||
|
fn step(&mut self, count: i64) {
|
||||||
|
for robot in &mut self.robots {
|
||||||
|
robot.step(count)
|
||||||
}
|
}
|
||||||
println!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_grid(robots: &Vec<Robot>, bounds: (i64, i64)) -> Grid<usize> {
|
impl Display for Robots {
|
||||||
let mut grid = Grid::with_shape(bounds.0 as usize, bounds.1 as usize, 0);
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for r in robots {
|
let grid = self.as_grid();
|
||||||
grid.increment(&r.pos, 1usize);
|
for row in 0..grid.height() {
|
||||||
|
for col in 0..grid.width() {
|
||||||
|
if *grid.get(&(col, row)).unwrap() != 0 {
|
||||||
|
"█".green().fmt(f)?;
|
||||||
|
} else {
|
||||||
|
" ".color(colored::Color::Black).fmt(f)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeln!(f)?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
grid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(input: &str) -> Vec<Robot> {
|
fn parse(input: &str, width: i64, height: i64) -> Vec<Robot> {
|
||||||
input.lines().map(|l| l.parse().unwrap()).collect()
|
input.lines().map(|l| Robot::from_str(l, (width, height))).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1_impl(input: &str, width: i64, height: i64) -> u64 {
|
fn part1_impl(input: &str, width: i64, height: i64) -> u64 {
|
||||||
let mut robots = parse(input);
|
let mut robots = Robots::from_vec(parse(input, width, height), width, height);
|
||||||
for _ in 0..100 {
|
robots.step(100);
|
||||||
for r in &mut robots {
|
let counts = robots.count_quads();
|
||||||
r.step((width, height))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut counts = [0; 4];
|
|
||||||
for r in robots {
|
|
||||||
if let Some(q) = r.quad((width, height)) {
|
|
||||||
counts[q as usize] += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
counts.iter().product()
|
counts.iter().product()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,13 +134,11 @@ pub fn part1(input: &str) -> u64 {
|
|||||||
pub fn part2(input: &str) -> u64 {
|
pub fn part2(input: &str) -> u64 {
|
||||||
let width = 101;
|
let width = 101;
|
||||||
let height = 103;
|
let height = 103;
|
||||||
let mut robots = parse(input);
|
let mut robots = Robots::from_vec(parse(input, width, height), width, height);
|
||||||
for i in 1.. {
|
for i in 1.. {
|
||||||
for r in &mut robots {
|
robots.step(1);
|
||||||
r.step((width, height))
|
|
||||||
}
|
|
||||||
// collect into lines
|
// collect into lines
|
||||||
let g = as_grid(&robots, (width, height));
|
let g = robots.as_grid();
|
||||||
if g.data
|
if g.data
|
||||||
.chunk_by(|a, b| *a != 0 && *b != 0)
|
.chunk_by(|a, b| *a != 0 && *b != 0)
|
||||||
.filter(|c| !c.is_empty() && c[0] != 0)
|
.filter(|c| !c.is_empty() && c[0] != 0)
|
||||||
|
25
utils/misc/Cargo.lock
generated
Normal file
25
utils/misc/Cargo.lock
generated
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "misc"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
7
utils/misc/Cargo.toml
Normal file
7
utils/misc/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "misc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
num-traits = "0.2.19"
|
95
utils/misc/src/lib.rs
Normal file
95
utils/misc/src/lib.rs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
use num_traits::Signed;
|
||||||
|
use std::ops::{Add, AddAssign};
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
/// Wrapped signed integer with custom upper bound with wrapping of 0s to the upper bound
|
||||||
|
#[derive(Eq, Clone, Copy)]
|
||||||
|
pub struct CustomWrapped<T: Signed + Copy> {
|
||||||
|
pub val: T,
|
||||||
|
pub bound: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Copy> Add<T> for CustomWrapped<T> {
|
||||||
|
type Output = CustomWrapped<T>;
|
||||||
|
fn add(self, rhs: T) -> Self::Output {
|
||||||
|
Self {
|
||||||
|
val: ((self.val + rhs % self.bound) + self.bound) % self.bound,
|
||||||
|
bound: self.bound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Copy> Add<T> for &CustomWrapped<T> {
|
||||||
|
type Output = CustomWrapped<T>;
|
||||||
|
fn add(self, rhs: T) -> Self::Output {
|
||||||
|
CustomWrapped {
|
||||||
|
val: ((self.val + rhs % self.bound) + self.bound) % self.bound,
|
||||||
|
bound: self.bound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Copy> AddAssign<T> for CustomWrapped<T> {
|
||||||
|
fn add_assign(&mut self, rhs: T) {
|
||||||
|
self.val = ((self.val + rhs % self.bound) + self.bound) % self.bound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Copy> CustomWrapped<T> {
|
||||||
|
pub fn new(val: T, bound: T) -> Self {
|
||||||
|
Self { val, bound }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Copy + PartialEq> PartialEq for CustomWrapped<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.val.eq(&other.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + PartialOrd + Copy> PartialOrd for CustomWrapped<T> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
self.val.partial_cmp(&other.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + Ord + Copy> Ord for CustomWrapped<T> {
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.val.cmp(&other.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + PartialEq + Copy> PartialEq<T> for CustomWrapped<T> {
|
||||||
|
fn eq(&self, other: &T) -> bool {
|
||||||
|
self.val == *other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Signed + PartialOrd + Copy> PartialOrd<T> for CustomWrapped<T> {
|
||||||
|
fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
|
||||||
|
self.val.partial_cmp(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Display + Signed + Copy> Display for CustomWrapped<T> where T: Display {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
self.val.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl<T> Into<T> for CustomWrapped<T> {
|
||||||
|
// fn into(self) -> T {
|
||||||
|
// self.val
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user