13
\$\begingroup\$

Background

The metallic means, starting with the famous golden mean, are defined for every natural number (positive integer), and each one is an irrational constant (it has an infinite non-recurring decimal expansion).

For a natural number , the metallic mean is the root of a quadratic equation

The roots are always

but the metallic mean is usually given as the positive root. So for this question it will be defined by:

For the result is the famous golden ratio:


Challenge

Your code should take 2 inputs: n and p (the order is not important as long as it is consistent)

  • n is a natural number indicating which metallic mean
  • p is a natural number indicating how many decimal places of precision

Your code should output the nth metallic mean to p decimal places precision.

Validity

Your code is valid if it works for values of n and p from 1 to 65,535.

You must output a decimal in the form

digit(s).digit(s) (without spaces)

For example, the golden mean to 9 decimal places is

1.618033988

Display the last digit without rounding, as it would appear in a longer decimal expansion. The next digit in the golden mean is a 7, but the final 8 in the example should not be rounded up to a 9.

The number of decimal digits must be p, which means any trailing zeroes must also be included.

Answers of the form

are not valid - you must use a decimal expansion.

You may output up to 1 leading newline and up to 1 trailing newline. You may not output any spaces, or any other characters besides digits and the single point/full stop/period.

Score

This is standard code golf: your score is the number of bytes in your code.


Leaderboard

(Using Martin's leaderboard snippet)

var QUESTION_ID=52493;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),e.has_more?getAnswers():process()}})}function shouldHaveHeading(e){var a=!1,r=e.body_markdown.split("\n");try{a|=/^#/.test(e.body_markdown),a|=["-","="].indexOf(r[1][0])>-1,a&=LANGUAGE_REG.test(e.body_markdown)}catch(n){}return a}function shouldHaveScore(e){var a=!1;try{a|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(r){}return a}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading),answers.sort(function(e,a){var r=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0],n=+(a.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0];return r-n});var e={},a=1,r=null,n=1;answers.forEach(function(s){var t=s.body_markdown.split("\n")[0],o=jQuery("#answer-template").html(),l=(t.match(NUMBER_REG)[0],(t.match(SIZE_REG)||[0])[0]),c=t.match(LANGUAGE_REG)[1],i=getAuthorName(s);l!=r&&(n=a),r=l,++a,o=o.replace("{{PLACE}}",n+".").replace("{{NAME}}",i).replace("{{LANGUAGE}}",c).replace("{{SIZE}}",l).replace("{{LINK}}",s.share_link),o=jQuery(o),jQuery("#answers").append(o),e[c]=e[c]||{lang:c,user:i,size:l,link:s.share_link}});var s=[];for(var t in e)e.hasOwnProperty(t)&&s.push(e[t]);s.sort(function(e,a){return e.lang>a.lang?1:e.lang<a.lang?-1:0});for(var o=0;o<s.length;++o){var l=jQuery("#language-template").html(),t=s[o];l=l.replace("{{LANGUAGE}}",t.lang).replace("{{NAME}}",t.user).replace("{{SIZE}}",t.size).replace("{{LINK}}",t.link),l=jQuery(l),jQuery("#languages").append(l)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\d&]*)*$)/,NUMBER_REG=/\d+/,LANGUAGE_REG=/^#*\s*([^,]+)/;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table></div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table></div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table><table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table>

\$\endgroup\$
17
\$\begingroup\$

dc, 12

?kdd*4+v+2/p
  • ? Push n and p onto the stack
  • k set precision to p
  • dd duplicate n twice (total three copies)
  • * multiply n*n
  • 4+ add 4
  • v take square root
  • + add n (last copy on stack)
  • 2/ divide by 2
  • p print

Testcase:

$ dc -f metalmean.dc <<< "1 9"
1.618033988
$
\$\endgroup\$
  • 7
    \$\begingroup\$ Right tool for the job. \$\endgroup\$ – Dennis Jul 2 '15 at 3:06
  • 5
    \$\begingroup\$ @Dennis its got to be the first time CJam is nearly 3 times as long as something else ;-) \$\endgroup\$ – Digital Trauma Jul 2 '15 at 3:20
2
\$\begingroup\$

R, 116 bytes

library(Rmpfr);s=scan();n=mpfr(s[1],1e6);r=(n+(4+n^2)^.5)/2;t=toString(format(r,s[2]+2));cat(substr(t,1,nchar(t)-1))

This reads two integers from STDIN and prints the result to STDOUT. You can try it online.

Ungolfed + explanation:

# Import the Rmpfr library for arbitrary precision floating point arithmetic
library(Rmpfr)

# Read two integers from STDIN
s <- scan()

# Set n equal to the first input as an mpfr object with 1e6 bits of precision
n <- mpfr(s[1], 1e6)

# Compute the result using the basic formula
r <- (n + sqrt(4 + n^2)) / 2

# Get the rounded string representation of r with 1 more digit than necessary
t <- toString(format(r, s[2] + 2))

# Print the result with p unrounded digits
cat(substr(t, 1, nchar(t) - 1))

If you don't have the Rmpfr library installed, you can install.packages("Rmpfr") and all of your dreams will come true.

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 50 bytes

SetAccuracy[Floor[(#+Sqrt[4+#^2])/2,10^-#2],#2+1]&

Defines an anonymous function that takes n and p in order. I use Floor to prevent rounding with SetAccuracy, which I need in order to get decimal output.

\$\endgroup\$
  • \$\begingroup\$ @Arcinde I can't use machine precision numbers unfortunately, since they wouldn't be able to handle p>15. \$\endgroup\$ – 2012rcampion Jul 2 '15 at 13:43
1
\$\begingroup\$

CJam, 35 bytes

1'el+~1$*_2#2$2#4*+mQ+2/1$md@+s0'.t

Reads p first, then n.

Try it online in the CJam interpreter.

How it works

We simply compute the formula from the question for n × 10p, get the integer and fractional part of the result divided by 10p, pad the fractional part with leading zeroes to obtain p digits and print the parts separated by a dot.

1'e  e# Push 1 and 'e'.
l+   e# Read a line from STDIN and prepend the 'e'.
~    e# Evaluate. This pushes 10**p (e.g., 1e3 -> 1000) and n.
1$*  e# Copy 10**p and multiply it with n.
_2#  e# Copy n * 10**p and square it.
2$   e# Copy 10**p.
2#4* e# Square and multiply by 4.
+    e# Add (n * 10**p)**2 and 4 * 10**2p.
mQ   e# Push the integer part of the square root.
+2/  e# Add to n * 10**p and divide by 2.
1$md e# Perform modular division by 10**p.
@+s  e# Add 10**p to the fractional part and convert to string. 
0'.t e# Replace the first character ('1') by a dot.
\$\endgroup\$
1
\$\begingroup\$

Python 2, 92 Bytes

As I am now looking at the answers, it looks like the CJam answer uses the same basic method as this. It calculates the answer for n*10**p and then adds in the decimal point. It is incredibly inefficient due to the way it calculates the integer part of the square root (just adding 1 until it gets there).

n,p=input()
e=10**p;r=0
while(n*n+4)*e*e>r*r:r+=1
s=str((n*e+r-1)/2);print s[:-p]+'.'+s[-p:]
\$\endgroup\$
1
\$\begingroup\$

PHP, 85 78 bytes

echo bcdiv(bcadd($n=$argv[bcscale($argv[2])],bcsqrt(bcadd(4,bcpow($n,2)))),2);

It uses the BC Math mathematical extension which, on some systems, could not be available. It needs to be included on the compilation time by specifying the --enable-bcmath command line option. It is always available on Windows and it seems it is included in the PHP version bundled with OSX too.

Update:

I applied all the hacks suggested by @blackhole in their comments (thank you!) then I squeezed the initialization of $n into its first use (3 more bytes saved) and now the code fits in a single line in the code box above.

\$\endgroup\$
  • \$\begingroup\$ @Blackhole. 85, indeed. I have probably read 86 (did a slightly larger selection) and wrote 68 by mistake. Fixed now. \$\endgroup\$ – axiac Aug 9 '15 at 22:41
  • 1
    \$\begingroup\$ No problem :). You can have 1 byte less by the way: remove the parenthesis around the echo, just leave a space after it. \$\endgroup\$ – Blackhole Aug 9 '15 at 22:43
  • 1
    \$\begingroup\$ And since you expect bcscale to return true, you can use $n=$argv[bcscale($argv[2])]; and save 2 more bytes. \$\endgroup\$ – Blackhole Aug 9 '15 at 22:45
  • \$\begingroup\$ That's a nice hack. \$\endgroup\$ – axiac Aug 9 '15 at 22:46
  • \$\begingroup\$ Code dirtiness is an art :P. Oh, the last one: bcpow($n,2) instead of bcmul($n,$n) saves you 1 byte. \$\endgroup\$ – Blackhole Aug 9 '15 at 22:48
1
\$\begingroup\$

J, 27 Bytes

4 :'}:":!.(2+x)-:y+%:4+*:y'

Explanation:

4 :'                      '   | Define an explicit dyad
                       *:y    | Square y
                     4+       | Add 4
                   %:         | Square root
                 y+           | Add y
               -:             | Half
      ":!.(2+x)               | Set print precision to 2+x
    }:                        | Remove last digit, to fix rounding

Call it like this:

    9 (4 :'}:":!.(2+x)-:y+%:4+*:y') 1
1.618033988

Another, slightly cooler solution:

4 :'}:":!.(2+x){.>{:p._1,1,~-y'

Which calculates the roots of the polynomial x^2 - nx - 1. Unfortunately, the way J formats the result makes retreving the desired root slightly longer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.