Как написать сценарий оболочки для присвоения буквенных оценок числовым диапазонам?

19

Я хочу создать скрипт, который подскажет вам число от 0 до 100, а затем даст вам оценку на основе номера.

Мне бы это понравилось в bash.

PS3='Please enter your choice: '
(Something here)

do
case $
    "0-59")
        echo "F"
        ;;
    "60-69")
        echo "D"
        ;;
    "70-79")
        echo "C"
        ;;
    "Quit")
        break
        ;;
    *) echo invalid option;;
esac
done
    
задан Temple Pate 09.05.2015 в 11:46
источник

9 ответов

20

Краткость и читаемость: средняя земля

Как вы видели, эта проблема допускает решения, которые являются умеренно длинными и несколько повторяющимися, но читаемыми ( terdon ) и ответы AB bash), а также те, которые очень короткие, но неинтуитивные и гораздо менее самодокументирующимся (Tim's python и ответы bash и glenn jackman's perl answer ). Все эти подходы ценны.

Вы также можете решить эту проблему с кодом в середине континуума между компактностью и удобочитаемостью. Этот подход почти так же читабельен, как и более длинные решения, длина которых ближе к малым эзотерическим решениям.

#!/usr/bin/env bash

read -erp 'Enter numeric grade (q to quit): '
case $REPLY in [qQ]) exit;; esac

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

for letter in F D C B A; do
    ((REPLY <= cutoffs[$letter])) && { echo $letter; exit; }
done
echo "Grade out of range."

В этом решении bash я включил некоторые пустые строки для повышения удобочитаемости, но вы можете удалить их, если хотите, чтобы это было еще короче.

Включены пустые строки, это на самом деле немного меньше компактный, все еще довольно читаемый вариант решение bash для решения . Основные преимущества этого метода заключаются в следующем:

  • Это более интуитивно понятно.
  • Легче изменить границы между классами (или добавить дополнительные оценки).
  • Он автоматически принимает ввод с ведущими и конечными пробелами (см. ниже объяснение того, как работает (( )) ).

Все три из этих преимуществ возникают из-за того, что этот метод использует ввод пользователя как числовые данные, а не вручную анализирует его составляющие цифры.

Как это работает

  1. Прочитайте ввод от пользователя. Пусть они используют клавиши со стрелками для перемещения по тексту они ввели ( -e ) и не интерпретируют \ как escape-символ ( -r ).
    Этот скрипт не является многофункциональным решением - см. ниже для уточнения- - но эти полезные функции только делают его двумя символами дольше. Я рекомендую всегда использовать -r с read , если вы не знаете, что вам нужно предоставить пользователю \ escapes.
  2. Если пользователь написал q или Q , закройте.
  3. Создайте ассоциативный array ( declare -A ). Заполните его наивысшим числом, связанным с каждым классом букв.
  4. Прокрутите по классам от наименьшего до самого высокого, проверяя, является ли предоставленный пользователем номер достаточно низко, чтобы попасть в числовой диапазон каждого слова.
    При оценке арифметики (( )) , имена переменных не нужно расширять с помощью $ . (В большинстве других ситуаций, если вы хотите использовать значение переменной вместо своего имени, вы должны это сделать .
  5. Если он попадает в диапазон, напечатайте оценку и выйти .
    Для краткости я использую оператор короткого замыкания и ( && ), а не if - then .
  6. Если цикл завершен и диапазон не согласован, предположим, что введенный номер слишком высок (более 100) и сообщает пользователю, что он вышел за пределы диапазона.

Как это работает, с Weird Input

Как и другие выпущенные решения short , этот скрипт не проверяет входные данные, прежде чем считать, что это число. Арифметическая оценка ( (( )) ) автоматически разделяет ведущее и конечное пробелы, поэтому нет проблем, но:

  • Ввод, который не похож на число вообще, интерпретируется как 0.
  • При вводе, который выглядит как число (то есть, если оно начинается с цифры), но содержит недопустимые символы, скрипт испускает ошибки.
  • Многозначный ввод, начинающийся с 0 , интерпретируется как в восьмеричное . Например, скрипт скажет вам, что 77 - это C, а 077 - D. Хотя некоторые пользователи могут этого захотеть, скорее всего, этого не произойдет, и это может вызвать путаницу.
  • С положительной стороны, когда задано арифметическое выражение, этот скрипт автоматически упрощает его и определяет соответствующий класс. Например, он скажет вам, что 320/4 - это B.

Расширенная, полнофункциональная версия

По этим причинам вы можете использовать что-то вроде этого расширенного скрипта, который проверяет правильность ввода и включает некоторые другие улучшения.

#!/usr/bin/env bash
shopt -s extglob

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

while read -erp 'Enter numeric grade (q to quit): '; do
    case $REPLY in  # allow leading/trailing spaces, but not octal (e.g. "03") 
        *( )@([1-9]*([0-9])|+(0))*( )) ;;
        *( )[qQ]?([uU][iI][tT])*( )) exit;;
        *) echo "I don't understand that number."; continue;;
    esac

    for letter in F D C B A; do
        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }
    done
    echo "Grade out of range."
done

Это еще довольно компактное решение.

Какие функции это добавляет?

Ключевыми моментами этого расширенного скрипта являются:

  • Проверка ввода. скрипт тердона проверяет ввод с if [[ ! $response =~ ^[0-9]*$ ]] ... , поэтому я показываю другой способ, который жертвует некоторой кратностью, но более надежным, что позволяет пользователь вводит ведущие и конечные пробелы и отказывается разрешить выражение, которое может или не может быть использовано как восьмеричное (если оно не равно нулю).
  • Я использовал case с расширенное globbing вместо [[ с сопоставлением % (как в ответе тердона ). Я сделал это, чтобы показать, что (и как) это также можно сделать таким образом. Глобусы и регулярные выражения - это два способа указания шаблонов, соответствующих тексту, и любой метод подходит для этого приложения.
  • Как сценарий AB's bash , я включил все это во внешний цикл (кроме начального создания массива =~ ). Он запрашивает номера и дает соответствующие градации букв, если терминал доступен, и пользователь не сказал ему прекратить работу. Судя по cutoffs ... do вокруг кода в вашем вопросе, похоже, что вы этого хотите.
  • Чтобы упростить выход, я принимаю любой нечувствительный к регистру вариант done или q .

Этот сценарий использует несколько конструкций, которые могут быть незнакомы новичкам; они подробно описаны ниже.

Объяснение: Использование quit

Когда я хочу пропустить оставшуюся часть внешнего цикла continue , я использую команду while . Это возвращает его к вершине цикла, чтобы читать больше ввода и запускать другую итерацию.

В первый раз, когда я делаю это, единственным циклом, в котором я состою, является внешний цикл continue , поэтому я могу вызвать while без аргумента. (Я в continue конструкции, но это не влияет на работу case или break .)

        *) echo "I don't understand that number."; continue;;

Во второй раз, однако, у меня есть внутренний цикл continue , который сам вложен внутри внешнего цикла for . Если я использовал while без аргумента, это было бы эквивалентно continue и продолжало бы внутренний цикл continue 1 вместо внешнего цикла for .

        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }

Итак, в этом случае я использую while , чтобы сделать bash find и продолжить второй цикл.

Объяснение: continue 2 Ярлыки с глобусами

Я не использую case , чтобы выяснить, в какой буквой bin> число попадает (как в < a href="https://askubuntu.com/a/621471/22949"> ответ bash от AB ). Но я использую case , чтобы решить, следует ли учитывать вход пользователя:

  • действительное число, case
  • команда quit, *( )@([1-9]*([0-9])|+(0))*( )
  • все остальное (и, следовательно, недопустимый ввод), *( )[qQ]?([uU][iI][tT])*( )

Это оболочки globs .

  • За каждым следует * , которое не соответствует ни одному открытию ) , который является синтаксисом ( для разделения шаблона на команды, которые выполняются, когда он сопоставляется.
  • case - синтаксис ;; для указания конца команд для выполнения для соответствия патакулярного случая (и что последующие случаи не должны проверяться после их запуска).

Обычное чередование оболочки обеспечивает case для соответствия нулю или нескольким символам, * для соответствия точно одному символу, а классы символов / диапазоны - в ? [ скобки. Но я использую расширенное globbing , что выходит за рамки этого. Расширенное глобальное включение включено по умолчанию при использовании ] в интерактивном режиме, но по умолчанию отключается при запуске скрипта. Команда bash в верхней части скрипта включает ее.

Объяснение: Расширенное Globbing

shopt -s extglob , который проверяет числовой ввод , соответствует последовательности:

  • Ноль или больше пробелов ( *( )@([1-9]*([0-9])|+(0))*( ) ). Конструкция *( ) *( соответствует нулевому или более шаблону в круглых скобках, который здесь просто пробел.
    На самом деле существуют два вида горизонтальных пробелов, пробелов и вкладок, и часто желательно, чтобы также совпадают. Но я не беспокоюсь об этом здесь, потому что этот скрипт написан для ручного, интерактивного ввода, а флаг ) для -e включает в себя GNU readline. Это значит, что пользователь может перемещаться назад и вперед в своем тексте с помощью клавиш со стрелками влево и вправо, но имеет побочный эффект, заключающийся в том, что обычно запрещается вводить вкладки буквально.
  • В одном случае ( read @( ) либо ( ) ):
    • Незначительная цифра ( | ), за которой следует ноль или более ( [1-9] *( ) любой цифры ( ) ).
    • Один или несколько ( [0-9] +( ) ) .
  • Нуль или больше пробелов ( 0 ), снова.

*( ) , который проверяет команду quit , соответствует последовательности:

  • Ноль или больше пробелов ( *( )[qQ]?([uU][iI][tT])*( ) ).
  • *( ) или q ( Q ).
  • Необязательно - то есть, ноль или один случай ( [qQ] ?( ) - от:
    • ) или u ( U ), за которыми следуют [uU] или i ( I ), за которыми следуют [iI] или t ( T ).
  • Нуль или больше пробелов ( [tT] ), снова.

Вариант: проверка ввода с расширенным регулярным выражением

Если вы предпочитаете проверять ввод пользователя на регулярное выражение, а не на glob оболочки, вы можете использовать эту версию, которая работает одинаково, но использует *( ) и [[ (например, в ответ от пользователя ) вместо =~ и расширенного глобуса.

#!/usr/bin/env bash
shopt -s nocasematch

declare -A cutoffs
cutoffs[F]=59 cutoffs[D]=69 cutoffs[C]=79 cutoffs[B]=89 cutoffs[A]=100

while read -erp 'Enter numeric grade (q to quit): '; do
    # allow leading/trailing spaces, but not octal (e.g., "03")
    if [[ ! $REPLY =~ ^\ *([1-9][0-9]*|0+)\ *$ ]]; then
        [[ $REPLY =~ ^\ *q(uit)?\ *$ ]] && exit
        echo "I don't understand that number."; continue
    fi

    for letter in F D C B A; do
        ((REPLY <= cutoffs[$letter])) && { echo $letter; continue 2; }
    done
    echo "Grade out of range."
done

Возможные преимущества этого подхода заключаются в следующем:

  • В этом конкретном случае синтаксис немного проще, по крайней мере во втором шаблоне, где я проверяю команду quit. Это связано с тем, что мне удалось установить параметр оболочки case , а затем все варианты case nocasematch и q были покрыты автоматически.

    Вот что делает команда quit . Команда shopt -s nocasematch опущена, поскольку в этой версии не используется globbing.

  • Регулярные навыки выражения более распространены, чем умение в extglobs bash.

Объяснение: Регулярные выражения

Что касается шаблонов, указанных справа от оператора shopt -s extglob , вот как работают эти регулярные выражения.

=~ , который проверяет числовой ввод , соответствует последовательности:

  • Начало - то есть левый край - строки ( ^\ *([1-9][0-9]*|0+)\ *$ ).
  • Нулевые или более ( ^ , прикладной постфикс) пробелы. Пространство обычно не должно быть * -escaped в регулярном выражении, но это необходимо для \ , чтобы предотвратить синтаксическую ошибку.
  • Подстрока ( [[ ( ), которая является одним или другим ( ) ):
    • | : отличная от нуля цифра ( [1-9][0-9]* ), за которой следует ноль или более ( [1-9] , прикладной постфикс) любой цифры ( * ).
    • [0-9] : один или несколько ( 0+ , прикладной постфикс) + .
  • Ноль или больше пробелов ( 0 ), как и раньше.
  • Конец - то есть правый край - строки ( \ * ).

В отличие от $ ярлыков, которые соответствуют всему тестируемому выражению, case возвращает true, если какая-либо часть его левого выражения соответствует шаблону, указанному как его правое выражение. Вот почему нужны якобы =~ и ^ , указывающие начало и конец строки, и не синтаксически соответствуют синтаксическому отношению к чему-либо, появляющемуся в методе с $ и extglobs.

Скобки необходимы, чтобы case и ^ связывались с дизъюнкцией $ и [1-9][0-9]* . В противном случае это будет дизъюнкция 0+ и ^[1-9][0-9]* , и будет соответствовать любому входу, начинающемуся с ненулевой цифры или , заканчивающейся с 0+$ (или обоими, которые могут по-прежнему включать не цифры в между ними). ​​

0 , который проверяет команду quit , соответствует последовательности:

  • Начало строки ( ^\ *q(uit)?\ *$ ).
  • Нуль или больше пробелов ( ^ , см. выше объяснение).
  • Буква \ * . Или q , так как Q включено.
  • Необязательно - то есть, ноль или один случай (postfix shopt nocasematch ) - подстроки ( ? ( ):
    • ) , затем u , а затем i . Или, поскольку t включено, shopt nocasematch может быть u ; независимо, U может быть i ; и независимо, I может быть t . (То есть, возможности not ограничены T и uit .)
  • Нуль или больше пробелов ( UIT ).
  • Конец строки ( \ * ).
ответ дан Eliah Kagan 09.05.2015 в 18:31
источник
23

У вас уже есть основная идея. Если вы хотите ввести код в bash (это разумный выбор, поскольку он является оболочкой по умолчанию для Ubuntu и большинства других Linux), вы не можете использовать case , потому что он не понимает диапазоны. Вместо этого вы можете использовать if / else :

#!/usr/bin/env bash

read -p "Please enter your choice: " response

## If the response given did not consist entirely of digits
if [[ ! $response =~ ^[0-9]*$ ]]
then
    ## If it was Quit or quit, exit
    [[ $response =~ [Qq]uit ]] && exit
    ## If it wasn't quit or Quit but wasn't a number either,
    ## print an error message and quit.
    echo "Please enter a number between 0 and 100 or \"quit\" to exit" && exit
fi
## Process the other choices
if [ $response -le 59 ]
then
    echo "F"
elif [ $response -le 69 ]
then
    echo "D"
elif  [ $response -le 79 ]
then
    echo "C"
elif  [ $response -le 89 ]
then
    echo "B"
elif [ $response -le 100 ]
then
    echo "A"
elif [ $response -gt 100 ]
then
    echo "Please enter a number between 0 and 100"
     exit
fi
    
ответ дан terdon 09.05.2015 в 12:04
12
#!/bin/bash

while true
do
  read -p "Please enter your choice: " choice

  case "$choice"
   in
      [0-9]|[1-5][0-9])
          echo "F"
          ;;
      6[0-9])
          echo "D"
          ;;
      7[0-9])
          echo "C"
          ;;
      8[0-9])
          echo "B"
          ;;
      9[0-9]|100)
          echo "A"
          ;;
      [Qq])
          exit 0
          ;;
      *) echo "Only numbers between 0..100, q for quit"
          ;;
  esac
done

и более компактную версию (Thx @EliahKagan ):

#!/usr/bin/env bash

while read -erp 'Enter numeric grade (q to quit): '; do
    case $REPLY in
        [0-9]|[1-5][0-9])   echo F ;;
        6[0-9])             echo D ;;
        7[0-9])             echo C ;;
        8[0-9])             echo B ;;
        9[0-9]|100)         echo A ;;

        [Qq])               exit ;;
        *)                  echo 'Only numbers between 0..100, q for quit' ;;
    esac
done
    
ответ дан A.B. 09.05.2015 в 11:58
9

У всех установок Ubuntu есть Python, так что вот сценарий python один лайнер. Если вам нужно, чтобы он находился в bash, я также написал эквивалент как сценарий оболочки .

print (chr(75-max(5,int('0'+raw_input('Enter the number: ')[:-1]))))

Чтобы запустить, сохраните его в файле (например, grade.py ), а затем запустите его в терминале следующим образом:

python grade.py

Вот что вы увидите:

Enter the number: 65
E

Как это работает?

  1. Взять ввод - 65 .
  2. Добавьте 0 в начало - 065 .
  3. Удалить последний символ - 06 .
  4. 75 вычесть это число - 70 .
  5. Преобразовать в букву (A - 65, B - 66) - E .
  6. Распечатайте его - E .
ответ дан Tim 09.05.2015 в 12:56
6

После создания его в Python 2 я решил сделать это в bash.

#! /bin/bash

read -p "Enter the number: " i
i=0$i
x=$((10#${i::-1}))
printf "\x$(printf %x $((11-($x>5?$x:5)+64)))\n"

Чтобы запустить, сохраните его в файле (например, grade.sh), сделайте его исполняемым с chmod +x grade.sh , а затем запустите с ./grade.sh .

Вот что вы увидите:

Enter the number: 65
E

Как это работает?

  1. Взять ввод - 65 .
  2. Добавьте 0 в начало - 06510# сохраняет базу 10).
  3. Удалить последний символ - 06 .
  4. 75 вычесть это число - 70 .
  5. Преобразовать в букву (A - 65, B - 66) - E .
  6. Распечатайте его - E .
ответ дан Tim 09.05.2015 в 13:33
6

Вот мое решение semi -esoteric bash, которое заполняет массив с 101 записями, а затем проверяет вход пользователя против них. Даже для реального использования это разумно - если вам нужна отличная производительность, вы бы не использовали bash, а сотни (или так) назначений все еще бывают быстрыми. Но это перестало бы быть разумным, если бы расширилось до большего диапазона (например, миллион).

#!/usr/bin/env bash
p(){ for i in 'seq  '; do g[$i]=; done; }
p A 90 100; p B 80 89; p C 70 79; p D 60 69; p F 0 59
while read -r n && [[ ! $n =~ ^[qQ] ]]; do echo ${g[$n]}; done

Преимущества:

  • На самом деле это не эзотерика. . Хотя он длиннее кратчайших решений и не совсем самодокументирован как более длинные решения ... это разумно самодокументирующийся , в то время как все еще решительно на крошечной стороне.
  • Это позволяет легко изменять изменения диапазонов оценок или добавлять / удалять оценки.
  • Он работает в цикле и завершает работу на q , quit или что-либо, начиная с q / Q .
  • Сначала перечисляет высшие оценки, чтобы помочь вам думать позитивно. :)
  • Хм, это делает работу, сохраняет смысл даже после того, как вы посмотрите на нее, и имеет важные функции. Вы действительно можете использовать это!

Недостатки:

  • Он дает вам F, когда вы вводите нечисловой ввод ... но это не так уж плохо, не так ли? Если вы дадите не номер, где нужно число, возможно, вы заслужили F!
  • Неоднозначный, возможно восьмеричный ввод рассматривается как восьмеричный (поскольку g является одномерным индексированным массивом ). Как говорится в старой поговорке: «Это не ошибка, это особенность!» Ну, может быть.
  • Ввод, который выходит за пределы допустимого диапазона или не содержит число, приводит к печати пустой строки. В этом нет ничего плохого: он сообщает вам, какой класс соответствует вашему входу, а для неправильного ввода его нет.
  • Положите отрицательное число, и это ... ну, назовите это пасхальное яйцо .
  • Все еще значительно дольше решение python от Tim . Да, я не могу сказать, что это преимущество.

Прикольно, а? (Ну, я так думаю.)

Как это работает

  1. Функция p p блокирует численный индексный массив g из g рад, при индексы от первого аргумента до второго, с (буквенным) значением, указанным в его третьем аргументе.
  2. p вызывается для каждого класса письма, чтобы определить его числовой диапазон.
  3. Продолжайте читать пользовательский ввод до тех пор, пока он доступен, и не запускается с q (или Q ), проверяя массив g , для которого соответствует класс букв, и печать этой буквы.
ответ дан Eliah Kagan 11.05.2015 в 05:13
5

И вот моя версия awk:

awk '{
  if($_ <= 100 && $_ >= 0) {
      sub(/^([0-9]|[1-5][0-9])$/, "F", $_);
      sub(/^(6[0-9])$/, "D", $_);
      sub(/^(7[0-9])$/, "C", $_);
      sub(/^(8[0-9])$/, "B", $_);
      sub(/^(9[0-9]|100)$/, "A", $_);
      print
    }
    else {
      print "Only numbers between 0..100"
    }
}' -

или как однострочный:

awk '{if($_ <= 100 && $_ >= 0) { sub(/^([0-9]|[1-5][0-9])$/, "F", $_); sub(/^(6[0-9])$/, "D", $_); sub(/^(7[0-9])$/, "C", $_); sub(/^(8[0-9])$/, "B", $_);sub(/^(9[0-9]|100)$/, "A", $_);   print} else { print "Only numbers between 0..100"}}' -
    
ответ дан A.B. 09.05.2015 в 19:13
4

Вот еще один «эзотерический» ответ

perl -E '
    print "number: "; 
    $n = <>; 
    say qw/A A B C D E F F F F F/[11-($n+1)/10]
       if $n=~/^\s*\d/ and 0<=$n and $n<=100
'

Объяснение

  • perl -E : -E , например -e , позволяет передавать сценарий в качестве аргумента командной строки. Это способ запуска perl one-liners. В отличие от -e , -E также включает все необязательные функции (например, say , в основном print с завершающей новой строкой.).
  • print "number: "; : предложит пользователю ввести номер.
  • $n = <>; : сохранить это число как $n .

Следующий бит нужно немного разбить. qw/string/ оценивает список, сделанный путем разбиения string на пробелы. Итак, qw/A A B C D E F F F F F/ на самом деле является этим списком:

0 : A
1 : A
2 : B
3 : C
4 : D
5 : E
6 : F
7 : F
8 : F
9 : F
10 : F

Следовательно, say qw/A A B C D E F F F F F/[11-($n+1)/10] эквивалентно

my @F=("A","A","B","C","D","E","F","F","F","F","F");
print "$F[11-($n+1)/10]\n"

Теперь Perl позволяет использовать отрицательные индексы для извлечения элементов, считанных с конца массива. Например, $arrray[-1] будет печатать последний элемент массива. Кроме того, индексы массивов с плавающей запятой (например, 10.7) автоматически усекаются до следующего нижнего целого числа (10,7 или 10,3 или любого другого).

Результат всего этого состоит в том, что индекс 11-($n+1)/10 всегда оценивает соответствующий элемент (класс) массива.     

ответ дан glenn jackman 09.05.2015 в 14:03
1

Хотя вы просили bash-решение, я думаю, что в python это можно сделать в элегантном коротком пути. Покрытие ошибок обработки в случае неправильного ввода и «преобразования» числа от 0 до 100 в буквы от A до F (или любого другого):

#!/usr/bin/env python3
try:
    n = int(input("number: ")); n = n if n>0 else ""
    print("FEDCBA"[[n>=f for f in [50,60,70,80,90,101]].count(True)])
except:
    print("invalid input")

Объяснение

  1. Сначала нам нужно получить номер от пользователя:

    n = int(input("number: "))
    
  2. Мы проверяем, что это число справедливо для ряда условий:

    n>=50, n>=60, n>=70, n>=80, n>=90
    

    Для каждого из этих тестов результат будет либо False , либо True . Поэтому (немного сжав код):

    [n>=f for f in [50,60,70,80,90]].count(True)]
    

    будет отображаться цифра от 0 до 5

  3. Впоследствии мы можем использовать этот показатель как index для строки, чтобы создать символ в качестве вывода, например.

    "ABCDEF"[3] 
    

    выведет «D» (поскольку первый символ = «A»)

  4. Дополнительный 101 к списку должен генерировать ошибку (Index-) в случае, если число превышает 100 , так как "ABCDEF"[6] не существует. То же самое касается n = n if n>=0 else "" , который будет создавать ошибку (Value-), если вводится число ниже 0
    В этих случаях, а также, если вход не является цифрой, результатом будет:

    invalid input
    

Тестирование:

number: 10
F

number: 50
E

number: 60
D

number: 70
C

number: 80
B

number: 90
A

number: 110
invalid input

number: -10
invalid input

number: Monkey
invalid input
    
ответ дан Jacob Vlijm 07.07.2015 в 13:05