Какой у меня индекс массы тела?


21

Проблема:

Ваша задача - написать программу, которая принимает в качестве входных данных рост (в метрах) и вес (в килограммах) и выводит соответствующую категорию ИМТ.

ИМТ - это показатель отношения вашего веса к вашему росту. Это датировано и неточно для многих людей , но это не имеет значения здесь!

ИМТ может быть рассчитан с использованием следующего уравнения:

BMI = (mass in kilograms) / (height in meters)^2

Категории будут определены следующим образом:

  • ИМТ <18,5: «Недостаточный вес»

  • 18,5 <= ИМТ <25: «Нормальный»

  • 25 <= ИМТ: «Избыточный вес»

Ради вызова я игнорирую все "экстремальные" категории. Кроме того, поскольку некоторые числа, такие как «25», расположены между двумя категориями, я немного скорректировал границы, чтобы получить определенный ответ.

Вы можете написать либо функцию, либо полную программу.

Входные данные:

Ввод может быть в любой разумной форме. Два числа (или строки), либо как 2 отдельных аргумента, либо как одна строка. Массив / список из 2 чисел, словарь с ключами "weight" и "height" ... Должны поддерживаться десятичные значения. Вы можете предположить, что ввод всегда будет действительным (без отрицательных значений, а высота никогда не будет 0).

Выход:

Вывод будет строкой, содержащей имена категорий без учета регистра . Строки должны соответствовать именам категорий точно так же, как указано выше, без учета регистра. Он может быть выведен на стандартный вывод, возвращен (в случае функции) или записан в файл.

Тестовые случаи (вес, рост => результат):

80, 1 =>   "Overweight"
80, 2 =>   "Normal"
80, 3 =>   "Underweight"

50, 1 =>   "Overweight"
50, 1.5 => "Normal"
50, 2 =>   "Underweight"

Edge Cases:

41, 1.5 => "Underweight" (18.2 BMI)
42, 1.5 => "Normal" (18.667 BMI)

56, 1.5 => "Normal" (24.889 BMI)
57, 1.5 => "Overweight" (25.3 BMI)

73, 2 =>   "Underweight" (18.25 BMI)
74, 2 =>   "Normal" (18.5 BMI)

99, 2 =>  "Normal" (24.75 BMI)
100, 2 => "Overweight" (25 BMI)

Вот некоторый псевдокод, который показывает пример реализации:

function bmi_category(weight, height):
    var bmi = (weight / (height**2))

    if (bmi < 18.5):
        return "Underweight"

    if (18.5 <= bmi < 25):
        return "Normal"

    if (25 <= bmi):
        return "Overweight"

Это код-гольф, поэтому выигрывает наименьшее количество байтов.

(Да, эта задача чрезвычайно тривиальна на большинстве языков. Большинство задач в последнее время кажутся сложнее, чем обычно, поэтому я решил опубликовать более доступную).


НОТА! Спустя час после того, как я опубликовал это задание, мне пришлось немного изменить диапазоны, поскольку указанные диапазоны имели «дыры», как указано в комментариях. Пожалуйста, смотрите новые диапазоны.

Ответы:


9

Желе , 24 байта

÷÷⁹Ḥ“%2‘>Sị“$⁽¿“;ṅẒ“&ċ)»

Попробуйте онлайн!

Как?

Вычисляет ИМТ, удваивает его, сравнивает с оператором «больше» с каждым из чисел 37 и 50 (удвоенные 18,5 и 25), суммирует итоговые значения и нули (получая 1, 2 или 0 для нормального, недостаточного веса и избыточного веса). соответственно) и указатели в список строк ["Normal","Underweight","Overweight"].

÷÷⁹Ḥ“%2‘>Sị“$⁽¿“;ṅẒ“&ċ)» - Main link: weight, height
÷                        - weight ÷ height
  ⁹                      - right argument, height
 ÷                       - ÷ by height again to get the BMI
   Ḥ                     - double the BMI
    “%2‘                 - list of code page indexes [37,50]
        >                - greater than? (vectorises) - i.e [18.5>bmi, 25>bmi]
         S               - sum -- both:=2 (Underweight), just 50:=1 (Normal) or neither:=0 (Overweight)
          ị              - index into (1-based)
           “$⁽¿“;ṅẒ“&ċ)» - compressed list of strings ["Normal","Underweight","Overweight"]
                         - implicit print

1
Вау. Поговорим о запутанности. Если это гольф, я думаю, у вас есть дыра в одном! Или 24 ...
Cullub

2
@cullub - это 24 символа и 24 байта - Jelly использует свою собственную кодовую страницу, на которую ссылается слово «bytes» в заголовке, mothereff.in считает Unicode, я считаю.
Джонатан Аллан

1
@TheBitByte, да, посмотри на TIO счетчика ссылок «24 символьных, 24 байт (SBC)» или считать его вручную , используя кодовую страницу , связанную с помощью байт в заголовке.
Джонатан Аллан

... в шестнадцатеричном виде:1C 1C 89 AF FE 25 32 FC 3E 53 D8 FE 24 8D 0B FE 3B F0 BD FE 26 E8 29 FB
Джонатан Аллан


10

TI-Basic, 58 54 байта

Input 
X/Y²→C
"NORMAL
If 2C≤37
"UNDERWEIGHT
If C≥26
"OVERWEIGHT

Кроме того, для забавы, вот более компактная версия, которая больше байтов:

Prompt A,B
sub("UNDERWEIGHTNORMAL      OVERWEIGHT ",sum(A/B²≥{18.5,25})11+1,11

Все, что я могу сказать, это спасибо, что сделали это без учета регистра;)

PS Inputпринимает граф ввода Xи YаналогиченPrompt X,Y


Кроме того, я смотрел на это несколько раз, и я не думаю, что есть какой-либо способ сохранить байты, хотя последние два разделяют строкуERWEIGHT
Timtech

Из любопытства, как бы изменился твой ответ, если бы я применял чувствительность к регистру?
Carcigenicate

1
@Carcigenicate В TI-Basic строчные буквы составляют два байта каждая. Таким образом, это значительно увеличило бы количество байтов.
Timtech

1
Ах я вижу. Это странно.
Carcigenicate

1
@Carcigenicate Важно помнить, что эта версия TI-Basic была введена в 1990 году как язык калькулятора ... никто не знал, что я буду играть в нее 27 лет спустя
Timtech

6

Mathematica, 67 байт

"Normal"["Underweight","Overweight"][[Sign@⌊(2#/#2^2-37)/13⌋]]&

Использует тот факт, что a[b,c][[Sign@d]]возвращает, aесли dравно 0, возвращает, bесли dположительно, и возвращает, cесли dотрицательно. ⌊...⌋является Floorфункцией Mathematica, использующей трехбайтовые символы U + 230A и U + 230B. Не могу понять, как сделать лучше, чем использовать weightдважды.


3
Удивленный Mathematica не имеет встроенного для этого
Даниэль

1
Вы должны пойти к фанфиков для этого;)
Greg Martin

5

Рубин, 91 77 74 67 байт

Первая наивная попытка:

->(w,h){case w/h/h
when 0..18.5
'underweight'
when 18.5..25
'normal'
else
'overweight'
end}

Вторая попытка с «вдохновением» из предыдущих ответов:

->w,h{["#{(w/=h*h)<18.5?'und':'ov'}erweight",'normal'][(18.5..25)===(w)?1:0]}

Третья попытка:

->w,h{["#{(w/=h*h)<18.5?'und':'ov'}erweight",'normal'][w>=18.5&&w<25?1:0]}

Четвертая попытка:

->w,h{18.5<=(w/=h*h)&&w<25?'normal':"#{w<18.5?'und':'ov'}erweight"}

Попробуйте онлайн!


Рейтермаркус из доморощенной бочки ?! Вау, не ожидал увидеть тебя здесь! : o
Numbermaniac

1
@numbermaniac, ха-ха, да, это я! 😂
reitermarkus

5

JavaScript (ES6), 70 67 64 63 байта

Сохранено 4B благодаря Арно

a=>b=>(a/=b*b)<25&a>=18.5?"Normal":(a<19?"Und":"Ov")+"erweight"

использование

f=a=>b=>(a/=b*b)<25&a>=18.5?"Normal":(a<19?"Und":"Ov")+"erweight"
f(80)(1)

Выход

"Overweight"

объяснение

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

Я предположил, что это Normalозначает ИМТ между 25 (исключая) и 18,5 (включительно). Underweightозначает ИМТ менее 18,5 и Overweightозначает ИМТ, больший или равный 25.


1
Теперь ответ не содержит никаких функций ES7 ;-)
ETHproductions



4

QBIC , 61 58 байт

::m=a/b^2~m<18.5|?@Und`+@erweight`\~m>=25|?@Ov`+B\?@Normal

@Luke использовал Силу и отрубил два байта. Благодарность!

Изменения правил сохранены еще один байт.

Объяснение:

::          gets weight and height as a and b
m=a/b^2     Calculates BMI
~m<18.5|    If BMI < 18.5 then
?@Und`      Print the string literal 'Und' (which is now A$)
+@erweight` and the string literal 'erweight'  (which is now B$)
\~m>=25|    else if the BMI is greater than or equal to 25
?@Ov`+B     Print 'Ov' and B$ ('erweight')
\?@Normal   Else, if we're here, BMI is normal.

3

Python 2 , 72 байта

lambda a,b:"UNOnovdreemrrawwlee ii gg hh tt"[(18.6<a/b/b)+(a/b/b>25)::3]

Попробуйте онлайн!


Как вы получаете цвета для Python? Я никогда не понимал это.

@JackBates Это просто, <!-- language-all: lang-python -->что TIO автоматически вставляется для меня.
DJMcMayhem

3

Python 3, 97 95 байт

a,b=map(int,input().split())
a/=b*b*5
print(["UOnvd"[a>93::2]+"erweight","Normal"][93<=a<=125])

Полная программа.

Умножьте на пять, чтобы сохранить байт. Спасибо Джонатан Аллан.

Построчно:

  1. Сопоставьте два разделенных пробелами пользовательских ввода с целыми числами. Распакуйте в a и b.

  2. Рассчитать

  3. Если bmi составляет от 18,6 до 25 включительно, выражение справа будет иметь значение True. Логические значения могут быть 0 или 1 при использовании в качестве индексов списка, поэтому мы получаем либо «Normal», либо составную строку в нулевом индексе. «erweight» - это общий суффикс для оставшихся двух опций, поэтому его не нужно повторять. Затем мы используем шаблон [start: stop: step] списка Python / нарезки строк. c> 18.6 оценивается как 0 или 1 (False или True) и становится нашим началом. Стоп не указан, поэтому мы идем до конца буквального. Шаг 2, поэтому мы берем каждый второй индекс. Если start start имеет значение 1, мы получаем «Ov», в противном случае мы получаем «Und». В любом случае, мы добавляем «erweight» к тому, что мы получили, и у нас есть окончательный результат.


1
Запишите это как функцию для 79:def f(h,w):c=h/w/w;print(["UOnvd"[c>18.6::2]+"erweight","Normal"][18.6<=c<=25])
Джонатан Аллан

Если вы сначала умножите на пять, вы можете сохранить байт, сравнивая с 93и 125. Если вы используете лямбду, вы должны рассчитывать cв обоих местах, но не должны называть функцию или использование print(), так можно сделать lambda h,w:["UOnvd"[h/w/w*5>93::2]+"erweight","Normal"][93<=h/w/w*5<=125]для 73.
Джонатан Аллан

... на самом деле, потому что вы будете вычислять cудвоенное умножение на 5, это будет стоить больше, чем экономит в лямбде, так что всего lambda h,w:["UOnvd"[h/w/w>18.6::2]+"erweight","Normal"][18.6<=h/w/w<=25]за 72
Джонатан Аллан

Джонатан Аллан Кто-то уже сделал это как функцию.
mypetlion

Все в порядке, ваш путь
Джонатан Аллан

3

R, 89 84 80 74 байта

f=pryr::f(c('Overweight','Normal','Underweight')[sum(w/h^2<c(18.5,25),1)])

Кивнув на ответ Октави в StewieGriffin, он создает массив строк, затем суммирует результат BMI < c(18.5,25)и ссылается на массив в этой позиции + 1.

Первым аргументом должен быть рост, затем вес; если это не разрешено, то

f=pryr::f(w,h,c('Overweight','Normal','Underweight')[sum(w/h^2<c(18.5,25),1)])

работает еще на 4 байта.


2

Clojure, 63 байта

#(condp <(/ %(* %2 %2))25"Overweight"18.5"Normal""Underweight")

Черт. Как всегда, это более короткая версия того, о чем я думал.
Carcigenicate

2

постоянный ток , 58 байт

Fk[Ov]?2^/d[[Normal]pq][[Und]26]sasb18.5>a25>bn[erweight]p

Принимает ввод как 2 разделенных пробелом числа в формате <mass> <height>. Выводит строку в отдельной строке.

Попробуйте онлайн!

объяснение

Для целей этого объяснения, ввод 80 1.

Fk                                                         # Set decimal precision to `16`.
  [Ov]                                                     # Push the string "Ov" onto the main stack.
                                                           # Main Stack: [[Ov]]
      ?2^/d                                                # Take and evaluate input, squaring the 2nd one, and the dividing by the first one by the 2nd. Then duplicate the result.
                                                           # Main Stack: [[Ov],80.000000000000000,80.000000000000000]
           [[Normal]pq][[Und]26]sasb                       # Push and store the executable macros "[Normal]pq" and "[Und]26" on registers "a" and "b", respectively.
                                                           # Main Stack: [[Ov],80.000000000000000,80.000000000000000], reg. a: [[[Normal]pq]], reg. b: [[[Und]26]]
                                    18.5>a25>b             # Push, "18.5" onto stack, and then pop top 2 values. If "18.5 > (top of stack)", then execute the macro on top of reg. "a", which in turn pushes the string "Und" onto the main stack followed by the number 26.
                                                           # The "26" will automatically prompt the next comparison to not execute the macro on top of reg. "b", regardless of the value on top of the main stack.
                                                           # Otherwise, if "18.5 <= (top of stack) < 25", then execute "b"s macro, which in turn pushes the string "Normal" onto the main stack, outputs it, then quits the program.
                                                           # In this case, Main stack: [[Ov]], reg. a: [[[Normal]pq]], reg. b: [[[Und]26]]
                                              n[erweight]p # If "Normal" has not been output, only then will the program get to this point. Here, it will output whatever string, either "Und" or "Ov", on top of the main stack, followed by "erweight" and a new line.

2

Октава, 64 байта

@(w,h){'Underweight','Normal','Overweight'}{3-sum(2*w/h^2<'%2')}

Попробуйте онлайн

Это анонимная функция, которая принимает два входных аргумента h(высота) иw (вес).

Функция создает массив ячеек, содержащий там строки 'Underweight','Normal','Overweight', и выводит номер строки 3-sum(2*w/h^2<'%2').

Да, это выглядит немного странно. Нам нужна первая строка if w/h^2<=18.5, вторая строка if (w/h^2 > 18.5) & (w/h^2 < 25)и третья строка, если ни одно из указанных выше условий не выполняется. Вместо создания группы сравнений, мы могли бы просто сравнить строку с:, w/h^2 < [18.5, 25]которая вернула бы один из следующих массивов [1 1], [0 1], [0,0]для Underweight, Normal и Overweight соответственно.

[18.5,25]занимает 9 байтов, что много. Вместо этого мы умножаем ИМТ на 2 и сравниваем результат с [37, 50]или '%2'в ASCII. Это экономит три байта.


2

Perl 6 , 59 байт

{<Overweight Normal Underweight>[sum 18.5,25 X>$^a/$^b**2]}

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

{                                                         }  # A lambda.
                                               $^a/$^b**2    # Compute BMI from arguments.
                                     18.5,25 X>              # Compare against endpoints.
                                 sum                         # Add the two booleans together.
 <Overweight Normal Underweight>[                        ]   # Index into hard-coded list.

Жаль, что строка erweight должна повторяться, но все варианты, которые я пробовал, чтобы избежать этого, привели к увеличению общего числа байтов:

  • С подстановкой строки, 62 байта:

    {<Ov_ Normal Und_>[sum 18.5,25 X>$^a/$^b**2].&{S/_/erweight/}}
  • С интерполяцией строки, 67 байтов:

    {$_='erweight';("Ov$_","Normal","Und$_")[sum 18.5,25 X>$^a/$^b**2]}
  • Примерный перевод решения xnor's Python , 65 байт:

    {$_=$^a/$^b**2;25>$_>=18.5??"Normal"!!<Und Ov>[$_>19]~"erweight"}

2

PowerShell , 81 байт

param($m,$h)('Underweight','Normal','Overweight')[(18.5,25-lt($m/($h*$h))).Count]

Попробуйте онлайн!

объяснение

Основной бит, который нуждается в объяснении, - это 18.5,25 -lt $b(где я заменяю $bИМТ, который вычисляется на месте в коде). Большинство операторов в PowerShell при задании массива с левой стороны возвращают массив элементов, которые удовлетворяют критерию, вместо того, чтобы возвращать логическое значение. Так что это вернет пустой массив, если$b он меньше 18,5, массив, содержащий только 18,5, если он посередине, и массив, содержащий как 18,5, так и 25, если он больше 25.

Я использую количество элементов в качестве индекса в массиве строк, поэтому count 0получает элемент, 0который 'Underweight'и т. Д.



2

Python, 75 74 байта

lambda h,w:18.5<=w/h/h<=25and"normal"or["ov","und"][25>w/h/h]+"erwe‌​ight"

Попробуйте онлайн!

Довольно базовое решение, которое использует методы других людей для его решения.

Спасибо @ovs за сохранение байта.

альтернативы

1. 73 байта

lambda h,w:"normal"if 18.5<=w/h/h<=25 else"uonvd"[25<w/h/h::2]+"erweight"

Я отклонил это, поскольку это было слишком похоже на другой ответ, который я видел.

2. 71 байт

lambda h,w:"normal"if 18.5<w/h/h<25 else"uonvd"[25<w/h/h::2]+"erweight"

Я отклонил это, потому что, несмотря на работу над всеми тестами в вопросе, есть некоторые цифры, на которых он может потерпеть неудачу, поскольку он пропускает =в <=.


Вам не нужно пространство между 25и else- но в любом случае использование короткого замыкания and/or(как прокомментировал @ovs) короче.
FlipTack

@FlipTack: относительно пространства между 25и else, вы , безусловно , сделать это нужно, с некоторыми (большинство?) Переводчиков ( в том числе CPython, IIRC). Если вы пишете это как 25else, то 25eинтерпретируется как начало числового литерала научной нотации, и интерпретатор тогда скрывается, когда нет следующих цифр.
Mac

2

C #, 63 62 61 байт

Сохранено еще 1 байт благодаря TheLethalCoder .

Сохранено 1 байт благодаря анонимному пользователю.

w=>h=>w/h/h<18.5?"Underweight":w/h/h<25?"Normal":"Overweight";

Довольно простая анонимная функция. Весь трюк использует троичный оператор для прямого возврата (таким образом, опуская returnключевое слово, пару фигурных скобок и объявление и присваивание переменной).

Полная программа с тестовыми примерами:

using System;

class BodyMassIndex
{
    static void Main()
    {
        Func<double, Func<double, string>> f =
        w=>h=>w/h/h<18.5?"Underweight":w/h/h<25?"Normal":"Overweight";

        // test cases:
        Console.WriteLine(f(80)(1));  // "Overweight"
        Console.WriteLine(f(80)(2));  // "Normal"
        Console.WriteLine(f(80)(3));  // "Underweight"
        Console.WriteLine(f(50)(1));  // "Overweight"
        Console.WriteLine(f(50)(1.5));  // "Normal"
        Console.WriteLine(f(50)(2));  // "Underweight"
    }
}

2

Common Lisp, 89 87 85 84 83 байта

Функция:

(lambda(w h)(if(< #1=(/ w(* h h))18.5)'underweight(if(< #1#25)'normal'overweight)))

Пример использования:

((lambda(w h)(if(< #1=(/ w(* h h))18.5)'underweight(if(< #1#25)'normal'overweight)))150 2)

Попробуйте онлайн! (Я добавил функцию печати, чтобы увидеть вывод в TIO)

Идеи по улучшению приветствуются.


2

MATL, 54 45 44 42 байта

U/E'%2'<sqt?q?'ov'}'und']'erweight'h}x17Y0

Попробуйте это на matl.suever.net

Начинается с вычисления ИМТ и его удвоения U\E, затем создается вектор [37 50]со строковым литералом "% 2". Сравнивает ИМТ с этим вектором и использует операторы if, чтобы получить ответ, используя normalв качестве предопределенного литерала 17Y0.


Вы можете заменить [BC]UQс '%2'и сохранить 2 байта.
sundar - Восстановить Монику

1

Java 8, 61 байт

w->h->w/h/h<18.5?"Underweight":w/h/h<25?"Normal":"Overweight"

Назначьте DoubleFunction<DoubleFunction<String>>и вызовите таким образом:

bmi.apply(50).apply(1.5)

Вы можете сэкономить один байт за счет многократного использования w: w->h->(w/=h*h)<18.5?"Underweight":w<25?"Normal":"Overweight".
Оливье Грегуар

@ OlivierGrégoire Нету :( Error: local variables referenced from a lambda expression must be final or effectively finalНе могу назначить на w.
Дэвид Конрад

1
Ох ... Я проверил с помощью встроенных вещей, таких как int w = ... , h = ... ; System.out.println((w/=h*h)<18.5?"Underweight":w<25?"Normal":"Overweight"), извините :)
Оливье Грегуар

@ OlivierGrégoire Нет проблем. Я хотел бы, чтобы Java позволил это.
Дэвид Конрад

1

Округ Колумбия , 64 байта

[erweight][[Und]PszPq]su[[Normal]Pq]sn9k?d*/d18.5>ud25>n[Ov]PszP

Попробуйте онлайн!


Черт возьми! Просто избей меня на несколько секунд. Я собирался опубликовать свой, пока я не увидел это. В любом случае, вот еще 64 байт ответа: 3k[Overweight]??2^/dsp[[Normal]][[Underweight]]sasb25>blp18.5>ap.
Р. Кап

@ R.Kap На самом деле вы можете получить свой на один байт короче моего, если опустить один из вопросительных знаков.
Митчелл Спектор

О да, я забыл, что могу это сделать. Вы можете опубликовать это как свой собственный, если хотите.
Р. Кап

Нет, все в порядке - иди и отправь это сам, это твое решение. (Вы можете указать мне один байт, если хотите.)
Митчелл Спектор

Кстати, мне удалось уменьшить его до 58 байт. :)
Р. Кап

1

Javascript (ES6), 63 байта

(m,h)=>(w="erweight",b=m/h/h)<18.5?"Und"+w:b<25?"Normal":"Ov"+w

пример

f=(m,h)=>(w="erweight",b=m/h/h)<18.5?"Und"+w:b<25?"Normal":"Ov"+w

console.log(f(80, 1));
console.log(f(80, 2));
console.log(f(80, 3));


1

Swift, 97 байт

{(w:Float,h)->String in return 18.5<=w/h/h&&w/h/h<25 ?"normal":"\(w/h/h>25 ?"ov":"und")erweight"}

1

Japt , 46 байт

/=V²U<25©U¨18½?`NŽµl`:ºU<19?`U˜`:"Ov")+`€³ight

Попробуйте онлайн!

Вдохновленный @ Люка ответом .

объяснение

/=V²U<25©U¨18½?`NŽµl`:ºU<19?`U˜`:"Ov")+`€³ight  

Распаковывает в:

U=U/V**2,U<25&&U>18.5?"Normal":(U<19?"Und":"Ov")+"erweight"

Джапт имеет скрытый вклад U. Второй вход есть V.

Japt использует библиотеку shoco для сжатия строк. Обратные галочки используются для распаковки строк.

Используемые ярлыки Unicode:

² : **2
© : &&
¨ : >=
½ : .5
º : ((


1

Скала, 124 байта

val x="erweight"
def b(i:Float,a:Float):Any=i/a/a match{case z if(z<18.5)=>"Und"+x
case z if(z<25)=>"Normal"
case z=>"Ov"+x}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.