Store the associated labels in "k": k=['Underweight','Normal','Overweight']
Find the first BMI step which is greater than the provided BMI: t.find(v=>w/(h^2)<=v). For example, it will return 25 if the processed BMI is between 18.5 and 25.
Find the associated array index: t.indexOf(...), in order to get the same element in the label array: k[...]. For example, if 25 is returned, it will fetch k[1], hence "Normal"
Finally, if no label is found (hence, if the BMI is greater than 30), return "Obese"
That is an interested method, but come back at your code in a few months with absolutely no explanation and I do think that it is not going to be that easy.
I think that a code should be self explanatory (especially to newcomers on your codebase) and, even if this one is a tour-de-force in terms of one-liner, it is not self explanatory. 😉
That is why, I would find that a switch case method would be better.
I completely agree with you on this one! (Hi fellow french dev!) I tend to try to golf a lot in these challenges, even though I completely agree on the fact that it's as ugly as it can be. That way, I can discover new principles (like the reduce method, that I hated a few months back even if it is really useful) that I can later use on my projects or at work.
Indeed, this challenge was clearly made for a switch/case solution, but as I had some free time I though I could try something different haha
Might propose a change? Instead of underweight, overweight, obsese, etc, how about we replace the return values with "no idea, consult a health professional and have your body composition correctly measured"? It will be significantly more accurate! :D
(w, h) => `A BMI of ${w/h**2}, means nothing. For an accurate representation of body mass measure water displacement in a big bath tub! To determine how healthy you are, consult a healthcare professional, do see how trip you are have your body composition measured, and to see how fit you are visit any good gym and undertake a fitness test in the area you wish to evaluate.`
19 yo student *and* a full-time developer.
Building with Rails currently, exploring new frontiers.
I enjoy functional programming, Linux, FOSS, refactoring and mentoring :)
Coding since 11yo, that makes it over 30 years now ~~~
Have a PhD in Comp Sci ~~~
Love to go on bike tours ~~~
I try to stay as generalist as I can in this crazy wide place coding is at now.
Let's say you need to run this a few billion times times, then a more complex look up table approach might be worth it.
functionindexFromBmi(bmi){// turn the BMI into an ranged integer still giving with enough precision and reach for our labelsreturnMath.max(0,Math.ceil((Math.min(30.5,bmi)-18.5)/0.5));}constbmi_lut=[]bmi_lut[indexFromBmi(18.5)]='Underweight';bmi_lut[indexFromBmi(25)]='Normal';bmi_lut[indexFromBmi(30)]='Overweight';bmi_lut[indexFromBmi(30.5)]='Obese';// fill in the entries below each label, so that, for example, the entry for bmi 27 will be "Overweight"for(letindex=bmi_lut.length-1,label;index>=0;index--){if(bmi_lut[index])label=bmi_lut[index];elsebmi_lut[index]=label;}functionbmiLabel(weight,height){returnbmi_lut[indexFromBmi(weight/height**2)];}
>bmiLabel(-100000000,1)<"Underweight">bmiLabel(18.5,1)<"Underweight">bmiLabel(18.5001,1)<"Normal">bmiLabel(25,1)<"Normal">bmiLabel(25.0001,1)<"Overweight">bmiLabel(30,1)<"Overweight">bmiLabel(30.001,1)<"Obese">bmiLabel(10000000000,1)<"Obese"// Test the weight/height relationship>bmiLabel(25*1e20**2,1e20)<"Normal"// Try some heavy lifting>for(leti=1e9;i;i--)bmiLabel(18.5,1);<//took 23 seconds for a billion bmis in the js console just now (oldish mac pro)
(in JS because I like it, and I find it can be nice to mock up performance code in a slowish language first up.)
Coding since 11yo, that makes it over 30 years now ~~~
Have a PhD in Comp Sci ~~~
Love to go on bike tours ~~~
I try to stay as generalist as I can in this crazy wide place coding is at now.
Fair point Craig, in this case it turns out to be a bunch slower due to the complexity in indexFromBmi.
I just figured it was worth posting as an alternative approach as there are problems where luts are gold. In this case apparently not.
I did two functions, one that expects imperial units (Go America!) and one that expects metric units (the rest of the world!).
body.go
packagebodyconst(underweightstring="Underweight"normalstring="Normal"overweightstring="Overweight"obesestring="Obese")// Attributes represents some properties of a person's physique, such as weight and heighttypeAttributesstruct{Heightfloat64Weightfloat64}// BMI gives a description of your body health based on your attributes using body mass indexfuncBMI(attrAttributes)string{returnstatus((attr.Weight/(attr.Height*attr.Height))*703)}// BMIMetric serves the same purpose as BMI but expects the attributes to be in the metric scale (kilograms, meters)funcBMIMetric(attrAttributes)string{returnstatus(attr.Weight/(attr.Height*attr.Height))}funcstatus(bmifloat64)string{switch{casebmi<=18.5:returnunderweightcasebmi<=25.0:returnnormalcasebmi<=30.0:returnoverweightdefault:returnobese}}
Well, I tried something different:
Apart from being ugly, it works like this:
t=[18.5,25,30]k=['Underweight','Normal','Overweight']t.find(v=>w/(h^2)<=v). For example, it will return25if the processed BMI is between 18.5 and 25.t.indexOf(...), in order to get the same element in the label array:k[...]. For example, if25is returned, it will fetchk[1], hence"Normal""Obese"That is an interested method, but come back at your code in a few months with absolutely no explanation and I do think that it is not going to be that easy.
I think that a code should be self explanatory (especially to newcomers on your codebase) and, even if this one is a tour-de-force in terms of one-liner, it is not self explanatory. 😉
That is why, I would find that a switch case method would be better.
I completely agree with you on this one! (Hi fellow french dev!) I tend to try to golf a lot in these challenges, even though I completely agree on the fact that it's as ugly as it can be. That way, I can discover new principles (like the
reducemethod, that I hated a few months back even if it is really useful) that I can later use on my projects or at work.Indeed, this challenge was clearly made for a switch/case solution, but as I had some free time I though I could try something different haha
I like it!
LabVIEW: ;)
Awesome, haven't seen LabVIEW since I was at uni.
Haskell
I couldn't resist posting a quick JavaScript solution... 😀
Might propose a change? Instead of underweight, overweight, obsese, etc, how about we replace the return values with "no idea, consult a health professional and have your body composition correctly measured"? It will be significantly more accurate! :D
Something like:
I concur with this response.
This seems to do the job
C++:
Rust:
Let's say you need to run this a few billion times times, then a more complex look up table approach might be worth it.
(in JS because I like it, and I find it can be nice to mock up performance code in a slowish language first up.)
Have you tested if your code is faster than a simpler conditional version (as most other solutions are written)?
Fair point Craig, in this case it turns out to be a bunch slower due to the complexity in
indexFromBmi.I just figured it was worth posting as an alternative approach as there are problems where luts are gold. In this case apparently not.
I'd say that here it's best to just use
and be done with it.
A solution in gwion
Scala:
I did two functions, one that expects imperial units (Go America!) and one that expects metric units (the rest of the world!).
body.go
body_test.go
[gist.github.com/devparkk/9117b0780...]