-3

I copied a Rust program from the website, and it ran well. However, when I changed the graph, it resulted in an error. What could be the reason for this?

use std::collections::HashMap as H;type I=i64;

type E=Vec<(I,I)>;fn d(g:&E)->bool{let mut s:Vec<(E,Vec<I>)>=vec![];for e in g{let(v,w)=e;
let f=(*v,*w);let z=|x|s.iter().position(|p|p.1.contains(x));
match(z(v),z(w))
{(Some(i),Some(j))=>{if i!=j{let mut p=s.remove(i);let q=s.remove(j-(i<j)as usize);p.0.extend(q.0);p.1.extend(q.1);s.push(p)}else{s[i].0.push(f)}}(Some(i),_)=>{s[i].0.push(f);s[i].1.push(*w)}(_,Some(j))=>{s[j].0.push(f);s[j].1.push(*v)}_=>{s.push((vec![f], vec![*v, *w]))}}}s.iter().map(|h|{let mut p=H::new();let mut r=H::new();let mut i=0;
for e in&h.0{let(v,w)=e;i+=2;p.insert(i-1,i);p.insert(i,i-1);r.entry(v).or_insert(vec![]).push(i-1);r.entry(w).or_insert(vec![]).push(i)}let mut r:Vec<Vec<I>>=r.values().cloned().collect();r.sort();let mut x=0;let m=r.iter().flat_map(|v|1..v.len()).fold(1,|p,n|p*n);for mut w in 0..m{let mut t=H::new();
for u in&r{let mut v=u.clone();

let s=v.pop().unwrap();let mut f=s;while v.len()>0
{let o=v.remove(w%v.len());w/=v.len()+1;t.insert(f,o);f=o}t.insert(f,s);}let mut f=vec![];let mut n=0;
for s in p.keys(){if!f.contains(s){n+=1;
let mut c=s;loop{f.push(*c);c=&t[&p[c]];if c==s{break}}}}x=x.max(n)}1-(r.len()as I-g.len()as I+x as I)/2}).sum::<I>()<2}



fn main() {
    let graph = vec![
        (0, 1),
        (0, 3),
        (0, 4),
        (2, 1),
        (2, 3),
        (2, 5),
        (4, 1),
        (4, 3),
        (4, 5),
        (5, 6),
        (5, 8),
        (5, 10),
        (7, 6),
        (7, 8),
        (7, 10),
        (9, 6),
        (9, 8),
        (9, 10),
    ];
    let result = d(&graph);
    println!("Result: {}", result);
}

I changed the graph to one with 12 vertices as follows.

fn main() {
    let graph = vec![
        (0, 1), 
    (0, 2),
    (0, 3), 
    (0, 4), 
    (0, 5), 
    (0, 6),
    (1, 2), 
    (1, 3), 
    (1, 4), 
    (1, 5), 
    (1, 7), 
    (2, 3), 
    (2, 4),
    (2, 6), 
    (2, 7), 
    (3, 5), 
    (3, 6), 
    (3, 7),
    (4, 5), 
    (4, 6), 
    (4, 8), 
    (4, 9), 
    (4, 10), 
    (5, 7), 
    (5, 8),
    (5, 9), 
    (5, 11), 
    (6, 7),
    (6, 8), 
    (6, 10), 
    (6, 11), 
    (7, 9), 
    (7, 10), 
    (7, 11),
    (8, 9),
    (8, 10), 
    (8, 11),
    (9, 10), 
    (9, 11),
    (10, 11),
    ];
    let result = d(&graph);
    println!("Result: {}", result);
}


It shows:

thread 'main' panicked at 'attempt to multiply with overflow', code.tio:1:816 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

I'm curious about what went wrong and how to get it to output correctly.

licheng
  • 115
  • 5
  • That's a link to the Stack Overflow homepage, and that code is clearly obfuscated. You need to either find a non-obfuscated version to debug or reverse engineer it yourself – Silvio Mayolo Mar 09 '23 at 14:52
  • @SilvioMayolo sorry I change it. – licheng Mar 09 '23 at 14:53
  • Ah, it's from our code golf sister site. It looks like the poster also showed a non-golfed version of the same code and provided a lengthy explanation of the logic behind it. Is there something you don't understand in the existing explanation? – Silvio Mayolo Mar 09 '23 at 16:06
  • @SilvioMayolo This is likely an integer overflow issue. – licheng Mar 10 '23 at 01:51

1 Answers1

1

I wrote this program. The number of rotation systems, as represented in the "num_rotations" variable in the ungolfed code, is exponential in the size of the graph. This is the variable that is overflowing and crashing the program. However, even if the variable didn't overflow, because each rotation system is individually evaluated it would take an infeasibly long time to evaluate each of them and find out whether the given graph is toroidal. For larger graphs, like the one you posted, an algorithm which relies less on brute-force is needed.

isaacg
  • 593
  • 6
  • 19