| Bytes | Lang | Time | Link |
|---|---|---|---|
| 019 | APLNARS | 251004T080420Z | Rosario |
| 007 | Nekomata | 230511T073517Z | alephalp |
| nan | C# Visual C# Interactive Compiler | 230512T061226Z | Ivan Nee |
| 072 | Scala | 230512T021257Z | 138 Aspe |
| 043 | Wolfram Language Mathematica | 230510T061129Z | Parcly T |
| 046 | Python 3 | 191122T082750Z | Jitse |
| 214 | APLNARS | 190727T223653Z | user5898 |
| 029 | MATL | 160505T235347Z | Luis Men |
| 083 | Java | 160506T135758Z | Leaky Nu |
| 015 | Pyth | 160506T170209Z | Leaky Nu |
| 012 | Jelly | 160506T160300Z | Leaky Nu |
| 046 | Ruby | 160505T222046Z | Doorknob |
| 052 | JavaScript ES6 | 160505T230930Z | Neil |
| 048 | Ruby | 160505T222812Z | Value In |
APL(NARS), 19 chars
{∞≤∣⍵:⍬⋄m,∇÷⍵-m←⌊⍵}
Input one number rational type, so one number of kind number_x or number_r_number.
Output one array of integers.
It seems that number_x is converted to number_r_number.
If the input number is not of type rational, than it is possible a stack full or a seg fault.
test:
c←{∞≤∣⍵:⍬⋄m,∇÷⍵-m←⌊⍵}
c 860438x
┌1──────┐
│ 860438│
└~──────┘
c 3.245x
┌4────────┐
│ 3 4 12 4│
└~────────┘
c ¯4.2x
┌3──────┐
│ ¯5 1 4│
└~──────┘
c ¯114.7802x
┌11───────────────────────┐
│ ¯115 4 1 1 4 1 1 5 1 1 4│
└~────────────────────────┘
c 0÷11x
┌1─┐
│ 0│
└~─┘
c 1r42
┌2────┐
│ 0 42│
└~────┘
c 2r7
┌3─────┐
│ 0 3 2│
└~─────┘
c ¯18r17056
┌6──────────────┐
│ ¯1 1 946 1 1 4│
└~──────────────┘
c ¯17056r18
┌3────────┐
│ ¯948 2 4│
└~────────┘
Nekomata, 7 bytes
ᶦ{1%ŗ}k
A port of @Parcly Taxel's Mathematica answer.
ᶦ{1%ŗ}k
ᶦ{ } Iterate the following function until it fails
1% Modulo 1
ŗ Reciprocal
k Floor
C# (Visual C# Interactive Compiler), 222 bytes/75 bytes
A function that takes a string, 222 bytes
(a,o)=>{var@b=$"{a}/1".Split("/");var@c=$"{b[0]}.0".Split(".");int@n=int.Parse(c[0]),m=int.Parse(c[1]),d=1,r;for(;d<m;d*=10);for(n=n*d+(n>0?1:-1)*m,d*=int.Parse(b[1]);d>0;(n,d)=(d,n-r*d))o.Add(r=(int)Math.Floor(1m*n/d));};
Just the part that takes numerator and denominator, 75 bytes
(n,d,o)=>{for(int@r;d>0;(n,d)=(d,n-r*d))o.Add(r=(int)Math.Floor(1m*n/d));};
Un-golfed code:
(input, output) =>
{
var fracStr = $"{input}/1".Split("/"); // append "/1" so we never get an array out of bounds
var decStr = $"{fracStr[0]}.0".Split("."); // append ".0" so we never get an array out of bounds
// parse the decimal number first,
// if we weren't passed a decimal, m will be 0
int n = int.Parse(decStr[0]);
int m = int.Parse(decStr[1]);
int d = 1;
// denominator will be the next power of 10 larger than m:
for (; d < m; d *= 10);
// scale the numerator by the denominator, and add the decimal part:
n = n * d + (n > 0 ? 1 : -1) * m;
// now handle the fraction case
// if we weren't passed a fraction then fracStr[1] will be "1"
// if we were passed a fraction, d will be 1
d *= int.Parse(fracStr[1]);
// now actually calculate the continued fraction:
for (; d > 0; )
{
int r = (int)Math.Floor(1m * n / d);
output.Add(r);
(n, d) = (d, n - r * d);
}
};
Scala, 72 bytes
Golfed version. Try it online!
(n,d)=>if(n<0)"-"+f(2*(d+n%d)-n,d)else n/d+(if(n%d<1)""else","+f(d,n%d))
Wolfram Language (Mathematica), 43 bytes
-4 from alephalpha
Floor@NestWhileList[1/t&,#,(t=#~Mod~1)>0&]&
APL(NARS), 107 chars, 214 bytes
dd←{⍵=0:0⋄0>k←1∧÷⍵:-k⋄k}⋄nn←{1∧⍵}⋄f←{⍵=0:0x⋄m←⎕ct⋄⎕ct←0⋄z←{0=(d←dd⍵)∣n←nn⍵:n÷d⋄r←⌊n÷d⋄r,∇d÷n-r×d}⍵⋄⎕ct←m⋄z}
The function of the exercise f, should have as input one rational number (where 23r33 means as "23/33" in math) ...The algo is the same of the one Neil posted as JavaScript solution... test
f 860438r1
860438
f 3245r1000
3 4 12 4
f ¯42r10
¯5 1 4
f ¯1147802r10000
¯115 4 1 1 4 1 1 5 1 1 4
f 0r11
0
f 1r42
0 42
f 2r7
0 3 2
f ¯18r17056
¯1 1 946 1 1 4
f ¯17056r18
¯948 2 4
f 17056r¯18
¯948 2 4
f 18r¯17056
¯1 1 946 1 1 4
f 123r73333333333333333333333333373
0 596205962059620596205962059 1 16 1 1 3
+∘÷/f 123r73333333333333333333333333373
123r73333333333333333333333333373
MATL, 29 bytes
`t1e7*Yo5M/kwy-t1e-5>?-1^T}xF
This works by repeatedly rounding and inverting (which I think is what Doorknob's answer does too). There may be numerical issues due to using floating point, but it works for all the test cases.
` % Do...while
t % Duplicate. Takes input implicitly the first time
1e7* % Multiply by 1e7
Yo % Round
5M/ % Divide by 1e7. This rounds to the 7th decimal, to try to avoid
% numerical precision errors
k % Round
w % Swap top two elements of stack
y % Copy the secomnd-from-bottom element
- % Subtract
t % Duplicate
1e-5> % Is it greater than 1e-5? (1e-5 rather than 0; this is again to
% try to avoid numerical precision errors)
? % If so
-1^ % Compute inverse
T % Push true as loop condition (to start a new iteration)
} % Else
xF % Delete and push false (to exit loop)
% End if implicitly
% End do...while implicitly
% Display implicitly
Java, 85 83 bytes
String f(int n,int d){return n<0?"-"+f(2*(d+n%d)-n,d):n/d+(n%d<1?"":","+f(d,n%d));}
Takes integer or fraction or decimal as String, 311 bytes
String c(String i){try{return""+Integer.decode(i);}catch(Exception e){int o=i.indexOf(46);if(o>=0)return c((i+"/"+Math.pow(10,i.length()-o-2)).replaceAll("\\.",""));String[]a=i.split("/");int n=Integer.decode(a[0]),d=Integer.decode(a[1]);return n<0?"-"+c(2*(d+n%d)-n+"/"+d):n%d<1?""+n/d:n/d+","+c(d+"/"+(n%d));}}
Sample input/output:
860438
860438
3.245
3,4,12,4
-4.2
-5,1,4
-114.7802
-115,4,1,1,4,1,1,5,1,1,4
0/11
0
1/42
0,42
2/7
0,3,2
-18/17056
-1,1,946,1,1,4
-17056/18
-948,2,4
Actual input/output from full program:
860438
860438
860438
860438
860438
3.245
3,4,12,4
3,4,12,4
3,4,12,4
3,4,12,4
-4.2
-5,1,4
-5,1,4
-5,1,4
-5,1,4
-114.7802
-115,4,1,1,4,1,1,5,1,1,4
-115,4,1,1,4,1,1,5,1,1,4
-115,4,1,1,4,1,1,5,1,1,4
-115,4,1,1,4,1,1,5,1,1,4
0/11
0
0
0
0
1/42
0,42
0,42
0,42
0,42
2/7
0,3,2
0,3,2
0,3,2
0,3,2
-18/17056
-1,1,946,1,1,4
-1,1,946,1,1,4
-1,1,946,1,1,4
-1,1,946,1,1,4
-17056/18
-948,2,4
-948,2,4
-948,2,4
-948,2,4
Full program (including ungolfed functions):
import java.util.Scanner;
public class Q79483 {
String cf_ungolfed(String input){
try{
int result = Integer.parseInt(input);
return Integer.toString(result);
}catch(Exception e){
if(input.indexOf('.')>=0){
int numerator = Integer.parseInt(input.replaceAll("\\.",""));
int denominator = (int) Math.pow(10, input.length()-input.indexOf('.')-1);
return cf_ungolfed(numerator+"/"+denominator);
}
int numerator = Integer.parseInt(input.substring(0,input.indexOf('/')));
int denominator = Integer.parseInt(input.substring(input.indexOf('/')+1));
if(numerator%denominator == 0){
return Integer.toString(numerator/denominator);
}
if(numerator < 0){
return "-"+cf_ungolfed((denominator-numerator+(denominator+2*(numerator%denominator)))+"/"+denominator);
}
return (numerator/denominator) + "," + cf_ungolfed(denominator+"/"+(numerator%denominator));
}
}
String c(String i){try{return""+Integer.decode(i);}catch(Exception e){int o=i.indexOf(46);if(o>=0)return c((i+"/"+Math.pow(10,i.length()-o-2)).replaceAll("\\.",""));int n=Integer.decode(i.split("/")[0]),d=Integer.decode(i.split("/")[1]);return n<0?"-"+c(2*(d+n%d)-n+"/"+d):n%d<1?""+n/d:n/d+","+c(d+"/"+(n%d));}}
String f_ungolfed(int numerator,int denominator){
if(numerator%denominator == 0){
return Integer.toString(numerator/denominator);
}
if(numerator < 0){
return "-"+f_ungolfed((denominator-numerator+(denominator+2*(numerator%denominator))),denominator);
}
return (numerator/denominator) + "," + f_ungolfed(denominator,(numerator%denominator));
}
String f(int n,int d){return n<0?"-"+f(2*(d+n%d)-n,d):n/d+(n%d<1?"":","+f(d,n%d));}
public static int[] format(String input){
if(input.indexOf('.') != -1){
int numerator = Integer.parseInt(input.replaceAll("\\.",""));
int denominator = (int) Math.pow(10, input.length()-input.indexOf('.')-1);
return new int[]{numerator,denominator};
}
if(input.indexOf('/') != -1){
int numerator = Integer.parseInt(input.substring(0,input.indexOf('/')));
int denominator = Integer.parseInt(input.substring(input.indexOf('/')+1));
return new int[]{numerator,denominator};
}
return new int[]{Integer.parseInt(input),1};
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String input = sc.next();
System.out.println(new Q79483().cf_ungolfed(input));
System.out.println(new Q79483().c(input));
int[] formatted = format(input);
System.out.println(new Q79483().f_ungolfed(formatted[0], formatted[1]));
System.out.println(new Q79483().f(formatted[0], formatted[1]));
}
sc.close();
}
}
Ruby, 45 43 46 bytes
f=->n{x,y=n.to_r.divmod 1;[x,*y==0?[]:f[1/y]]}
Accepts input as a string.
All test cases pass:
llama@llama:~$ for n in 860438 3.245 -4.2 -114.7802 0/11 1/42 2/7 -18/17056 -17056/18; do ruby -e 'f=->n{x,y=n.to_r.divmod 1;[x,*y==0?[]:f[1/y]]}; p f["'$n'"]'; done
[860438]
[3, 4, 12, 4]
[-5, 1, 4]
[-115, 4, 1, 1, 4, 1, 1, 5, 1, 1, 4]
[0]
[0, 42]
[0, 3, 2]
[-1, 1, 946, 1, 1, 4]
[-948, 2, 4]
Thanks to Kevin Lau for 2 bytes!
JavaScript (ES6), 52 bytes
f=(n,d)=>n%d?[r=Math.floor(n/d),...f(d,n-r*d)]:[n/d]
Accepts numerator and denominator and returns an array, e.g. f(-1147802, 1e4) returns [-115, 4, 1, 1, 4, 1, 1, 5, 1, 1, 4].
Ruby, 50 48 bytes
I noticed @Doorknob♦ beat me to a Ruby answer right before posting, and theirs is also shorter! As such this is just here for posterity now. Takes in a string or an integer (floats have rounding issues, so decimal values need to be put in as strings)
f=->s{s=s.to_r;[s.floor]+(s%1!=0?f[1/(s%1)]:[])}