Problem:
Score : 100 points

Problem Statement

Snuke is buying a bicycle.
The bicycle of his choice does not come with a bell, so he has to buy one separately.

He has very high awareness of safety, and decides to buy two bells, one for each hand.

The store sells three kinds of bells for the price of a, b and c yen (the currency of Japan), respectively.
Find the minimum total price of two different bells.

Constraints

1 \leq a,b,c \leq 10000

a, b and c are integers.

Input

Input is given from Standard Input in the following format:

a b c

Output

Print the minimum total price of two different bells.

Sample Input 1

700 600 780

Sample Output 1

1300

Buying a 700-yen bell and a 600-yen bell costs 1300 yen.

Buying a 700-yen bell and a 780-yen bell costs 1480 yen.

Buying a 600-yen bell and a 780-yen bell costs 1380 yen.

The minimum among these is 1300 yen.

Sample Input 2

10000 10000 10000

Sample Output 2

20000

Buying any two bells costs 20000 yen.

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unknown_lints)]
#![allow(unused_imports, unused_macros, non_snake_case, bare_trait_objects)]
#![allow(renamed_and_removed_lints, redundant_field_names)]
use std::cmp::Ordering::{self, Greater, Less};
use std::cmp::{max, min};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::error::Error;
use std::io::{self, BufReader, BufWriter, Read, Write};
use text_scanner::{scan, scan_iter, scanln, scanln_iter};

//{{{ macros missing in 1.15.1
#[macro_use]
mod macros {
    macro_rules! eprint {
        ($($t:tt)*) => {{
            use ::std::io::Write;
            let _ = write!(::std::io::stderr(), $($t)*);
        }};
    }
    macro_rules! eprintln {
        () => { eprintln!(""); };
        ($($t:tt)*) => {{
            use ::std::io::Write;
            let _ = writeln!(::std::io::stderr(), $($t)*);
        }};
    }
    macro_rules! dbg {
        ($val:expr) => {
            match $val {
                tmp => {
                    eprintln!(
                        "[{}:{}] {} = {:#?}",
                        file!(),
                        line!(),
                        stringify!($val),
                        &tmp
                    );
                    tmp
                }
            }
        };
    }
}
//}}}

fn run() {
    let a: usize = scan();
    let b: usize = scan();
    let c: usize = scan();
    let mut v = vec![a, b, c];
    v.sort();
    println!("{}", v[0] + v[1]);
}

fn main() {
    std::thread::Builder::new()
        .name("run".to_string())
        .stack_size(256 * 1024 * 1024)
        .spawn(run)
        .unwrap()
        .join()
        .unwrap()
}

//{{{ utils
pub mod text_scanner {
    use std;
    #[derive(Debug)]
    pub enum Error {
        IoError(std::io::Error),
        EncodingError(std::string::FromUtf8Error),
        ParseError(String),
        Eof,
    }

    impl std::fmt::Display for Error {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            match *self {
                Error::IoError(ref e) => writeln!(f, "IO Error: {}", e),
                Error::EncodingError(ref e) => writeln!(f, "Encoding Error: {}", e),
                Error::ParseError(ref e) => writeln!(f, "Parse Error: {}", e),
                Error::Eof => writeln!(f, "EOF"),
            }
        }
    }

    impl std::error::Error for Error {
        // dummy implementation for 1.15.1
        fn description(&self) -> &str {
            "description() is deprecated; use Display"
        }
    }

    pub fn read_line() -> Option<String> {
        let stdin = std::io::stdin();
        let mut stdin = stdin.lock();
        fread_line(&mut stdin).expect("IO error")
    }

    pub fn scan<T: FromTokens>() -> T {
        let stdin = std::io::stdin();
        let mut stdin = stdin.lock();
        fscan(&mut stdin).expect("IO error")
    }

    pub fn scanln<T: FromTokens>() -> T {
        let stdin = std::io::stdin();
        let mut stdin = stdin.lock();
        fscanln(&mut stdin).expect("IO error")
    }

    pub fn scan_iter<T: FromTokens>() -> ScanIter<T> {
        ScanIter {
            item_type: std::marker::PhantomData,
        }
    }

    pub fn scanln_iter<T: FromTokens>() -> ScanlnIter<T> {
        let stdin = std::io::stdin();
        let mut stdin = stdin.lock();
        let s = fread_line(&mut stdin)
            .expect("IO error")
            .unwrap_or_else(String::new);
        ScanlnIter {
            cursor: std::io::Cursor::new(s),
            item_type: std::marker::PhantomData,
        }
    }

    pub fn fread_line<R: std::io::BufRead>(r: &mut R) -> Result<Option<String>, std::io::Error> {
        let mut buf = String::new();
        let length = r.read_line(&mut buf)?;
        if let Some('\n') = buf.chars().last() {
            buf.pop();
        }
        if let Some('\r') = buf.chars().last() {
            buf.pop();
        }
        if length == 0 {
            Ok(None)
        } else {
            Ok(Some(buf))
        }
    }

    pub fn fscan<R: std::io::Read, T: FromTokens>(reader: &mut R) -> Result<T, Error> {
        let mut tokenizer = Tokenizer::new(reader);
        FromTokens::from_tokens(&mut tokenizer)
    }

    pub fn fscanln<R: std::io::BufRead, T: FromTokens>(reader: &mut R) -> Result<T, Error> {
        let s = match fread_line(reader) {
            Ok(Some(s)) => s,
            Ok(None) => return Err(Error::Eof),
            Err(e) => return Err(Error::IoError(e)),
        };
        let mut bytes = s.as_bytes();
        let mut tokenizer = Tokenizer::new(&mut bytes);
        FromTokens::from_tokens(&mut tokenizer)
    }

    pub fn fscan_iter<R: std::io::Read, T: FromTokens>(reader: &mut R) -> FscanIter<R, T> {
        FscanIter {
            tokenizer: Tokenizer::new(reader),
            item_type: std::marker::PhantomData,
        }
    }

    pub fn fscanln_iter<R: std::io::BufRead, T: FromTokens>(
        reader: &mut R,
    ) -> Result<ScanlnIter<T>, Error> {
        let s = match fread_line(reader) {
            Ok(Some(s)) => s,
            Ok(None) => "".to_string(),
            Err(e) => return Err(Error::IoError(e)),
        };
        Ok(ScanlnIter {
            cursor: std::io::Cursor::new(s),
            item_type: std::marker::PhantomData,
        })
    }

    pub struct ScanIter<T>
    where
        T: FromTokens,
    {
        item_type: std::marker::PhantomData<T>,
    }

    impl<T: FromTokens> Iterator for ScanIter<T> {
        type Item = T;

        fn next(&mut self) -> Option<Self::Item> {
            let stdin = std::io::stdin();
            let mut stdin = stdin.lock();
            let mut tokenizer = Tokenizer::new(&mut stdin);
            match FromTokens::from_tokens(&mut tokenizer) {
                Err(Error::Eof) => None,
                r => Some(r.expect("IO error")),
            }
        }
    }

    pub struct FscanIter<'a, R, T>
    where
        R: std::io::Read + 'a,
        T: FromTokens,
    {
        tokenizer: Tokenizer<'a, R>,
        item_type: std::marker::PhantomData<T>,
    }

    impl<'a, R: std::io::Read, T: FromTokens> Iterator for FscanIter<'a, R, T> {
        type Item = Result<T, Error>;

        fn next(&mut self) -> Option<Self::Item> {
            match FromTokens::from_tokens(&mut self.tokenizer) {
                Err(Error::Eof) => None,
                r => Some(r),
            }
        }
    }

    pub struct ScanlnIter<T>
    where
        T: FromTokens,
    {
        cursor: std::io::Cursor<String>,
        item_type: std::marker::PhantomData<T>,
    }

    impl<'a, T: FromTokens> Iterator for ScanlnIter<T> {
        type Item = T;

        fn next(&mut self) -> Option<Self::Item> {
            let mut tokenizer = Tokenizer::new(&mut self.cursor);
            match FromTokens::from_tokens(&mut tokenizer) {
                Err(Error::Eof) => None,
                r => Some(r.expect("IO error")),
            }
        }
    }

    pub trait FromTokens
    where
        Self: Sized,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error>;
    }

    macro_rules! from_tokens_primitives {
    ($($t:ty),*) => { $(
        impl FromTokens for $t {
            fn from_tokens(tokenizer: &mut Iterator<Item = Result<String, Error>>) -> Result<Self, Error> {
                let token = tokenizer.next();
                match token {
                    Some(s) => s?
                        .parse::<$t>()
                        .map_err(|e| Error::ParseError(format!("{}", e))),
                    None => Err(Error::Eof),
                }
            }
        }
    )* }
}

    from_tokens_primitives! {
        String,
        bool,
        f32,
        f64,
        isize,
        i8,
        i16,
        i32,
        i64,
        usize,
        u8,
        u16,
        u32,
        u64
    }

    impl<T1, T2> FromTokens for (T1, T2)
    where
        T1: FromTokens,
        T2: FromTokens,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error> {
            Ok((T1::from_tokens(tokenizer)?, T2::from_tokens(tokenizer)?))
        }
    }

    impl<T1, T2, T3> FromTokens for (T1, T2, T3)
    where
        T1: FromTokens,
        T2: FromTokens,
        T3: FromTokens,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error> {
            Ok((
                T1::from_tokens(tokenizer)?,
                T2::from_tokens(tokenizer)?,
                T3::from_tokens(tokenizer)?,
            ))
        }
    }

    impl<T1, T2, T3, T4> FromTokens for (T1, T2, T3, T4)
    where
        T1: FromTokens,
        T2: FromTokens,
        T3: FromTokens,
        T4: FromTokens,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error> {
            Ok((
                T1::from_tokens(tokenizer)?,
                T2::from_tokens(tokenizer)?,
                T3::from_tokens(tokenizer)?,
                T4::from_tokens(tokenizer)?,
            ))
        }
    }

    impl<T1, T2, T3, T4, T5> FromTokens for (T1, T2, T3, T4, T5)
    where
        T1: FromTokens,
        T2: FromTokens,
        T3: FromTokens,
        T4: FromTokens,
        T5: FromTokens,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error> {
            Ok((
                T1::from_tokens(tokenizer)?,
                T2::from_tokens(tokenizer)?,
                T3::from_tokens(tokenizer)?,
                T4::from_tokens(tokenizer)?,
                T5::from_tokens(tokenizer)?,
            ))
        }
    }

    impl<T1, T2, T3, T4, T5, T6> FromTokens for (T1, T2, T3, T4, T5, T6)
    where
        T1: FromTokens,
        T2: FromTokens,
        T3: FromTokens,
        T4: FromTokens,
        T5: FromTokens,
        T6: FromTokens,
    {
        fn from_tokens(
            tokenizer: &mut Iterator<Item = Result<String, Error>>,
        ) -> Result<Self, Error> {
            Ok((
                T1::from_tokens(tokenizer)?,
                T2::from_tokens(tokenizer)?,
                T3::from_tokens(tokenizer)?,
                T4::from_tokens(tokenizer)?,
                T5::from_tokens(tokenizer)?,
                T6::from_tokens(tokenizer)?,
            ))
        }
    }

    struct Tokenizer<'a, R: std::io::Read + 'a> {
        reader: &'a mut R,
    }

    impl<'a, R: std::io::Read> Tokenizer<'a, R> {
        pub fn new(reader: &'a mut R) -> Self {
            Tokenizer { reader: reader }
        }

        pub fn next_token(&mut self) -> Result<Option<String>, Error> {
            use std::io::Read;
            let mut token = Vec::new();
            for b in self.reader.by_ref().bytes() {
                let b = b.map_err(Error::IoError)?;
                match (is_ascii_whitespace(b), token.is_empty()) {
                    (false, _) => token.push(b),
                    (true, false) => break,
                    (true, true) => {}
                }
            }
            if token.is_empty() {
                return Ok(None);
            }
            String::from_utf8(token)
                .map(Some)
                .map_err(Error::EncodingError)
        }
    }

    impl<'a, R: std::io::Read> Iterator for Tokenizer<'a, R> {
        type Item = Result<String, Error>;
        fn next(&mut self) -> Option<Self::Item> {
            match self.next_token() {
                Ok(Some(s)) => Some(Ok(s)),
                Ok(None) => None,
                Err(e) => Some(Err(e)),
            }
        }
    }

    fn is_ascii_whitespace(b: u8) -> bool {
        // Can use u8::is_ascii_whitespace once removing support of 1.15.1
        match b {
            b'\t' | b'\n' | b'\x0C' | b'\r' | b' ' => true,
            _ => false,
        }
    }
}

pub trait SetMinMax {
    fn set_min(&mut self, v: Self) -> bool;
    fn set_max(&mut self, v: Self) -> bool;
}

impl<T> SetMinMax for T
where
    T: PartialOrd,
{
    fn set_min(&mut self, v: T) -> bool {
        *self > v && {
            *self = v;
            true
        }
    }
    fn set_max(&mut self, v: T) -> bool {
        *self < v && {
            *self = v;
            true
        }
    }
}

#[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
pub struct Reverse<T>(pub T);

impl<T: PartialOrd> PartialOrd for Reverse<T> {
    #[inline]
    fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
        other.0.partial_cmp(&self.0)
    }

    #[inline]
    fn lt(&self, other: &Self) -> bool {
        other.0 < self.0
    }
    #[inline]
    fn le(&self, other: &Self) -> bool {
        other.0 <= self.0
    }
    #[inline]
    fn ge(&self, other: &Self) -> bool {
        other.0 >= self.0
    }
    #[inline]
    fn gt(&self, other: &Self) -> bool {
        other.0 > self.0
    }
}

impl<T: Ord> Ord for Reverse<T> {
    #[inline]
    fn cmp(&self, other: &Reverse<T>) -> Ordering {
        other.0.cmp(&self.0)
    }
}

#[derive(PartialEq, PartialOrd, Debug, Copy, Clone, Default)]
pub struct Num(pub f64);

impl Eq for Num {}

impl Ord for Num {
    fn cmp(&self, other: &Num) -> Ordering {
        self.0
            .partial_cmp(&other.0)
            .expect("unexpected NaN when compare")
    }
}

// See https://docs.rs/superslice/1.0.0/superslice/trait.Ext.html
pub trait SliceExt {
    type Item;

    fn lower_bound(&self, x: &Self::Item) -> usize
    where
        Self::Item: Ord;

    fn lower_bound_by<'a, F>(&'a self, f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> Ordering;

    fn lower_bound_by_key<'a, K, F>(&'a self, k: &K, f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> K,
        K: Ord;

    fn upper_bound(&self, x: &Self::Item) -> usize
    where
        Self::Item: Ord;

    fn upper_bound_by<'a, F>(&'a self, f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> Ordering;

    fn upper_bound_by_key<'a, K, F>(&'a self, k: &K, f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> K,
        K: Ord;
}

impl<T> SliceExt for [T] {
    type Item = T;

    fn lower_bound(&self, x: &Self::Item) -> usize
    where
        T: Ord,
    {
        self.lower_bound_by(|y| y.cmp(x))
    }

    fn lower_bound_by<'a, F>(&'a self, mut f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> Ordering,
    {
        let s = self;
        let mut size = s.len();
        if size == 0 {
            return 0;
        }
        let mut base = 0usize;
        while size > 1 {
            let half = size / 2;
            let mid = base + half;
            let cmp = f(unsafe { s.get_unchecked(mid) });
            base = if cmp == Less { mid } else { base };
            size -= half;
        }
        let cmp = f(unsafe { s.get_unchecked(base) });
        base + (cmp == Less) as usize
    }

    fn lower_bound_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> K,
        K: Ord,
    {
        self.lower_bound_by(|e| f(e).cmp(k))
    }

    fn upper_bound(&self, x: &Self::Item) -> usize
    where
        T: Ord,
    {
        self.upper_bound_by(|y| y.cmp(x))
    }

    fn upper_bound_by<'a, F>(&'a self, mut f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> Ordering,
    {
        let s = self;
        let mut size = s.len();
        if size == 0 {
            return 0;
        }
        let mut base = 0usize;
        while size > 1 {
            let half = size / 2;
            let mid = base + half;
            let cmp = f(unsafe { s.get_unchecked(mid) });
            base = if cmp == Greater { base } else { mid };
            size -= half;
        }
        let cmp = f(unsafe { s.get_unchecked(base) });
        base + (cmp != Greater) as usize
    }

    fn upper_bound_by_key<'a, K, F>(&'a self, k: &K, mut f: F) -> usize
    where
        F: FnMut(&'a Self::Item) -> K,
        K: Ord,
    {
        self.upper_bound_by(|e| f(e).cmp(k))
    }
}

//}}}