diff --git a/src/expand_n_contract.rs b/src/expand_n_contract.rs
index e75599674f5824825ccf59b759bcb5bc1ba80593..a043c718cf4e13fa910438677939c4ae2e56fc85 100644
--- a/src/expand_n_contract.rs
+++ b/src/expand_n_contract.rs
@@ -31,10 +31,10 @@ pub fn expand_n_contract(
     let mut g_idx: usize = 0;
     loop {
         // dbg!(&g_idx);
-        let dg_data: HashMap<UndirectedGraph, (i64, Vec<usize>)> =
+        let dg_data: Vec<(i64, UndirectedGraph, Vec<usize>)> =
             cocycle_graphs[g_idx].expanding_differential(&cocycle_graph_vertex_orbits[g_idx]);
 
-        for (dg, (c, dg_edge_orbits)) in dg_data {
+        for (c, dg, dg_edge_orbits) in dg_data {
             // eprintln!("{:?}", dg);
             let dg_idx: usize = if let Some(&idx) = cocycle_differential_graph_index.get(&dg) {
                 // eprintln!("old graph in differential: {}", idx);
@@ -51,7 +51,7 @@ pub fn expand_n_contract(
             writeln!(sparse_matrix_file, "{} {} {}", dg_idx + 1, g_idx + 1, c)?;
             num_nonzeros += 1;
 
-            let cg_data: HashMap<UndirectedGraph, Vec<usize>> = dg.contractions(&dg_edge_orbits);
+            let cg_data: Vec<(UndirectedGraph, Vec<usize>)> = dg.contractions(&dg_edge_orbits);
             for (cg, cg_vertex_orbits) in cg_data {
                 // eprintln!("{:?}", cg);
                 if !cocycle_graph_index.contains_key(&cg) {
diff --git a/src/undirected_graph.rs b/src/undirected_graph.rs
index fc6a0a72ccef738a45d01a2e0c94e78b7f316a59..cde40ee40e383f9150b975a39642d71afe9ef7c8 100644
--- a/src/undirected_graph.rs
+++ b/src/undirected_graph.rs
@@ -463,19 +463,24 @@ impl UndirectedGraph {
     pub fn expanding_differential(
         &self,
         orbits: &[usize],
-    ) -> HashMap<UndirectedGraph, (i64, Vec<usize>)> {
-        let mut diff: HashMap<UndirectedGraph, (i64, Vec<usize>)> = HashMap::new();
+    ) -> Vec<(i64, UndirectedGraph, Vec<usize>)> {
+        let mut diff: Vec<(i64, UndirectedGraph, Vec<usize>)> = vec![];
+        let mut graph_pos_in_diff: HashMap<UndirectedGraph, usize> = HashMap::new();
 
-        let mut orbit_reps: HashMap<usize, usize> = HashMap::new();
+        // NOTE: We do some extra work to make the ordering of the result deterministic.
+        let mut orbit_sizes: HashMap<usize, usize> = HashMap::new();
+        let mut orbit_reps: Vec<usize> = vec![];
         for &orbit_rep in orbits {
-            if let Some(orbit_size) = orbit_reps.get_mut(&orbit_rep) {
+            if let Some(orbit_size) = orbit_sizes.get_mut(&orbit_rep) {
                 *orbit_size += 1;
             } else {
-                orbit_reps.insert(orbit_rep, 1);
+                orbit_reps.push(orbit_rep);
+                orbit_sizes.insert(orbit_rep, 1);
             }
         }
 
-        for (orbit_rep, orbit_size) in orbit_reps {
+        for orbit_rep in orbit_reps {
+            let orbit_size: usize = orbit_sizes[&orbit_rep];
             for (c, mut dg) in self.expand_vertex(&orbit_rep) {
                 let (normal_dg_sign, normal_dg_edge_orbits) = dg.normal_form(true);
                 if normal_dg_sign == 0 {
@@ -483,19 +488,22 @@ impl UndirectedGraph {
                 }
                 // TODO: Fix coefficient types.
                 let normal_dg_coeff: i64 = (normal_dg_sign as i64) * (orbit_size as i64) * c;
-                if let Some((diff_coeff, _)) = diff.get_mut(&dg) {
-                    *diff_coeff += normal_dg_coeff;
+                if let Some(&diff_idx) = graph_pos_in_diff.get(&dg) {
+                    diff[diff_idx].0 += normal_dg_coeff;
                 } else {
-                    diff.insert(dg, (normal_dg_coeff, normal_dg_edge_orbits));
+                    graph_pos_in_diff.insert(dg.clone(), diff.len());
+                    diff.push((normal_dg_coeff, dg, normal_dg_edge_orbits));
                 }
             }
         }
-        diff.retain(|_dg, (dg_coeff, _)| *dg_coeff != 0);
+        diff.retain(|(dg_coeff, _, _)| *dg_coeff != 0);
         diff
     }
 
-    pub fn contractions(&self, edge_orbits: &Vec<usize>) -> HashMap<UndirectedGraph, Vec<usize>> {
-        let mut contractions: HashMap<UndirectedGraph, Vec<usize>> = HashMap::new();
+    pub fn contractions(&self, edge_orbits: &Vec<usize>) -> Vec<(UndirectedGraph, Vec<usize>)> {
+        let mut contractions: Vec<(UndirectedGraph, Vec<usize>)> = vec![];
+        let mut graphs_seen: HashSet<UndirectedGraph> = HashSet::new();
+
         let mut edge_orbit_reps: HashSet<usize> = HashSet::new();
         for &edge_orbit_rep in edge_orbits {
             // Skip orbits already seen.
@@ -574,7 +582,9 @@ impl UndirectedGraph {
                 continue;
             }
 
-            contractions.insert(cg, normal_cg_orbits);
+            if graphs_seen.insert(cg.clone()) {
+                contractions.push((cg, normal_cg_orbits));
+            }
         }
         contractions
     }