extern crate graph_builder;
use std::str::FromStr;
use graph_builder::*;
fn main() {
let n: usize = if let Some(x) = std::env::args_os().skip(1).take(1).next() {
usize::from_str(&x.into_string().expect("number")).unwrap()
} else {
3
};
let solution_terms: usize = if let Some(x) = std::env::args_os().skip(2).take(1).next() {
usize::from_str(&x.into_string().expect("number")).unwrap()
} else {
1
};
let start = Eq {
side: {
if solution_terms == 1 && n > 0 {
let mut res = vec![true; n-1];
res.push(false);
res
} else {
vec![true; n]
}
},
positive: vec![true; n],
};
let f = |eq: &Eq, ind: usize| {
let mut eq = eq.clone();
eq.side[ind] = !eq.side[ind];
eq.positive[ind] = !eq.positive[ind];
Ok((eq, Swap(vec![ind])))
};
let g = |eq: &Eq| eq.len_right() == solution_terms;
let h = |a: &Swap, b: &Swap| if a.0 >= b.0 {Err(None)} else {Ok(Swap({
let mut a = a.0.clone();
a.extend_from_slice(&b.0);
a.sort();
a
}))};
let settings = GenerateSettings {
max_nodes: 1000,
max_edges: 1000,
};
let seed = (vec![start], vec![]);
let (eqs, mut edges) = match gen(seed, n, f, g, h, &settings) {
Ok(x) => x,
Err((x, ())) => x,
};
bidir(&mut edges);
edges.sort();
for i in 0..eqs.len() {
println!("{}: {}", i, eqs[i]);
}
for i in 0..edges.len() {
println!("{:?}", edges[i]);
}
println!("(nodes, edges): ({}, {})", eqs.len(), edges.len());
}
#[derive(PartialEq, Eq, Clone, Hash)]
pub struct Eq {
pub side: Vec<bool>,
pub positive: Vec<bool>,
}
impl Eq {
pub fn len_right(&self) -> usize {
self.side.iter().filter(|&&n| n).count()
}
pub fn unique_right(&self) -> Option<usize> {
let mut found = None;
for i in 0..self.side.len() {
if self.side[i] {
if found.is_some() {return None};
found = Some(i);
}
}
found
}
pub fn signs(&self) -> (&'static str, &'static str) {
if let Some(ind) = self.unique_right() {
if self.positive[ind] {("+", "-")}
else {("-", "+")}
} else {("+", "-")}
}
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Swap(pub Vec<usize>);
impl std::fmt::Display for Eq {
fn fmt(&self, w: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
let mut left: usize = 0;
let (plus, minus) = self.signs();
for i in 0..self.side.len() {
if !self.side[i] {
if self.positive[i] {write!(w, "{}", plus)?}
else {write!(w, "{}", minus)?}
write!(w, "x{} ", i)?;
left += 1;
}
}
if left == 0 {write!(w, "0 ")?}
write!(w, "= ")?;
if self.side.len() - left == 0 {
write!(w, "0")?;
} else {
for i in 0..self.side.len() {
if self.side[i] {
if self.positive[i] {write!(w, "{}", plus)?}
else {write!(w, "{}", minus)?}
write!(w, "x{} ", i)?
}
}
}
Ok(())
}
}