diff --git a/src/bin/search_missing_coin_sum.rs b/src/bin/search_missing_coin_sum.rs new file mode 100644 index 0000000..492d032 --- /dev/null +++ b/src/bin/search_missing_coin_sum.rs @@ -0,0 +1,107 @@ +// I/O boilerplate // + +pub struct UnsafeScanner<'a> { + // not actually dead code, needed for buf_iter to work + #[allow(dead_code)] + buf_str: Vec, + buf_iter: std::str::SplitAsciiWhitespace<'a>, +} + +impl UnsafeScanner<'_> { + pub fn new(mut reader: R) -> Self { + let mut buf_str = vec![]; + unsafe { + reader.read_to_end(&mut buf_str).unwrap_unchecked(); + } + let buf_iter = unsafe { + let slice = std::str::from_utf8_unchecked(&buf_str); + std::mem::transmute(slice.split_ascii_whitespace()) + }; + + Self { buf_str, buf_iter } + } + + /// Use "turbofish" syntax `token::()` to select data type of next token. + /// + /// # Panics + /// Panics if there's no more tokens or if the token cannot be parsed as T. + pub fn token(&mut self) -> T { + unsafe { + self.buf_iter + .next() + .unwrap_unchecked() + .parse() + .unwrap_unchecked() + } + } +} + +// problem // + +/// You have n coins with positive integer values. What is the smallest sum you cannot create using a subset of the coins? +/// +/// Input +/// +/// The first input line has an integer n: the number of coins. +/// +/// The second line has n integers x1,x2,...,xn: the value of each coin. +/// +/// Output +/// +/// Print one integer: the smallest coin sum.. +/// +/// Constraints +/// +///
    +///
  • 1 ≤ n ≤ 2 * 105
  • +///
  • 1 ≤ xi ≤ 109
  • +///
+fn solve(mut scan: UnsafeScanner, out: &mut W) { + let n: u32 = scan.token(); + let mut coins: Vec = (0..n).map(|_| scan.token()).collect(); + coins.sort_unstable(); + + let mut sum = 1; + + for coin in coins { + if coin > sum { + break; + } + sum += coin; + } + writeln!(out, "{sum}").ok(); +} + +// entrypoints // + +fn main() { + let scan = UnsafeScanner::new(std::io::stdin()); + let mut out = std::io::BufWriter::new(std::io::stdout().lock()); + solve(scan, &mut out); +} + +#[cfg(test)] +mod test { + use super::*; + + fn test(input: &[u8], target: &[u8]) { + let scan = UnsafeScanner::new(input); + let mut out = Vec::with_capacity(target.len()); + solve(scan, &mut out); + + assert_eq!(out, target); + } + + #[test] + fn test_example() { + let input = b"\ +5 +2 9 1 2 7 +"; + let target = b"\ +6 +"; + + test(input, target); + } +}