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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! 例:handle。
//!
//! ## Samples
//!
//! 以下のような API を提供するクラスを考える。
//!
//! - $`S \gets \varnothing`$ で初期化。
//! - $`i = |S|`$ として $`S \gets S\cup (i, i)`$ で更新。
//! - $`(i, j)`$ を受け取る。$`(i, j')\in S`$ として $`S \gets (S\smallsetminus (i, j'))\cup (i, j)`$ で更新。
//! - $`i`$ を受け取る。$`\angled{i, f(i), f(f(i)), \dots}`$ を返す。
//!     - ただし、$`{}^{\exists!}j.\: (i, j)\in S`$ のとき $`f(i) = j`$ とする。
//!
//! 当然 `Vec<usize>` で実現できるが、ここではポインタを扱う練習として、$`i`$ 番目のノードから
//! $`j`$ 番目のノードに対するポインタを持つような実装を考える。
//!
//! ```
//! use std::ptr::NonNull;
//!
//! // --- implementations ---
//! pub struct Node {
//!     val: usize,
//!     mapsto: NonNull<Node>,
//! }
//! #[derive(Clone, Copy)]
//! pub struct Handle {
//!     node: NonNull<Node>,
//! }
//! pub struct Graph {
//!     nodes: Vec<NonNull<Node>>,
//! }
//!
//! impl Node {
//!     pub fn new(val: usize) -> NonNull<Self> {
//!         let node = Box::new(Node { val, mapsto: NonNull::dangling() });
//!         let ptr = NonNull::from(Box::leak(node));
//!         unsafe { (*ptr.as_ptr()).mapsto = ptr };
//!         ptr
//!     }
//! }
//!
//! impl Handle {
//!     fn new(node: NonNull<Node>) -> Self { Self { node } }
//!     pub fn mapsto(&mut self, other: Self) {
//!         unsafe { (*self.node.as_ptr()).mapsto = other.node }
//!     }
//!     pub fn walk(&self) -> impl Iterator<Item = usize> {
//!         std::iter::successors(Some(self.node), |&ptr| unsafe {
//!             Some((*ptr.as_ptr()).mapsto)
//!         })
//!         .map(|ptr| unsafe { (*ptr.as_ptr()).val })
//!     }
//! }
//!
//! impl Graph {
//!     pub fn new() -> Self { Self { nodes: vec![] } }
//!     pub fn push(&mut self) -> Handle {
//!         let val = self.nodes.len();
//!         let ptr = Node::new(val);
//!         self.nodes.push(ptr);
//!         Handle::new(ptr)
//!     }
//! }
//!
//! impl Drop for Graph {
//!     fn drop(&mut self) {
//!         for ptr in self.nodes.drain(..) {
//!             unsafe { drop(Box::from_raw(ptr.as_ptr())) };
//!         }
//!     }
//! }
//!
//! // --- tests ---
//! let mut graph = Graph::new();
//! let mut x0 = graph.push();
//! let mut x1 = graph.push();
//! let mut x2 = graph.push();
//! let mut x3 = graph.push();
//! let mut x4 = graph.push();
//!
//! x0.mapsto(x1);
//! x1.mapsto(x3);
//! x2.mapsto(x1);
//! x3.mapsto(x1);
//! x4.mapsto(x2);
//!
//! // 0 -> 1 <> 3
//! //      ^
//! //      2 <- 4
//!
//! let a: Vec<_> = x0.walk().take(10).collect();
//! assert_eq!(a, [0, 1, 3, 1, 3, 1, 3, 1, 3, 1]);
//!
//! x3.mapsto(x4);
//! x4.mapsto(x2);
//!
//! // 0 -> 1 -> 3
//! //      ^    v
//! //      2 <- 4
//!
//! let a: Vec<_> = x0.walk().take(10).collect();
//! assert_eq!(a, [0, 1, 3, 4, 2, 1, 3, 4, 2, 1]);
//!
//! x0.mapsto(x0); // self loop
//!
//! let a: Vec<_> = x0.walk().take(10).collect();
//! assert_eq!(a, [0; 10]);
//! ```
//!
//! ## Notes
//!
//! 「node を作成し、handle を返す」「handle を渡し、構造を更新する」が基本的な方針になると思われる。
//! より複雑な例においては「更新の際に、別の handle(が持っている pointer が指す node)を無効化する」
//! ということも起きうるので、注意する必要がある。
//!
//! これが問題なく書けるのであれば、Fibonacci heap なども書けそうな気がするが果たして?
//!
//! おそらくは次のような構造で書けると思う (cf. [CS166 (1186), Fibonacci Heaps](https://web.stanford.edu/class/archive/cs/cs166/cs166.1186/lectures/09/Slides09.pdf#page=208))。
//!
//! ```
//! use std::ptr::NonNull;
//!
//! pub struct FibHeap<T: Ord> {
//!     roots: Vec<FibHeapNode<T>>,
//!     max: Option<T>,
//! }
//! struct FibHeapNode<T> {
//!     val: T,
//!     parent: Option<NonNull<FibHeapNode<T>>>,
//!     neighbor: (NonNull<FibHeapNode<T>>, NonNull<FibHeapNode<T>>),
//!     any_child: Option<NonNull<FibHeapNode<T>>>,
//!     order: usize,
//!     cut: bool,
//! }
//! pub struct FibHeapHandle<T> {
//!     node: NonNull<FibHeapNode<T>>,
//! }
//!
//! impl<T: Ord> FibHeap<T> {
//!     pub fn new() -> Self { todo!() }
//!     pub fn push(&mut self, elt: T) -> FibHeapHandle<T> { todo!() }
//!     pub fn pop(&mut self) -> Option<T> { todo!() }
//!     pub fn meld(&mut self, other: Self) { todo!() }
//! }
//! impl<T: Ord> FibHeapHandle<T> {
//!     pub unsafe fn urge(&mut self, elt: T) -> bool { todo!() }
//! }
//! ```
//!
//! 優先度を変えるインターフェースとしては [`std::collections::binary_heap::PeekMut`]
//! のようなものも存在しているが、Fibonacci heap を使いたい状況では、最大値に限らない要素を(検索含め)
//! 償却定数時間で行える必要があり、handle 経由で行う必要があると思われる。当然、deterministic
//! に行いたいので hash map は使いたくない。
//!
//!