16
\$\begingroup\$

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

gear train

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.

\$\endgroup\$
  • 6
    \$\begingroup\$ Since you're allowing floating point output, you should probably clarify how accurate results have to be. \$\endgroup\$ – Martin Ender Jul 23 '16 at 5:56
  • \$\begingroup\$ Can we take input as a flattened list instead of list of tuples? \$\endgroup\$ – Leaky Nun Jul 23 '16 at 6:11
  • \$\begingroup\$ Yes, like [6,12,3,10,5,8]. just mention it if you wanna use it. \$\endgroup\$ – user54200 Jul 23 '16 at 6:12
  • 11
    \$\begingroup\$ 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. \$\endgroup\$ – Dennis Jul 23 '16 at 6:14

17 Answers 17

8
\$\begingroup\$

Haskell, 19 bytes

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.

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

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.
\$\endgroup\$
  • 1
    \$\begingroup\$ Ah, alternating division. That's clever. \$\endgroup\$ – Dennis Jul 23 '16 at 6:07
5
\$\begingroup\$

Jelly, 7 bytes

U÷Ḣµ2\P

Try it online! or verify all test cases.

\$\endgroup\$
5
\$\begingroup\$

C, 115 123 121 83 80 76 71 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;
}
\$\endgroup\$
  • 5
    \$\begingroup\$ Welcome to PPCG! :) \$\endgroup\$ – Martin Ender Jul 23 '16 at 8:55
  • \$\begingroup\$ What is the maximum number of numbers you can support? Welcome to PPCG! \$\endgroup\$ – Leaky Nun Jul 23 '16 at 9:07
  • \$\begingroup\$ j;float r=1;float f(int a[]){for(;j<sizeof a;)r=r*a[j++]/a[j++];return r;} (not tested) \$\endgroup\$ – Leaky Nun Jul 23 '16 at 10:13
  • \$\begingroup\$ Not j++, ++j and sizeof-2. 4 bytes saved. Thanks! \$\endgroup\$ – betseg Jul 23 '16 at 10:24
  • \$\begingroup\$ It seems we can't measure the size of passed arrays. I edited the answer. \$\endgroup\$ – betseg Jul 23 '16 at 10:57
4
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ inspired answer there... I couldn't have gone lower than that... \$\endgroup\$ – WallyWest Jul 28 '16 at 23:58
3
\$\begingroup\$

Pyth, 8 bytes

.UcZb_Pt

Test suite.

\$\endgroup\$
3
\$\begingroup\$

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)
\$\endgroup\$
3
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

PHP, 80 79 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]);
\$\endgroup\$
  • 1
    \$\begingroup\$ <?for($r=$i=1;$i<count($a=$_GET[a]);)$r*=$a[$i-1][1]/$a[$i++][0];echo$r; 72 Bytes \$\endgroup\$ – Jörg Hülsermann Oct 30 '16 at 18:33
0
\$\begingroup\$

JavaScript, 59 58 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.

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

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

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

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.
\$\endgroup\$
0
\$\begingroup\$

Actually, 14 bytes

pXdX2@╪k`i/`Mπ

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

This program takes a flattened list as input.

Explanation:

pXdX2@╪k`i/`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
\$\endgroup\$
0
\$\begingroup\$

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

`

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy