Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Inbetween 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.

share|improve this question
    
Could the fraction be taken as 2 integer inputs, making 4 total inputs? – Mego yesterday
    
I think ill keep the restraint of maximum of 3 inputs - I would like to see the code for 4 inputs aswell – VisualBean yesterday
    
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 yesterday
    
@Mego After thinking it through, I can't see why it shouldn't be allowed Changed to "code that takes atleast 3 inputs" – VisualBean yesterday
    
It seems that the rule 4 is the only critical point (for languages that don't have a native fraction or rational type) – edc65 yesterday

10 Answers 10

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.

share|improve this answer

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.)

share|improve this answer
    
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 yesterday
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 yesterday
1  
More 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 yesterday

Ruby, 32 54 bytes

->a,b,c{(p((a==a.to_i)?(a.to_i):a);a+=c)while a<b;p b}

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

Edit: Fixed a bug where integers weren't presented like integers.

The functions are called in this way:

> f=->a,b,c{(p((a==a.to_i)?(a.to_i):a);a+=c)while a<b;p b}
> f[1,4,Rational(2,3)]
1
(5/3)
(7/3)
3
(11/3)
4
share|improve this answer
    
(3/1) should not be simply 3? – edc65 yesterday
    
The simplest Rational form of 3 in Ruby is (3/1) – Sherlock9 yesterday

Sqlserver 2012+ TSQL, 831 bytes

May not be the best language for this type of question.

CREATE FUNCTION[dbo].[f_x](@n int,@d int)RETURNS varchar(50)AS BEGIN IF @d=0 RETURN null IF @n=0 RETURN 0 IF abs(@n)=abs(@d)RETURN @n/@d DECLARE @z int=sign(@n)*sign(@d);WITH N(N)AS(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),t(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f),CTE as(SELECT top 5000000 N FROM t WHERE N<=ABS(IIF(ABS(@n)>ABS(@d),@n,@d))/2 AND @n%n=0 AND @d%n=0 ORDER BY N DESC)SELECT @z*=IIF(@z%n=0,1,n)FROM CTE RETURN LEFT(ABS(@n)/@z,9)+COALESCE('/'+NULLIF(LEFT(ABS(@d/@z),9),1),'')END
GO
DECLARE @f INT=-2,@t INT=3,@n INT=1,@d INT=2;WITH N(N)AS(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),t(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N) FROM N,N a,N b,N c,N d,N e,N f)SELECT top 5000000 dbo.f_x(@f*@d+@n*(n-1),@d)FROM t WHERE N<=(@t*@d-@f*@d)/@n+1

In human readable language:

CREATE FUNCTION[dbo].[f_x](@n int,@d int)
RETURNS varchar(50)
AS
BEGIN
IF @d=0 RETURN null
IF @n=0 RETURN 0
IF abs(@n)=abs(@d)RETURN @n/@d
DECLARE @z int=sign(@n)*sign(@d)
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),
t(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f)
,CTE as(
SELECT top 5000000 N
FROM t
WHERE
N<=ABS(IIF(ABS(@n)>ABS(@d),@n,@d))/2 AND @n%n=0 AND @d%n=0
ORDER BY N DESC
)
SELECT @z*=IIF(@z%n=0,1,n)
FROM CTE
RETURN LEFT(ABS(@n)/@z,9)+COALESCE('/'+NULLIF(LEFT(ABS(@d/@z),9),1),'')
END

GO

DECLARE @f INT=-2,@t INT=3,@n INT=1,@d INT=2
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)),
t(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N f)
SELECT top 5000000 dbo.f_x(@f*@d+@n*(n-1),@d)
FROM t
WHERE N<=(@t*@d-@f*@d)/@n+1
share|improve this answer
    
Isn't the language called T-SQL, and not "Sqlserver"? – David Conrad yesterday
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 yesterday

Octave, 34 bytes

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

Four inputs to avoid that whole str2num business.

Sample on ideone

share|improve this answer
1  
So why can't you use @(a,b,c)rats(union([a:c:b],b))? – Luis Mendo yesterday
    
@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 yesterday
    
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 yesterday
    
@LuisMendo I added a question for the OP in the comments. We'll see. – beaker yesterday

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

share|improve this answer

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
share|improve this answer

Matlab with Symbolic Toolbox / Octave with SymPy, 18 bytes

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

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

Example:

>> @(a,b,c)sym(a:c:b)
ans = 
    @(a,b,c)sym(a:c:b)
>> ans(-2,3,1/2)
ans =
[ -2, -3/2, -1, -1/2, 0, 1/2, 1, 3/2, 2, 5/2, 3]
share|improve this answer

Javascript, 108, 90, 86 bytes

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

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

var f=(a,b,n,d)=>
{ let s="";
  for(var i=a*d;i<b*d;i+=n)
    s+=(i%d?i+"/"+d:i/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 

A straight forward approach using javascript, no recursion or functional programming.

share|improve this answer

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.