Advertisement
Guest User

Untitled

a guest
Apr 25th, 2019
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.14 KB | None | 0 0
  1. use std::collections::btree_map::{BTreeMap, Entry};
  2. use std::ops::{Add, Sub};
  3.  
  4. type Variable = usize;
  5. type Coefficient = isize;
  6.  
  7. #[derive(Clone)]
  8. struct LinComb(Vec<(Variable, Coefficient)>);
  9. struct CanonicalLinComb(BTreeMap<Variable, Coefficient>);
  10.  
  11. impl Add for LinComb {
  12. type Output = LinComb;
  13.  
  14. fn add(self, other: LinComb) -> Self::Output {
  15. LinComb(self.0.into_iter().chain(other.0.into_iter()).collect())
  16. }
  17. }
  18.  
  19. impl Sub for LinComb {
  20. type Output = LinComb;
  21.  
  22. fn sub(self, other: LinComb) -> Self::Output {
  23. LinComb(
  24. self.0
  25. .into_iter()
  26. .chain(other.0.into_iter().map(|(var, coeff)| (var, -coeff)))
  27. .collect(),
  28. )
  29. }
  30. }
  31.  
  32. impl LinComb {
  33. fn as_canonical<'a>(&'a self) -> CanonicalLinComb {
  34. CanonicalLinComb(self.0.clone().into_iter().fold(
  35. BTreeMap::new(),
  36. |mut acc, (val, coeff)| {
  37. // if we're adding 0 times some variable, we can ignore this term
  38. if coeff != 0 {
  39. match acc.entry(val) {
  40. Entry::Occupied(o) => {
  41. // if the new value is non zero, update, else remove the term entirely
  42. if o.get() + coeff != 0 {
  43. *o.into_mut() += coeff;
  44. } else {
  45. o.remove();
  46. }
  47. }
  48. Entry::Vacant(v) => {
  49. // We checked earlier but let's make sure we're not creating zero-coeff terms
  50. assert!(coeff != 0);
  51. v.insert(coeff);
  52. }
  53. }
  54. }
  55.  
  56. acc
  57. },
  58. ))
  59. }
  60. }
  61.  
  62. fn main() {
  63. let a = LinComb(vec![(0, 1), (1, 1)]);
  64. let b = LinComb(vec![(0, 1), (1, -1)]);
  65. for i in (a + b).as_canonical().0.iter() {
  66. println!("{:?}", i);
  67. }
  68.  
  69. let a = LinComb(vec![(0, 1), (1, 1)]);
  70. let b = LinComb(vec![(0, 1), (1, -1)]);
  71. for i in (a - b).as_canonical().0.iter() {
  72. println!("{:?}", i);
  73. }
  74. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement