Created
June 24, 2020 09:59
-
-
Save AnthonyMikh/f7529cfa7c9b995fee9e41bdaf0cd600 to your computer and use it in GitHub Desktop.
Solution to "Single Number II" Leetcode problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
impl Solution { | |
pub fn single_number(nums: Vec<i32>) -> i32 { | |
let compressed = nums.iter() | |
.map(|&n| evenly_space_bits(n as u32)) | |
.fold(0, |acc, n| omit_threes(acc + n)); | |
unspace_bits(compressed) as _ | |
} | |
} | |
fn evenly_space_bits(n: u32) -> u64 { | |
let n = u64::from(n); | |
// 0000 0000 0000 0000 0000 0000 0000 0000 XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX | |
// v | |
// 0000 0000 0000 0000 XXXX XXXX XXXX XXXX 0000 0000 0000 0000 XXXX XXXX XXXX XXXX | |
// v | |
// 0000 0000 XXXX XXXX 0000 0000 XXXX XXXX 0000 0000 XXXX XXXX 0000 0000 XXXX XXXX | |
// v | |
// 0000 XXXX 0000 XXXX 0000 XXXX 0000 XXXX 0000 XXXX 0000 XXXX 0000 XXXX 0000 XXXX | |
// v | |
// 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX 00XX | |
// v | |
// 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X 0X0X | |
// | |
// 0xF = 0b1111 | |
// 0xC = 0b1100, 0x3 = 0b0011 | |
// 0x2 = 0b0010, 0x1 = 0b0001 | |
let n = ((n & 0x0000_0000_FFFF_0000) << (1 << 4)) | (n & 0x0000_0000_0000_FFFF); | |
let n = ((n & 0x0000_FF00_0000_FF00) << (1 << 3)) | (n & 0x0000_00FF_0000_00FF); | |
let n = ((n & 0x00F0_00F0_00F0_00F0) << (1 << 2)) | (n & 0x000F_000F_000F_000F); | |
let n = ((n & 0x0C0C_0C0C_0C0C_0C0C) << (1 << 1)) | (n & 0x0303_0303_0303_0303); | |
let n = ((n & 0x2222_2222_2222_2222) << (1 << 0)) | (n & 0x1111_1111_1111_1111); | |
n | |
} | |
fn unspace_bits(n: u64) -> u32 { | |
let n = ((n & 0x4444_4444_4444_4444) >> (1 << 0)) | (n & 0x1111_1111_1111_1111); | |
let n = ((n & 0x3030_3030_3030_3030) >> (1 << 1)) | (n & 0x0303_0303_0303_0303); | |
let n = ((n & 0x0F00_0F00_0F00_0F00) >> (1 << 2)) | (n & 0x000F_000F_000F_000F); | |
let n = ((n & 0x00FF_0000_00FF_0000) >> (1 << 3)) | (n & 0x0000_00FF_0000_00FF); | |
let n = ((n & 0x0000_FFFF_0000_0000) >> (1 << 4)) | (n & 0x0000_0000_0000_FFFF); | |
n as _ | |
} | |
fn omit_threes(n: u64) -> u64 { | |
const ODD_BITS: u64 = 0x5555_5555_5555_5555; | |
const EVEN_BITS: u64 = ODD_BITS << 1; | |
let has_threes = ((n & EVEN_BITS) >> 1) & (n & ODD_BITS); | |
let allow_nonthrees = (!has_threes) & ODD_BITS; | |
let nonthrees_mask = allow_nonthrees | (allow_nonthrees << 1); | |
n & nonthrees_mask | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment