私のボディマス指数は何ですか?


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つの数値(または文字列)。2つの数字の配列/リスト、「weight」および「height」キーのある辞書... 10進数の値がサポートされる必要があります。入力は常に有効であると仮定できます(負の値はなく、高さは決して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"

これはコードゴルフなので、バイト数が最も少なくなります。

(はい、このタスクはほとんどの言語で非常に簡単です。最近の課題のほとんどは通常よりも難しいようですので、よりアクセスしやすいものを投稿したいと思いました)。


注意!このチャレンジを投稿してから1時間後、コメントで指摘されている範囲に「穴」があったため、範囲をわずかに変更する必要がありました。新しい範囲をご覧ください。

回答:


9

ゼリー、24 バイト

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

オンラインでお試しください!

どうやって?

BMIを計算し、それを2倍し、37と50の各数値(18.5と25を2倍にした)より大きい演算子と比較し、結果の1と0を合計します(標準、低体重、および過体重に対して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はユニコードをカウントしています。
ジョナサンアラン

1
@TheBitByte、はい、TIOリンクカウンター「24文字、24バイト(SBCS)」を調べるか、見出しのバイトでリンクされたコードページを使用して手動でカウントします
ジョナサンアラン

... hexとして: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グラフに入力取りXYに類似しPrompt X,Y


また、私は、この複数回見てきた、と私も最後の二つのシェアかかわらず、文字列のバイトを保存するにはどのような方法がありますとは思わないERWEIGHT
Timtech

好奇心から、大文字と小文字の区別を強制した場合、どのように答えが変わりましたか?
発癌性

1
@Carcigenicate TI-Basicでは、小文字はそれぞれ2バイトです。したがって、バイトカウントが大幅に増加します。
ティムテック

1
ああ、なるほど。それは変です。
発癌性

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、3バイト文字U + 230AおよびU + 230Bを使用するMathematicaの関数です。weight2回使用するよりもうまくやる方法がわかりませんでした。


3
驚いたMathematicaにはこのための組み込み機能がありません
ダニエル

1
あなたはそのためのファンフィクションに行かなければなりません;)
グレッグ・マーティン

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]}

3回目の試行:

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

4回目の試行:

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

オンラインでお試しください!


homebrew-caskの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"

説明

この答えは非常に簡単ですが、巧妙なトリックが1つUnderweightあります。Overweight両方ともで終わるerweightため、これらの文字を変更するだけです。

これは、Normal25(排他的)から18.5(包括的)までのBMI を意味すると想定しました。Underweightは18.5未満のBMIをOverweight意味し、25以上のBMI を意味します。


1
現在、答えにはES7機能が含まれていません
;



4

QBIC61 58バイト

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

@LukeはForceを使用し、2バイトを切り取りました。ありがとう!

ルールの変更により、もう1バイト節約されました。

説明:

::          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 3、97 95バイト

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

完全なプログラム。

5倍してバイトを保存します。ジョナサン・アランに感謝します。

1行ずつ:

  1. スペースで区切られた2つのユーザー入力番号をintにマッピングします。aとbに開梱します。

  2. 計算する

  3. bmiが18.6〜25(両端を含む)の場合、右側の式はTrueと評価されます。リストインデックスとして使用する場合、ブール値は0または1になる可能性があるため、ゼロインデックスで「標準」または構築された文字列を取得します。「erweight」は、残りの2つのオプションの共有サフィックスであるため、繰り返す必要はありません。次に、Pythonリスト/文字列スライスの[start:stop:step]パターンを使用します。c> 18.6は0または1(FalseまたはTrue)に評価され、開始点になります。停止は示されていないため、リテラルの最後に移動します。ステップは2なので、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])
ジョナサンアラン

最初に5を掛けると、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倍のコストで2倍の乗算を計算するため、ちょうどlambda h,w:["UOnvd"[h/w/w>18.6::2]+"erweight","Normal"][18.6<=h/w/w<=25]72
ジョナサンアラン

ジョナサン・アラン誰かがすでにそれを単なる機能としてやっていた。
mypetlion

D:のはOK、あなたの方法は、アウトゴルフそれらなること
ジョナサン・アラン

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

くそー。いつものように、これは私が考えていたものの短縮版です。
発がん性

2

dc、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')}

オンラインで試す

これは、2つの入力引数h(高さ)とw(weight)を。

関数はそこに文字列を含むセル配列を作成し、'Underweight','Normal','Overweight'文字列番号を出力します3-sum(2*w/h^2<'%2')

はい、それは少し奇妙に見えます。最初の文字列if w/h^2<=18.5、2番目の文字列if (w/h^2 > 18.5) & (w/h^2 < 25)、および上記の条件のいずれにも当てはまらない場合の3番目の文字列が必要です。一連の比較を作成する代わりに、文字列を単純に比較することができます。w/h^2 < [18.5, 25]これは[1 1], [0 1], [0,0]、それぞれ、Underweight、Normal、Overweightの次の配列のいずれかを返します。

[18.5,25]9バイトかかります。代わりに、BMIに2を掛けて、結果を[37, 50]、または'%2'ASCII で比較します。これにより、3バイト節約されます。


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$bコード内の所定の場所で計算されるBMIを代用している)です。PowerShellのほとんどの演算子は、左側に配列を指定すると、ブール値を返す代わりに、テストを満たすアイテムの配列を返します。したがって、これは$b、18.5より小さい場合は空の配列を返し、中央にある場合は18.5のみを含む配列を返し、25より大きい場合は18.5と25の両方を含む配列を返します。

カウントがので、私は、文字列の配列へのインデックスとしての要素の数を使用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:間のスペースについて25else、あなたは間違いない(IIRC CPythonと、を含む)いくつかの(ほとんど?)の通訳でそれを必要とします。として記述した場合25else25eは科学表記法の数値リテラルの開始として解釈され、その後、次の数字がない場合にインタープリターはbaきます。
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、それを2倍にすることから始めて、[37 50]文字列リテラル '%2'でベクトルを作成します。BMIをこのベクトルと比較し、ifステートメントを使用して答えを取得します。normal事前定義されたリテラルとして利用し17Y0ます。


2バイトに置き換え[BC]UQ'%2'保存できます。
スンダ

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)

再利用することで1バイトを節約できます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缶ワットに割り当てない。
デヴィッド・コンラッド

1
ああ...のようなインラインのもので確認しましたint w = ... , h = ... ; System.out.println((w/=h*h)<18.5?"Underweight":w<25?"Normal":"Overweight")、ごめんなさい:)
オリビエグレゴワール

@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.ガプス

@ R.Kap実際には、疑問符の1つを省略することで、自分よりも1バイト短くすることができます。
ミッチェルスペクター

そうそう、私はそれができることを忘れていました。必要に応じて自分で投稿できます。
R.ガプス

いいえ、それは結構です-先に進んで自分で投稿してください、それがあなたのソリューションです。(必要に応じて、1バイトをクレジットできます。)
ミッチェルスペクター

ちなみに、私はそれを58バイトまで減らすことができました。:)
R.キャップ

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

Japt、46バイト

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

オンラインでお試しください!

@Lukeの回答に触発されました。

説明

/=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。2番目の入力はVです。

Japtは、文字列の圧縮にshocoライブラリを使用します。バックティックは、文字列を圧縮解除するために使用されます。

使用されるUnicodeショートカット:

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


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}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.