I have a C++ program that is the competitive programming problem's solution. This program is entirely correct. I tried to rewrite it in Rust 1.49.0, but it does not behave as expected. The target platform is x86-64.
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
int add(int x, const int y) {
x += y;
if (x < 0) {
x += MOD;
} else if (x >= MOD) {
x -= MOD;
}
return x;
}
int main() {
int n, m;
cin >> n >> m;
string a, b;
cin >> a >> b;
int pw = 1;
int res = 0;
int ans = 0;
for (int i = 0; i < m; ++i) {
if (i < n && a[n - i - 1] == '1') {
res = add(res, pw);
}
if (b[m - i - 1] == '1') {
ans = add(ans, res);
}
pw = add(pw, pw);
}
cout << ans << '\n';
}
I tried to make the Rust program as close as possible to the original one, and here is one of my attempts.
use std::*;
use io::{stdin, Read};
const MOD: i32 = 998_244_353;
fn add(x: i32, y: i32) -> i32 {
let mut res = x.wrapping_add(y);
if res < 0 {
res += MOD;
} else if res >= MOD {
res -= MOD;
}
res
}
fn main() {
let mut n_and_m = String::new();
stdin().read_line(&mut n_and_m);
let mut n_and_m: Vec<&str> = n_and_m.trim().split(" ").collect();
let m = n_and_m.pop().unwrap().parse::<usize>().unwrap();
let n = n_and_m.pop().unwrap().parse::<usize>().unwrap();
drop(n_and_m);
let mut a = vec![b'\0'; n];
stdin().read(&mut a);
stdin().read_line(&mut String::new());
let mut b = vec![b'\0'; m];
stdin().read(&mut b);
let mut pw = 1 as i32;
let mut res = 0 as i32;
let mut ans = 0 as i32;
for i in 0..m {
if i < n && a[n - i - 1] == b'1' {
res = add(res, pw);
}
if b[m - i - 1] == b'1' {
ans = add(ans, res);
}
pw = add(pw, pw);
}
println!("{}", ans)
}
But, for some reason, it fails to pass all the tests.
It is guaranteed that the length of a string a
is n
and the length of a string b
is m
.
Here are my other attempts:
u64, cast to u128, rem_euclid
i128
Can anyone give me any advice, please?