| Bytes | Lang | Time | Link |
|---|---|---|---|
| 039 | APLNARS | 250113T220539Z | Rosario |
| 008 | Vyxal | 210405T020321Z | lyxal |
| 087 | Retina | 210405T011738Z | Neil |
| 018 | 05AB1E legacy | 211110T095003Z | Kevin Cr |
| 104 | R | 210405T224214Z | Dominic |
| 099 | Perl 5 apl | 210408T021840Z | Kirill M |
| 091 | R + MASS | 210405T150757Z | Kirill L |
| 092 | R | 210405T084936Z | pajonk |
| 070 | APL Dyalog Extended | 210406T224044Z | Andrew O |
| 061 | JavaScript Node.js | 210406T070809Z | tsh |
| 011 | Jelly fork | 210405T213200Z | caird co |
| 013 | M | 210405T212448Z | caird co |
| 092 | Clojure | 210405T134140Z | Kirill L |
| 076 | JavaScript ES7 | 210405T010916Z | Arnauld |
| 055 | Charcoal | 210405T104356Z | Neil |
| 058 | Haskell | 210405T012416Z | Delfad0r |
| 033 | Wolfram Language Mathematica | 210405T051319Z | att |
| 025 | J | 210405T023134Z | Bubbler |
| nan | J | 210405T010840Z | Jonah |
| 020 | Jelly | 210405T003029Z | hyperneu |
APL(NARS), 39 chars
{k←-(⍎⍺)÷¯1+10x*≢⍺⋄⍵≡'':k⋄(⍎⍵)+k×10*≢⍵}
Implement the formula show Bubbler in J solution, in APL... It use rational 2r9 means 2/9. The notation x'y is traslated as x is the argument of function on the left seen as a string, and y is the argument of function on the right seen as string. If argument on the right y not exist, it will be rapresented from void string ''.
test:
f←{k←-(⍎⍺)÷¯1+10x*≢⍺⋄⍵≡'':k⋄(⍎⍵)+k×10*≢⍵}
'31' f '491'
17609r99
'844' f '80'
¯4480r999
'4' f '128'
¯2848r9
'247' f '0'
¯2470r999
'0' f '716'
716
'592' f ''
¯16r27
'3' f '45'
35r3
'9' f '7'
¯3
'9' f ''
¯1
'3' f '0'
¯10r3
'764'f'31'
¯45431r999
'81'f'09'
¯801r11
'81'f'9'
9r11
'123456'f''
¯41152r333333
'9'f'0'
¯10
Vyxal, 8 bytes
⌊?@↵÷⌐/β
-3 bytes thanks to emanresu
Old Answer
vL↵‡⌐/R?⌊$β
Haha rationals go brrr. Obligatory port of Jelly, M and Bubbler.
Explained
vL↵‡⌐/R?⌊$β # Full program, takes ["x", "y"]
vL # vectorise length over each
↵ # and raise 10 to the power of each
‡⌐/ # lambda x, y: x / 1 - y
R # reduce the above list by that
?⌊ # cast each string in input to it
$β # and convert to the result of reducing the lambda
Retina, 96 92 87 bytes
(.+)'(.*)
$($($.1*9)*$2*)-$($1$.2*0)*_/$($.1*9)*
+`_-_
-
-/
/
(\b_+|\1)+/(\1)+$
$#1/$#2
Try it online! Link includes faster test cases. Explanation:
(.+)'(.*)
$($($.1*9)*$2*)-$($1$.2*0)*_/$($.1*9)*
Write out yw-xz/w. (Edit: I don't actually multiply x by z, I just suffix the appropriate number of 0s to it, which saves on a 1 amongst other things.)
+`_-_
-
-/
/
Perform the subtraction, slowly.
(\b_+|\1)+/(\1)+$
$#1/$#2
Slowly divide by the GCD and convert to decimal.
Just for completeness, optimising for speed results in code that readily dispatches all of the test cases. Try it online!
05AB1E (legacy), 18 bytes
ÂI‚JÆ-нID®ì+н>‚D¿÷
Despite 05AB1E's name (when 05AB1E converted to hexadecimal is interpret as base64 it spells Base), it can't do base conversion from decimal values, so @Bubbler's approach won't work for it.
Instead, this is a port of @tsh's JavaScript answer, so make sure to upvote that answer as well!
This uses the legacy version of 05AB1E, because the GCD builtin ¿ will always result in a positive integer in the new version of 05AB1E (the D¿÷ should be Ð.±s¿*ß÷ as workaround in that case).
Try it online or verify all test cases.
Explanation:
Uses the formula:
$$(x,y) = [x-(y\mathbin\Vert x-x\mathbin\Vert y), \text{-1}\mathbin\Vert x + x + 1]$$
integer-divided by their \$\gcd\$ afterwards; where \$\mathbin\Vert\$ is concatenation, taking precedence over the other operators.
 # Reverse the (implicit) input-pair (without popping)
I‚ # Pair it with the input-pair
J # Join both inner pairs together
Æ # Reduce this pair by subtracting
- # Subtract this integer from both values of the input-pair
н # Pop and only keep the first one
ID # Push the input-pair twice again
®ì # Prepend both integers in the top pair with "-1"
+ # Add both to the input-pair at the same positions
н # Pop and only keep the first one
> # Increase it by 1
‚ # Pair the two values together
D # Duplicate this pair
¿ # Get the GCD (Greatest Common Divisor)
÷ # Integer-divide the values in the pair by this GCD
# (after which the pair is output implicitly as result)
R, 114 110 109 107 104 bytes
Edit: -4 and then -2 more bytes thanks to Giuseppe's comments on pajonk's answer, and then -3 bytes after copying a trick from Robin Ryder's answer here
function(s,z=10^nchar(s)-1:0,n=scan(t=pmax(s,0)),a=c(diff(n*z[2:1]),z[1]),c=1:z)a/max(c[!a%%c&!a[2]%%c])
Input is a vector of two strings representing x and y.
I tried to answer this without peeking at the other R answers, but now I realise that pajonk's answer is probably golfier... Bah!
Perl 5 -apl, 99 bytes
($w,$z)=map s/./9/gr,@F;@e=($F[1]*$w-$F[0]*($z+1),$w);$w--while grep$_%$w,@e;$_=join"/",map$_/$w,@e
Takes two space separated strings from stdin, outputs a fraction.
R + MASS, 99 91 bytes
function(x,y,`[`=gsub)MASS::fractions(eval(parse(t=paste0(y,"-",x,"."[0,y],"/","."[9,x]))))
Takes input as two strings (y possibly empty), outputs a rational fraction or an integer.
R, 118 116 108 103 98 92 bytes
function(x,y,`+`=nchar,B=10^+x-1,A=el(max(y,0):0)*B-x*10^+y,q=1:x)c(A,B)/max(q[!A%%q&!B%%q])
Takes first input as integer and second as string (empty if no \$y\$).
GCD implementation borrowed from here: https://codegolf.stackexchange.com/a/48845/55372
-8 bytes thanks to @Kirill & @Dominic;
-5 and another -6 bytes thanks to @Giuseppe
APL (Dyalog Extended), 70 bytes
Not great, but I felt like submitting it anyway
{⍺←⍬⋄{⍵÷⊃⌽⊃∩⍥(⍸0=⊢|⍨⍳)/|⍵}((W×⍎'0',⍺)-(⍎⍵)×⍎'1','0'\⍨⍴,⍺),W←⍎'9'\⍨⍴,⍵}
Not sure why, but my code to handle single arguments works in TryAPL.org but not in tio.run
Also, because of how APL handles default arguments, I had to swap the order on input...like I said, not the best solution :|
⍺←⍬⋄ ⍝ assign Empty Set to the default value for the left argument (Y from the problem statement)
⍵÷⊃⌽ ⍝ divide the 2-tuple (a and b from the problem statement) by their gcd
⊃ ⍝ pick (removes one layer of nesting)
∩ ⍝ intersection
⍥ ⍝ function composition operator (Over)
(⍸0=⊢|⍨⍳)/ ⍝ fold/reduce by finding divisors
|⍵ ⍝ absolute value of 2-tuple (a and b from the problem statement)
W×⍎'0',⍺ ⍝ W (from problem statement) times the integer representation of the left argument (Y from the problem statement) or zero if alpha is the empty set
-(⍎⍵) ⍝ subtract the integer representation of the right argument (X from the problem statement)
×⍎ ⍝ decode then multiply
'1', ⍝ concatenate the character 1
'0'\⍨⍴ ⍝ expand the character 0 by the number of characters in Y
,⍺ ⍝ ravel Y (effectively making single characters into singleton arrays)
, ⍝ concatenate
W←⍎'9'\⍨⍴ ⍝ assign the integer representation of the expansion of the character 9 by the number of characters in X
,⍵ ⍝ ravel X
JavaScript (Node.js), 61 bytes
x=>y=>(G=(a,b)=>b?G(b,a%b):[x/a,z/a])(z=-1+x-~x,x-=y+x-(x+y))
Take input as two strings, output an array with two numbers.
JavaScript use + for both number plus and string concatenation. When any operand is string, it works as string concatenation.
Jelly (fork), 11 bytes
ḌḅẈ⁵*C÷@¥/Ʋ
Try it online!, or rather, don't
As of last week, my fork now includes symbolic math support! Unfortunately, M (Jelly's version with symbolic math) only implements this in the İ atom, not in the ÷ division atom. My fork does both.
Again, implements Bubbler's strategy to evaluate \$[x, y]\$ in base \$-\frac z w\$.
How it works
ḌḅẈ⁵*C÷@¥/Ʋ - Main link. Takes [x, y] as lists of digits on the left
Ḍ - Convert [x, y] to integers
Ʋ - Do the following to [x, y]:
Ẉ - Lengths of each
⁵* - Raise 10 to the power of each length
¥/ - Reduce by the following:
C - Complement; 1 - a
÷@ - Divide b by that; b / (1 - a)
M, 13 bytes
Cİ×
L€⁵*ç/ḅ@Ḍ
Implements Bubbler's method
How it works
Cİ× - Helper link. Takes a on the left and b on the right
C - Yield 1-a
İ - Inverse; Yield 1 / (1-a)
× - Times; Yield b / (1-a)
L€⁵*ç/ḅ@Ḍ - Main link. Takes [x, y] as lists of digits
L€ - Length of each
⁵* - Raise 10 to the power of the lengths
ç/ - Run the helper link with the powers of 10 as a and b
Ḍ - Convert [x, y] into integers
ḅ@ - Evaluate [x, y] as base b / (1-a)
Clojure, 92 bytes
#(let[b biginteger p(fn[x](.pow(b 10)(count x)))](-(b(or %2 0))(/(*(b %)(p %2))(dec(p %)))))
Relies on the formula from Wikipedia. Takes input as two strings (nil when there is no y), outputs a rational fraction, or a bigint when denominator is 1.
JavaScript (ES7), 80 76 bytes
Expects (x)(y) as strings (y may be an empty string) and returns [numerator, denominator].
x=>y=>(G=(a,b)=>b?G(b,a%b):[p/a,q/a])(q=1-10**x.length,p=y*q+x*10**y.length)
Commented
x => // outer function taking x
y => // inner function taking y
( G = (a, b) => // G is a helper function which takes 2 integers,
b ? G(b, a % b) // computes their GCD a
: [ p / a, q / a ] // and eventually returns [ p / a, q / a ]
)( // we invoke G with (q, p) defined as follows:
q = // q =
1 - // 1 - 10 ** len(x)
10 ** x.length, //
p = // p =
y * q + // y * q + x * 10 ** len(y)
x * 10 ** y.length //
) //
Charcoal, 55 bytes
F⪪S'«≔ζη≔ιζ»≔I⭆η⁹δ≔⁻×IζδI⁺η⭆ζ⁰ε⊞υε⊞υδW﹪εδ«≔δε≔ιδ»⪫÷υ↔δ/
Try it online! Link is to verbose version of code. Explanation:
F⪪S'«≔ζη≔ιζ»
Split the input string on ' and save the parts into separate variables.
≔I⭆η⁹δ
Change the digits of the first part to 9s and save the result as an integer.
≔⁻×IζδI⁺η⭆ζ⁰ε
Multiply that by the second part as an integer, then change the digits of the second part to 0s, append that to the first part, and subtract the integer value.
⊞υε⊞υδ
Save the fraction to the predefined empty list.
W﹪εδ«≔δε≔ιδ»
Find the GCD.
⪫÷υ↔δ/
Reduce the fraction to its lowest terms and output it with a / separator.
Haskell, 58 bytes
x#y=f y-f x*0!y/1!x
c!s=10^length s-c
f x=read$'0':x++"%1"
The relevant function is (#), which takes x and y as strings, with y possibly empty. Returns a Rational.
DISCLAIMER: the compiler is unable to correctly deduce the type of (#), unless it is specified by some other part of the program, either explicitly (i.e. ::Rational) or implicitly (i.e. by using the return value as if it were a Rational). Based on this Meta answer I believe this should be allowed, but since I'm quite inexperienced I'm not sure. If that's not the case, then the best I can do is:
Haskell, 63 bytes
x#y=f y-f x*0!y/1!x
c!s=10^length s-c
f x=toRational.read$'0':x
Wolfram Language (Mathematica), 37 33 bytes
d[#/d[0#-9]]~d~#2&
d=Fold[9#+##&]
Input two lists of digits.
Fold[9#+##&] is longer than FromDigits, but has more flexibility with its input.
J, 25 bytes
(%-.)~/@(10^#&>)#.10#.&>]
Takes a boxed 2-item vector containing the digit vectors of \$x\$ and \$y\$, and returns a rational number. The digits must be given in extended precision. \$y\$ may be an empty vector. I guess it's pretty well golfed when Jelly is at 20 bytes :)
How it works
Uses the formula at the end of the challenge. If we define \$\#x\$ as the number of digits of \$x\$,
$$ z = 10^{\#y}, \quad w=10^{\#x}-1, \quad x'y = -\frac{z}{w}x+y, $$
and observe that the result is the same as the 2-vector \$[x,y]\$ evaluated in base \$-\frac{z}{w}\$.
(%-.)~/@(10^#&>)#.10#.&>] NB. Monadic train; input = (digits of x;digits of y)
10#.&>] NB. Evaluate each in base 10 to get [x,y]
#. NB. Evaluate in base...
(10^#&>) NB. 10 raised to the power of length of each; [10^#x, 10^#y]
(%-.)~/@ NB. (10^#y) / (1 - 10^#x) = -z/w
J, 23 bytes
(%-.)~&(10x^#)#.,&{.&".
Modification of Jonah's solution to use the same base trick. This one is a dyadic function accepting plain strings as its two args. One caveat is that eval(".) of an empty string is an empty vector, so we need to make it a 0 explicitly using {..
J, 39 32 30 27 bytes
{.@".@]-".@[*(%<:)~&(10x^#)
-5 thanks to Bubbler. Also go upvote his j answer, which is more creative and has delightful application of base #.
The wikipedia formula translated into J. The only part that might be of some interest is the calculation of z/w:
(%&x:<:)~&(10^#)&(1>.10^#)Convert each string input by raising 10 to the power of its length10^#(which will be 1 when length is 0).(%&x:<:)~Next swap the argument order~and subtract 1<:from the new right arg, to get a number whose digits are all nines. Divide the left argument by that%.