Skip to main content

ik_geo/
solutionset.rs

1use {
2    crate::subproblems::setups::DELTA,
3    std::fmt::{Debug, Display, Formatter, Result},
4};
5
6#[derive(Debug, Clone)]
7pub enum SolutionSet2<T> {
8    Zero,
9    One(T),
10    Two(T, T),
11}
12
13#[derive(Debug, Clone)]
14pub enum SolutionSet4<T> {
15    Zero,
16    One(T),
17    Two(T, T),
18    Three(T, T, T),
19    Four(T, T, T, T),
20}
21
22const DELTAS_SIZE_2: usize = 4;
23const DELTAS_SIZE_4: usize = 8;
24
25impl<T: Copy> SolutionSet2<T> {
26    pub fn expect_one(&self) -> T {
27        match self {
28            Self::Zero => panic!("Found no soliutions where one was expected"),
29            Self::One(s) => *s,
30            Self::Two(..) => panic!("Found two solutions where one was expected"),
31        }
32    }
33
34    pub fn expect_two(&self) -> (T, T) {
35        match self {
36            Self::Zero => panic!("Found no soliutions where two were expected"),
37            Self::One(_) => panic!("Found one solution where two were expected"),
38            Self::Two(s1, s2) => (*s1, *s2),
39        }
40    }
41
42    pub fn get_first(&self) -> T {
43        match self {
44            Self::Zero => panic!("No solutions"),
45            Self::One(s) => *s,
46            Self::Two(s, _) => *s,
47        }
48    }
49
50    pub fn get_all(&self) -> Vec<T> {
51        match self {
52            Self::Zero => vec![],
53            Self::One(s) => vec![*s],
54            Self::Two(s1, s2) => vec![*s1, *s2],
55        }
56    }
57
58    pub fn deltas() -> [(f64, f64); DELTAS_SIZE_2] {
59        [(-DELTA, 0.0), (DELTA, 0.0), (0.0, -DELTA), (0.0, DELTA)]
60    }
61
62    pub fn duplicated(&self) -> Self {
63        match &self {
64            SolutionSet2::One(s) => SolutionSet2::Two(*s, *s),
65            SolutionSet2::Two(s1, s2) => SolutionSet2::Two(*s1, *s2),
66            SolutionSet2::Zero => SolutionSet2::Zero,
67        }
68    }
69
70    pub fn size(&self) -> usize {
71        match self {
72            SolutionSet2::Zero => 0,
73            SolutionSet2::One(_) => 1,
74            SolutionSet2::Two(..) => 2,
75        }
76    }
77}
78
79impl<T: Copy + Debug> SolutionSet2<T> {
80    pub fn as_csv(&self) -> String {
81        let mut results = self
82            .get_all()
83            .into_iter()
84            .map(|v| format!("{v:?}"))
85            .collect::<Vec<String>>();
86        results.append(&mut vec![String::new(); 2 - results.len()]);
87        results.join(",")
88    }
89
90    pub fn from_vec(vec: &Vec<T>) -> Self {
91        match vec.len() {
92            0 => Self::Zero,
93            1 => Self::One(vec[0]),
94            2 => Self::Two(vec[0], vec[1]),
95            i => panic!("Vector {vec:?} contains too many solutions: {i}"),
96        }
97    }
98}
99
100impl<T: Copy> SolutionSet4<T> {
101    pub fn expect_one(&self) -> T {
102        match self {
103            Self::One(s) => *s,
104            _ => panic!("Expected one solution"),
105        }
106    }
107
108    pub fn expect_two(&self) -> (T, T) {
109        match self {
110            Self::Two(s1, s2) => (*s1, *s2),
111            _ => panic!("Expected two solutions"),
112        }
113    }
114
115    pub fn expect_three(&self) -> (T, T, T) {
116        match self {
117            Self::Three(s1, s2, s3) => (*s1, *s2, *s3),
118            _ => panic!("Expected two solutions"),
119        }
120    }
121
122    pub fn expect_four(&self) -> (T, T, T, T) {
123        match self {
124            Self::Four(s1, s2, s3, s4) => (*s1, *s2, *s3, *s4),
125            _ => panic!("Expected two solutions"),
126        }
127    }
128
129    pub fn get_first(&self) -> T {
130        match self {
131            Self::Zero => panic!("No solutions"),
132            Self::One(s) => *s,
133            Self::Two(s, ..) => *s,
134            Self::Three(s, ..) => *s,
135            Self::Four(s, ..) => *s,
136        }
137    }
138
139    pub fn get_all(&self) -> Vec<T> {
140        match self {
141            Self::Zero => vec![],
142            Self::One(s) => vec![*s],
143            Self::Two(s1, s2) => vec![*s1, *s2],
144            Self::Three(s1, s2, s3) => vec![*s1, *s2, *s3],
145            Self::Four(s1, s2, s3, s4) => vec![*s1, *s2, *s3, *s4],
146        }
147    }
148
149    pub fn deltas() -> [(f64, f64, f64, f64); DELTAS_SIZE_4] {
150        [
151            (-DELTA, 0.0, 0.0, 0.0),
152            (DELTA, 0.0, 0.0, 0.0),
153            (0.0, -DELTA, 0.0, 0.0),
154            (0.0, DELTA, 0.0, 0.0),
155            (0.0, 0.0, -DELTA, 0.0),
156            (0.0, 0.0, DELTA, 0.0),
157            (0.0, 0.0, 0.0, -DELTA),
158            (0.0, 0.0, 0.0, DELTA),
159        ]
160    }
161}
162
163impl<T: Copy + Debug> SolutionSet4<T> {
164    pub fn as_csv(&self) -> String {
165        let mut results = self
166            .get_all()
167            .into_iter()
168            .map(|v| format!("{v:?}"))
169            .collect::<Vec<String>>();
170        results.append(&mut vec![String::new(); 4 - results.len()]);
171        results.join(",")
172    }
173
174    pub fn from_vec(vec: &Vec<T>) -> Self {
175        match vec.len() {
176            0 => Self::Zero,
177            1 => Self::One(vec[0]),
178            2 => Self::Two(vec[0], vec[1]),
179            3 => Self::Three(vec[0], vec[1], vec[2]),
180            4 => Self::Four(vec[0], vec[1], vec[2], vec[3]),
181            i => panic!("Vector {vec:?} contains too many solutions: {i}"),
182        }
183    }
184}
185
186impl<T: Display> Display for SolutionSet2<T> {
187    fn fmt(&self, f: &mut Formatter) -> Result {
188        match self {
189            Self::Zero => write!(f, "{{ }}"),
190            Self::One(s) => write!(f, "{{ {} }}", s),
191            Self::Two(s1, s2) => write!(f, "{{ {} {} }}", s1, s2),
192        }
193    }
194}
195
196impl<T: Display> Display for SolutionSet4<T> {
197    fn fmt(&self, f: &mut Formatter) -> Result {
198        match self {
199            Self::Zero => write!(f, "{{ }}"),
200            Self::One(s) => write!(f, "{{ {} }}", s),
201            Self::Two(s1, s2) => write!(f, "{{ {} {} }}", s1, s2),
202            Self::Three(s1, s2, s3) => write!(f, "{{ {} {} {} }}", s1, s2, s3),
203            Self::Four(s1, s2, s3, s4) => write!(f, "{{ {} {} {} {} }}", s1, s2, s3, s4),
204        }
205    }
206}