我的体重指数是多少?


21

问题:

您的任务是编写一个程序,该程序将身高(米)和体重(公斤)作为输入,并输出相应的BMI类别。

BMI是您的体重与身高之比的量度。对于许多人来说它已过时且不准确,但这并不重要!

BMI可以使用以下公式计算:

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

类别将定义如下:

  • BMI <18.5:“体重不足”

  • 18.5 <= BMI <25:“正常”

  • 25 <= BMI:“超重”

为了挑战,我忽略了所有“极端”类别。另外,由于某些数字(例如“ 25”)位于2个类别之间,因此我略微调整了界限,因此有明确的答案。

您可以编写函数或完整程序。

输入:

输入可以采用任何合理的形式。两个数字(或字符串),可以是2个单独的参数,也可以是一个字符串。包含2个数字的数组/列表,带有“ weight”和“ height”键的字典...应该支持十进制值。您可以假设输入将始终有效(没有负值,并且高度永远不会为0)。

输出:

输出将是一个字符串,其中包含不区分大小写的类别名称。字符串必须与上面的类别名称完全匹配,忽略大小写。可以将其输出到stdout,返回(对于函数)或写入文件。

测试用例(体重,身高=>结果):

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"

这是代码高尔夫球,因此获胜的字节数最少。

(是的,在大多数语言中,这项任务极其琐碎。最近的大多数挑战似乎比平时要难,因此我认为我会发布一个更易于访问的挑战)。


注意!发布此挑战后一个小时,由于注释中指出的范围存在“漏洞”,因此我不得不稍作修改范围。请查看新范围。

Answers:


9

果冻,24 字节

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

在线尝试!

怎么样?

计算BMI,将其加倍,将其与大于运算符进行比较,将数字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使用它自己的代码页,该页由标题中的“字节”一词链接,mothereff.in正在计算Unicode。
乔纳森·艾伦

1
@TheBitByte,是的,请看一下TIO链接计数器“ 24个字符,24个字节(SBCS)”,或使用标题中与字节链接的代码页手动对其进行计数。
乔纳森·艾伦,

...作为十六进制:1C 1C 89 AF FE 25 32 FC 3E 53 D8 FE 24 8D 0B FE 3B F0 BD FE 26 E8 29 FB
乔纳森·艾伦

21

Python,69个字节

lambda w,h:["UOnvd"[w/h/h>20::2]+"erweight","Normal"][18.5<=w/h/h<25]

在线尝试!

比较72个字节:

lambda w,h:"Underweight"*(w/h/h<18.5)or"Normal"*(w/h/h<25)or"Overweight"

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将图输入到XY类似于Prompt X,Y


另外,我已经看过多次了,即使最后两个共享字符串,我也不认为有任何方法可以保存字节ERWEIGHT
Timtech '17

出于好奇,如果我强制区分大小写,它将如何改变您的答案?
Carcigenicate'2

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是负的。⌊...⌋是Mathematica的Floor函数,使用三字节字符U + 230A和U + 230B。想不出要比weight两次使用更好的方法。


3
惊讶的Mathematica没有内置的功能
Daniel

1
您必须为此而去歌迷小说;)
Greg Martin

5

Ruby,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"}

在线尝试!


来自自制酒桶的reitermarkus?哇,没想到在这里见到你!:o
numbermaniac

1
@numbermaniac,哈哈,是的,是我!😂
reitermarkus

5

JavaScript(ES6),70 67 64 63字节

感谢Arnauld,节省了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"

说明

这个答案是很琐碎,但有一个巧招:UnderweightOverweight在两端erweight,所以我们只需要改变这些字符。

我认为这Normal意味着BMI在25(不含)和18.5(含)之间。Underweight表示BMI小于18.5,并且Overweight表示BMI大于或等于25。


1
现在答案不包含任何ES7功能;-)
ETHproductions's

4

C,81字节

f(float m,float h){m/=h*h;puts(m<26?m<18.6?"Underweight":"Normal":"Overweight");}


4

QBIC61 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. 将两个用空格分隔的用户输入数字映射为int。打开包装到a和b。

  2. 计算

  3. 如果bmi在18.6到25(含)之间,则右侧的表达式将计算为True。当用作列表索引时,布尔值可以为0或1,因此我们可以在零索引中获得“ Normal”或构造的字符串。“ erweight”是其余两个选项的共享后缀,因此不需要重复。然后,我们使用Python列表/字符串切片的[start:stop:step]模式。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])
Jonathan Allan

如果先乘以五,则可以通过比较93和来保存一个字节125。如果您使用lambda你必须计算c在这两个地方,但并不需要命名的功能或用途print(),所以可以做lambda h,w:["UOnvd"[h/w/w*5>93::2]+"erweight","Normal"][93<=h/w/w*5<=125]的73
乔纳森·艾伦

...实际上是因为您将要计算c乘以5的两倍的成本,而不是在lambda中节省的成本,所以lambda h,w:["UOnvd"[h/w/w>18.6::2]+"erweight","Normal"][18.6<=h/w/w<=25]对于72
Jonathan Allan

乔纳森·艾伦(Jonathan Allan)有人已经将其作为功能来完成。
mypetlion

没关系,您的出路将使他们
乔纳森·艾伦

3

R,89 84 80 74字节

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

向StewieGriffin的Octave答案致意,创建了一个字符串数组,然后求和结果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

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')

是的,那看起来有些奇怪。如果上述条件都不成立w/h^2<=18.5,我们需要第一个字符串if ,第二个字符串if (w/h^2 > 18.5) & (w/h^2 < 25)和第三个字符串。无需创建一堆比较,我们可以简单地将字符串与:进行比较w/h^2 < [18.5, 25],这将分别返回以下数组[1 1], [0 1], [0,0]之一,分别代表欠权,正常和超重。

[18.5,25]需要9个字节,这很多。我们要做的是将BMI乘以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的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(我用$bBMI 代替,它是在代码中适当计算的)。在PowerShell中,大多数运算符在左侧有一个数组时,会返回一个满足测试条件的项目数组,而不是返回布尔值。所以这将返回一个空数组,如果$b小于18.5,位于中间,则将仅包含18.5;如果大于25,则将同时包含18.5和25的数组。

我将元素的计数用作字符串数组的索引,因此count 0获得的元素0'Underweight',等等。


2

OCaml,93个字节

let b w h=if w/.h/.h<18.5 then"underweight"else if w/.h/.h>=25.0 then"overweight"else"normal"

不,这是一个功能。
reitermarkus

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:关于之间的空间25else,你肯定需要它的一些(大多数?)口译(包括CPython的,IIRC)。如果将其写为25else,则将25e解释为科学计数数字文字的开头,然后当没有后续数字时,解释器将提示输入。
Mac

2

C#,63 62 61字节

多亏了TheLethalCoder,节省了1个字节。

感谢匿名用户,节省了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上尝试

首先通过计算BMI并将其加倍U\E,然后创建[37 50]带有字符串文字'%2' 的向量。将BMI与该向量进行比较,并使用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)

您可以通过重复使用备用一个字节ww->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égoire17年

@OlivierGrégoire没问题。我希望Java允许它。
大卫·康拉德

1

dc,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

@ R.Kap通过省略问号之一,实际上可以使您的地址比我的地址短一个字节。
米切尔·史派克

哦,是的,我忘记了我可以做到。如果需要,可以将其发布为自己的。
卡普

不,没关系-继续自己发布,这是您的解决方案。(如果需要,可以给我一个字节的信用。)
Mitchell Spector

顺便说一句,我能够将其减少到58个字节。:)
R. Kap

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

在线尝试!

灵感来自@ Luke's 答案的

说明

/=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"

Japt具有隐式输入 U。第二个输入是V

Japt使用 shoco库进行字符串压缩。反引号用于解压缩字符串。

使用的Unicode快捷方式:

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

1

PHP,121字节

function f($a,$b){$i=$a/($b*$b);$x = 18.5;print ($i<$x?"Underweight":($i>=$x&&$i<25?"Normal":($i>=25?"Overweight":"")));}

在线尝试!


1

Scala,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}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.