1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use std::{
fmt::{self, Debug},
ops::Index,
};
/// 座標圧縮です。
///
/// # Examples
///
/// ```
/// use zarts::SortedSeq;
/// let values = vec![2, -1, -1, 5, -1, 2, -3];
/// // -3, -1, 2, 5
/// let seq = SortedSeq::new(values);
/// assert_eq!(seq.ord(&-3), 0);
/// assert_eq!(seq.ord(&-1), 1);
/// assert_eq!(seq.ord(&2), 2);
/// assert_eq!(seq.ord(&5), 3);
///
/// assert_eq!(seq.at(0), &(-3));
/// assert_eq!(seq.at(1), &(-1));
/// assert_eq!(seq.at(2), &2);
/// assert_eq!(seq.at(3), &5);
/// ```
///
/// # Panics
///
/// 構築時に与えられなかったキーを引くとパニックです。
///
/// ```should_panic
/// use zarts::SortedSeq;
/// let primes = vec![2, 3, 5, 7, 11];
/// let seq = SortedSeq::new(primes);
/// seq.ord(&4);
/// ```
///
/// index が集合のサイズ以上だとパニックです。
///
/// ```should_panic
/// use zarts::SortedSeq;
/// let values = vec![1, 1, 2, 2, 3, 4, 9, 9];
/// let seq = SortedSeq::new(values);
/// seq.at(5);
/// ```
///
pub struct SortedSeq<T>(Vec<T>);
impl<T> FromIterator<T> for SortedSeq<T>
where
T: Ord,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self::new(iter)
}
}
impl<T> SortedSeq<T>
where
T: Ord,
{
pub fn new(values: impl IntoIterator<Item = T>) -> Self {
let mut values = values.into_iter().collect::<Vec<_>>();
values.sort_unstable();
values.dedup();
Self(values)
}
/// 集合内で小さいほうから何番目か (0-indexed) を返します
pub fn ord(&self, value: &T) -> usize {
self.0
.binary_search(value)
.unwrap_or_else(|_| panic!("not found"))
}
/// index 番目の値を返します
pub fn at(&self, index: usize) -> &T {
&self[index]
}
/// 集合のサイズを返します
pub fn size(&self) -> usize {
self.0.len()
}
}
impl<T> Index<usize> for SortedSeq<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
impl<T> Debug for SortedSeq<T>
where
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
#[cfg(test)]
mod tests {
use crate::SortedSeq;
#[test]
fn ord_test() {
let seq = SortedSeq::new(vec![4, 4, 2, 5, 2, 9]);
// 2, 4, 5, 9
assert_eq!(seq.ord(&2), 0);
assert_eq!(seq.ord(&4), 1);
assert_eq!(seq.ord(&5), 2);
assert_eq!(seq.ord(&9), 3);
}
#[test]
fn index_test() {
let seq = SortedSeq::new([4, 4, 2, 5, 2, 9]);
// 2, 4, 5, 9
assert_eq!(seq.at(0), &2);
assert_eq!(seq.at(1), &4);
assert_eq!(seq.at(2), &5);
assert_eq!(seq.at(3), &9);
}
#[test]
#[should_panic]
fn not_found_test() {
let seq: SortedSeq<i32> = SortedSeq::new(vec![4, 4, 2, 5, 2, 9]);
seq.ord(&6);
}
}