Trem de engrenagem, Girando

16

As engrenagens transferem uma quantidade diferente de velocidades, dependendo do tamanho da engrenagem engrenada.

trem de engrenagem

Jack tem uma máquina que gira um trem de engrenagens. mas você não sabe a velocidade da última marcha.

Felizmente, você é um ótimo jogador de código, para ajudá-lo!

Então, o que eu deveria fazer?

Cada engrenagem é representada por 2 números, o raio da engrenagem interna e o raio das engrenagens externas.

Se a engrenagem Aé [a,b]e a engrenagem Bé [c,d], então a relação entre a velocidade de Ae a velocidade de Bseria c:b.

Dada uma lista de marchas (lista de 2 tuplas), produza a velocidade da última marcha.

Você pode assumir que a velocidade da primeira marcha é 1.

Exemplo elaborado

Digamos que nossa entrada seja [[6,12],[3,10],[5,8]].

A primeira marcha [6,12],, teria uma velocidade de 1.

Então, a segunda marcha [3,10],, teria uma velocidade de 1*12/3 = 4.

Então, a última marcha [5,8],, teria uma velocidade de 4*10/5 = 8.

Casos de teste

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)

Regras

Aplicam-se regras básicas .

Freira Furada
fonte
6
Como você está permitindo a saída de ponto flutuante, você provavelmente deve esclarecer a precisão dos resultados.
Martin Ender
Podemos considerar a entrada como uma lista achatada em vez da lista de tuplas?
Freira vazando
Sim sim [6,12,3,10,5,8]. apenas mencione se você quiser usá-lo.
11
Isso é um pouco injusto. Eu tinha uma versão diferente de 7 bytes que não publiquei porque a considerava menos interessante. Seria 6 bytes sem achatar. Considere usar o sandbox da próxima vez para evitar esse tipo de situação.
Dennis

Respostas:

8

Haskell, 19 bytes

foldr1(/).tail.init

Dada uma lista simples como [a,b,c,d,e,f] , tail.initremove os primeiros e últimos elementos, e, em seguida, foldr1(/)cria uma cascata de divisões b/(c/(d/e))))que trabalha para fora para alternada *e /: b/c*d/e.

xnor
fonte
mas a pergunta afirma que os programas obtêm uma lista de 2-tuplas, não uma lista simples
Nome de exibição
1
Uma lista simples foi permitida nos comentários.
xnor
7

Geléia , 6 bytes

ḊṖU÷@/

Suíte de teste.

ḊṖ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.
Freira Furada
fonte
1
Ah, divisão alternada. Isso é esperto.
Dennis
5

C, 115 123 121 83 80 76 71 70 bytes

4 bytes salvos graças a @LeakyNun!

Meu primeiro golfe, provavelmente não o melhor.

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

Toma uma matriz e tamanho.

Ungolfed:

int counter;
float ret=1;
float gear(int *arr, int size) {
    for(; counter < size-2; )
        ret = ret * arr[++counter] / arr[++counter];
    return ret;
}
betseg
fonte
5
Bem-vindo ao PPCG! :)
Martin Ender
Qual é o número máximo de números que você pode suportar? Bem-vindo ao PPCG!
Leaky Nun
j;float r=1;float f(int a[]){for(;j<sizeof a;)r=r*a[j++]/a[j++];return r;}(não testada)
gotejante Nun
Não j ++, ++ j e sizeof-2. 4 bytes salvos. Obrigado!
betseg
Parece que não podemos medir o tamanho das matrizes passadas. Eu editei a resposta.
betseg
4

JavaScript (ES6), 44 bytes

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

37 bytes para uma matriz nivelada:

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

Ao contrário de (por exemplo) Haskell, reduceRighté um nome tão longo que é mais barato para reduceo lado errado e assume o recíproco no final.

Neil
fonte
resposta inspirada lá ... Eu não poderia ter ido mais baixa do que ...
Wally West
3

Pitão, 8 bytes

.UcZb_Pt

Suíte de teste.

Freira Furada
fonte
3

J, 8 bytes

%/@}:@}.

Experimente online!

Uso

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

>> f 1 1 2 2
<< 0.5

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

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

onde >>está STDIN e<< STDOUT.

Explicação

"Reduzir" os Jpadrões da direita para a esquerda, que decolaram alguns bytes: p

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

f =: (divide reduce) atop (remove_last) atop (remove_first)
Freira Furada
fonte
3

Mathematica, 26 bytes

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

Uma função sem nome que pega uma lista plana e uniforme de valores e retorna o resultado exato (como uma fração, se necessário).

Isso usa a mesma abordagem que algumas outras respostas da divisão de dobras na lista invertida (após remover o primeiro e o último elemento).

Martin Ender
fonte
2

MATL , 9 bytes

6L)9L&)/p

O formato de entrada é um destes:

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

EDIT (30 de julho de 2016): o código vinculado substitui 9Lpor 1Lpara se adaptar às alterações recentes no idioma.

Experimente online!

Explicação

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
Luis Mendo
fonte
1

JavaScript, 54 bytes

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

Uso

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

Obviamente, a variante do golfe é um pouco diferente. Com .map(), ele substitui o primeiro valor da matriz pela velocidade após a segunda roda, o segundo valor pela velocidade da terceira roda e o último valor e o segundo último valor pela velocidade da última roda. Então, apenas pegamos o último elemento com .pop().

LarsW
fonte
1

PHP, 80 79 69 bytes

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

recebe entrada do parâmetro GET a; imprime resultado

inicializa $rcom 1, depois faz o loop da penúltima penúltima para multiplicar com o primeiro elemento do anterior e dividir pelo segundo elemento da tupla atual.


Agradeço a Jörg por me lembrar $_GET; que economizou 7 bytes.


versão mais elegante, 88 bytes:

<?=array_reduce($a=$_GET[a],function($r,$x){return$r*$x[1]/$x[0];},$a[0][0]/end($a)[1]);
Titus
fonte
1
<?for($r=$i=1;$i<count($a=$_GET[a]);)$r*=$a[$i-1][1]/$a[$i++][0];echo$r;72 Bytes
Jörg Hülsermann 30/10
0

JavaScript, 59 58 56 bytes

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

Explicação

Reduza a matriz e multiplique por cada segundo valor e divida por cada primeiro valor. Então, para [[6,12],[3,10],[5,8]]isso acontece 12/6*10/3*8/5. Obviamente, o cálculo real que queríamos era 12/3*10/5apenas o de ignorar o primeiro /6e o último *8, multiplicando de *6volta e dividindo de /8volta. Esse cancelamento é feito definindo 6/8como o valor inicial para a redução.

Davis
fonte
Eu vim para a mesma solução. Você pode salvar dois bytes anexando as pós-operações *.../...ao valor inicial 1.
Titus
0

Python 2, 52 bytes

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

Uma função anônima que recebe entrada de uma lista nivelada por meio de argumento e retorna a saída.

Isso faz uso da idéia de cascata de divisão, como na resposta do xnor .

Experimente no Ideone

TheBikingViking
fonte
0

Python 3, 59 bytes

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

Uma função anônima que recebe entrada de uma lista não nivelada por meio de argumento e retorna a saída.

Como funciona

Para cada par de números inteiros na entrada, uma sequência do formulário 'int1*int2'é criada. A união de todos esses pares /fornece uma sequência do formulário'int1*int2/int3*int4/...' , que é o cálculo desejado, mas inclui o primeiro e o último número inteiro indesejados. Eles são removidos cortando os dois primeiros e os últimos dois caracteres da picada, deixando o cálculo desejado. Isso é então avaliado e retornado.

Experimente no Ideone

TheBikingViking
fonte
0

Pascal, 88 bytes

Uma função recursiva (tinha que fazer isso ..) que usa uma matriz 2D estática e seu comprimento (número de linhas) como entrada. Usando alguma matemática de ponteiro na matriz.

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;

Sem jogar com o exemplo de uso:

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.
hdrz
fonte
0

Na verdade, 14 bytes

pXdX2@╪k`i/`Mπ

Experimente online! (atualmente não está funcionando porque o TIO está algumas versões atrasado)

Este programa usa uma lista achatada como entrada.

Explicação:

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
Mego
fonte
0

R, 64 bytes

Acontece que a abordagem vetorizada e a for loop são equivalentes neste caso:

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

ou o for loop:

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

`

Billywob
fonte