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
|
// check-pass
#![feature(adt_const_params, generic_const_exprs)]
#![allow(incomplete_features)]
mod lib {
const N_ISLANDS: usize = 4;
const N_BRIDGES: usize = 7;
const BRIDGES: [(usize, usize); 7] = [(0, 1), (0, 1), (0, 2), (0, 3), (0, 3), (1, 2), (2, 3)];
pub type Matrix = [[usize; N_ISLANDS]; N_ISLANDS];
const EMPTY_MATRIX: Matrix = [[0; N_ISLANDS]; N_ISLANDS];
const fn build(mut matrix: Matrix, (to, from): (usize, usize)) -> Matrix {
matrix[to][from] += 1;
matrix[from][to] += 1;
matrix
}
pub const fn walk(mut matrix: Matrix, from: usize, to: usize) -> Matrix {
matrix[from][to] -= 1;
matrix[to][from] -= 1;
matrix
}
const fn to_matrix(bridges: [(usize, usize); N_BRIDGES]) -> Matrix {
let matrix = EMPTY_MATRIX;
let matrix = build(matrix, bridges[0]);
let matrix = build(matrix, bridges[1]);
let matrix = build(matrix, bridges[2]);
let matrix = build(matrix, bridges[3]);
let matrix = build(matrix, bridges[4]);
let matrix = build(matrix, bridges[5]);
let matrix = build(matrix, bridges[6]);
matrix
}
const BRIDGE_MATRIX: [[usize; N_ISLANDS]; N_ISLANDS] = to_matrix(BRIDGES);
pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> {
_p: (),
}
impl Walk<0, BRIDGE_MATRIX> {
pub const fn new() -> Self {
Self { _p: () }
}
}
impl<const CURRENT: usize, const REMAINING: Matrix> Walk<CURRENT, REMAINING> {
pub fn proceed_to<const NEXT: usize>(
self,
) -> Walk<NEXT, { walk(REMAINING, CURRENT, NEXT) }> {
Walk { _p: () }
}
}
pub struct Trophy {
_p: (),
}
impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {
pub fn collect_prize(self) -> Trophy {
Trophy { _p: () }
}
}
}
pub use lib::{Trophy, Walk};
fn main() {
// Example, taking the first step
let _ = Walk::new().proceed_to::<1>();
// Don't be so eager to collect the trophy
// let trophy = Walk::new()
// .proceed_to::<1>()
// .proceed_to::<0>()
// .collect_prize();
// Can't just make a Trophy out of thin air, you must earn it
// let trophy: Trophy = Trophy { _p: () };
// Can you collect the Trophy?
}
|