haar_lib/macros/
sort_with.rs

1//! `sort_with!`
2
3/// 複数の配列をソートする。
4///
5/// 第一引数の比較関数に基づいて、順列`0,1,..,n-1`をソートする。
6/// 第二引数以降の配列を、この順列に基づいてソートする。
7#[macro_export]
8macro_rules! sort_with {
9    ($cmp:expr, $($a:expr),+) => {
10        {
11            let n = vec![$($a.len()),+].into_iter().min().unwrap();
12            let mut ord = (0..n).collect::<Vec<usize>>();
13            ord.sort_by($cmp);
14
15            let mut check = vec![false; n];
16
17            for i in 0..n {
18                if !check[i] {
19                    check[i] = true;
20                    let mut j = i;
21                    while ord[j] != i {
22                        {
23                            $(
24                                $a.swap(j, ord[j]);
25                            )+
26                        }
27                        j = ord[j];
28                        check[j] = true;
29                    }
30                }
31            }
32        }
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    #[test]
39    fn test() {
40        let mut a = vec![0, 1, 2, 3];
41        let mut b = vec![3, 2, 9, 4];
42
43        sort_with!(|&i, &j| b[i].cmp(&b[j]), a, b);
44
45        assert_eq!(b, vec![2, 3, 4, 9]);
46        assert_eq!(a, vec![1, 0, 3, 2]);
47    }
48}