Take the (integer) number of human years that the dog has lived, $$\n\$$, as input and return its age in dog years, $$\d\$$, to two decimal places.
The number of human years, $$\n\$$, will be between $$\1\$$ and $$\122\$$ inclusive: $$\n \in [1,122], n \in \Bbb{N}\$$.

According to BBC's Science Focus Magazine, the correct function for determining your dog's age is: $$n = 16 \times \ln(d) + 31$$ Where

$$\n\$$ is the age in human years

$$\d\$$ is the age in dog years

# Rules

The final output in dog years must be a decimal, rounded to 2 decimal places.

• Is 'rounded to 2 digits' a firm rule? Neither of the current answers do this. Aug 2, 2020 at 12:37
• At 969 years, floating point imprecision becomes significant (the correct answer is 28874468684703116351749853 point something, while a simple calculation with doubles returns 28874468684703116489129984.00. Are you sure you want to set the upper limit to such a high value? Aug 2, 2020 at 13:00
• Ok, I set the max age to 122, which keeps the maximum age to 295.15. Thanks! Aug 2, 2020 at 13:06
• ...also I imagine trailing zeros may be implicit, right? (i.e. that 0.5 is an acceptable output when given an input of 20 [rather than 0.50]) Aug 2, 2020 at 15:03
• This question misinterprets the formula. n and d are the wrong way around. From the source paper: (equivalent) human_age = 16 ln(dog_age) + 31 Dec 12, 2020 at 4:36

# Io, 114 bytes

While you all are enjoying rounding built-ins in your language, Io doesn't have any of those convenient rounding built-ins...

method(x,I :=((((x-31)/16)exp*100)round asString);I=if(I size<3,"0","").. I;I asMutable atInsertSeq(I size-2,"."))


Try it online!

# Perl 5, 36 31 bytes

printf"%.2f",1.0644944**($_-31)  Try it online! Command line one-liner examples: echo 52 | perl -ne 'printf"%.2f\n",2.71828**(($_-31)/16)'
echo 52 | perl -ne 'printf"%.2f\n",1.06449445**($_-31)' echo 52 | perl -ne 'printf"%.2f",1.06449445**($_-31)'
echo 52 | perl -ne 'printf"%.2f",1.0644944**($_-31)' for a in {1..122};do echo "Man:$a Dog: "echo $a|perl -ne'printf"%.2f\n",1.0644944**($_-31)';done

• printf"%.2f\n",1.06449445**($_-31) saves two. Aug 2, 2020 at 16:51 • Do you need the \n? (You can only take one input at a time without it, but there's nothing wrong with that.) Aug 3, 2020 at 3:22 • @JonathanAllan Thanks, and I also see that for the range 0-125 then 1.06449445 can be shortened to 1.0644944 and still give the same results when rounding to 2 decimals. Aug 3, 2020 at 7:48 • Thanks to @Dingus also. Aug 3, 2020 at 7:49 • Shorter yet: 27 bytes Dec 12, 2020 at 6:46 # Jelly, 10 bytes _31÷⁴Æeær2  A monadic Link accepting a float which yields a float. (As a full program a decimal input causes the result to be printed.) Try it online! ### How? _31÷⁴Æeær2 - Link: float, n 31 - 31 _ - subtract -> n-31 ⁴ - 16 ÷ - divide -> (n-31)/16 Æe - exp(x) -> exp((n-31)/16) 2 - 2 ær - round to 10^(-y) -> round(exp((n-31)/16), 2)  # Integral, 14 11 Bytes My first Integral answer! x▼◄w‼5*↕u*‼  Try it! An alternative: ▲w‼!◄5*↕u*‼ (11 bytes) ## Explanation x Push 32 ▼ x-1 ◄ Subtraction w Push 16 ‼ Divide 5 e ^ a * 100 ↕ Multiplicaiton u Round to the closest integer * 100 ‼ Division  # Orst, 9 bytes 31FᎽGć2Š  Try it online! As bytes, this is F3 F1 1B FF 30 1C 64 F2 42  Or, encoded as UTF-8, óñÿ0 dòB which can be run by omitting the -u flag (filled by default on TIO). Note the not shown 0x1b and 0x1c bytes ## How it works 31FᎽGć2Š - Full program. n is pushed to the stack 31 - Push 31 F - Subtract; n-31 Ꮍ - Push 16 G - Divide; (n-31)÷16 ć - Exp; exp((n-31)÷16) 2Š - Round to 2 decimal places  • Just curious: What's with the "undefined bytes?" Apr 20, 2021 at 1:08 • @Makonede Orst uses a 512 byte code byte, using a continuation byte (FF). When adding Orst to TIO, it was easier to use "undefined" than try to add in a special byte-counting script Apr 20, 2021 at 1:09 # APL+WIN, 13 bytes Prompts for input of n: ⍎2⍕*(⎕-31)÷16  Try it online! Courtesy of Dyalog Classic # Vyxals, 23 bytes 31-16/W∆ehS\.€ḣh2wi\.$W


Try it Online!

From this answer two stupid features of Vyxal:

• Why $$\ln(x)^{-1}\$$ needs to take a list instead of digit?
• Seriously it cannot round a digit to n decimal places, so that part is handrolled.
• y'know, there's nicer and more direct ways of asking for feature requests ;p Jun 7, 2021 at 13:14
• @lyxal I'll refer to the Vyxal room as soon as possible (tomorrow) Jun 7, 2021 at 14:22

# JavaScript (V8), 33 32 bytes

a=>Math.exp(-~a/16-2).toFixed(2)


Try it online!

Thanks to @my pronoun is monicareinstate for -1 byte

# cQuents, 24 bytes

:b$)/100 :R100*x_+$/16-2


Try it online!

For some reason, rounding works on the whole line. I would do /100/R100*, but floats went all 9y on me.

# R, 28 bytes

round(exp((scan()-31)/16),2)


Try it online!

There seems to be some controversy about whether trailing zeros must be printed. If so, the following 35 byte solution works:

sprintf("%.2f",exp((scan()-31)/16))


# bc, 40 bytes

scale=2
define f(n){return e((n-31)/16)}


Try it online!

# C (gcc), 354438 36 bytes

Saved a byte thanks to my pronoun is monicareinstate!!!
Saved 2 bytes thanks to Arnauld!!!
Added 10 bytes to fix a bug kindly pointed out by Kjetil S.

f(n){printf("%.2f",exp(-~n/16.-2));}


Try it online!

• Rounding should be inside function f? Aug 2, 2020 at 12:58
• Ignoring rounding, which should be added, 34 bytes (assuming I didn't make a dumb mistake) Aug 2, 2020 at 12:59
• @KjetilS. Oops, missed that - fixed! :-) Aug 2, 2020 at 14:05
• Do you really need the \n? Aug 2, 2020 at 15:23
• @Arnauld Of course not - thanks! :D Aug 2, 2020 at 17:05

# Japt, 12 11 bytes

-1 byte thanks to @Shaggy

Me°U/G-2 x2


Try it

## Explanation

Me°U/G-2 x2
Me            //  exp(
°U          //      (U + 1)
/G-2      //              / 16 - 2
//  )
x2  //  round to 2 decimal digits

• 16 can be G. Aug 2, 2020 at 17:18

# Python 3, 5236 35 bytes

Saved a whopping 16 17 bytes thanks to Jonathan Allan!!!

lambda n:round(1.0644944**(n-31),2)


Try it online!

• @petStorm I disagree, "The final output in dog years must be a decimal, rounded to 2 digits." states nothing about necessitating trailing zeros (and that's assuming it means 2dp rather than 2sf). Furthermore, many answers will give no trailing zero, e.g. 0.5 when given 20. Aug 2, 2020 at 14:52
• lambda n:round(math.exp(-~n/16-2),2) saves 4 Aug 2, 2020 at 15:24
• If we can't assume n is an integer we can't use ~; if we can assume n is an integer (in $[1,122]$) we can do lambda n:round(2.71828**((n-31)/16),2) for 38. Aug 2, 2020 at 16:36
• ...actually, lambda n:round(1.06449445**(n-31),2) would work for 36. Aug 2, 2020 at 16:48
• @JonathanAllan Oh wow, that's great - thanks! :D Aug 2, 2020 at 17:02

# MathGolf, 19 bytes

T-☻/e▬♪*i♂‼/%5≥+♀∩*


If only MathGolf had a round builtin.. :/
6 bytes are used for the actual formula, 13 for rounding to 2 decimals, haha.

I/O both as a float.

Try it online.

Explanation:

T-            # Subtract 31 from the (implicit) input-float
#  i.e. 50.0 → 19.0
☻/          # Divide it by 16
#  → 1.1875
e▬        # Push 2.718281828459045 to the power this value
#  → 3.2788737679386735
♪*            # Multiply it by 1000
#  → 3278.8737679386735
i           # Convert it to an integer, truncating the decimal values
#  → 3278
♂          # Push 10
‼         # Apply the following two commands separated to the stack:
/        #  Integer-division
%       #  Modulo
#   → 327 and 8
5≥     # Check if the modulo-10 result (the last digit) is >= 5
# (1 if truthy; 0 if falsey)
#   → 327 and 1
+    # Add that to the division-by-10 result
#   → 328
♀∩  # Push 1/100
* # Multiply that to the integer
#   → 3.28
# (note: ♀/ cannot be used, because it would act as integer division)
# (after which the entire stack is output implicitly as result)


# Rust, 38 bytes

|n|print!("{:.2}",((n-31.)/16.).exp())


Try it online

# Charcoal, 20 bytes

﹪%.2fＸ¹·⁰⁶⁴⁴⁹⁴⁴⁵⁻Ｎ³¹


Try it online! Link is to verbose version of code. Numeric constant stolen from @JonathanAllan. Explanation:

                Ｎ      Input as a number
⁻ ³¹    Subtract literal 31
Ｘ¹·⁰⁶⁴⁴⁹⁴⁴⁵        Raise literal 1.06449445 to that power
﹪%.2f                   Format using literal format string %.2f
Implicitly print


# Zsh, 50 bytes

zmodload zsh/mathfunc
printf %.2f $[16*log($1)+31]


Try it Online!

Gives "dog years" per the original refs and examples. For example, the "ScienceFocus" article gives 2 examples, and the "Cell Systems" paper gives 1 example, as tabulated:
 dog age | equivalent human age
actual years | approx. "dog years"
 1 | ~30
 4 | ~52
 12 | ~70

• This was my first question, and I wrote it in a bit of a hurry, so it is bad and not very well researched. Thanks for the help, and nice answer. Dec 12, 2020 at 6:40

# 05AB1E, 12 bytes

>16/Ížrsm2.ò


Try it online!

>16/Ížrsm2.ò  # full program
.ò  # round...
žr       # 2.718281828459045...
sm     # to the power of...
# implicit input...
>             # plus 1...
/          # divided by...
16           # literal...
Í         # minus 2...
.ò  # to...
2    # literal...
.ò  # decimal places
# implicit output


## HP‑41C series, 18 B

You must place $$\n\$$ on top of the stack first (a. k. a. the X register). Then you can XEQ (execute) the following program:

01♦LBL "Y"         5 Bytes    global label requires 4 + (length of string) Bytes
NULL            1 Byte     invisible Null byte before numbers
02 31              2 Bytes    X ≔ 31;  Y ≔ 𝘯
03 −               1 Byte     X ≔ 𝘯 − 31
NULL            1 Byte     invisible Null byte before numbers
04 16              2 Bytes    place the value 16 on top of the stack; X ≔ 16
05 ∕               1 Byte     X ≔ (𝘯 − 31) ∕ 16
06 E↑X             1 Byte     𝘦 raised to the power of X
07 FIX 2           2 Bytes    show (up to) two place after the radix point
08 RND             1 Byte     round the value
09 RTN             1 Byte     RTN does not affect local label search


The fixed decimal point display is always rounded. However, the display settings do not affect the internally stored numbers. To ensure all digits after the second decimal place are zero, too, RND (round) is applied.