# Find the smallest integer multiple of a Decimal

## The Challenge

Given a rational number, determine the smallest number which is a positive integer multiple of it. Eg.

Given: 1.25
x1: 1.25
x2: 2.5
x3: 3.75
x4: 5
Thus: Answer is 5


## Clarifications

Inputs will be a rational number in the range of (0,100] of which the Decimal Representation has no more than 4 digits after the point.

Output must be an integer that is the total after multiplication (5 in the example, rather than 4).

I/O may be in any Standard Format, including as a Fraction type.

Be careful if using repeated addition with floats, as 0.3 + 0.3... results in 2.9999....

## Test Cases

1.25   -> 5
4.0    -> 4
0.3    -> 3
4.625  -> 37
3.1428 -> 7857


## Rules

• Surely a fraction type trivialises the question?
– Neil
Sep 14, 2023 at 22:56
• @Neil If you've got a trivial solution, I implore you to submit it. Also worth noting many, even modern languages, don't have fractional types. Sep 14, 2023 at 23:01
• Essentially, this is just finding the numerator of the fraction form of a decimal Sep 14, 2023 at 23:26
• "determine the smallest number which is a positive integer multiple of it." -> "determine the smallest positive integer which is a positive integer multiple of it."? To me the first sounds like we can just output 1*input. Sep 15, 2023 at 12:09
• @DominicvanEssen Inaccuracies due to floating-point errors are disallowed. Answers that fail on this point should clarify explicitly, and attempt to provide an answer that does not. I'll add this as a test case. Sep 19, 2023 at 22:44

# Vyxal 2.4.1, 2 bytes

ƒh


Try it Online!

A version downgrade improves my byte count somehow.

Well not somehow. 2.4.1 and earlier versions didn't use exact numbers/rationals under the hood, so there was still a "convert decimal to numerator and denominator" built-in (because I've always wanted some form of rationals).

This is a back port of the Factor answer which half ported my original answer.

Takes input as floats because, well, only float input was supported in 2.4.1.

Converts to numerator, denominator. Then gets the first item of that.

## Vyxal >=2.6, 35 bitsv2, 4.375 bytes

S\//h


Try it Online!

Maths? No thank you!

Takes input as either a fraction object or a float. Both are interpreted as rational implicitly so it doesn't really matter.

Simply casts input to string (which'll be a fraction because vyxal 2 be like that), split on / and get the first item.

• Oh! Smart approach! Sep 14, 2023 at 23:16
• Funny thing is that I noticed the pattern after having written a math inspired answer and running test cases :p Sep 14, 2023 at 23:17

# J, 4 bytes

1&*.


Attempt This Online!

LCM with 1 to get the numerator of a fractional value.

J has a built-in to extract the numerator/denominator from a number too, but is longer to get just the numerator:

# J, 6 bytes

0{2&x:


Attempt This Online!

• TIL about dyadic x: Sep 15, 2023 at 6:16

# Excel, 37 bytes

=0+TEXTBEFORE(TEXT(A1,"0/00000"),"/")


Input in cell A1.

# Factor, 9 bytes

numerator


Attempt This Online!

Same idea as lyxal's Vyxal answer, just no need for string manipulation.

Less "cheaty," perhaps? This version takes floats as input instead of ratios:

# Factor + math.floating-point, 26 bytes

[ double>ratio numerator ]


Attempt This Online!

And my original answer for posterity:

# Factor, 34 bytes

[ 0 [ 1 + 2dup * ratio? ] loop * ]


Attempt This Online!

• 0 push zero — this is our multiplier
• [ ... ratio? ] loop do ... while top of stack is a ratio (a number like 5/5 promotes itself to integer automatically)
• 1 + increment the multiplier
• 2dup * multiply but keep the input and multiplier on the stack too
• * at this point, the input and correct multiplier are on the stack so multiply them
• I managed to backport your answer by downgrading my vyxal version :p Sep 14, 2023 at 23:30

# Julia, 11 bytes

~x=lcm(x,1)


Attempt This Online!

Takes rational number inputs. Julia also has the function rationalize for converting floating point values.

# Julia 0.6, 33 bytes

>(x,i=1)=isinteger(i*x)?i*x:x>i+1


Try it online!

Recursive approach which takes an iterator as its own optional argument. The > operator is overloaded, since it has lower precedence than +, which saves a set of parentheses. Spaces are required around ternary operators beginning in Julia 1.0.The function isinteger is a good fit; last("$(i*x)")<'1' would be another (longer) approach. # R, 39 31 bytes \(x,y=x*1:1e6)y[!(y+1e7)%%1][1]  Attempt This Online! Correctly handles difficult inputs that otherwise suffer from floating-point inaccuracies. # R, 25 bytes (non-competing) \(x,y=x*1:1e6)y[!y%%1][1]  Attempt This Online! Original answer: fails due to floating-point inaccuracies for 3.1428, and probably other difficult inputs. # Google Sheets, 31 bytes =+split(text(A1,"#/#####"),"/") Put the input in cell A1 and the formula in B1. Uses number formatting like the Excel answer to get a fraction, then takes advantage of an undocumented feature of the unary plus operator +, i.e., uplus(), to get the numerator. # Ruby, 26 bytes ->d{(1..).find{_1/d%1==0}}  Attempt This Online! ## Original: Ruby, 31 bytes f=->d,x=1{d*x%1>0?f[d,x+1]:d*x}  Attempt This Online! The more obvious f=->d{d.to_r.numerator} does not seem to work for 0.300. Thanks Value Ink for the tips, but I think that it should be a separate answer. • ->d{d.to_s.to_r.numerator} does work and is shorter by 5 bytes, and taking input as a string will lead to the obvious solution you posited. In fact, since the rules explicitly say a fractional input is allowed, proc &:numerator also works for the truly "cheaty" version. Sep 15, 2023 at 18:53 # PARI/GP, 25 bytes n->numerator(bestappr(n))  Attempt This Online! # Perl 5-p, 26 bytes ($\=$_*++$i)=~/\./&&redo}{


Try it online!

# Maxima, 17 bytes

Try it online!

f(n):=num(rat(n))


# APL(Dyalog Unicode), 3 bytes SBCS

∧∘1


Try it on APLgolf!

LCM between input and 1. This is actually really similar to a problem in the APL Competition, 1:7 Let's Be Rational.

# Pyth, 6 bytes

*fsI*Q


Takes input as a float.

Try it online!

*fsI*Q
f        Find the first integer, starting at 1 and counting upward, such that
*Q    The integer multiplied by the input
I      Is unchanged when
s       Cast to an integer
*         Multiply the result (the denominator) by the input


Same length:

fsIcTQ


Finds the numerator directly using division.

• Fails for 3.1428 Sep 23, 2023 at 19:34
• @NickKennedy My other answer, fsIcTQ, works for that input - do you know if it also has a counterexample? Sep 24, 2023 at 22:29

# Rust, 39 38 bytes

-1 thanks to @corvus_192

|mut x|{let n=x;while x%1.>0.{x+=n};x}


Try it online!

Closure naively loops and increments x by its intial value until it becomes a whole number.

• I think using > instead of != works. Sep 16, 2023 at 17:18
• @corvus_192 you're right, thanks.
– code
Sep 16, 2023 at 18:26

# Python 3, 53 bytes

Trivial solution (thanks to lyxal for the comment).

lambda n:Fraction(n).numerator
from fractions import*


Originally (65 bytes, returns a float which can be converted to an int while being the same value):

def x(n,i=1):
while not str(i*n).endswith('.0'):i+=1
return i*n


20 bytes from SuperStormer:

lambda n:n.numerator

• 20 bytes: lambda n:n.numerator meta Sep 15, 2023 at 14:50
• The number is not explicitly passed as a Fraction (I assume it is an int), however, I guess I'll add that as an extra answer. Sep 17, 2023 at 9:27

# Nekomata, 1 byte

ṇ


Attempt This Online!

ṇ = 'numerator' = 'Get the numerator of a number'

# AWK, 35 24 bytes

{while($1*++a%1);$1*=a}1


Try it online!

(Several improvements by @Dominic van Essen to my original answer: -11 bytes)

{while($1*++a>int($1*a));print$1*a}  Try it online! • 24 bytes... Sep 19, 2023 at 21:39 • Fails for 3.1428 Sep 23, 2023 at 19:30 # Python, 20 bytes lambda n:n.numerator  An unnamed function that accepts a Fraction object and returns the integer. Try it online! • Floating point inaccuracy I think - it accepts a float and does not perform repeated addition. Sep 23, 2023 at 21:50 • @NickKennedy removed. Sep 24, 2023 at 23:12 # Vyxal, 39 bitsv2, 4.875 bytes {D⌊≠|+  Try it Online! Posting as a separate answer because it doesn't use any fraction string cheese :p Takes input as either a fraction or a float, as both are implicitly converted to rationals. ## Explained {D⌊≠|+­⁡​‎‎⁪⁡⁪⁠⁪⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁪‏‏​⁡⁠⁡‌⁢​‎⁪⁪⁠‎⁪⁡⁪⁠⁪⁣⁪‏⁠‎⁪⁡⁪⁠⁪⁤⁪‏‏​⁡⁠⁡‌⁣​‎‎⁪⁡⁪⁠⁪⁢⁪‏‏​⁡⁠⁡‌⁤​‎‎⁪⁡⁪⁠⁪⁢⁢⁪‏‏​⁡⁠⁡‌­ { | # ‎⁡While ⌊≠ # ‎⁢ The floor of the top of the stack doesn't equal the top of the stack D # ‎⁣ (triplicate before the check so there's a copy left over) + # ‎⁤Add the input to the top of the stack 💎  Created with the help of Luminespire. # Charcoal, 27 bytes ≔Ｉ⁻θ.ηＦ⊟⪪θ.Ｆ25Ｆ¬﹪ηＩκ≧÷ＩκηＩη  Try it online! Link is to verbose version of code. Explanation: ≔Ｉ⁻θ.η  Remove the decimal point from the input and cast it to integer. Ｆ⊟⪪θ.  Loop over each decimal place. Ｆ25Ｆ¬﹪ηＩκ≧÷Ｉκη  Divide the integer by 2 and/or 5 if possible. Ｉη  Output the resulting integer. # Retina, 95 71 bytes \.(\d+)$
$1,$.1*0
.*5,0
$.(*2*),0 .*[2468],0$.(*5*),0
}0,0
,
^0+|,0*



Try it online! Link includes test cases. Explanation:

\.(\d+)1,$.1*0  On the first pass, delete the decimal point but keep track of how many digits there were after it. (It's golfier to repeat this stage but it has no effect on subsequent passes.) (.*5),0$.(*2*),0


Try doubling the number to create a trailing zero to match.

(.*[2468]),0
$.(*5*),0  Try multiplying the number by 5 to create a trailing zero to match. 0,0 ,  Remove a pair of matching zeros. }  Repeat until there are no more trailing zeros to remove or the number ends in 1, 3, 7 or 9. ^0+|,0*  Delete any leading zeros and any remaining working digits. # T-SQL, 51 bytes DECLARE @2 real=4.625 DECLARE @ REAL=@2 WHILE @>floor(@)SET @+=@2 PRINT @  # Swift 2.2, floating-point, 65 bytes func f(x:Float,y:Float=1)->Float{return x*y%1==0 ?x*y:f(x,y:y+1)}  Back in Swift 2, % was supported for floating-point types. I also can't figure out what Decimal was called back then. Try it on SwiftFiddle! ## Swift 5.8 + Foundation, decimal, 109 bytes func f(x:Decimal,y:Decimal=1)->Decimal{var z=x,w=x*y NSDecimalRound(&z,&w,0,.up) return w==z ?w:f(x:x,y:y+1)}  Rounding mode doesn't matter; I chose .up because it's the shortest. The function signature of NSDecimalRound makes more sense in Objective-C where you only work with NSDecimal* and not the struct directly. Try it on SwiftFiddle! # 05AB1E, 8 bytes ∞.ΔI/DïQ  Explanation: ∞ # Push an infinite positive list: [1,2,3,...] .Δ # Pop and find the first integer that's truthy for: I/ # Divide the current integer by the input-decimal D # Duplicate the decimal ï # Cast/floor its copy to an integer Q # Check if both are the same value # (after which the found integer is output implicitly as result)  • @NickKennedy Should be fixed, although it's plausible another test case might still fail due to floating point accuracy tbh. Sep 24, 2023 at 11:39 # JavaScript (V8), 31 bytes f=(n,m=n)=>(m+1e9)%1?f(n,m+n):m  Try it online! Take float # JavaScript (V8), 4 bytes x=>x  Try it online! • Is the 4-byte answer a joke? It obviously fails if input is given as a non-reduced fraction. Sep 25, 2023 at 8:47 • @DominicvanEssen I'd say requiring reduced fraction input is usually reasonable, but yeah it's not serious here – l4m2 Sep 25, 2023 at 9:15 # Ruby, 16 bytes Builtin solution posted as a separate answer from G B's answer per their suggestion. Takes a Rational as input. proc &:numerator  Attempt This Online! ## Ruby-n, 18 bytes The same idea but takes input from STDIN via -n and prints the answer. p$_.to_r.numerator


Attempt This Online!