# Gear Train, Rotating

Gears transfer different amount of speeds, depending on the size of the meshed gear.

Jack has a machine, that rotates a Gear Train. but you don't know the speed of the last gear.

Luckily, You are a great code golfer, so you can help him!

# So, What should I do?

Each gear is represented by 2 numbers, the radius of the inner gear and the radius of the outer gears.

If gear A is [a,b] and gear B is [c,d], then the ratio between the speed of A and the speed of B would be c:b.

Given a list of gears (list of 2-tuples), output the speed of the last gear.

You can assume the speed of the first gear is 1.

# Worked out example

Let's say our input is [[6,12],[3,10],[5,8]].

The first gear, [6,12], would have a speed of 1.

Then, the second gear, [3,10], would have a speed of 1*12/3 = 4.

Then, the last gear, [5,8], would have a speed of 4*10/5 = 8.

# Testcases

input                    output
[[1,1],[2,2]]            0.5     (1/2)
[[1,2],[1,2],[1,2]]      4       (2/1*2/1)
[[6,12],[3,10],[5,8]]    8       (12/3*10/5)


# Rules

Basic rules apply.

• Since you're allowing floating point output, you should probably clarify how accurate results have to be. Jul 23 '16 at 5:56
• Can we take input as a flattened list instead of list of tuples? Jul 23 '16 at 6:11
• Yes, like [6,12,3,10,5,8]. just mention it if you wanna use it.
– user54200
Jul 23 '16 at 6:12
• That's a tad unfair. I had a different 7-byte version that I didn't post because I considered it less interesting. It would have been 6 bytes without flattening. Please consider using the sandbox next time to avoid this kind of situation. Jul 23 '16 at 6:14

foldr1(/).tail.init


Given a flat list like [a,b,c,d,e,f], tail.init removes the first and last elements, and then foldr1(/) creates a cascade of divisions b/(c/(d/e)))) that works out to alternating * and /: b/c*d/e.

• but the question states that the programs gets list of 2-tuples, not a flat list Jul 23 '16 at 16:23
• A flat list was allowed in the comments.
– xnor
Jul 23 '16 at 19:43

# Jelly, 6 bytes

ḊṖU÷@/


Test suite.

ḊṖU÷@/   Main monadic chain. temp <- third argument (first input)
Ḋ        temp <- temp with first element removed
Ṗ       temp <- temp with last element removed
U      temp <- temp reversed
÷@/   temp <- temp reduced by reversed floating-point division.
implicitly output temp.

• Ah, alternating division. That's clever. Jul 23 '16 at 6:07

# Jelly, 7 bytes

U÷Ḣµ2\P


# C, 11512312183807671 70 bytes

4 bytes saved thanks to @LeakyNun!

My first golf, probably not the best.

c;float r=1;float g(a,s)int*a;{for(;c<s-2;)r*=a[++c]/a[++c];return r;}


Takes an array and size.

Ungolfed:

int counter;
float ret=1;
float gear(int *arr, int size) {
for(; counter < size-2; )
ret = ret * arr[++counter] / arr[++counter];
return ret;
}

• Welcome to PPCG! :) Jul 23 '16 at 8:55
• What is the maximum number of numbers you can support? Welcome to PPCG! Jul 23 '16 at 9:07
• j;float r=1;float f(int a[]){for(;j<sizeof a;)r=r*a[j++]/a[j++];return r;} (not tested) Jul 23 '16 at 10:13
• Not j++, ++j and sizeof-2. 4 bytes saved. Thanks! Jul 23 '16 at 10:24
• It seems we can't measure the size of passed arrays. I edited the answer. Jul 23 '16 at 10:57

## JavaScript (ES6), 44 bytes

a=>(t=1,a.reduce((x,y)=>(t*=x[1]/y[0],y)),t)


37 bytes for a flattened array:

a=>1/a.slice(1,-1).reduce((x,y)=>y/x)


Unlike (e.g.) Haskell, reduceRight is such a long name that it's cheaper to reduce the wrong way and take the reciprocal at the end.

• inspired answer there... I couldn't have gone lower than that... Jul 28 '16 at 23:58

# Pyth, 8 bytes

.UcZb_Pt


Test suite.

# J, 8 bytes

%/@}:@}.


Try it online!

## Usage

>> f =: %/@}:@}.

>> f 1 1 2 2
<< 0.5

>> f 1 2 1 2 1 2
<< 4

>> f 6 12 3 10 5 8
<< 8


where >> is STDIN and << is STDOUT.

## Explanation

"Reduce" in J defaults from right to left, which took off a few bytes :p

divide       =: %
reduce       =: /
atop         =: @
remove_first =: }.
remove_last  =: }:

f =: (divide reduce) atop (remove_last) atop (remove_first)


## Mathematica, 26 bytes

#2/#&~Fold~#[[-2;;2;;-1]]&


An unnamed function that takes a flat even-length list of values and returns the exact result (as a fraction if necessary).

This uses the same approach as some other answers of folding division over the reversed list (after removing the first and last element).

# MATL, 9 bytes

6L)9L&)/p


Input format is any of these:

[[6,12],[3,10],[5,8]]
[6,12,3,10,5,8]
[6 12 3 10 5 8]


EDIT (July 30, 2016): the linked code replaces 9L by 1L to adapt to recent changes in the language.

Try it online!

### Explanation

6L    % Predefined literal: index from second to second-last element
)     % Apply index to implicit input. Removes first and last elements
9L    % Predefined literal: index for elements at odd positions
&)    % Two-output indexing. Gives an array with the odd-position elements
% and the complementary array, with the even-position elements of the
% original array
/     % Divide those two arrays element-wise
p     % Product of all entries. Implicitly display


# JavaScript, 54 bytes

(a,s=1)=>a.map((v,i)=>s*=(x=a[i+1])?v[1]/x[0]:1).pop()


## Usage

f=(a,s=1)=>a.map((v,i)=>s*=(x=a[i+1])?v[1]/x[0]:1).pop()

document.write([
f([[1,1],[2,2]]),
f([[1,2],[1,2],[1,2]]),
f([[6,12],[3,10],[5,8]])
].join('<br>'))

## Ungolfed

function ( array ) {
var s = 1;                                  // Set initial speed

for ( var i = 0; i < array.length ; i++ ) { // Loop through array
if ( array[i + 1] === undefined ) {       // If last element
return s;                               // Return speed
} else {                                  // Else
s = s * ( array[i][0] / array[i+1][0])  // Calculate speed
}
}
}


Of course, the golfed variant is a bit different. With .map(), it replaces the first value of the array with the speed after the second wheel, the second value with the speed of the third wheel, and the last value and the second last value with the speed of the last wheel. So, we just take the last element with .pop().

# PHP, 8079 69 bytes

<?for($r=1;++$i<count($a=$_GET[a]);)$r*=$a[$i-1][1]/$a[$i][0];echo$r;


takes input from GET parameter a; prints result

initializes $r with 1, then loops from second to last tuple to multiply with first element of previous and divide through second element of current tuple. Thanks to Jörg for reminding me of $_GET; that saved 7 bytes.

more elegant version, 88 bytes:

<?=array_reduce($a=$_GET[a],function($r,$x){return$r*$x[1]/$x[0];},$a[0][0]/end($a)[1]);  • <?for($r=$i=1;$i<count($a=$_GET[a]);)$r*=$a[$i-1][1]/$a[$i++][0];echo$r; 72 Bytes Oct 30 '16 at 18:33

# JavaScript, 5958 56 bytes

a=>a.reduce((p,c)=>p*c[1]/c[0],a[0][0]/a[a.length-1][1])


# Explanation

Reduce the array and multiply by every second value and divide by every first value. So for [[6,12],[3,10],[5,8]] it does 12/6*10/3*8/5. Of course, the actual computation we wanted was 12/3*10/5 so we just want to ignore that first /6 and last *8 by multiplying *6 back in and dividing /8 back out. That cancelling out is done by setting 6/8 as the initial value for the reduce.

• I came to the same solution. You can save two bytes by appending the post-operations *.../... to the initial value 1. Jul 23 '16 at 19:24

# Python 2, 52 bytes

lambda x:reduce(lambda x,y:y/float(x),x[1:-1][::-1])


An anonymous function that takes input of a flattened list via argument and returns the output.

This makes use of the division cascade idea, as in xnor's answer.

Try it on Ideone

# Python 3, 59 bytes

lambda x:eval('/'.join('{}*{}'.format(*i)for i in x)[2:-2])


An anonymous function that takes input of a non-flattened list via argument and returns the output.

How it works

For every pair of integers in the input, a string of the form 'int1*int2' is created. Joining all these pairs on / gives a string of the form 'int1*int2/int3*int4/...', which is the desired calculation, but includes the undesired first and last integers. These are removed by slicing out the first two and last two characters in the sting, leaving the desired calculation. This is then evaluated and returned.

Try it on Ideone

# Pascal, 88 bytes

A recursive (had to do it..) function that takes a static 2D array and its length (no. of rows) as an input. Using some pointer math on the array.

function r(a:p;n:integer):double;begin r:=a[1]/a[2];if n=2then exit;r:=r*r(a+2,n-1);end;


Ungolfed with usage example:

type
p = ^double;
var
n: integer = 3;
garray: array [0..2, 0..1] of double;

function ratio(a: p; n: integer): double;
begin
ratio := a[1] / a[2];
if n=2 then
Exit;
ratio := ratio * ratio(a+2, n-1);
end;

begin
garray[0,0] := 6; garray[0,1] := 12;
garray[1,0] := 3; garray[1,1] := 10;
garray[2,0] := 5; garray[2,1] := 8;
writeln(ratio(@garray, n));
end.


## Actually, 14 bytes

pXdX2@╪ki/Mπ


Try it online! (currently not working because TIO is a few versions behind)

This program takes a flattened list as input.

Explanation:

pXdX2@╪ki/Mπ
pXdX            remove the first and last elements
2@╪k        push a list where each element is a list containing every two elements of the original list (chunk into length-2 lists)
i/M   map division over each sublist
π  product


# R, 64 bytes

Turns out the vectorized approach and the for loop are equivalent in this case:

x=scan();prod(sapply(1:(sum(1|x)/2-1)*2,function(i)x[i]/x[i+1]))


or the for loop:

x=scan();for(i in 1:(sum(1|x)/2-1)*2)T=c(T,x[i]/x[i+1]);prod(T)}


$$`$$