use std::io::{self, BufRead};
use std::collections::HashSet;
const MAX: i32 = 1000;
fn get_midpoint(a: i32, b: i32) -> i32 {
(a + b)/2
}
fn cipher(a: &i32, b: &i32) -> (i32, i32) {
if *a == 999 && *b == 0 {
return (500, 501);
}
let right_size = b - a;
let left_size = (a - b).rem_euclid(MAX);
// eprintln!("a: {a} b: {b} left_size: {left_size} right_size: {right_size}");
let (a, b) = (*a, *b + if right_size <= 1 { MAX } else { 0 });
// assert!(b > a, "b must be greater than a: a: {a} b: {b}");
let size = b - a;
let mid = get_midpoint(a, b) + (size % 2);
let (c, d) = (mid, mid + size);
// eprintln!(" Cipher: c: {c} d: {d}");
return (c.rem_euclid(MAX), d.rem_euclid(MAX))
}
fn decipher(c: &i32, d: &i32) -> (i32, i32) {
if *c == 500 && *d == 501 {
return (999, 0);
}
let (c, d) = (*c, *d + if *d < *c { MAX } else { 0 });
let size = d - c;
let mid = get_midpoint(c, d) + if size == 1 { MAX/2 } else { 0 };
let size = if size == 1 { size + MAX } else { size };
// if c % MAX != *c2 % MAX || size != *size2 {
// eprintln!("c: {c} size: {size} != c2: {c2} size2: {size2}")
// }
// if mid.rem_euclid(MAX) != *b {
// eprintln!("mid: {mid} != b: {b}");
// }
let (a, b) = (mid - size, mid);
return (a.rem_euclid(MAX), b.rem_euclid(MAX))
}
fn main() {
let stdin = io::stdin().lock();
let mut lines = stdin.lines();
let name = lines.next().unwrap().unwrap();
let operation = match name.as_str() {
"Algosia" => cipher,
"Bajtek" => decipher,
_ => panic!("Unknown name: {}", name)
};
let nums = lines.next().unwrap().unwrap();
let nums: Vec<i32> = nums
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect();
let (a, b) = (nums[0] - 1, nums[1] - 1);
let (c, d) = operation(&a, &b);
println!("{} {}", c + 1, d + 1);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | use std::io::{self, BufRead}; use std::collections::HashSet; const MAX: i32 = 1000; fn get_midpoint(a: i32, b: i32) -> i32 { (a + b)/2 } fn cipher(a: &i32, b: &i32) -> (i32, i32) { if *a == 999 && *b == 0 { return (500, 501); } let right_size = b - a; let left_size = (a - b).rem_euclid(MAX); // eprintln!("a: {a} b: {b} left_size: {left_size} right_size: {right_size}"); let (a, b) = (*a, *b + if right_size <= 1 { MAX } else { 0 }); // assert!(b > a, "b must be greater than a: a: {a} b: {b}"); let size = b - a; let mid = get_midpoint(a, b) + (size % 2); let (c, d) = (mid, mid + size); // eprintln!(" Cipher: c: {c} d: {d}"); return (c.rem_euclid(MAX), d.rem_euclid(MAX)) } fn decipher(c: &i32, d: &i32) -> (i32, i32) { if *c == 500 && *d == 501 { return (999, 0); } let (c, d) = (*c, *d + if *d < *c { MAX } else { 0 }); let size = d - c; let mid = get_midpoint(c, d) + if size == 1 { MAX/2 } else { 0 }; let size = if size == 1 { size + MAX } else { size }; // if c % MAX != *c2 % MAX || size != *size2 { // eprintln!("c: {c} size: {size} != c2: {c2} size2: {size2}") // } // if mid.rem_euclid(MAX) != *b { // eprintln!("mid: {mid} != b: {b}"); // } let (a, b) = (mid - size, mid); return (a.rem_euclid(MAX), b.rem_euclid(MAX)) } fn main() { let stdin = io::stdin().lock(); let mut lines = stdin.lines(); let name = lines.next().unwrap().unwrap(); let operation = match name.as_str() { "Algosia" => cipher, "Bajtek" => decipher, _ => panic!("Unknown name: {}", name) }; let nums = lines.next().unwrap().unwrap(); let nums: Vec<i32> = nums .split_whitespace() .map(|s| s.parse().unwrap()) .collect(); let (a, b) = (nums[0] - 1, nums[1] - 1); let (c, d) = operation(&a, &b); println!("{} {}", c + 1, d + 1); } |
English