#![allow(non_snake_case, unused_macros, unused_unsafe)] use Default::default; use regex::Regex; use rustc_hash::FxHashMap as HashMap; use rustc_hash::FxHashSet as HashSet; use std::collections::VecDeque; use std::iter::Zip; use std::iter::empty; use std::iter::successors; use std::ops::RangeFrom; use std::sync::LazyLock; use std::{ cmp::Reverse, collections::BinaryHeap, fmt::{Debug, Display, Write}, hash::Hash, mem::swap, ops::RangeInclusive, str::FromStr, }; pub mod prelude { pub use super::{ AndF, BoolTools, DigiCount, Dir, FilterBy, FilterBy3, FirstMax, GreekTools, GridFind, IntoCombinations, IntoLines, IterͶ, Left, MapWith, NumTupleIterTools, PRead, ParseIter, PartitionByKey, Position, Printable, Skip, Splib, SplitU8, Str, TakeLine, TupleIterTools2, TupleIterTools2R, TupleIterTools3, TupleUtils, TwoWayMapCollect, UnifiedTupleUtils, UnsoundUtilities, Widen, countmap, even, gcd, gt, infinite_successors, l, lcm, lt, nail, pa, python, r, rand, reading, reading::Ext, sort, spiral, twice, Ͷ, Α, Ι, Κ, Λ, Μ, }; #[allow(unused_imports)] pub(crate) use super::{C, bits, dang, leek, mat, shucks}; pub use Default::default; pub use itertools::Itertools; pub use itertools::iproduct; pub use itertools::izip; pub use rustc_hash::FxHashMap as HashMap; pub use rustc_hash::FxHashSet as HashSet; pub use std::{ cmp::Ordering::*, cmp::{max, min}, collections::{VecDeque, hash_map::Entry}, fmt::{Debug, Display}, hint::black_box as boxd, intrinsics::transmute_unchecked as transmute, io::{self, Read, Write}, iter, iter::{chain, once, repeat_n, successors, zip}, mem::{replace as rplc, swap}, ops::Range, }; } macro_rules! C { ($obj:ident.$what:ident$($tt:tt)+) => {{ let x = &mut $obj.$what; C!( x$($tt)+ ) }}; (&$buf:ident[$n:expr]) => {{ #[allow(unused_unsafe)] unsafe { $buf.get_unchecked($n) } }}; ($buf:ident[$n:expr]) => {{ #[allow(unused_unsafe)] *unsafe { $buf.get_unchecked($n) } }}; (&mut $buf:ident[$n:expr]) => {{ #[allow(unused_unsafe)] unsafe { $buf.get_unchecked_mut($n) } }}; ($buf:ident[$a:expr] = $rbuf:ident[$b:expr]) => { *unsafe { $buf.get_unchecked_mut($a) } = unsafe { *$rbuf.get_unchecked($b) } }; ($buf:ident[$n:expr] = $e:expr) => { *unsafe { $buf.get_unchecked_mut($n) } = $e }; ($buf:ident[$a:expr][$b:expr]) => { unsafe { *$buf.get_unchecked($a).get_unchecked($b) } }; ($buf:ident[$a:expr][$b:expr] = $rbuf:ident[$ra:expr]) => { *unsafe { $buf.get_unchecked_mut($a).get_unchecked_mut($b) } = unsafe { *$rbuf.get_unchecked($ra) } }; ($buf:ident[$a:expr][$b:expr] = $rbuf:ident[$ra:expr][$rb:expr]) => { *unsafe { $buf.get_unchecked_mut($a).get_unchecked_mut($b) } = unsafe { *$rbuf.get_unchecked($ra).get_unchecked($rb) } }; ($buf:ident[$a:expr][$b:expr] = $c:expr) => {{ #[allow(unused_unsafe)] { *unsafe { $buf.get_unchecked_mut($a).get_unchecked_mut($b) } = unsafe { $c } } }}; } pub(crate) use C; macro_rules! shucks { () => { if cfg!(debug_assertions) { unreachable!(); } else { unsafe { std::hint::unreachable_unchecked() } } }; ($fmt:literal $(, $args:expr)* $(,)?) => { if cfg!(debug_assertions) { unreachable!($fmt $(, $args)*); } else { unsafe { std::hint::unreachable_unchecked() } } }; (if $x:expr) => { if $x { if cfg!(debug_assertions) { unreachable!(); } else { unsafe { std::hint::unreachable_unchecked() } } } }; } pub(crate) use shucks; macro_rules! dang { () => { panic!() }; } pub(crate) use dang; macro_rules! leek { ($($allocation:ident)+) => { $(std::mem::forget($allocation);)+ }; } pub(crate) use leek; macro_rules! mat { ($thing:ident { $($what:pat => $b:expr,)+ }) => { match $thing { $($what => { $b })+ _ => shucks!() } }; } pub(crate) use mat; #[cfg(target_feature = "avx2")] unsafe fn count_avx(hay: &[u8; N], needle: u8) -> usize { use std::arch::x86_64::*; let find = _mm256_set1_epi8(needle as i8); let mut counts = _mm256_setzero_si256(); for i in 0..(N / 32) { counts = _mm256_sub_epi8( counts, _mm256_cmpeq_epi8( _mm256_loadu_si256(hay.as_ptr().add(i * 32) as *const _), find, ), ); } const MASK: [u8; 64] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, ]; counts = _mm256_sub_epi8( counts, _mm256_and_si256( _mm256_cmpeq_epi8( _mm256_loadu_si256(hay.as_ptr().add(N - 32) as *const _), find, ), _mm256_loadu_si256(MASK.as_ptr().add(N % 32) as *const _), ), ); let sums = _mm256_sad_epu8(counts, _mm256_setzero_si256()); (_mm256_extract_epi64(sums, 0) + _mm256_extract_epi64(sums, 1) + _mm256_extract_epi64(sums, 2) + _mm256_extract_epi64(sums, 3)) as usize } pub fn count(hay: &[u8; N], what: u8) -> usize { #[cfg(target_feature = "avx2")] return unsafe { count_avx(hay, what) }; #[cfg(not(target_feature = "avx2"))] hay.iter().filter(|&&x| x == what).count() } pub fn lcm(n: impl IntoIterator) -> u64 { let mut x = n.into_iter(); let mut lcm = x.by_ref().next().expect("cannot compute LCM of 0 numbers"); let mut gcd; for x in x { gcd = crate::util::gcd(x, lcm); lcm = (lcm * x) / gcd; } lcm } #[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] pub enum Dir { N = 0, E = 1, S = 2, W = 3, } impl Dir { pub const ALL: [Self; 4] = [Self::N, Self::E, Self::S, Self::W]; pub fn urdl(x: u8) -> Self { match x { b'U' => Self::N, b'R' => Self::E, b'D' => Self::S, b'L' => Self::W, x => unreachable!("{}", x as char), } } pub fn add_1(self) -> Self { use Dir::*; unsafe { std::mem::transmute((self as u8 + 1) % 4) } } pub fn sub_1(self) -> Self { use Dir::*; unsafe { std::mem::transmute(((self as u8).wrapping_sub(1)) % 4) } } pub fn turdl(self) -> u8 { match self { Self::N => b'U', Self::E => b'R', Self::S => b'D', Self::W => b'L', } } } pub struct UnionFind { p: Vec, s: Vec, } impl UnionFind { pub fn new(size: usize) -> Self { Self { s: vec![1; size], p: (0..size).collect(), } } pub fn reset(&mut self) { self.s.fill(1); self.p .iter_mut() .enumerate() .for_each(|(idx, val)| *val = idx); } pub fn find(&mut self, key: usize) -> usize { if self.p[key] == key { return key; } let parent = self.find(self.p[key]); self.p[key] = parent; parent } pub fn union(&mut self, a: usize, b: usize) -> bool { let α = self.find(a); let β = self.find(b); if α == β { return false; } let a = self.s[α]; let b = self.s[β]; if a >= b { self.s[α] += b; self.p[β] = α; } else { self.s[β] += a; self.p[α] = β; } true } pub fn group_size(&self, group: usize) -> usize { self.s[group] } } pub trait UnsoundUtilities { fn ψ(self) -> T; } impl UnsoundUtilities for Option { #[cfg_attr(debug_assertions, track_caller)] fn ψ(self) -> T { if cfg!(debug_assertions) && self.is_none() { panic!(); } unsafe { self.unwrap_unchecked() } } } impl UnsoundUtilities for Result { #[cfg_attr(debug_assertions, track_caller)] fn ψ(self) -> T { if cfg!(debug_assertions) && self.is_err() { panic!(); } unsafe { self.unwrap_unchecked() } } } pub struct LMap(HashMap, fn(&K) -> V) where K: Eq + Hash + Clone; impl LMap { pub fn new(f: fn(&K) -> V) -> Self { Self { 0: HashMap::default(), 1: f, } } pub fn with_cap(f: fn(&K) -> V, cap: usize) -> Self { Self { 0: HashMap::with_capacity_and_hasher(cap, rustc_hash::FxBuildHasher::default()), 1: f, } } pub fn get(&mut self, k: K) -> V { if let Some(x) = self.0.get(&k) { return *x; } let elm = self.1(&k); self.0.insert(k.clone(), elm); elm } } macro_rules! memoize { (|$pat:pat_param in $in:ty| -> $out:ty $body:block; $arg:expr) => {{ static mut MEMOIZER: std::sync::OnceLock> = std::sync::OnceLock::new(); unsafe { MEMOIZER.get_mut_or_init(|| crate::util::LMap::new(|$pat: &$in| -> $out { $body })) } .get($arg) }}; (|$pat:pat_param in $in:ty| -> $out:ty $body:block; $arg:expr; with cap $cap:literal) => {{ static mut MEMOIZER: std::sync::OnceLock> = std::sync::OnceLock::new(); unsafe { MEMOIZER.get_mut_or_init(|| { crate::util::LMap::with_cap(|$pat: $in| -> $out { $body }, $cap) }) } .get($arg) }}; } #[allow(unused_imports)] pub(crate) use memoize; pub fn countg_with_check>( start: N, graph: &mut impl Fn(N) -> I, ok: &mut impl Fn(N, N) -> bool, sum: &mut usize, end: &mut impl Fn(N) -> bool, ) { if end(start) { *sum += 1; } else { graph(start).for_each(|x| { if ok(start, x) { // println!("\"{start:?}\" -> \"{x:?}\""); countg_with_check(x, graph, ok, sum, end); } }); } } pub fn countg_uniq_with_check>( start: N, graph: &mut impl Fn(N) -> I, ok: &mut impl Fn(N, N) -> bool, sum: &mut usize, end: &mut impl Fn(N) -> bool, has: &mut HashSet, ) { if end(start) && has.insert(start) { *sum += 1; } else { graph(start).for_each(|x| { if ok(start, x) { countg_uniq_with_check(x, graph, ok, sum, end, has); } }); } } pub fn countg>( start: N, graph: &mut impl FnMut(N) -> I, end: &mut impl FnMut(&N) -> bool, sum: &mut usize, has: &mut HashSet, ) { if end(&start) { *sum += 1; } else { graph(start).for_each(|x| { countg(x, graph, end, sum, has); }); } } // pub fn appearances(x: ) pub fn iterg>( start: N, graph: &mut impl Fn(N) -> I, end: &mut impl Fn(&N) -> bool, finally: &mut impl FnMut(N), ) { if end(&start) { finally(start); } else { graph(start).for_each(|x: N| iterg(x, graph, end, finally)); }; } pub fn show, D: Display>( start: N, graph: impl Fn(N) -> I, end: impl Fn(N) -> bool, name: impl Fn(N) -> D, ) { println!("digraph {{"); let mut s = HashSet::default(); let mut q = BinaryHeap::new(); q.push(Reverse((0, start))); while let Some(Reverse((c, n))) = q.pop() { if end(n) { println!("}}"); return; } if !s.insert(n) { continue; } print!("\t{}", name(n)); for (n, d) in graph(n) { if s.contains(&n) { continue; } print!(" -> {}", name(n)); q.push(Reverse((c + d, n))); } println!(";"); } dang!(); } fn memo_countg_( start: T, successors: &mut FN, success: &mut FS, cache: &mut HashMap, ) -> usize where T: Eq + Hash, FN: FnMut(&T) -> IN, IN: IntoIterator, FS: FnMut(&T) -> bool, { if let Some(&n) = cache.get(&start) { return n; } let count = if success(&start) { 1 } else { successors(&start) .into_iter() .map(|successor| memo_countg_(successor, successors, success, cache)) .sum() }; cache.insert(start, count); count } pub fn memo_countg(start: T, mut successors: FN, mut success: FS) -> usize where T: Eq + Hash, FN: FnMut(&T) -> IN, IN: IntoIterator, FS: FnMut(&T) -> bool, { memo_countg_( start, &mut successors, &mut success, &mut HashMap::default(), ) } pub fn reachable>( start: (N, D), graph: impl Fn((N, D)) -> I, ) -> HashSet { let mut map = HashSet::default(); let mut stack = VecDeque::from_iter([start]); while let Some((x, d)) = stack.pop_front() { if map.insert(x) { stack.extend(graph((x, d))); } } map } pub fn ccomponents>(graph: impl Fn(usize) -> I, length: usize) -> usize { let mut s = UnionFind::new(length); for n in 0..length { graph(n).map(|y| s.union(n, y)).θ(); } (0..length).map(|x| s.find(x)).collect::>().len() } pub fn dijkstra_h>( start: N, graph: impl Fn(N) -> I, end: impl Fn(N) -> bool, h: impl Fn(N) -> u16, ) -> u16 { let mut q = BinaryHeap::new(); let mut s = HashSet::default(); q.push(Reverse((h(start), 0, start))); while let Some(Reverse((_, c, n))) = q.pop() { if end(n) { return c; } if !s.insert(n) { continue; } for (n, d) in graph(n) { if s.contains(&n) { continue; } q.push(Reverse((h(n) + c + d, c + d, n))); } } dang!() } #[derive(Debug, Clone, Copy)] pub struct Left(pub T, pub U); impl Hash for Left { fn hash(&self, state: &mut H) { self.0.hash(state); } } impl PartialEq for Left { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl Eq for Left {} impl PartialOrd for Left { fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } } impl Ord for Left { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.0.cmp(&other.0) } } pub fn steps>( start: N, graph: impl Fn(N) -> I, end: impl Fn(&N) -> bool, ) -> Option> { bfs( Left(start, 0usize), |Left(n, steps)| graph(n).map(move |x| Left(x, steps + 1)), |x| end(&x.0), ) } pub fn steps_astar>( start: N, graph: impl Fn(N) -> I, heuristic: impl Fn(&N) -> i16, goal: impl Fn(&N) -> bool, ) -> Option<(i16, Left)> { astar( Left(start, 0usize), |Left(n, steps)| graph(n).map(move |(x, cost)| (Left(x, steps + 1), cost)), |x| heuristic(&x.0), |x| goal(&x.0), ) } pub fn bfs>( start: N, graph: impl Fn(N) -> I, end: impl Fn(&N) -> bool, ) -> Option { let mut q = VecDeque::with_capacity(1024); let mut s = HashSet::with_capacity_and_hasher(1024, rustc_hash::FxBuildHasher::default()); q.push_back(start); while let Some(n) = q.pop_front() { if end(&n) { return Some(n); } if !s.insert(n.clone()) { continue; } for n in graph(n) { if s.contains(&n) { continue; } // print!("{n:?} "); q.push_back(n); } } None } pub fn astar>( start: N, graph: impl Fn(N) -> I, heuristic: impl Fn(&N) -> i16, goal: impl Fn(&N) -> bool, ) -> Option<(i16, N)> { let mut q = BinaryHeap::with_capacity(1024); let mut score = HashMap::default(); score.insert(start.clone(), 0); q.push(Reverse(Left(heuristic(&start), start))); while let Some(Reverse(Left(c, n))) = q.pop() { if goal(&n) { return Some((c, n)); } for (n_, d) in graph(n.clone()) { let g = score[&n] + d; let of = score.get(&n_).unwrap_or(&i16::MAX); if g < *of { score.insert(n_.clone(), g); let f = g + heuristic(&n_); q.push(Reverse(Left(f, n_))); } } } None } pub fn dijkstra>( start: N, graph: impl Fn(N) -> I, end: impl Fn(&N) -> bool, ) -> Option<(u16, N)> { let mut q = BinaryHeap::new(); let mut s = HashSet::default(); q.push(Reverse(Left(0, start))); while let Some(Reverse(Left(c, n))) = q.pop() { if end(&n) { return Some((c, n)); } if !s.insert(n.clone()) { continue; } for (n, d) in graph(n) { if s.contains(&n) { continue; } // print!("{n:?} "); q.push(Reverse(Left(c + d, n))); } } None } impl std::ops::Add<(i64, i64)> for Dir { type Output = (i64, i64); fn add(self, (x, y): (i64, i64)) -> Self::Output { match self { Dir::N => (x, y - 1), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x - 1, y), } } } impl std::ops::Add<(u32, u32)> for Dir { type Output = Option<(u32, u32)>; fn add(self, (x, y): (u32, u32)) -> Self::Output { Some(match self { Dir::N => (x, y.checked_sub(1)?), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x.checked_sub(1)?, y), }) } } impl Dir { pub fn lim_add( self, (x, y): (usize, usize), [minx, maxx]: [usize; 2], [miny, maxy]: [usize; 2], ) -> Option<(usize, usize)> { let (x, y) = match self { Dir::N => (x, y.checked_sub(1)?), Dir::E => (x.wrapping_add(1), y), Dir::S => (x, y.wrapping_add(1)), Dir::W => (x.checked_sub(1)?, y), }; ((minx..maxx).contains(&x) & (miny..maxy).contains(&y)).then_some((x, y)) } } impl std::ops::Add<(usize, usize)> for Dir { type Output = Option<(usize, usize)>; fn add(self, (x, y): (usize, usize)) -> Self::Output { Some(match self { Dir::N => (x, y.checked_sub(1)?), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x.checked_sub(1)?, y), }) } } impl std::ops::Add<(i32, i32)> for Dir { type Output = (i32, i32); fn add(self, (x, y): (i32, i32)) -> Self::Output { match self { Dir::N => (x, y - 1), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x - 1, y), } } } impl std::ops::Add<(u16, u16)> for Dir { type Output = (u16, u16); fn add(self, (x, y): (u16, u16)) -> Self::Output { match self { Dir::N => (x, y - 1), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x - 1, y), } } } impl std::ops::Add<(i16, i16)> for Dir { type Output = (i16, i16); fn add(self, (x, y): (i16, i16)) -> Self::Output { match self { Dir::N => (x, y - 1), Dir::E => (x + 1, y), Dir::S => (x, y + 1), Dir::W => (x - 1, y), } } } impl std::ops::Add<(u8, u8)> for Dir { type Output = (u8, u8); fn add(self, (x, y): (u8, u8)) -> Self::Output { match self { Dir::N => (x, y.wrapping_sub(1)), Dir::E => (x.wrapping_add(1), y), Dir::S => (x, y.wrapping_add(1)), Dir::W => (x.wrapping_sub(1), y), } } } impl std::ops::Add for Dir { type Output = Self; fn add(self, rhs: i8) -> Self::Output { unsafe { std::mem::transmute(((self as u8 as i8) + rhs).rem_euclid(4)) } } } impl std::ops::Add for Dir { type Output = Self; fn add(self, rhs: u8) -> Self::Output { unsafe { std::mem::transmute(((self as u8).wrapping_add(rhs)) % 4) } } } impl Dir { pub fn turn_90(self) -> Self { match self { Dir::N => Dir::E, Dir::E => Dir::S, Dir::S => Dir::W, Dir::W => Dir::N, } } pub fn turn_90ccw(self) -> Self { match self { Dir::N => Dir::W, Dir::E => Dir::N, Dir::S => Dir::E, Dir::W => Dir::S, } } } pub fn pa(a: &[T]) { for e in a { print!("{e:?}"); } println!(); } pub fn gcd(mut a: u64, mut b: u64) -> u64 { if a == 0 || b == 0 { return a | b; } let shift = (a | b).trailing_zeros(); a >>= shift; loop { b >>= b.trailing_zeros(); if a > b { swap(&mut a, &mut b); } b -= a; if b == 0 { break; } } a << shift } pub trait Λ { fn λ(&self) -> T where ::Err: std::fmt::Display; } impl Λ for String { fn λ(&self) -> T where ::Err: std::fmt::Display, { self.as_str().λ() } } impl Λ for [u8] { #[cfg_attr(debug_assertions, track_caller)] fn λ(&self) -> T where ::Err: std::fmt::Display, { std::str::from_utf8(self).α().λ() } } impl Λ for &str { /// parse, unwrap #[cfg_attr(debug_assertions, track_caller)] fn λ(&self) -> T where ::Err: std::fmt::Display, { match self.parse() { Ok(v) => v, Err(e) => { panic!( "{e}: {self} should parse into {}", std::any::type_name::() ) } } } } pub trait Κ { fn κ(self) -> impl Iterator where ::Err: std::fmt::Display; } impl Κ for &[u8] { fn κ(self) -> impl Iterator where ::Err: std::fmt::Display, { self.str().κ() } } impl Κ for &str { fn κ(self) -> impl Iterator where ::Err: std::fmt::Display, { self.split_ascii_whitespace().map(|x| x.λ()) } } pub trait Α { fn α(self) -> T; } impl Α for Result { #[cfg_attr(debug_assertions, track_caller)] fn α(self) -> T { match self { Ok(v) => v, Err(e) => { panic!("unwrap failed: {e}"); } } } } impl Α for Option { #[cfg_attr(debug_assertions, track_caller)] fn α(self) -> T { match self { Some(v) => v, None => panic!("nothingness!"), } } } pub trait DigiCount { fn ͱ(self) -> u32; } pub const powers: [u64; 20] = car::from_fn!(|x| 10u64.pow(x as u32)); // https://stackoverflow.com/a/9721570 impl DigiCount for u64 { fn ͱ(self) -> u32 { static powers: [u64; 20] = car::from_fn!(|x| 10u64.pow(x as u32)); static mdigs: [u32; 65] = car::from_fn!(|x| 2u128.pow(x as u32).ilog10() + 1); let bit = std::mem::size_of::() * 8 - self.leading_zeros() as usize; let mut digs = mdigs[bit]; if self < C! { powers[digs as usize - 1] } { digs -= 1; } digs } } impl DigiCount for u32 { fn ͱ(self) -> Self { static powers: [u32; 10] = car::from_fn!(|x| 10u32.pow(x as u32)); static mdigs: [u32; 33] = car::from_fn!(|x| 2u128.pow(x as u32).ilog10() + 1); let bit = std::mem::size_of::() * 8 - self.leading_zeros() as usize; let mut digs = mdigs[bit]; if self < C! { powers[digs as usize - 1] } { digs -= 1; } digs } } impl DigiCount for u16 { fn ͱ(self) -> u32 { self.checked_ilog10().ψ() + 1 } } impl DigiCount for u8 { fn ͱ(self) -> u32 { self.checked_ilog10().ψ() + 1 } } impl DigiCount for u128 { fn ͱ(self) -> u32 { self.checked_ilog10().ψ() + 1 } } pub trait Ͷ { fn ͷ(self) -> impl Iterator; fn Ͷ(self, i: u8) -> u8; } macro_rules! digs { ($for:ty) => { impl Ͷ for $for { fn ͷ(self) -> impl Iterator { let digits = self.ͱ() as u8; (0..digits).rev().map(move |n| self.Ͷ(n)) } fn Ͷ(self, i: u8) -> u8 { ((self / (10 as $for).pow(i as _)) % 10) as u8 } } }; } digs!(u128); digs!(u64); digs!(u32); digs!(u16); digs!(u8); #[derive(Copy, Clone, PartialEq, PartialOrd)] pub struct Ronge { pub begin: u16, pub end: u16, } impl Debug for Ronge { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}..{}", self.begin, self.end) } } impl Display for Ronge { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}..{}", self.begin, self.end) } } impl From> for Ronge { fn from(value: RangeInclusive) -> Self { Self { begin: *value.start(), end: *value.end(), } } } impl PartialEq> for Ronge { fn eq(&self, other: &RangeInclusive) -> bool { self == &Self::from(other.clone()) } } impl Ronge { pub fn sane(self) -> bool { self.end >= self.begin } pub fn checked_len(self) -> Option { self.sane().then(|| self.len()) } pub fn len(self) -> u16 { self.end - self.begin } /// push up pub fn pushu(&mut self, to: u16) { self.begin = self.begin.max(to); } /// push down pub fn pushd(&mut self, to: u16) { self.end = self.end.min(to); } pub fn intersect(self, with: Self) -> Self { Self { begin: self.begin.max(with.begin), end: self.end.min(with.end), } } pub fn news(&self, begin: u16) -> Self { Self { begin, end: self.end, } } pub fn newe(&self, end: u16) -> Self { Self { begin: self.begin, end, } } pub fn shrink(&mut self, with: Ronge) { self.pushu(with.begin); self.pushd(with.end); } } impl IntoIterator for Ronge { type Item = u16; type IntoIter = std::ops::Range; fn into_iter(self) -> Self::IntoIter { self.begin..self.end } } pub trait Μ where Self: Sized, { fn μ(self, d: char) -> (Self, Self); fn μκ(self, d: char) -> impl Iterator where ::Err: std::fmt::Display; fn μ1(self, d: char) -> Self { self.μ(d).1 } fn μ0(self, d: char) -> Self { self.μ(d).0 } fn between(self, a: char, b: char) -> Self { self.μ1(a).μ0(b) } } impl Μ for &[u8] { fn μ(self, d: char) -> (Self, Self) { let i = memchr::memchr(d as u8, self) .unwrap_or_else(|| shucks!("{} should split at {d} fine", self.p())); (&self[..i], &self[i + 1..]) } fn μκ(self, d: char) -> impl Iterator where ::Err: std::fmt::Display, { let (α, β) = self.μ(d); α.κ::().zip(β.κ::()) } } pub fn gt, T>(n: T) -> impl Fn(A) -> bool { move |a| a > n } pub fn lt, T>(n: T) -> impl Fn(A) -> bool { move |a| a < n } pub trait SplitU8 { fn μₙ(&self, x: u8) -> impl Iterator + Clone; } impl SplitU8 for [u8] { fn μₙ(&self, x: u8) -> impl Iterator + Clone { self.split(move |&y| y == x) } } impl Μ for &str { fn μ(self, d: char) -> (Self, Self) { self.split_once(d) .unwrap_or_else(|| shucks!("{self} should split at {d} fine")) } fn μκ(self, d: char) -> impl Iterator where ::Err: std::fmt::Display, { let (α, β) = self.μ(d); α.κ::().zip(β.κ::()) } } pub trait IterͶ: Iterator { fn ͷ(self) -> impl Iterator; } impl> IterͶ for I { fn ͷ(self) -> impl Iterator { self.flat_map(Ͷ::ͷ) } } pub trait TupleIterTools3: Iterator { fn l(self) -> impl Iterator; fn m(self) -> impl Iterator; fn r(self) -> impl Iterator; fn lm(self) -> impl Iterator; fn lr(self) -> impl Iterator; fn mr(self) -> impl Iterator; } pub trait TupleIterTools2: Iterator { fn l(self) -> impl Iterator; fn r(self) -> impl Iterator; fn map_l(self, f: impl FnMut(T) -> V) -> impl Iterator; fn map_r(self, f: impl FnMut(U) -> V) -> impl Iterator; } pub trait TupleIterTools2R: Iterator { fn l(self) -> impl Iterator; fn r(self) -> impl Iterator; } pub fn l(f: impl Fn(T) -> R) -> impl Fn((T, U)) -> R { move |(x, _)| f(x) } pub fn r(f: impl Fn(U) -> R) -> impl Fn((T, U)) -> R { move |(_, x)| f(x) } pub trait FilterBy3: Iterator { fn fl(self, f: impl Fn(T) -> bool) -> impl Iterator; fn fm(self, f: impl Fn(U) -> bool) -> impl Iterator; fn fr(self, f: impl Fn(V) -> bool) -> impl Iterator; } impl> FilterBy3 for I { fn fl(self, f: impl Fn(T) -> bool) -> impl Iterator { self.filter(move |(x, _, _)| f(*x)) } fn fm(self, f: impl Fn(U) -> bool) -> impl Iterator { self.filter(move |(_, x, _)| f(*x)) } fn fr(self, f: impl Fn(V) -> bool) -> impl Iterator { self.filter(move |(_, _, x)| f(*x)) } } pub trait FilterBy: Iterator { fn fl(self, f: impl FnMut(T) -> bool) -> impl Iterator; fn fr(self, f: impl FnMut(U) -> bool) -> impl Iterator; } impl> FilterBy for I { fn fl(self, mut f: impl FnMut(T) -> bool) -> impl Iterator { self.filter(move |(x, _)| f(*x)) } fn fr(self, mut f: impl FnMut(U) -> bool) -> impl Iterator { self.filter(move |(_, x)| f(*x)) } } pub trait NumTupleIterTools { fn πολλαπλασιάζω_και_αθροίζω(&mut self) -> u64; } impl> NumTupleIterTools for I { fn πολλαπλασιάζω_και_αθροίζω(&mut self) -> u64 { self.map(|(a, b)| a * b).sum() } } impl> TupleIterTools2 for I { fn l(self) -> impl Iterator { self.map(|(x, _)| x) } fn r(self) -> impl Iterator { self.map(|(_, x)| x) } fn map_l(self, mut f: impl FnMut(T) -> V) -> impl Iterator { self.map(move |(x, y)| (f(x), y)) } fn map_r(self, mut f: impl FnMut(U) -> V) -> impl Iterator { self.map(move |(x, y)| (x, f(y))) } } impl<'a, T: Copy + 'a, U: Copy + 'a, I: Iterator> TupleIterTools2R for I { fn l(self) -> impl Iterator { self.map(|&(x, _)| x) } fn r(self) -> impl Iterator { self.map(|&(_, x)| x) } } impl> TupleIterTools3 for I { fn l(self) -> impl Iterator { self.map(|(x, _, _)| x) } fn m(self) -> impl Iterator { self.map(|(_, x, _)| x) } fn r(self) -> impl Iterator { self.map(|(_, _, x)| x) } fn lm(self) -> impl Iterator { self.map(|(a, b, _)| (a, b)) } fn lr(self) -> impl Iterator { self.map(|(a, _, b)| (a, b)) } fn mr(self) -> impl Iterator { self.map(|(_, a, b)| (a, b)) } } pub trait GreekTools: Iterator { fn Δ(&mut self) -> T; fn ν(self, into: &mut [T; N]) -> usize; fn θ(self); } pub trait ParseIter { fn κ(&mut self) -> impl Iterator where ::Err: std::fmt::Display; } impl<'x, I: Iterator> ParseIter for I { fn κ(&mut self) -> impl Iterator where ::Err: std::fmt::Display, { self.flat_map(|x| x.κ()) } } pub trait Ι: Iterator + Sized { fn ι(self) -> Zip> { self.zip(N::default()..) } fn ι1(self) -> Zip>> { self.zip((N::default()..).skip(1)) } } impl> Ι for I {} pub fn nail(x: &[T]) -> &[T; N] { unsafe { &*(x.as_ptr() as *const [T; N]) } } pub mod reading { pub struct Integer<'a, 'b, T, const BY: u8 = b'\n'> { pub x: &'a mut &'b [u8], pub _ph: std::marker::PhantomData, } impl<'a, 'b, T: Copy, const BY: u8> Integer<'a, 'b, T, BY> { pub fn new(x: &'a mut &'b [u8]) -> Self { Self { x, _ph: std::marker::PhantomData, } } } impl< 'a, 'b, const BY: u8, T: Default + std::ops::Mul + Add + From + Copy + Ten + Debug, > Iterator for Integer<'a, 'b, T, BY> { type Item = T; fn next(&mut self) -> Option { (!self.x.is_empty()).then(|| read_until(self.x, BY)) } } #[inline] pub fn 八(n: u64) -> u64 { // reinterpret as u64 ("92233721" => 92233721) // let n = u64::from_le_bytes(s); // combine 4 pairs of single digits: // split pieces into odd and even // 1_7_3_2_ (le repr) // _2_3_2_9 // then combine // _21_37_23_92 (le repr, each byte as 2 digits) let n = ((n & 0x0f000f000f000f00) >> 8) + ((n & 0x000f000f000f000f) * 10); // combine 2 pairs of 2 digits: // split again // _21___23__ // ___37___92 // then combine // __14|137__36|7 (le repr, pipes separating bytes) let n = ((n & 0x00ff000000ff0000) >> 16) + ((n & 0x000000ff000000ff) * 100); // combine pair of 4 digits // split again // __14|137____ (then moved to ______14|137, as u64:3721) // ______36|07 (as u64: 9223) // then combine ((n & 0x0000ffff00000000) >> 32) + ((n & 0x000000000000ffff) * 10000) } use std::{ io::{self, Read}, ops::{Add, BitOrAssign, Shl}, }; pub trait Ext { fn rd(&mut self) -> io::Result<[u8; N]>; fn by(&mut self) -> io::Result { Ok(self.rd::<1>()?[0]) } } impl Ext for T { fn rd(&mut self) -> io::Result<[u8; N]> { let mut buf = [0; N]; self.read_exact(&mut buf)?; Ok(buf) } } use crate::util::prelude::*; pub fn κ< T: Default + std::ops::Mul + Add + From + Copy + Ten + Debug, >( x: &[u8], v: &mut [T], ) -> usize { let mut n = 0; let mut s = T::default(); for &b in x { match b { b' ' => { C! { v[n] = s }; n += 1; s = T::default(); } b => { s = s * T::TEN + T::from(b - b'0'); } } } C! {v[n] = s}; n + 1 } pub trait Ten { const TEN: Self; const ONE: Self; } macro_rules! tenz { ($for:ty) => { impl Ten for $for { const TEN: Self = 10; const ONE: Self = 1; } }; } tenz!(u8); tenz!(u16); tenz!(u32); tenz!(u64); tenz!(u128); tenz!(usize); tenz!(i8); tenz!(i16); tenz!(i32); tenz!(i64); tenz!(i128); tenz!(isize); const DIG: [u8; 256] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; pub fn hex_dig(b: u8) -> u8 { DIG[b.nat()] // (b & 0xF) + 9 * (b >> 6) } pub fn hexN< T: From + TryFrom + Shl + BitOrAssign, const N: usize, >( a: [u8; N], ) -> T { let mut c = T::from(hex_dig(a[0])) << T::try_from((N - 1) * 4).ψ(); for (&n, sh) in a[1..].iter().zip((0..N - 1).rev()) { c |= T::from(hex_dig(n)) << T::try_from(sh * 4).ψ(); } c } pub fn hex(mut d: &[u8]) -> Result { let &b = d.split_off_first().ok_or(())?; let mut num = hex_dig(b) as u32; while let Some(&b) = d.split_off_first() { num = num * 16 + hex_dig(b) as u32; } Ok(num) } pub fn read_until< T: Default + std::ops::Mul + Add + From + Copy + Ten, >( x: &mut &[u8], until: u8, ) -> T { let mut n = T::from(x.by().ψ() - b'0'); loop { let x = x.by().ψ(); if x == until { return n; } n = n * T::TEN + T::from(x - b'0') } } pub fn 負迄(x: &mut &[u8], until: u8) -> i64 { let (sign, mut n) = match x.by().ψ() { b'-' => (-1, 0), b => (1, i64::from(b - b'0')), }; loop { let byte = x.by().ψ(); if byte == until { return n * sign as i64; } n = n * 10 + i64::from(byte - b'0'); } } pub fn until + Add + From + Copy + Ten>( x: &mut &[u8], until: u8, ) -> T { let mut n = T::from(x.by().ψ() - b'0'); loop { let byte = x.by().ψ(); if byte == until { return n; } n = n * T::TEN + T::from(byte - b'0'); } } #[cfg_attr(debug_assertions, track_caller)] pub fn all< T: Default + std::ops::Mul + Add + From + Copy + Ten, >( x: &[u8], ) -> T { let mut n = T::default(); for &byte in x { n = n * T::TEN + T::from(byte - b'0'); } n } } pub fn even(x: &usize) -> bool { x % 2 == 0 } impl> GreekTools for I { #[cfg_attr(debug_assertions, track_caller)] fn Δ(&mut self) -> T { self.next().ψ() } fn ν(mut self, into: &mut [T; N]) -> usize { let mut set = 0; for e in into { let Some(y) = self.next() else { break }; *e = y; set += 1; } set } fn θ(self) { for _ in self {} } } pub trait TupleUtils { fn mr(self, f: impl FnOnce(U) -> W) -> (T, W); fn ml(self, f: impl FnOnce(T) -> V) -> (V, U); fn rev(self) -> (U, T); } pub trait Widen { fn nat(self) -> usize; fn widen(self) -> Wide; } macro_rules! wide { ($t:ty: $upper:ty) => { impl Widen<$upper> for $t { fn nat(self) -> usize { self as _ } fn widen(self) -> $upper { self as _ } } }; } wide!(u8: u16); wide!(u16: u32); wide!(u32: u64); wide!(u64: u128); wide!(i64: i128); pub trait UnifiedTupleUtils { fn mb(self, f: impl FnMut(T) -> U) -> (U, U); } impl UnifiedTupleUtils for (T, T) { fn mb(self, mut f: impl FnMut(T) -> U) -> (U, U) { (f(self.0), f(self.1)) } } impl TupleUtils for (T, U) { fn mr(self, f: impl FnOnce(U) -> W) -> (T, W) { (self.0, f(self.1)) } fn ml(self, f: impl FnOnce(T) -> V) -> (V, U) { (f(self.0), self.1) } fn rev(self) -> (U, T) { (self.1, self.0) } } #[allow(dead_code)] fn cast_to>(x: bool, _to: T) -> T { x.into() } #[allow(unused_macros)] macro_rules! bits { ($bitset:ident + $bit:expr) => { $bitset |= 1 << $bit }; ($holder:ident[$index:expr] + $bit:expr) => { $holder[$index] |= 1 << $bit; }; ($bitset:ident[$bit:expr]) => { ($bitset & 1 << $bit) != 0 }; ($holder:ident[$index:expr][$bit:expr]) => { ($holder[$index] & 1 << $bit) != 0 }; ($holder:ident[$index:expr][$index2:expr][$bit:expr]) => { ($holder[$index][$index2] & 1 << $bit) != 0 }; ($holder:ident[$index:expr][$index2:expr] + $bit:expr) => { $holder[$index][$index2] |= 1 << $bit }; ($bitset:ident[$bit:expr] = $val:expr) => { $bitset = ($bitset & !(1 << $bit)) | (crate::util::cast_to($val, $bitset) << $bit) }; ($bitset:ident - $bit:expr) => { $bitset &= !(1 << $bit) }; ($bitset:ident ! $bit:expr) => { $bitset ^= 1 << $bit }; } pub(crate) use bits; #[derive(Clone, Copy)] pub struct Lines<'a> { pub bytes: &'a [u8], } impl<'a> Iterator for Lines<'a> { type Item = &'a [u8]; fn next(&mut self) -> Option { self.bytes.take_line() } } impl<'a> std::iter::FusedIterator for Lines<'a> {} impl<'a> DoubleEndedIterator for Lines<'a> { #[inline] fn next_back(&mut self) -> Option { self.bytes.take_backline() } } #[link(name = "c")] unsafe extern "C" { fn mmap(addr: *mut u8, len: usize, prot: i32, flags: i32, fd: i32, offset: i64) -> *mut u8; fn lseek(fd: i32, offset: i64, whence: i32) -> i64; } #[allow(dead_code)] #[unsafe(no_mangle)] unsafe fn mmaped<'a>() -> (*const u8, i64) { let seek_end = 2; let size = lseek(0, 0, seek_end); if size == -1 { unsafe { std::hint::unreachable_unchecked() } } let prot_read = 0x01; let map_private = 0x02; let map_populate = 0x08000; let ptr = mmap( 0 as _, size as usize, prot_read, map_private | map_populate, 0, 0, ); if ptr as isize == -1 { unsafe { std::hint::unreachable_unchecked() } } (ptr, size) } pub trait IntoLines { fn 行<'a>(&'a self) -> Lines<'a>; } impl IntoLines for [u8] { fn 行(&self) -> Lines<'_> { Lines { bytes: self } } } impl IntoLines for str { fn 行(&self) -> Lines<'_> { Lines { bytes: self.as_ref(), } } } pub trait Str { fn str(&self) -> &str; } impl Str for [u8] { #[cfg_attr(debug_assertions, track_caller)] fn str(&self) -> &str { std::str::from_utf8(self).ψ() } } pub trait Printable { fn p(&self) -> impl std::fmt::Display; } struct PrintU8s<'a>(&'a [u8]); impl std::fmt::Display for PrintU8s<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for &b in self.0 { if b.is_ascii() { f.write_char(b as char)?; } else { write!(f, "\\x{b:x}")?; } } Ok(()) } } struct PrintManyU8s<'a, T: AsRef<[u8]>>(&'a [T]); impl> std::fmt::Display for PrintManyU8s<'_, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { for row in self.0.as_ref() { write!(f, "{},", row.as_ref().p())?; } Ok(()) } } impl Printable for [Vec] { fn p(&self) -> impl std::fmt::Display { PrintManyU8s(self) } } impl Printable for [&&[u8]] { fn p(&self) -> impl std::fmt::Display { PrintManyU8s(self) } } impl Printable for [&[u8]] { fn p(&self) -> impl std::fmt::Display { PrintManyU8s(self) } } impl Printable for [u8] { fn p(&self) -> impl std::fmt::Display { PrintU8s(self) } } impl Printable for Vec { fn p(&self) -> impl std::fmt::Display { PrintU8s(self) } } pub fn sort(mut x: Vec) -> Vec { x.sort_unstable(); x } pub trait TakeLine<'b> { fn take_line<'a>(&'a mut self) -> Option<&'b [u8]>; fn take_backline<'a>(&'a mut self) -> Option<&'b [u8]>; } impl<'b> TakeLine<'b> for &'b [u8] { fn take_line<'a>(&'a mut self) -> Option<&'b [u8]> { match memchr::memchr(b'\n', self) { None if self.is_empty() => None, None => Some(std::mem::replace(self, b"")), Some(end) => { let line = C! { &self[..end]}; *self = C! { &self[end + 1..]}; Some(line) } } } fn take_backline<'a>(&'a mut self) -> Option<&'b [u8]> { let end = self.len().checked_sub(1)?; match memchr::memrchr(b'\n', &self[..end]) { None => Some(std::mem::replace(self, b"")), Some(end) => { let line = &self[end + 1..]; *self = &self[..end]; Some(line) } } } } impl<'b> TakeLine<'b> for &'b str { fn take_line<'a>(&'a mut self) -> Option<&'b [u8]> { match memchr::memchr(b'\n', self.as_bytes()) { None if self.is_empty() => None, None => Some(std::mem::replace(self, "").as_bytes()), Some(end) => { let line = self[..end].as_bytes(); *self = &self[end + 1..]; Some(line) } } } fn take_backline<'a>(&'a mut self) -> Option<&'b [u8]> { let end = self.len().checked_sub(1)?; match memchr::memrchr(b'\n', &self.as_bytes()[..end]) { None => Some(std::mem::replace(self, "").as_bytes()), Some(end) => { let line = &self[end + 1..]; *self = &self[..end]; Some(line.as_bytes()) } } } } pub trait IntoCombinations: Iterator { /// LEAKY fn combine(self) -> impl Iterator; } impl> IntoCombinations for I { fn combine(self) -> impl Iterator { let x = Box::leak(self.collect::>()); x.iter() .enumerate() .flat_map(|(i, &a)| x[i..].iter().map(move |&b| (a, b))) } } pub trait Skip { fn skip(&mut self, n: usize); fn skip_n(&mut self, n: &'static str) { self.skip(n.len()) } } impl Skip for &[T] { #[cfg_attr(debug_assertions, track_caller)] fn skip(&mut self, n: usize) { if cfg!(debug_assertions) { *self = &self[n..]; } else { *self = C! { &self[n..] }; } } } impl Skip for &str { #[cfg_attr(debug_assertions, track_caller)] fn skip(&mut self, n: usize) { if cfg!(debug_assertions) { *self = &self[n..]; } else { *self = C! { &self[n..] }; } } } /// WYRAND based rng's pub mod rand { /// WYRAND pub fn u64() -> u64 { static mut STATE: u64 = 0; let tmp = unsafe { STATE = STATE.wrapping_add(0x60bee2bee120fc15); (STATE as u128).wrapping_mul(0xa3b195354a39b70d) }; let m1 = (tmp >> 64) ^ tmp; let tmp = m1.wrapping_mul(0x1b03738712fad5c9); ((tmp >> 64) ^ tmp) as u64 } /// 0..N pub mod limit { use crate::Widen; pub fn u64(of: u64) -> u64 { ((super::u64().widen().wrapping_mul(of.widen())) >> 64) as u64 } } pub fn u32() -> u32 { u64() as u32 } pub fn u16() -> u16 { u64() as u16 } pub fn f32() -> f32 { (1.0 / ((1u32 << 24) as f32)) * ((u32() >> 8) as f32) } pub fn f64() -> f64 { (1.0 / ((1u64 << 53) as f64)) * ((u64() >> 11) as f64) } } pub fn manhattan((x1, y1): (i32, i32), (x2, y2): (i32, i32)) -> i32 { (x1 - x2).abs() + (y1 - y2).abs() } pub fn ints(x: &'static [u8]) -> impl Iterator where T::Err: std::fmt::Display, { static RE: LazyLock = LazyLock::new(|| Regex::new("-?[0-9]+").unwrap()); RE.find_iter(x.str()).map(|x| x.as_str().λ()) } pub fn uints(x: &[u8]) -> impl Iterator where T::Err: std::fmt::Display, { static RE: LazyLock = LazyLock::new(|| Regex::new("[0-9]+").unwrap()); RE.find_iter(x.str()).map(|x| x.as_str().λ()) } pub fn nb< T: Default + std::ops::Sub + std::ops::Add + Copy + reading::Ten, >( (x, y): (T, T), ) -> [(T, T); 8] { [ (x - T::ONE, y - T::ONE), (x, y - T::ONE), (x + T::ONE, y - T::ONE), (x - T::ONE, y), // this (x + T::ONE, y), (x - T::ONE, y + T::ONE), (x, y + T::ONE), (x + T::ONE, y + T::ONE), ] } pub fn twice(x: T) -> impl Iterator + Clone + ExactSizeIterator { std::iter::repeat_n(x, 2) } pub fn infinite_successors(x: T, mut f: impl FnMut(T) -> T) -> impl Iterator { successors(Some(x), move |x| Some(f(*x))) } pub fn countmap( x: impl Iterator, ) -> impl Iterator { let mut h = HashMap::<_, usize>::default(); for e in x { *h.entry(e).or_default() += 1; } let mut v = h.into_iter().collect::>(); v.sort_unstable_by_key(move |&(x, y)| (Reverse(y), x)); v.into_iter() } pub trait MapWith { fn map_w(self, f: impl FnMut(T) -> U) -> impl Iterator; fn fmap_w(self, f: impl FnMut(T) -> Option) -> impl Iterator; } impl> MapWith for I { fn map_w(self, mut f: impl FnMut(T) -> U) -> impl Iterator { self.map(move |x| (x, f(x))) } fn fmap_w(self, mut f: impl FnMut(T) -> Option) -> impl Iterator { self.flat_map(move |x| Some(x).zip(f(x))) } } pub fn md5(x: &[u8]) -> [u8; 16] { use md5::Digest; let mut hasher = md5::Md5::new(); hasher.update(x); hasher.finalize().into() } pub fn md5s(x: &[u8]) -> String { let mut s = String::with_capacity(32); for element in md5(x) { write!(s, "{element:02x}").unwrap(); } s } pub trait PartitionByKey { fn partition_by_key + Default>( self, f: impl FnMut(&T) -> bool, key: impl FnMut(T) -> V, ) -> [U; 2]; } impl> PartitionByKey for I { fn partition_by_key + Default>( self, mut f: impl FnMut(&T) -> bool, mut key: impl FnMut(T) -> V, ) -> [U; 2] { let mut o: [U; 2] = [default(), default()]; for x in self { match f(&x) { true => &mut o[0], false => &mut o[1], } .extend_one(key(x)); } o } } pub trait BoolTools { fn thn(self, f: impl FnMut()) -> Self; } impl BoolTools for bool { fn thn(self, mut f: impl FnMut()) -> Self { if self { f(); } self } } pub trait GridFind { fn find(self, c: u8) -> (usize, usize); fn find_iter(&self, c: u8) -> impl Iterator; } impl GridFind for [[u8; N]; M] { fn find(self, c: u8) -> (usize, usize) { let i = memchr::memchr(c, self.as_flattened()).ψ(); (i % N, i / N) } fn find_iter(&self, c: u8) -> impl Iterator { memchr::memchr_iter(c, self.as_flattened()).map(|i| (i % N, i / N)) } } impl GridFind for &[&[u8]] { fn find(self, c: u8) -> (usize, usize) { self.iter() .zip(0..) .find_map(|(x, y)| x.iter().position(|&x| x == c).map(|x| (x, y))) .unwrap() } fn find_iter(&self, c: u8) -> impl Iterator { self.iter().zip(0..).flat_map(move |(x, y)| { x.iter() .ι::() .fl(move |&x| x == c) .map(move |(_, x)| (x, y)) }) } } impl GridFind for &[Vec] { fn find(self, c: u8) -> (usize, usize) { self.iter() .zip(0..) .find_map(|(x, y)| x.iter().position(|&x| x == c).map(|x| (x, y))) .unwrap() } fn find_iter(&self, c: u8) -> impl Iterator { self.iter().zip(0..).flat_map(move |(x, y)| { x.iter() .ι::() .fl(move |&x| x == c) .map(move |(_, x)| (x, y)) }) } } pub trait TwoWayMapCollect: Iterator { fn collect_twm(self) -> HashMap<(K, K), V>; } impl> TwoWayMapCollect for I { fn collect_twm(self) -> HashMap<(K, K), V> { let mut m = HashMap::default(); for ((a, b), c) in self { m.insert((a.clone(), b.clone()), c.clone()); m.insert((b, a), c); } m } } /// for spiral such as /// 9 10 11 12 /// 8 1 2 13 /// 7 0 3 14 /// 6 5 4 15 pub mod spiral { // https://www.desmos.com/calculator/qpn25p39v9 pub fn coordinate_of(n: u64) -> (i64, i64) { let m = n.isqrt() as i64; ( (-1i64).pow(m as u32 + 1) * (((n as i64 - m * (m + 1)) // _ * (((2.0 * (n as f64).sqrt()).floor() as i64 + 1) % 2)) + (m + 1) / 2), (-1i64).pow(m as u32) * ((n as i64 - m * (m + 1)) // _ * ((2.0 * (n as f64).sqrt()).floor() as i64 % 2) - (m + 1) / 2), ) } //https://math.stackexchange.com/a/1860731 pub fn index_at((x, y): (i64, i64)) -> i64 { let s = if x.abs() >= y.abs() { x } else { -y }; if s >= 0 { 4 * s * s - x + -y } else { 4 * s * s + (-1_i64).pow((s == x) as u32) * (2 * s + x + -y) } } } pub trait AndF { fn and(self, f: impl FnOnce(&Self) -> T) -> Self; } impl AndF for T { fn and(self, f: impl FnOnce(&Self) -> U) -> Self { f(&self); self } } pub trait MapF: Sized { #[doc(alias = "map")] fn 𝙢𝙖𝙥(self, f: impl FnOnce(Self) -> T) -> T; } impl MapF for U { fn 𝙢𝙖𝙥(self, f: impl FnOnce(Self) -> T) -> T { f(self) } } pub trait Splib { fn splib(&'_ self, seq: &'static [u8]) -> impl Iterator + '_; } impl Splib for [u8] { fn splib(&'_ self, seq: &'static [u8]) -> impl Iterator + '_ { self.str().split(seq.str()).map(str::as_bytes) } } pub fn parse_digraph<'a, N: Hash + Ord, D>( x: &'a [u8], mut f: impl FnMut(&'a [u8]) -> (N, D), ) -> HashMap>)> { let mut map = HashMap::default(); x.行().for_each(|x| { let (node, connections) = match memchr::memmem::find(x, b"->") { Some(index) => ( &x[..index - 1], Some( x[index + 3..] .μₙ(b',') .map(<[u8]>::trim_ascii) .collect::>(), ), ), None => (x, None), }; let (k, d) = f(node); map.insert(k, (d, connections)); }); map } pub fn parse_graph<'a, N: Hash + Ord + Clone>( x: &'a [u8], mut f: impl FnMut(&'a [u8]) -> N + Copy, ) -> HashMap> { let mut map = HashMap::default(); x.行().for_each(|x| { let (node, connections) = match memchr::memmem::find(x, b"--") { Some(index) => ( &x[..index - 1], x[index + 2..] .μₙ(b',') .map(<[u8]>::trim_ascii) .map(f) .collect::>(), ), None => (x, vec![]), }; // for c in &connections { // map.entry(c.clone()).or_default().push(c); // } map.entry(f(node)).or_insert(connections); }); map } pub mod python { use std::cell::RefCell; use std::ffi::CStr; use std::ffi::CString; use std::sync::Mutex; use std::sync::RwLock; // struct R(proc_macro::TokenStream); // impl<'py, 's> FromPyObject<'py> for R { // fn extract_bound(x: &Bound<'py, PyAny>) -> Result { // let tree: TokenTree = match () { // () if let Ok(x) = x.extract::() => Literal::i128_unsuffixed(x).into(), // () if let Ok(x) = x.extract::() => Literal::f64_unsuffixed(x).into(), // () if let Ok(x) = x.extract::() => { // Ident::new(&x.to_string(), Span::call_site()).into() // } // () if let Ok(x) = x.extract::() => { // return Ok(R(x // .parse::() // .unwrap_or(quote::quote!(compile_error!("lex failure")).into()))); // } // // () if let Ok(x) = x.downcast::() => { // // if let Ok(y) = x.get_item(0) { // // match () { // // () if y.is_instance_of::() => Val::Array(Array::Float( // // x.into_iter().map(|x| x.extract::()).try_collect()?, // // )), // // () if y.is_instance_of::() => Val::Array(Array::Int( // // x.into_iter().map(|x| x.extract::()).try_collect()?, // // )), // // _ => { // // return Err(PyTypeError::new_err("bad array types")); // // } // // } // // } else { // // Val::Array(Array::Int(vec![])) // // } // // } // // () if let Ok(x) = x.downcast::() => Val::Set( // // x.into_iter() // // .map(|x| x.extract::>()) // // .try_collect()?, // // ), // _ => return Err(PyTypeError::new_err("bad types")), // }; // let mut t = TokenStream::new(); // t.extend([tree]); // Ok(R(t)) // } // } macro_rules! eval { ($fmt:literal $(, $args:expr)* $(,)? => $t:ty) => {{ use pyo3::*; use pyo3::exceptions::PyTypeError; use pyo3::prelude::*; use pyo3::types::*; pyo3::Python::initialize(); pyo3::Python::attach(|g| { g.eval(&std::ffi::CString::new(format!($fmt $(, $args)*)).unwrap(), None, None) .unwrap_or_else(|x| { eprintln!("error:"); x.display(g); std::process::exit(1) }) .extract::<$t>() }) .unwrap() }}; } pub(crate) use eval; } pub mod hexagon { use atools::prelude::*; pub const n: [i64; 2] = [0, -1]; pub const ne: [i64; 2] = [1, -1]; pub const se: [i64; 2] = [1, 0]; pub const s: [i64; 2] = [0, 1]; pub const sw: [i64; 2] = [-1, 1]; pub const nw: [i64; 2] = [-1, 0]; pub fn distance(a: [i64; 2], b: [i64; 2]) -> i64 { let [q, r] = a.asub(b); ((q).abs() + (q + r).abs() + (r).abs()) / 2 } } pub fn each_bit< T: reading::Ten + Default + std::ops::Shl + std::ops::BitAnd + std::cmp::PartialEq + Copy, >( b: T, ) -> [bool; size_of::() * 8] { use atools::prelude::*; atools::range() .rev() .map(|x| b & (T::ONE << x) != T::default()) } pub trait Position { fn position(&self, x: T) -> usize; } impl Position for [T] { fn position(&self, x: T) -> usize { self.iter().position(|y| &x == y).ψ() } } pub trait PRead { unsafe fn λ(&mut self) -> T; } impl PRead for *const T { unsafe fn λ(&mut self) -> T { let b = self.read(); *self = self.add(1); b } } pub trait FirstMax { fn fmax_by_left(self) -> T; } impl> FirstMax<(T, U)> for I { fn fmax_by_left(self) -> (T, U) { let mut best = (T::default(), U::default()); for el in self { if best.0 < el.0 { best = el } } best } }