LINUX.ORG.RU

История изменений

Исправление zurg, (текущая версия) :

const ND:usize = 9;

#[derive(Debug, Copy, Clone)]
enum Op {
    Plus,
    Minus,
    Void,
}
impl Op {
    fn next_op(&mut self, pos: usize, iter: usize) {
        if iter % 3usize.pow(pos as u32) == 0 {
            *self = match self {
                Op::Void => Op::Minus,
                Op::Minus => Op::Plus,
                Op::Plus => Op::Void,
            }
        }
    }
}
fn calc_expr(ops: &[Op]) -> isize {
    let (mut sum, mut num, mut sign) = (0, ND as isize, 1);
    for (di, op) in ops.into_iter().enumerate() {
        let nxt_dig = (ND-1-di) as isize; 
        match op {
            Op::Void => num = num*10 + nxt_dig,
            Op::Plus => {
                sum += num * sign;
                num = nxt_dig; 
                sign = 1;
            }
            Op::Minus => {
                sum += num * sign;
                num = nxt_dig;
                sign = -1;
            }
        };
    }
    sum + num*sign
}
fn expr_to_str(ops:&[Op])->String {
    let mut s = "9".to_string();
    for (di, op) in ops.into_iter().enumerate() {
        match op {
            Op::Minus => s.push('-'),
            Op::Plus => s.push('+'),
            _ => ()
        }
        s.push(char::from_digit((ND-1-di) as u32, 10).unwrap());
    }
    s
}
fn main() {
    let target = 200;
    let mut ops = [Op::Void; ND];
    for i in 0..3usize.pow(ND as u32) { 
        if calc_expr(&ops) == target {
            println!("{}={target}", expr_to_str(&ops));
        }
        for p in 0..ND {
            ops[p].next_op(p, i);
        }
    }
}
cargo r -r
98-7+65+43+2-1-0=200
98-7+65+43+2-1+0=200
98+76-5+43-2-10=200
9-8+7-6-5-4-3+210=200
9-8-7-6-5+4+3+210=200

hyperfine --runs 500 -N  ./target/release/lortst
Benchmark 1: ./target/release/lortst
  Time (mean ± σ):       2.8 ms ±   1.1 ms    [User: 1.5 ms, System: 1.1 ms]
  Range (min … max):     1.2 ms …   4.4 ms    500 runs

Исходная версия zurg, :

const ND:usize = 9;

#[derive(Debug, Copy, Clone)]
enum Op {
    Plus,
    Minus,
    Void,
}
impl Op {
    fn next_op(&mut self, pos: usize, iter: usize) {
        if iter % 3usize.pow(pos as u32) == 0 {
            *self = match self {
                Op::Void => Op::Minus,
                Op::Minus => Op::Plus,
                Op::Plus => Op::Void,
            }
        }
    }
}
fn calc_expr(ops: &[Op]) -> isize {
    let (mut sum, mut num, mut sign) = (0, ND as isize, 1);
    for (di, op) in ops.into_iter().enumerate() {
        let nxt_dig = (ND-1-di) as isize; 
        match op {
            Op::Void => num = num*10 + nxt_dig,
            Op::Plus => {
                sum += num * sign;
                num = nxt_dig; 
                sign = 1;
            }
            Op::Minus => {
                sum += num * sign;
                num = nxt_dig;
                sign = -1;
            }
        };
    }
    sum + num*sign
}
fn expr_to_str(ops:&[Op])->String {
    let mut s = "9".to_string();
    for (di, op) in ops.into_iter().enumerate() {
        match op {
            Op::Minus => s.push('-'),
            Op::Plus => s.push('+'),
            _ => ()
        }
        s.push(char::from_digit((ND-1-di) as u32, 10).unwrap());
    }
    s
}
fn main() {
    let target = 200;
    let mut ops = [Op::Void; ND];
    for i in 0..3usize.pow(ND as u32) { 
        if calc_expr(&ops) == target {
            println!("{}={target}", expr_to_str(&ops));
        }
        for p in 0..ND {
            ops[p].next_op(p, i);
        }
    }
}

cargo r -r 98-7+65+43+2-1-0=200 98-7+65+43+2-1+0=200 98+76-5+43-2-10=200 9-8+7-6-5-4-3+210=200 9-8-7-6-5+4+3+210=200

hyperfine –runs 500 -N ./target/release/lortst Benchmark 1: ./target/release/lortst Time (mean ± σ): 2.8 ms ± 1.1 ms [User: 1.5 ms, System: 1.1 ms] Range (min … max): 1.2 ms … 4.4 ms 500 runs