Problem:
Score : 100 points

Problem Statement

There are three airports A, B and C, and flights between each pair of airports in both directions.

A one-way flight between airports A and B takes P hours, a one-way flight between airports B and C takes Q hours, and a one-way flight between airports C and A takes R hours.

Consider a route where we start at one of the airports, fly to another airport and then fly to the other airport.

What is the minimum possible sum of the flight times?

Constraints

1 \leq P,Q,R \leq 100

All values in input are integers.

Input

Input is given from Standard Input in the following format:

P Q R

Output

Print the minimum possible sum of the flight times.

Sample Input 1

1 3 4

Sample Output 1

4

The sum of the flight times in the route A \rightarrow B \rightarrow C: 1 + 3 = 4 hours

The sum of the flight times in the route A \rightarrow C \rightarrow C: 4 + 3 = 7 hours

The sum of the flight times in the route B \rightarrow A \rightarrow C: 1 + 4 = 5 hours

The sum of the flight times in the route B \rightarrow C \rightarrow A: 3 + 4 = 7 hours

The sum of the flight times in the route C \rightarrow A \rightarrow B: 4 + 1 = 5 hours

The sum of the flight times in the route C \rightarrow B \rightarrow A: 3 + 1 = 4 hours

The minimum of these is 4 hours.

Sample Input 2

3 2 3

Sample Output 2

5

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ContestTemplate
{
    #region interface class

    /// <summary>
    /// IO method interface
    /// </summary>
    public interface IInputOutput
    {
        /// <summary>
        /// read a single line from any stream
        /// </summary>
        /// <returns></returns>
        string ReadLine();

        /// <summary>
        /// write the data as a single line to any stream
        /// </summary>
        /// <param name="data"></param>
        void WriteLine(string data);
    }

    /// <summary>
    /// executable interface
    /// </summary>
    public interface IRunner
    {
        /// <summary>
        /// execute main process
        /// </summary>
        void Execute();
    }

    #endregion

    #region common class

    /// <summary>
    /// factory class of the main process runnger
    /// </summary>
    internal static class RunnerFactory
    {
        /// <summary>
        /// create executable main process runner
        /// </summary>
        /// <param name="isTest">test mode or one for submitting as a final code</param>
        /// <returns></returns>
        internal static IRunner Create(bool isTest)
        {
            if (isTest == false)
            {
                return new ConsoleInputOutputRunner();
            }
            else
            {
                return new TestRunner();
            }
        }
    }

    /// <summary>
    /// IO to/from console
    /// </summary>
    internal class ConsoleInputOutput : IInputOutput
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        string IInputOutput.ReadLine()
        {
            return Console.ReadLine();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        void IInputOutput.WriteLine(string data)
        {
            Console.WriteLine(data);
        }
    }

    /// <summary>
    /// IO to/from test data
    /// </summary>
    internal class TestInputOutput : IInputOutput, IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly TextReader inputDataStream;

        /// <summary>
        /// 
        /// </summary>
        private readonly StringBuilder outputDataStream;

        /// <summary>
        /// 
        /// </summary>
        private bool isDisposed = false;

        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="input">test input data</param>
        internal TestInputOutput(string input)
        {
            this.inputDataStream = new StringReader(input);
            this.outputDataStream = new StringBuilder();
        }

        /// <summary>
        /// finalizer
        /// </summary>
        ~TestInputOutput()
        {
            this.Dispose(false);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="isDisposing"></param>
        protected virtual void Dispose(bool isDisposing)
        {
            if (this.isDisposed == true)
            {
                return;
            }

            if (isDisposing == true)
            {
                this.inputDataStream.Dispose();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        string IInputOutput.ReadLine()
        {
            return this.inputDataStream.ReadLine();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        void IInputOutput.WriteLine(string data)
        {
            this.outputDataStream.Append(data + "\n");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal string ObtainOutputData()
        {
            return this.outputDataStream.ToString();
        }
    }

    /// <summary>
    /// console input/output executable runner 
    /// for submitting as a final code
    /// </summary>
    internal class ConsoleInputOutputRunner : IRunner
    {
        /// <summary>
        /// execute main proces using console input/ ouput
        /// </summary>
        public void Execute()
        {
            Program.DoMainProcess(new ConsoleInputOutput());
        }
    }

    /// <summary>
    /// unit test executable runner
    /// </summary>
    internal class TestRunner : IRunner
    {
        /// <summary>
        /// execute all test cases
        /// </summary>
        public void Execute()
        {
            foreach (var inputAndExpectedResult in TestDataForLocal.ObtainTestInputAndExpectedResultMap())
            {
                var input = inputAndExpectedResult.Key;
                var expectedResult = inputAndExpectedResult.Value;

                Console.WriteLine(string.Format("TEST:: input=[\n{0}\n], \nexpectedOutput=[{1}]", input, expectedResult));

                using (var inputOutput = new TestInputOutput(input))
                {
                    Program.DoMainProcess(inputOutput);
                    var result = inputOutput.ObtainOutputData();

                    Console.WriteLine(string.Format("TEST:: result=[\n{0}], \njudge::[{1}]", result, result == expectedResult));
                    Console.WriteLine(string.Empty);
                }
            }

            // just to wait (to check the result)
            Console.ReadKey();
        }
    }

    #endregion

    #region test data

    /// <summary>
    /// unit test data
    /// </summary>
    internal static class TestDataForLocal
    {
        /// <summary>
        /// get the mapped data of input and expected result string
        /// **EDIT THIS DATA TO CHANGE TEST CASES** 
        /// </summary>
        /// <returns></returns>
        internal static Dictionary<string, string> ObtainTestInputAndExpectedResultMap()
        {
            return new Dictionary<string, string>()
            {
                {"1 3 4", "4\n"},
                {"3 2 3", "5\n"},
            };
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            const bool isTest = false;
            RunnerFactory.Create(isTest).Execute();
        }

        /// <summary>
        /// main algorithm of the question
        /// </summary>
        /// <param name="inputOuput"></param>
        internal static void DoMainProcess(IInputOutput inputOuput)
        {
            var line = inputOuput.ReadLine();
            var lineArray = line.Split(' ');

            var p = int.Parse(lineArray[0]);
            var q = int.Parse(lineArray[1]);
            var r = int.Parse(lineArray[2]);

            var outArray = new int[3];

            var intArray = new int[] { p, q, r };

            var combination = intArray.Comb(2).Select(x => x.ToArray()).ToArray();

            for (int i = 0; i < combination.Count(); i++)
            {
                var array = combination[i];
                outArray[i] = array[0] + array[1];
            }

            int min = outArray.Min();

            inputOuput.WriteLine(string.Format("{0}", min));
            return;
        }

    }

    public static class UtilityEx
    {
        public static IEnumerable<IEnumerable<T>> Perm<T>(this IEnumerable<T> items, int? k = null)
        {
            if (k == null)
                k = items.Count();

            if (k == 0)
            {
                yield return Enumerable.Empty<T>();
            }
            else
            {
                var i = 0;
                foreach (var x in items)
                {
                    var xs = items.Where((_, index) => i != index);
                    foreach (var c in Perm(xs, k - 1))
                        yield return c.Before(x);

                    i++;
                }
            }
        }

        // 要素をシーケンスに追加するユーティリティ
        public static IEnumerable<T> Before<T>(this IEnumerable<T> items, T first)
        {
            yield return first;

            foreach (var i in items)
                yield return i;
        }

        public static IEnumerable<IEnumerable<T>> Comb<T>(this IEnumerable<T> items, int r)
        {
            if (r == 0)
            {
                yield return Enumerable.Empty<T>();
            }
            else
            {
                var i = 1;
                foreach (var x in items)
                {
                    var xs = items.Skip(i);
                    foreach (var c in Comb(xs, r - 1))
                        yield return c.Before(x);

                    i++;
                }
            }

        }
    }
}