fn main() { let stdin = std::io::read_to_string(std::io::stdin().lock()).unwrap(); let mut stdin = stdin.split_ascii_whitespace(); let n: u32 = stdin.next().unwrap().parse().unwrap(); let start: u32 = stdin.next().unwrap().parse().unwrap(); let end: u32 = stdin.next().unwrap().parse().unwrap(); let stones: Vec = (0..n) .map(|_| stdin.next().unwrap().parse().unwrap()) .collect(); use std::io::Write; std::io::stdout() .lock() .write_all(output(solve(start, end, stones)).as_bytes()) .unwrap(); } fn prepare(stones: Vec) -> Vec> { let mut groups = vec![Vec::new(); 31]; stones .into_iter() .for_each(|s| groups[s.count_ones() as usize].push(s)); groups } fn solve(start: u32, end: u32, stones: Vec) -> Option { let mut stones = prepare(stones); let mut q = std::collections::VecDeque::new(); q.push_back((start, 0)); while let Some((cur_pos, cur_dist)) = q.pop_front() { if (cur_pos ^ end).count_ones() == 1 { return Some(cur_dist); } if cur_pos.count_ones() >= 1 { stones[(cur_pos.count_ones() - 1) as usize] = stones[(cur_pos.count_ones() - 1) as usize] .iter() .filter_map(|&next| match (cur_pos ^ next).count_ones() == 1 { true => { q.push_back((next, cur_dist + 1)); None } false => Some(next), }) .collect(); } if cur_pos.count_ones() <= 29 { stones[(cur_pos.count_ones() + 1) as usize] = stones[(cur_pos.count_ones() + 1) as usize] .iter() .filter_map(|&next| match (cur_pos ^ next).count_ones() == 1 { true => { q.push_back((next, cur_dist + 1)); None } false => Some(next), }) .collect(); } } None } fn output(ans: Option) -> String { match ans { Some(ans) => ans.to_string(), None => String::from("-1"), } }