In-between fractions

13

1

In-between fractions

The challenge:

You will need to create code that takes atleast 3 inputs; 2 integers and "a fraction representation" - whichever type suits your language for representing the fraction increments) ie. If you choose string the input would be "1/4" or you could choose 2 extra integer inputs or a tuple or w/e.

Input can be anywhere reasonable (STDIN, function arguments, from a file, etc.), and so can output (STDOUT, function return value, to a file, etc.)

Rules:

  1. The input "fraction" will always be a valid fraction, less than 1; example "1/4"
  2. The second input integer will always have a higher value than the first integer. I.E the first input integer will always have a lower value than the second.
  3. The input integers can be negative.
  4. Outputted fractions should be reduced as much as possible (simplified)

The code will need to output every "fraction step" between the 2 numbers in increments of the input fraction.

The code should be a program or function as stated here

Example 1:

Input: -2,3,"1/2"

Output:

 -2
 -3/2 
 -1 
 -1/2 
  0 
  1/2 
  1 
  3/2  
  2 
  5/2 
  3

Example 2:

Input: 1,2,"2/3"

Output:

1
5/3
2

or

1
4/3
2

Note: Counting can start from either direction (thank you @Mego)

This is , so the shortest answer in bytes wins.

Alex Carlsen

Posted 2016-04-15T07:07:30.767

Reputation: 387

Could the fraction be taken as 2 integer inputs, making 4 total inputs? – Mego – 2016-04-15T07:40:54.380

I think ill keep the restraint of maximum of 3 inputs - I would like to see the code for 4 inputs aswell – Alex Carlsen – 2016-04-15T07:42:58.403

In that case, what about having a list/tuple/array/some other iterable type containing two integers for the third input? That's not fundamentally different than 4 integer inputs. You should also clarify that the fraction will not be equal to 0. – Mego – 2016-04-15T07:44:52.210

@Mego After thinking it through, I can't see why it shouldn't be allowed Changed to "code that takes atleast 3 inputs" – Alex Carlsen – 2016-04-15T07:48:57.500

It seems that the rule 4 is the only critical point (for languages that don't have a native fraction or rational type) – edc65 – 2016-04-15T08:25:12.597

@edc65 I agree... I thought it to be harder tbh. (next ill create a similar challenge, but restrict answers to not rely on internal fraction features of certain languages :) - on the other hand, it's nice not to see a plethora of cjam answers < 3 bytes :) – Alex Carlsen – 2016-04-15T08:27:46.813

Can you clarify what constitutes "a fraction representation"? I took this to mean two distinct values expressing the numerator and denominator, but would this include a numeric expression, such as btw(-2, 3, 1/2) where 1/2 automatically evaluates to 0.5? (Even if this is the case I would still expect output to be num / den.) – beaker – 2016-04-15T17:45:10.107

Is inbetween supposed to be 2 words, in between? I usually see it separated. – Rɪᴋᴇʀ – 2016-04-16T07:20:11.207

1@beaker as long as the output is correct and the input comes from atleast 2 integers, the rest is up to you :) - i've kept the input part pretty openended, to see different answers – Alex Carlsen – 2016-04-18T19:25:14.073

You should change the first example input to be -2,3,"3/6" – mbomb007 – 2016-04-19T19:45:07.373

Can c be a symbolic variable? That is a data type used for symbolic computations – Luis Mendo – 2016-05-09T14:10:19.937

Answers

5

Octave, 34 30 bytes

@(a,b,c)rats(union([a:c:b],b))

Now takes the fraction as a numeric expression rather than separate numerator and denominator.

Sample on ideone

beaker

Posted 2016-04-15T07:07:30.767

Reputation: 2 349

1So why can't you use @(a,b,c)rats(union([a:c:b],b))? – Luis Mendo – 2016-04-15T17:32:08.940

@LuisMendo I can if mathematical expressions are acceptable inputs (the effective result of 1/2 as a numeric rather than string input), but that's not the way I interpreted "a fraction representation". If the OP agrees, I'll be glad to shave off 4 bytes. – beaker – 2016-04-15T17:38:50.603

Oh, I see. Well, I'm using that in my Matlab answer. So does the Mathematica answer apparently, unless "rational number" is a specific data type – Luis Mendo – 2016-04-15T17:42:30.593

@beaker i did actually respond – Alex Carlsen – 2016-04-19T17:07:34.553

@VisualBean Code already updated. – beaker – 2016-04-19T17:10:52.017

@LuisMendo Code updated. – beaker – 2016-04-19T17:11:31.577

11

Mathematica, 16 bytes

Range@##⋃{#2}&

An unnamed function that takes two integers and a rational number and returns a list of numbers, e.g.:

Range@##⋃{#2}&[-2, 3, 1/2]
(* {-2, -(3/2), -1, -(1/2), 0, 1/2, 1, 3/2, 2, 5/2, 3} *)

Mathematica's Range does exactly what the challenge asks, except that it omits the upper bound if the difference between lower and upper bound isn't exactly a multiple of the step size. Therefore we take the Union (using ) with the list containing only the upper bound which ensures that it appears exactly once. Note that Union will sort the result but we want it sorted anyway, since the step size is always positive. Also since we're working with rationals, they're automatically reduced as much as possible.

Martin Ender

Posted 2016-04-15T07:07:30.767

Reputation: 184 808

10

T-SQL 2012+, 831 535 477 270 246 240 219 bytes

Please note this is a one liner - sql doesn't have build in function to reduce the fraction. May not be the best language for this type of question. It is human readable(kind of - compared to some of the other languages).

DECLARE @f INT=-5,@t INT=3,@n INT=3,@ INT=8;

WITH C as(SELECT
top((@t*@-@f*@)/@n+1)ROW_NUMBER()OVER(ORDER BY @)M
FROM sys.messages)SELECT(SELECT
IIF(V%@=0,LEFT(V/@,9),CONCAT(V/MAX(M),'/',ABS(@)/MAX(M)))FROM c
WHERE V%M=0AND @%M=0)FROM(SELECT
@f*@+@n*~-M V FROM c)k

Try it online

t-clausen.dk

Posted 2016-04-15T07:07:30.767

Reputation: 2 874

Isn't the language called T-SQL, and not "Sqlserver"? – David Conrad – 2016-04-15T12:15:41.200

1@DavidConrad the language is TSQL, but there are different versions of sqlserver and the TSQL for this will work for sqlserver 2012 because of the keyword IIF. Which would use the keyword CASE in older versions. Added your suggestion – t-clausen.dk – 2016-04-15T12:19:56.313

Good Job. You can save a few by changing either @n or @d to plain @. Your CTE query for N could be N AS(SELECT N FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)) or N AS(SELECT 1N FROM sys.all_views). Given that there is almost guaranteed to be a few hundred in this view, you could reduce the cross joins as well. ISNULL is shorter than COALESCE and should work – MickyT – 2016-04-18T19:32:03.353

@MickyT thanks to your suggestions and a few of my own, I managed to reduce the length by 296 bytes, – t-clausen.dk – 2016-04-19T08:13:15.667

Great work there – MickyT – 2016-04-19T08:17:49.060

6

Python 2, 81 bytes

from fractions import*
a,b,c=map(Fraction,input())
while a<b:print a;a+=c
print b

Try it online

Mego

Posted 2016-04-15T07:07:30.767

Reputation: 32 998

5

Ruby, 32 54 48 bytes

->a,b,c{(a..b).step(c){|x|p x%1>0?x:x.to_i};p b}

This solution is based on Mego's Python answer and assumes that c will always be a Rational, Ruby's fraction format. Try it online!

Edit: Fixed a bug where integers weren't presented like integers. -6 bytes thanks to Not That Charles and MegaTom.

The functions are called in this way:

> f=->a,b,c{(a..b).step(c){|x|p x%1>0?x:x.to_i};p b}
> f[1,4,Rational(2,3)]
1
(5/3)
(7/3)
3
(11/3)
4

Sherlock9

Posted 2016-04-15T07:07:30.767

Reputation: 11 664

(3/1) should not be simply 3? – edc65 – 2016-04-15T09:24:19.657

The simplest Rational form of 3 in Ruby is (3/1) – Sherlock9 – 2016-04-15T09:34:17.903

.step(b,c).map should reduce the byte count here – Not that Charles – 2016-04-18T20:57:21.467

(a==a.to_i) can be a%1==0 for -4 bytes. – MegaTom – 2019-06-22T05:31:55.827

-2,3,1/2r (example 1) prints the last 3 twice. – Value Ink – 2019-07-08T19:45:54.190

Switching to (a...b) should probably fix the test case for example 1 at the cost of +1 byte. – Value Ink – 2019-07-08T19:53:55.283

5

Haskell, 31 26 bytes

f a b c=min[b]$a:f(a+c)b c

Lazy evaluation FTW! Demo:

*Main> import Data.Ratio
*Main Data.Ratio> f (-2) 3 (1%2)
[(-2) % 1,(-3) % 2,(-1) % 1,(-1) % 2,0 % 1,1 % 2,1 % 1,3 % 2,2 % 1,5 % 2,3 % 1]
*Main Data.Ratio> f 1 2 (2%3)
[1 % 1,5 % 3,2 % 1]

(I was initially tempted by Haskell’s [a,a+c..b] notation, but it has some quirks that necessitate something like f a b c|l<-[a,a+c..b-c/2]=l++[b|last l<b] for 41 bytes or f a b c=[x|x<-[a,a+c..],x<b]++[b] for 33.)

Anders Kaseorg

Posted 2016-04-15T07:07:30.767

Reputation: 29 242

I like your solution! However I think you need to include import Data.Ratio in your byte count too, I think you cannot use f without that, right? – flawr – 2016-04-15T10:34:21.870

2@flawr: nice edge case: you don't need Data.Ratio for f itself, because it's polymorphic for all numeric types. However, when you want to call it with values of type Ratio, then you need the import. The challenge only requires to "create code that ...", not to use it. I think it's fine without the import. – nimi – 2016-04-15T15:37:16.500

1More precisely, you only need the import for the % operator to create the test fractions 1 % 2 and 2 % 3. I’m not cheating here: you can really put those 26 bytes in a file by themselves, run the interpreter on that module, and have the interaction I displayed.

(You could even avoid typing import Data.Ratio in the demo interaction, if you instead spell % as Data.Ratio.%.) – Anders Kaseorg – 2016-04-15T16:20:01.260

5

MATL, 16 15 bytes

3$:3Gvu9X10ZGZD

This may fail for very large denominators. I hope output format is acceptable.

Try it online!

3$:    % take three inputs and generate range
3G     % push third input again
v      % vertically concatenate. Gives vertical array as output 
u      % get unique elements (i.e. remove the last one if it is repeated)
9X1    % predefined literal 'rat'
0ZG    % set rational format
ZD     % display using that format

Luis Mendo

Posted 2016-04-15T07:07:30.767

Reputation: 87 464

3

Matlab with Symbolic Toolbox / Octave with SymPy, 27 bytes

Thanks to @sanchises for pointing out an error, now corrected

@(a,b,c)sym(union(a:c:b,b))

This is an anonymous function. To call it, assign it to a variable or use ans.

Example:

>> @(a,b,c)sym(union(a:c:b,b))
ans = 
    @(a,b,c)sym(union(a:c:b,b))
>> ans(-2,3,1/2)
ans =
[ -2, -3/2, -1, -1/2, 0, 1/2, 1, 3/2, 2, 5/2, 3]

Luis Mendo

Posted 2016-04-15T07:07:30.767

Reputation: 87 464

This does not conform to the spec, since the upper bound is not always included (try example 2). – Sanchises – 2016-05-09T11:44:33.620

@sanchises Thanks! Corrected now – Luis Mendo – 2016-05-09T13:52:11.617

And also, I think for c you can use, I quote, whichever type suits your language for representing the fraction increments [...] or w/e. I think it's pretty clear that symbolic is a logical and allowed (@VisualBean might want to confirm this) choice. The result of the colon operator is then 'upgraded' to a symbolic array, which means you can get rid of the sym() call altogether. – Sanchises – 2016-05-09T13:57:45.773

@sanchises Thanks, I've asked for clarification – Luis Mendo – 2016-05-09T14:10:49.923

3

Julia, 14 bytes

f(a,b,c)=a:c:b

This is similar to the Mathematica answer, except that Julia's ranges are already in the desired format, so it is even shorter. Also returns a collection of numbers. Example output:

11-element StepRange{Rational{Int64},Rational{Int64}}:
 -3//1,-5//2,-2//1,-3//2,-1//1,-1//2,0//1,1//2,1//1,3//2,2//1

Note that the integers are displayed with 1 in the denominator, and a double-slash is used for fractions. To get the output exactly as defined in the question requires some more code:

f(a,b,c)=map(x->println(x.num,x.den<2?"":"/$(x.den)"),a:c:b)

Fengyang Wang

Posted 2016-04-15T07:07:30.767

Reputation: 185

2

Javascript, 108 90 86  81 bytes

(a,b,n,d)=>{var s="";for(a=a*d;a<b*d;a+=n)s+=(a%d?a+"/"+d:a/d)+" ";s+=b;return s}

An anonymous function. After assignment to a named variable with white space:

var f=(a,b,n,d)=>
{ var s="";
  for(a=a*d; a<b*d; a+=n)
    s+= (a%d ? a + "/" + d : a/d) + " ";
  s+=b;
  return s
}

Test examples:

console.log(f(1,2,1,8)); //writes:
1 9/8 10/8 11/8 12/8 13/8 14/8 15/8 2

console.log(f(-3,3,4,7)); // writes:
-3 -17/7 -13/7 -9/7 -5/7 -1/7 3/7 1 11/7 15/7 19/7 3 

An imperative approach using javascript, no recursion, library or functional programming.

traktor53

Posted 2016-04-15T07:07:30.767

Reputation: 299

1

Pyret, 56 bytes

{(b,e,n,d):link(e,map(_ / d,range(b * d, e * d))).sort()}

Takes in beginning (b), end (e), numerator (n), and denominator (d). Creates a range of integers, divides those through and appends the end to the list (by linking and then sorting).

MLavrentyev

Posted 2016-04-15T07:07:30.767

Reputation: 181

1

Smalltalk – 89 bytes

For once Smalltalk is almost competitive!

Number extend[p:e q:i[|h|self to:e by:i do:[:x|h:=x. x printNl].h=e ifFalse:[e printNl]]]

Call like this:

> 2 p:5 q:1/2
2
5/2
3
7/2
4
9/2
5

> 1 p:2 q:2/3
1
5/3
2

user15259

Posted 2016-04-15T07:07:30.767

Reputation:

1

R - 71 bytes

Assumes you have already installed the MASS package

f=function(x,y,z)MASS::fractions(union(seq(x,y,eval(parse(text=z))),y))

> f(1, 2, '1/3')
[1]   1 4/3 5/3   2
> f(2, 5, '1/2')
[1]   2 5/2   3 7/2   4 9/2   5

bouncyball

Posted 2016-04-15T07:07:30.767

Reputation: 401