1use serde::{Deserialize, Serialize};
52use std::fmt;
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
70pub enum ProblemCategory {
71 Graph(GraphSubcategory),
73 Satisfiability(SatisfiabilitySubcategory),
75 Set(SetSubcategory),
77 Optimization(OptimizationSubcategory),
79 Scheduling(SchedulingSubcategory),
81 Network(NetworkSubcategory),
83 String(StringSubcategory),
85 Specialized(SpecializedSubcategory),
87}
88
89impl ProblemCategory {
90 pub fn name(&self) -> &'static str {
92 match self {
93 ProblemCategory::Graph(_) => "graph",
94 ProblemCategory::Satisfiability(_) => "satisfiability",
95 ProblemCategory::Set(_) => "set",
96 ProblemCategory::Optimization(_) => "optimization",
97 ProblemCategory::Scheduling(_) => "scheduling",
98 ProblemCategory::Network(_) => "network",
99 ProblemCategory::String(_) => "string",
100 ProblemCategory::Specialized(_) => "specialized",
101 }
102 }
103
104 pub fn subcategory_name(&self) -> &'static str {
106 match self {
107 ProblemCategory::Graph(sub) => sub.name(),
108 ProblemCategory::Satisfiability(sub) => sub.name(),
109 ProblemCategory::Set(sub) => sub.name(),
110 ProblemCategory::Optimization(sub) => sub.name(),
111 ProblemCategory::Scheduling(sub) => sub.name(),
112 ProblemCategory::Network(sub) => sub.name(),
113 ProblemCategory::String(sub) => sub.name(),
114 ProblemCategory::Specialized(sub) => sub.name(),
115 }
116 }
117
118 pub fn path(&self) -> String {
120 format!("{}/{}", self.name(), self.subcategory_name())
121 }
122}
123
124impl fmt::Display for ProblemCategory {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 write!(f, "{}", self.path())
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
132pub enum GraphSubcategory {
133 Coloring,
135 Covering,
137 Independent,
139 Paths,
141 Structure,
143 Trees,
145 Matching,
147}
148
149impl GraphSubcategory {
150 pub fn name(&self) -> &'static str {
152 match self {
153 GraphSubcategory::Coloring => "coloring",
154 GraphSubcategory::Covering => "covering",
155 GraphSubcategory::Independent => "independent",
156 GraphSubcategory::Paths => "paths",
157 GraphSubcategory::Structure => "structure",
158 GraphSubcategory::Trees => "trees",
159 GraphSubcategory::Matching => "matching",
160 }
161 }
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
166pub enum SatisfiabilitySubcategory {
167 Sat,
169 Circuit,
171 Qbf,
173}
174
175impl SatisfiabilitySubcategory {
176 pub fn name(&self) -> &'static str {
178 match self {
179 SatisfiabilitySubcategory::Sat => "sat",
180 SatisfiabilitySubcategory::Circuit => "circuit",
181 SatisfiabilitySubcategory::Qbf => "qbf",
182 }
183 }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
188pub enum SetSubcategory {
189 Covering,
191 Packing,
193 Partition,
195 Matching,
197}
198
199impl SetSubcategory {
200 pub fn name(&self) -> &'static str {
202 match self {
203 SetSubcategory::Covering => "covering",
204 SetSubcategory::Packing => "packing",
205 SetSubcategory::Partition => "partition",
206 SetSubcategory::Matching => "matching",
207 }
208 }
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
213pub enum OptimizationSubcategory {
214 Quadratic,
216 Linear,
218 Constraint,
220}
221
222impl OptimizationSubcategory {
223 pub fn name(&self) -> &'static str {
225 match self {
226 OptimizationSubcategory::Quadratic => "quadratic",
227 OptimizationSubcategory::Linear => "linear",
228 OptimizationSubcategory::Constraint => "constraint",
229 }
230 }
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
235pub enum SchedulingSubcategory {
236 Machine,
238 Sequencing,
240 Resource,
242}
243
244impl SchedulingSubcategory {
245 pub fn name(&self) -> &'static str {
247 match self {
248 SchedulingSubcategory::Machine => "machine",
249 SchedulingSubcategory::Sequencing => "sequencing",
250 SchedulingSubcategory::Resource => "resource",
251 }
252 }
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
257pub enum NetworkSubcategory {
258 Flow,
260 Routing,
262 Connectivity,
264}
265
266impl NetworkSubcategory {
267 pub fn name(&self) -> &'static str {
269 match self {
270 NetworkSubcategory::Flow => "flow",
271 NetworkSubcategory::Routing => "routing",
272 NetworkSubcategory::Connectivity => "connectivity",
273 }
274 }
275}
276
277#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
279pub enum StringSubcategory {
280 Sequence,
282 Matching,
284 Compression,
286}
287
288impl StringSubcategory {
289 pub fn name(&self) -> &'static str {
291 match self {
292 StringSubcategory::Sequence => "sequence",
293 StringSubcategory::Matching => "matching",
294 StringSubcategory::Compression => "compression",
295 }
296 }
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
301pub enum SpecializedSubcategory {
302 Geometry,
304 Number,
306 Game,
308 Other,
310}
311
312impl SpecializedSubcategory {
313 pub fn name(&self) -> &'static str {
315 match self {
316 SpecializedSubcategory::Geometry => "geometry",
317 SpecializedSubcategory::Number => "number",
318 SpecializedSubcategory::Game => "game",
319 SpecializedSubcategory::Other => "other",
320 }
321 }
322}
323
324#[cfg(test)]
325mod tests {
326 use super::*;
327
328 #[test]
329 fn test_category_path() {
330 let cat = ProblemCategory::Graph(GraphSubcategory::Independent);
331 assert_eq!(cat.path(), "graph/independent");
332 assert_eq!(cat.name(), "graph");
333 assert_eq!(cat.subcategory_name(), "independent");
334 }
335
336 #[test]
337 fn test_category_display() {
338 let cat = ProblemCategory::Satisfiability(SatisfiabilitySubcategory::Sat);
339 assert_eq!(format!("{}", cat), "satisfiability/sat");
340 }
341
342 #[test]
343 fn test_all_subcategories() {
344 assert_eq!(GraphSubcategory::Coloring.name(), "coloring");
346 assert_eq!(GraphSubcategory::Covering.name(), "covering");
347 assert_eq!(GraphSubcategory::Independent.name(), "independent");
348 assert_eq!(GraphSubcategory::Paths.name(), "paths");
349 assert_eq!(GraphSubcategory::Structure.name(), "structure");
350 assert_eq!(GraphSubcategory::Trees.name(), "trees");
351 assert_eq!(GraphSubcategory::Matching.name(), "matching");
352
353 assert_eq!(SatisfiabilitySubcategory::Sat.name(), "sat");
355 assert_eq!(SatisfiabilitySubcategory::Circuit.name(), "circuit");
356 assert_eq!(SatisfiabilitySubcategory::Qbf.name(), "qbf");
357
358 assert_eq!(SetSubcategory::Covering.name(), "covering");
360 assert_eq!(SetSubcategory::Packing.name(), "packing");
361 assert_eq!(SetSubcategory::Partition.name(), "partition");
362 assert_eq!(SetSubcategory::Matching.name(), "matching");
363
364 assert_eq!(OptimizationSubcategory::Quadratic.name(), "quadratic");
366 assert_eq!(OptimizationSubcategory::Linear.name(), "linear");
367 assert_eq!(OptimizationSubcategory::Constraint.name(), "constraint");
368
369 assert_eq!(SchedulingSubcategory::Machine.name(), "machine");
371 assert_eq!(SchedulingSubcategory::Sequencing.name(), "sequencing");
372 assert_eq!(SchedulingSubcategory::Resource.name(), "resource");
373
374 assert_eq!(NetworkSubcategory::Flow.name(), "flow");
376 assert_eq!(NetworkSubcategory::Routing.name(), "routing");
377 assert_eq!(NetworkSubcategory::Connectivity.name(), "connectivity");
378
379 assert_eq!(StringSubcategory::Sequence.name(), "sequence");
381 assert_eq!(StringSubcategory::Matching.name(), "matching");
382 assert_eq!(StringSubcategory::Compression.name(), "compression");
383
384 assert_eq!(SpecializedSubcategory::Geometry.name(), "geometry");
386 assert_eq!(SpecializedSubcategory::Number.name(), "number");
387 assert_eq!(SpecializedSubcategory::Game.name(), "game");
388 assert_eq!(SpecializedSubcategory::Other.name(), "other");
389 }
390}