Armas de instrução matemática


44

A última vez em que tentei criar algo fácil que não fosse duplicado, acabou sendo muito difícil. Então, espero que desta vez seja algo que os novatos também possam tentar.

Entrada:

Uma matriz / lista com números inteiros / decimais. (Ou uma sequência que representa uma matriz com números inteiros / decimais.)

Resultado:

Faça um loop pelos números e aplique os cinco operandos matemáticos a seguir nesta ordem:

  • Adição ( +);
  • Subtração ( );
  • Multiplicação ( *ou ×ou ·);
  • Divisão Real / Calculadora ( /ou ÷);
  • Exponenciação ( ^ou **).

(NOTA: Os símbolos entre parênteses são apenas adicionados como esclarecimento. Se sua linguagem de programação usa um símbolo completamente diferente para a operação matemática dos exemplos, é claro que isso é completamente aceitável.)

Continue continuando até chegar ao final da lista e forneça o resultado da soma.

Regras do desafio:

  • A exponenciação por 0 ( n ^ 0) deve resultar em 1 (isso também se aplica a 0 ^ 0 = 1).
  • Não há casos de teste para divisão por 0 ( n / 0), então você não precisa se preocupar com esse caso extremo.
  • Se a matriz contiver apenas um único número, retornamos isso como resultado.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados, programas completos. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.

Casos de teste:

[1,2,3,4,5] -> 0
-> 1 + 2 = 3
  -> 3 - 3 = 0
    -> 0 * 4 = 0
      -> 0 / 5 = 0 

[5,12,23,2,4,4,2,6,7] -> 539
-> 5 + 12 = 17
  -> 17 - 23 = -6
    -> -6 * 2 = -12
      -> -12 / 4 = -3
        -> -3 ^ 4 = 81
          -> 81 + 2 = 83
            -> 83 - 6 = 77
              -> 77 * 7 -> 539

[-8,50,3,3,-123,4,17,99,13] -> -1055.356...
-> -8 + 50 = 42
  -> 42 - 3 = 39
    -> 39 * 3 = 117
      -> 117 / -123 = -0.9512...
        -> -0.9512... ^ 4 = 0.818...
          -> 0.818... + 17 = 17.818...
            -> 17.818... - 99 -> -81.181...
              -> -81.181... * 13 = -1055.356...

[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256
-> 2 + 2 = 4
  -> 4 - 2 = 2
    -> 2 * 2 = 4
      -> 4 / 2 = 2
        -> 2 ^ 2 = 4
          -> 4 + 2 = 6
            -> 6 - 2 = 4
              -> 4 * 2 = 8
                -> 8 / 2 = 4
                  -> 4 ^ 2 = 16
                    -> 16 + 2 = 18
                      -> 18 - 2 = 16
                        -> 16 * 2 = 32
                          -> 32 / 2 = 16
                            -> 16 ^ 2 = 256

[1,0,1,0,1,0] -> 1
-> 1 + 0 = 1
  -> 1 - 1 = 0
    -> 0 * 0 = 0
      -> 0 / 1 = 0
        -> 0 ^ 0 = 1

[-9,-8,-1] -> -16
  -> -9 + -8 = -17
    -> -17 - -1 = -16

[0,-3] -> -3
  -> 0 + -3 = -3

[-99] -> -99

Não é divisão inteira?
Freira vazada

@LeakyNun Não. Talvez eu deva alterar a entrada para uma lista com casas decimais em vez de números inteiros devido à divisão (e caso de teste 3)?
Kevin Cruijssen

Isso estava na caixa de areia?
Bálint

9
Em matemática, existem duas "regras" conflitantes:, n ^ 0 = 1mas 0 ^ n = 0. O conflito é resolvido definindo as n != 0duas regras, mas deixa 0 ^ 0indefinido. No entanto, existem muitas coisas que se encaixam perfeitamente na matemática, se isso 0 ^ 0for definido 1. Veja a Wikipedia para alguns detalhes.
Mego

1
@ Bálint As regras afirmam que nunca haverá uma entrada válida com uma divisão por zero. Você não precisa se preocupar com esse caso extremo.
Mego

Respostas:


7

Gelatina , 13 bytes

“+_×÷*”ṁṖ⁸żFV

Experimente online! ou verifique todos os casos de teste .

Como funciona

“+_×÷*”ṁṖ⁸żFV  Main link. Argument: A (list of integers)

“+_×÷*”        Yield the list of operations as a string.
        Ṗ      Yield A popped, i.e., with its last element removed.
       ṁ       Mold; reshape the string as popped A.
               This repeats the characters of the string until it contains
               length(A)-1 characters.
         ⁸ż    Zipwith; pairs the integers of A with the corresponding characters.
           F   Flatten the result.
            V  Eval the resulting Jelly code.
               Jelly always evaluates left-to-right (with blatant disregard towards
               the order of operations), so this returns the desired result.

Bom, isso é um número de bytes 8 menor que o Pyke , que estava atualmente na liderança.
Kevin Cruijssen

3
Ninguém supera o Dennis. Nunca.
Azul

1
Apenas uma pergunta: ele realmente conta como 13 bytes com todos esses caracteres não-ascii?
Xavier Dury

3
@XavierDury Sim. O link de bytes no cabeçalho leva à própria página de códigos de Jelly, que codifica os 256 caracteres que Jelly entende como um único byte cada.
Dennis

@ Dennis Obrigado pela precisão!
Xavier Dury

19

Javascript ES7 49 bytes

a=>a.reduce((c,d,e)=>[c**d,c+d,c-d,c*d,c/d][e%5])

Economizou 9 bytes graças a Dom Hastings, economizou outros 6 graças a Leaky Nun

Usa o novo operador de exponenciação.


@LeakyNun isso não produzirá apenas Infinity, não será um erro?
Dom Hastings

Tente usar eval pode ser mais curto
Downgoat

@Upgoat Ela costumava eval primeiro, depois Leaky Nun me mostrou, que é melhor, para fazê-lo assim
Bálint

@ Por que você está usando tantas vírgulas?
Rɪᴋᴇʀ

1
@ EᴀsᴛᴇʀʟʏIʀᴋ Falante não nativo. Bálint costuma fazer isso. A gramática inglesa é tola na melhor das hipóteses.
wizzwizz4

11

Haskell, 76 65 64 62 bytes

Obrigado a @ Damien por remover mais dois bytes =)

f(u:v)=foldl(\x(f,y)->f x y)u(zip(v>>[(+),(-),(*),(/),(**)])v)

Isso usa o >>que aqui apenas anexa a lista [(+),...]às length vvezes em si . O restante ainda funciona da mesma forma que as versões antigas.

Versões antigas:

Essas soluções fazem uso das listas infinitas, como cycle[...]apenas repete a lista fornecida infinitamente. Então, basicamente, ele é zipeditado com a lista de números e nós apenas fold( reduzimos em outros idiomas) a lista compactada por meio de um lambda, que aplica os operadores ao elemento acumulador / lista atual.

f(u:v)=foldl(\x(f,y)->f x y)u(zip(cycle[(+),(-),(*),(/),(**)])v)

f(u:v)=foldl(\x(y,f)->f x y)u(zip v(cycle[(+),(-),(*),(/),(**)]))

f l=foldl(\x(y,f)->f x y)(head l)(zip(drop 1l)(cycle[(+),(-),(*),(/),(**)]))

você pode substituir o ciclo por: v >>
Damien

@ Damien Muito obrigado!
flawr

Hum foldl(&)u$zipWith(&)v(flip<$>v>>[…])?
Bergi

@ Bergi Sinceramente, não consigo mais ler o que isso está fazendo =) De qualquer forma, precisamos de um importpara &, de modo que seria mais longo novamente, mas, de qualquer forma, obrigado!
flawr

@ flawr: Na verdade, minha ideia foi exatamente a mesma que Lazersmoke postou como resposta , eu simplesmente não tinha lido. Eu consegui ao tentar simplificar essa sua lamda com algo parecido uncurry. Não deu certo, mas notei que você deve salvar outro byte usando em $vez de parênteses.
Bergi

8

Pyke, 22 21 bytes

lt5L%"+-*/^"L@\RJQ_XE

Experimente aqui!

lt5L%                 -    map(len(input)-1, %5)
     "+-*/^"L@        -   map(^, "+-*/^"[<])
              \RJ     -  "R".join(^)
                    E - pyke_eval(^, V)
                 Q_X  -  splat(reversed(input))

7

Haskell, 61 bytes

foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])

Cria uma série de transformações em uma lista, como em [adicionar 1, adicionar 2, subtrair 3, ...], começando com 2 adições porque começamos com 0 na dobra. A seguir, fazemos o que chamo de List Application Fold, ou foldl (flip id), que aplica uma lista de homomorfismos em série. Isso começa com zero, adiciona o valor inicial e depois todas as transformações computadas acima para obter um resultado final.

Observe que (flip id) é igual a (\ x y-> yx), apenas mais curto.

Uso da amostra:

f = foldl(flip id)0.zipWith flip((+):cycle[(+),(-),(*),(/),(**)])
f [1,2,3,4,5] -- Is 0.0

Em vez de flip id, você pode simplesmente usar &. Or flip($). Uau, eu nunca percebi($) = id
Bergi

1
@ Bergi: &está definido em Data.Function, então você precisa do importtambém. Talvez algum intérprete online o importe por padrão, mas você precisará especificar qual deles usar.
N

7

TSQL 116 115 88 bytes

Graças à sugestão de Ross Presser, consegui jogar com até 88 caracteres

-- In Try-it code, this must be DECLARE @y TABLE 
CREATE TABLE T(a real, i int identity)
INSERT T values(5),(12),(23),(2),(4),(4),(2),(6),(7)

DECLARE @ REAL SELECT @=CHOOSE(i%5+1,@/a,ISNULL(POWER(@,a),a),@+a,@-a,@*a)FROM T
PRINT @

Experimente online


1
1 byte a menos: exige que a tabela de entrada seja nomeada T em vez de @y. A solução PL / SQL tinha isso, então por que não o TSQL.
Ross Presser

@RossPresser sim, é claro. como eu senti falta disso? Não é possível no link de teste, não há permissões para criar tabelas e somente será executado corretamente na primeira vez em um banco de dados. Mas o que importa quando um personagem pode jogar golfe? Obrigado pela sua dica, sua melhoria foi adicionada
t-clausen.dk 13/06/16

Golpeou outros 12 bytes: use CHOOSE em vez de IIF aninhado, deixando um IIF para o caso i = 1. Com sua permissão, editarei a resposta.
precisa

resposta editada. Aqui está o try-lo ligar - eu sou anônimo para que ele não tem nome depois dele: data.stackexchange.com/stackoverflow/query/edit/499612
Ross Presser

1
@ RossPresser Eu não sabia ESCOLHER. incluída a sua sugestão e golfed-lo um pouco mais
t-clausen.dk

6

Pitão, 27 26 25 bytes

.v+>tlQ*lQ"^c*-+":jdQ\-\_

Suíte de teste.

Pyth usa a notação de prefixo: 1+2é escrito como +1 2(espaço necessário para separar números).

Portanto, para o primeiro caso de teste, a expressão seria (((1+2)-3)*4)/5, que na notação de prefixo, seria escrita como /*-+ 1 2 3 4 5.

Em Pyth, a divisão de flutuação é em cvez de /, então ela se torna c*-+ 1 2 3 4 5.

Além disso, em Pyth, -100está escrito como alternativa _100.

Portanto, para o caso de teste em terceiro lugar, que é ((((((((-8+50)-3)*3)/-123)^4)+17)-99)*13), torna-se: *-+^c*-+ _8 50 3 3 _123 4 17 99 13.

.v+>tlQ*lQ"^c*-+":jdQ\-\_
                  jdQ       Join input by space.
                 :   \-\_   Replace "-" with "_".
   >tlQ*lQ"^c*-+"           Generate the string "...^c*-+" of suitable length.
  +                         Join the two strings above.
.v                          Evaluate as a Pyth expression.

História


Você é rápido! Parece que eu consegui fazer um desafio mais fácil. Ou você é tão bom assim. ;)
Kevin Cruijssen



6

Na verdade, 23 bytes

;l"+-*/ⁿ"*@R':j':+'?o+ƒ

Experimente online!

Na verdade, usa a notação postfix para matemática, e os operadores que apenas recebem dois argumentos (como os operadores para adição, subtração, multiplicação, divisão e exponenciação) não fazem nada quando existe apenas um elemento na pilha. Assim, transformar a entrada em código na verdade é tão simples quanto reverter a entrada, formatá-la como numérica e anexar as operações. Em seguida, o código resultante pode ser executado, fornecendo a saída desejada.

Explicação:

;l"+-*/ⁿ"*@R':j':+'?o+ƒ
;l"+-*/ⁿ"*               repeat the operations a number of times equal to the length of the input
                            (since extraneous operations will be NOPs, there's no harm in overshooting)
          @R             reverse the input
            ':j          join on ":" (make a string, inserting ":" between every pair of elements in the list)
               ':+       prepend a ":" (for the first numeric literal)
                  '?o    append a "?"
                           (this keeps the poor numeric parsing from trying to gobble up the first + as part of the numeric literal, since ? isn't interpreted as part of the literal, and is a NOP)
                     +   append the operations string
                      ƒ  cast as a function and call it

Exemplo de código traduzido para entrada 1,2,3,4,5:

:5:4:3:2:1?+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ+-*/ⁿ

3
Amo a maneira como o nome das fusões idioma com a contagem de bytes
user6245072

3
s/Actually uses postfix notation/Actually actually uses postfix notation/
Leaky Nun


5

J, 40 bytes

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)

Localiza o número de valores necessários para usar um múltiplo de 5 operadores, que pads com os valores de identidade desses operadores. Em ordem, +é 0, -é 0, *é 1, %é 1 e ^é 1, que pode ser um valor de bit 00111ou 7 na base 10. Em seguida, opera nessa lista enquanto percorre os operadores.

Uso

   f =: ^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#)
   f 1 2 3 4 5
0
   f 5 12 23 2 4 4 2 6 7
539
   f _8 50 3 3 _123 4 17 99 13
_1055.36
   f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
256
   f 1 0 1 0 1 0
1
   f _9 _8 _1
_16
   f 0 _3
_3
   f _99
_99

Explicação

^~`(%~)`*`(-~)`+/@(|.@,7#:~#&2)(5-5|4+#) Input: A
                                      #  Get length of A
                                    4+   Add four to it
                                  5|     Take it mod 5
                                5-       Find 5 minus its value, call it x
                           #&2           Create x copies of 2
                       7#:~              Convert 7 to base 2 and take the last x digits
                      ,                  Append those x digits to the end of A
                   |.@                   Reverse it, call it A'
^~                                       Power, reversed operators
    %~                                   Division, reversed operators
       *                                 Multiplication
         -~                              Subtraction, reversed operators
            +                            Addition
             /@                          Insert the previous operations, separated by `,
                                         into A' in order and cycle until the end
                                         Then evaluate the equation from right-to-left
                                         and return

5

Python 2, 81 67 64 bytes

i=10
for n in input():exec'r%s=n'%'*+-*/*'[i::5];i=-~i%5
print r

Entrada é uma matriz de carros alegóricos. Teste em Ideone .

Como funciona

'*+-*/*'[i::5]seleciona cada quinto caractere da sequência, começando com o do índice i , portanto, isso gera **se i = 0 , +se i = 1 , -se i = 2 , *se i = 3 e /se i = 4 . Como a cadeia tem comprimento 6 , a expressão produzirá uma cadeia vazia se i> 5 .

Inicializamos a variável i para 10 . Para cada número n na matriz de entrada, construímos a string r<op>=nque é execexecutada.

Inicialmente, i = 10 , também <op>é a string vazia e inicializa r com r+=n. Após cada etapa, incrementamos i modulo 5 com i=-~i%5, por isso, o próximo passo será recuperar o operador adequado.

Quando todos os números de entrada tiverem sido processados, imprimiremos r , que mantém a saída desejada.


5

Matlab - 95 91 85 bytes / oitava - 81 bytes

A entrada está nesta forma a = ['1' '2' '3' '4' '5'];:, espero que isso seja coberto por "string representando uma matriz com números inteiros / decimais"; caso contrário, são necessários 2 num2str adicionalmente.

Todo resultado intermediário é impresso no console, porque isso me salva alguns pontos e vírgulas. a(1)é executado para que seu valor seja salvo em ans. Também é claro que usar anscódigo não é uma boa prática.

b='+-*/^'
a(1)
for i=2:length(a)
  ['(',ans,')',b(mod(i-2,5)+1),a(i)]
end
eval(ans)

No Octave, '+-*/^'(mod(i+2,5)+1)também funciona, o que economiza outros 4 bytes, graças a Adám e Luis Mendo:

a(1)
for i=2:length(a)
  strcat('(',ans,')','+-*/^'(mod(i-2,5)+1),a(i))
end
eval(ans)

Changelog:

  • Espaços removidos sempre que possível
  • solução Octave adicionada
  • strcat () substituído por []

Olá, seja bem-vindo ao PPCG! A entrada é boa assim, pois ainda é facilmente distinguível qual é a entrada. Hmm, eu nunca usei Matlab, então talvez eu estou dizendo coisas idiotas aqui, mas não pode b = '+-*/^'ser golfed de b='+-*/^'e for i = 2:length(a)para for i=2:length(a)(retirar os espaços)? Além disso, talvez Dicas para jogar golfe no MATLAB possam ser interessantes para você. :)
Kevin Cruijssen

É '+-*/^'(mod(i+2,5)+1)válido?
Adám 14/06/16

@ Adám Não, mas ele provavelmente está em Octave
Luis Mendo

@ Adám: funciona em oitava, adicionei.
Lukas K.

4

Mathematica, 67 66 65 bytes

Fold[{+##,#-#2,#2#,#/#2,If[#2==0,1,#^#2]}[[i++~Mod~5+1]]&,i=0;#]&

Simples Foldcom uma variável isegurando o índice.


Um byte pode ser salvo por, em +##vez de#+#2
LLlAMnYP

4

CJam, 18 bytes

q~{"+-*/#"W):W=~}*

Entrada é uma matriz de carros alegóricos. Experimente online!

Como funciona

q~                  Read and evaluate all input.
  {             }*  Reduce:
   "+-*/#"            Push the string of operators.
          W           Push W (initially -1).
           ):W        Increment and save in W.
              =       Retrieve the character at that index.
               ~      Evaluate.

4

R , 87 78 70 bytes

i=0
Reduce(function(a,j)get(substr("+-*/^",i<<-i%%5+1,i))(a,j),scan())

Experimente online!


em algum momento eu realmente preciso aprender a usar do.call... Eu provavelmente não deveria me considerar um programador R até que o faça!
Giuseppe

1
@Giuseppe Advanced Rpor Hadley Wickam é uma grande praia ler :)
Jayce

@ Giuseppe obrigado por apontar do.call- me fez perceber que estava procurando get.
jayce

3

Haskell - 74

f(x:xs)=foldl(\x(o,y)->o x y)x(zip(cycle[(+),(-),(*),(/),flip(^).floor])xs)

Casos de teste:

λ> f[1,2,3,4,5] -> 0.0
λ> f[5,12,23,2,4,4,2,6,7] -> 539.0
λ> f[-8,50,3,3,-123,4,17,99,13] -> -1055.356943846277
λ> f [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] -> 256.0

Provavelmente poderia ser mais curto; O suporte de Haskell a listas infinitas e funções de ordem superior torna a solução direta bastante agradável. Uma versão do ^ :: Double -> Double -> Doubleseria mais agradável para jogar golfe, mas não consegui encontrar uma. Felizmente, eu não precisava de um lambda completo, de modo que o estilo inútil raspava alguns bytes.


2
Você pode preceder uma única (+)à lista de operadores e começar a foldlcom 0a ir completamente pointfree e salvar o nome da função e parâmetros: foldl(\x(o,y)->o x y)0.zip((+):cycle[(+),(-),(*),(/),(**)]).
N

3

PowerShell v2 +, 124 bytes

param($n)$o=$n[0];if($y=$n.count-1){1..$y|%{$o=if(($x=$i++%5)-4){"$o"+'+-*/'[$x]+$n[$_]|iex}else{[math]::pow($o,$n[$_])}}}$o

Muito tempo, porque o PowerShell não possui um operador ^ou **, portanto, precisamos contabilizar um caso separado e usar uma chamada .NET.

Pega a entrada $ncomo uma matriz, define nossa saída $ocomo o primeiro dígito. Em seguida, verificamos o .countarray e, desde que seja maior que um, inserimos o if. Caso contrário, pularemos o if.

Dentro do ifloop pela matriz 1..$y|%{...}e a cada iteração, redefinimos $opara um novo valor, o resultado de outra if/elseinstrução. Desde que nosso contador $i++não seja o módulo-5 igual a 4 (ou seja, não estamos no ^operador), simplesmente o aceitamos $oe concatenamos com o símbolo apropriado '+-*/'[$x]e o próximo número na matriz de entrada $n[$_]. Nós canalizamos isso para iex(apelido para Invoke-Expressione semelhante a eval), e isso é salvo novamente $o. Se estamos no ^operador, estamos no else, então executamos uma [math]::Pow()chamada e esse resultado é salvo novamente $o.

Nos dois casos, simplesmente enviamos $opara o pipeline e saímos , com a saída implícita.


3

Ferrugem, 123 , 117 bytes

Resposta original:

fn a(v:&[f32])->f32{v.iter().skip(1).enumerate().fold(v[0],|s,(i,&x)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

nomes estúpidos de métodos longos ^^ ahh muito melhor

fn f(v:&[f32])->f32{v[1..].iter().zip(0..).fold(v[0],|s,(&x,i)|match i%5{0=>s+x,1=>s-x,2=>s*x,3=>s/x,_=>s.powf(x)})}

destroçado

fn f(values : &[f32]) -> f32 {
    values[1..].iter().zip(0..)
    .fold(values[0], |state,(&x,i)|
        match i%5 {
            0=>state+x,
            1=>state-x,
            2=>state*x,
            3=>state/x,
            _=>state.powf(x)
        }
    )
}

3

Perl 6 ,  70 68 65   62 bytes

{$/=[(|(&[+],&[-],&[*],&[/],&[**])xx*)];.reduce: {$/.shift.($^a,$^b)}}
{(@_ Z |(&[+],&[-],&[*],&[/],&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{(@_ Z |(*+*,*-*,&[*],*/*,&[**])xx*).flat.reduce: {&^b($^a,$^c)}}
{reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],*/*,&[**])xx*}

Explicação:

-> *@_ {
  reduce
    -> $a, &b, $c { b($a,$c) },

    flat       # flatten list produced from zip
      zip
        @_,    # input

        slip(  # causes the list of operators to flatten into the xx list

          # list of 5 infix operators
          &infix:<+>, &infix:<->, &infix:<*>, &infix:</>, &infix:<**>

        ) xx * # repeat the list of operators infinitely
}

Tecnicamente, * + *é uma lambda Qualquer que seja, mas é efetivamente a mesma &[+]que é a abreviação &infix:<+>do conjunto de sub-rotinas que lidam com adição numérica de infix.
Eu não usei isso para multiplicação ou exponenciação, pois as maneiras de escrevê-las dessa maneira são pelo menos contanto que eu tenho ( *×*ou * * *e * ** *)

Teste:

Teste no ideone.com
(depois de atualizarem para uma versão Rakudo que não é de um ano e meio antes do lançamento oficial dos shows do Perl 6 )

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
  [1,2,3,4,5] => 0,
  [5,12,23,2,4,4,2,6,7] => 539,
  [-8,50,3,3,-123,4,17,99,13] => -1055.35694385, # -2982186493/2825761
  [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] => 256,
  [1,0,1,0,1,0] => 1,
  [-9,-8,-1] => -16,
  [0,-3] => -3,
  [-99] => -99,
);

plan +@tests;

my &code = {reduce {&^b($^a,$^c)},flat @_ Z |(*+*,*-*,&[*],&[/],&[**])xx*}

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is code(@input), $expected, .gist
}
1..8
ok 1 - [1 2 3 4 5] => 0
ok 2 - [5 12 23 2 4 4 2 6 7] => 539
ok 3 - [-8 50 3 3 -123 4 17 99 13] => -1055.35694385
ok 4 - [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] => 256
ok 5 - [1 0 1 0 1 0] => 1
ok 6 - [-9 -8 -1] => -16
ok 7 - [0 -3] => -3
ok 8 - [-99] => -99


3

Python 3, 88 93 bytes

f=lambda x:eval('('*(len(x)-1)+'){}'.join(map(str,x)).format(*['+','-','*','/','**']*len(x)))

Começou sendo muito mais curto, mas a precedência do operador me derrotou e eu tive que incluir muitos parênteses ...


3

Oracle PL / SQL, 275 254 bytes

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Os dados devem ser inseridos em uma tabela chamada Tcom uma coluna Ndo tipoNUMBER

Uso:

drop table t;
create table t (n number);
insert into t values (-8);
insert into t values (50);
insert into t values (3);
insert into t values (3);
insert into t values (-123);
insert into t values (4);
insert into t values (17);
insert into t values (99);
insert into t values (13);

declare r number;begin for x in (select n,mod(rownum,5)r from t) loop if r is null then r:=x.n;elsif x.r=2then r:=r+x.n;elsif x.r=3then r:=r-x.n;elsif x.r=4then r:=r*x.n;elsif x.r=0then r:=r/x.n;else r:=r**x.n;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

Resultado:

-1055,356943846277162152071601242992595623

Versão de 275 bytes:

declare r number;cursor c is select n,mod(rownum,5) r from t;begin for x in c loop if r is null then r:=x.n;else case x.r when 2 then r:=r+x.n;when 3 then r:=r-x.n;when 4 then r:=r*x.n;when 0 then r:=r/x.n;else r:=r**x.n; end case;end if;end loop;DBMS_OUTPUT.PUT_LINE(r);end;

3

Java 8, 173 172 167 138 137 118 113 bytes

a->{double r=a[0],t;for(int i=1;i<a.length;r=new double[]{Math.pow(r,t),r+t,r-t,r*t,r/t}[i++%5])t=a[i];return r;}

Explicação:

Experimente aqui.

a->{                     // Method with double-array parameter and double return-type
  double r=a[0],         //  Result-double, starting at the first item of the input
         t;              //  Temp double
  for(int i=1;           //  Index-integer, starting at the second item
      i<a.length;        //  Loop over the input-array
      r=new double[]{    //    After every iteration, change `r` to:
         Math.pow(r,t),  //      If `i%5` is 0: `r^t`
         r+t,            //      Else-if `i%5` is 1: `r+t`
         r-t,            //      Else-if `i%5` is 2: `r-t`
         r*t,            //      Else-if `i%5` is 3: `r*t`
         r/t}[i++%5])    //      Else-if `i%5` is 4: `r/t`
                         //      And increase `i` by 1 afterwards with `i++`
    t=a[i];              //   Change `t` to the next item in the array
  return r;}             //  Return result-double

2
Porque, você sabe, os tempos java.1.5 mais tempo do que a resposta mais longa corrente .... wich é no SQL
Bálint

1
Você pode alterar double r=a[0];a double r=a[0],b;salvar alguns bytes.
Leaky Nun

1
@LeakyNun Originalmente eu tinha float, mas não há um Math.powpara carros alegóricos, daí o doublelugar. Obrigado pelo ,b. E com i++<a.lengtheu recebo uma ArrayOutOfBoundsException em b=a[i];(a menos que eu faça isso i++<a.length-1, que é um byte a mais em vez de mais curto).
Kevin Cruijssen

1
Você pode mudar == 4para > 3e == 0para < 1. Não tenho certeza, mas acho que você poderia economizar um pouco criando uma variável para i % 5.
Frozn 13/06/16

1
Achei que você pode mudar tudo para uma concatenação de ternários. Em todas as comparações, você pode usar o <xtruque, reduzindo a função inteira para 137 caracteres.
Frozn 13/06/19

3

Alguns truques podem reduzir a abordagem do @ Willmore em 23 a 174 bytes (requer o php 5.6 ou posterior). A parte mais econômica é remover parênteses desnecessários (-10 bytes).

função f ($ a) {while (count ($ a)> 1) {$ l = array_shift ($ a); $ r = array_shift ($ a); array_unshift ($ a, ($ j = $ i ++% 5) ($ j == 1? $ l- $ r: ($ j == 2? $ l * $ r: ($ j == 3? $ l / $ r: $ l ** $ r))): $ l + $ r);} retorno final ($ a);}

Mas usar o **operador em vez de pow()também permite usar evalcom uma matriz para as operações; e com mais alguns truques ...

PHP> = 5,6, 82 bytes

while(--$argc)eval('$x'.['/','**','+','-','*'][$i++?$i%5:2]."=$argv[$i];");echo$x;

pega a lista nos parâmetros da linha de comando. Corra com php -nr '<code>'ou experimente online .

versão antiga, 161 157 151 145 144 144 140 137 117 bytes

function f($a){while(count($a)>1)eval('$a[0]=array_shift($a)'.['+','-','*','/','**'][$i++%5].'$a[0];');return$a[0];}

O golfe mais eficaz veio da escrita do resultado intermediário diretamente no primeiro elemento - após a mudança do resultado anterior da matriz.

demolir

function f($a)
{
    while(count($a)>1)  // while array has more than one element ...
        eval('$a[0]='                           // future first element :=
            . 'array_shift($a)'                 // = old first element (removed)
            . ['+','-','*','/','**'][$i++%5]    // (operation)
            .'$a[0];'                           // new first element (after shift)
        );
    return$a[0];        // return last remaining element
}

suíte de teste

$cases = array (
    0=>[1,2,3,4,5],
    539=>[5,12,23,2,4,4,2,6,7],
    '-1055.356...' => [-8,50,3,3,-123,4,17,99,13],
    256 => [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
    1 => [1,0,1,0,1,0],
    -16 => [-9,-8,-1],
    -3 => [0, -3],
    -99 => [-99]
);
echo '<table border=1><tr><th>values</th><th>expected</th><th>actual result</th></tr>';
foreach ($cases as $expect=>$a)
{
    $result=f($a);
    echo "<tr><td>[", implode(',',$a),"]</td><td>$expect</td><td>$result</td></tr>";
}
echo '</table>';

Bem feito. Você pode remover mais 3 bytes retornando o último valor como uma matriz (altere 'return $ a [0]' para 'return $ a'), o que não estou vendo é especificamente contra as regras. :)
640KB 7/01

@gwaugh Imo If the array contains just a single number, we return that as the result.é bastante claro. Mas obrigado por me deixar revisitar isso.
Titus

Pode-se argumentar semântica de que o "que" na frase pode se referir ao "conjunto". Independentemente disso, sua resposta é de longe o PHP mais curto. Muito bem feito, e thx novamente para ponteiros na minha apresentação mais longa.
640KB 10/01

3

PHP ,135 130 bytes

Obrigado @titus, -5 bytes, mais 0 correção de caso!

function f($z){return array_reduce($z,function($c,$x)use(&$i){eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');return$c;});};

Experimente online!

Menos golfe:

function f( $t ) {
    return array_reduce( $t,
        function( $c, $x ) use( &$i ) {
            eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x;');
            return $c;
        }
    );
};

Estava realmente torcendo para que array_reduce () funcionasse para isso, mas requer muitos caracteres para superar a menor pontuação atual do PHP.

Publicá-lo de qualquer maneira, caso alguém tenha alguma sugestão!


1
Boa abordagem; mas acho que falhará sempre que $cocorrer 0. Salve dois bytes com uma função anônima em vez de w. eval('$c'.['/','**','+','-','*'][$i++?$i%5:5].'=$x');return$c;é seis bytes mais curto e deve resolver o problema zero.
Titus

Obrigado @Titus! Você está absolutamente certo sobre o caso 0. Eu tive que adicionar de volta o; após o = $ x porque eval não funcionaria sem ele. Se eu fizesse uma função anon, teria que ter uma atribuição de variável ou executá-la dentro do código de teste, certo? Não gostaria de questionar a contagem de bytes. : D
640KB 10/01

2

Braquilog , 68 bytes

hI,?bL,1:+:-:*:/:^b:L:I{bhv?t.|[O:L:I]h$(P,LbM,OhA,Lh:Ir:A&:M:Pr&.}.

Isso é longo ... mas não usa predicado de avaliação.

Explicação

  • Predicado principal

    hI,                                  Unify I with the first element of the input
       ?bL,                              L is the input minus the first element
           1:+:-:*:/:^b                  Construct the list of predicates [+:-:*:/:^]
                       :L:I{...}.        Call predicate 1 with [[+:-:*:/:^]:L:I] as input
    
  • Predicado 1

    bhv?t.                               If the second element of Input is empty (i.e. L),
                                         unify Output with the last element of Input
    |                                    Or
    [O:L:I]                              Input = [O:L:I]
           h$(P,                         P is O circularly permutated to the left
                LbM,                     M is L minus the first element
                    OhA,                 A is the first element of O
                        Lh:Ir:A&         Call predicate A on [I:First element of L]
                                :M:Pr&.  Call predicate 1 recursively with P:M:
    

Beat you por 1̶ ̶b̶y̶t̶e̶ 2 bytes;)
LegionMammal978

2

IBM PC 8087 FPU, 66. 82 bytes

Usa apenas o coprocessador matemático Intel 8087 do PC IBM para cálculos.

Experimente offline! (no DOSBox ou o que for). Dê ao chip 8087 entediado do seu PC antigo algo a fazer, além de todas as planilhas do Lotus 1-2-3 que você costumava fazer nos anos 80.

9bdf 0783 c302 499b de07 83c3 0249 e342 9bde 2783 c302 49e3 399b de0f 83c3 0249 
e330 9bde 3783 c302 49e3 2751 8b0f 9bd9 e883 f900 7413 9c7f 02f7 d99b d8c9 e2fb 
9d7d 069b d9e8 9bd8 f159 83c3 0249 e302 ebb5 c3

Ungolfed (desmontado):

START: 
    ; RUN TESTS  
    MOV  BX, OFFSET TST     ; 5, 12, 23, 2, 4, 4, 2, 6, 7
    MOV  CX, CTST           ; input array length
    CALL WOMI               ; calculate sequence
    CALL PRINT_FLT          ; output to console

    MOV  BX, OFFSET TST1    ; 5, 12, 23, 2, 4, -4, 2, 6, 7
    MOV  CX, CTST1
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST2    ; -8, 50, 3, 3, -123, 4, 17, 99, 13
    MOV  CX, CTST2
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST3    ; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
    MOV  CX, CTST3
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST4    ; 1,0,1,0,1,0
    MOV  CX, CTST4
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST5    ; -9, -8, -1
    MOV  CX, CTST5
    CALL WOMI
    CALL PRINT_FLT

    MOV  BX, OFFSET TST6    ; 0, -3
    MOV  CX, CTST6
    CALL WOMI
    CALL PRINT_FLT

    MOV  AX, 4C00H          ; exit to DOS
    INT  21H

;  TEST DATA

TST   DW  5, 12, 23, 2, 4, 4, 2, 6, 7
CTST  EQU ($-TST)/(SIZE TST)    ; count of items on list

TST1  DW  5, 12, 23, 2, 4, -4, 2, 6, 7
CTST1 EQU ($-TST1)/(SIZE TST1)  ; count of items on list

TST2  DW -8, 50, 3, 3, -123, 4, 17, 99, 13
CTST2 EQU ($-TST2)/(SIZE TST2)  ; count of items on list

TST3  DW 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
CTST3 EQU ($-TST3)/(SIZE TST3)  ; count of items on list

TST4  DW 1,0,1,0,1,0
CTST4 EQU ($-TST4)/(SIZE TST4)  ; count of items on list

TST5  DW -9, -8, -1
CTST5 EQU ($-TST5)/(SIZE TST5)  ; count of items on list

TST6  DW 0, -3
CTST6 EQU ($-TST6)/(SIZE TST6)  ; count of items on list

; 8087 exponent: ST(0) = ST(0) ^ EXP
FIEXP   MACRO   EXP
        LOCAL   REPEAT, DONE
        PUSH CX
        MOV  CX, EXP        ; Exponent is count for loop
        FLD1                ; load 1 into ST
        CMP  CX, 0          ; is exponent pos, neg or 0?
        JZ   DONE           ; exit (with value 1) if exponent is 0
        PUSHF               ; save result flags for later
        JG   REPEAT         ; if exp > 1 start calculation
        NEG  CX             ; make exponent positive for loop
REPEAT:
        FMUL ST(0), ST(1)   ; multiply ST0 = ST0 * ST1
        LOOP REPEAT
        POPF                ; retrieve flags from earlier
        JGE  DONE           ; if exponent was negative, divide 1 by result
        FLD1                ; push 1 into numerator
        FDIV ST(0), ST(1)   ; ST0 = 1 / ST1
DONE:
        POP  CX
        ENDM

; Function WOMI: (Weapons of Math Instruction)
; input: BX - address of start of input array
;       CX - length of input array
; output: ST - result on top of 8087 register stack
WOMI PROC
    FILD WORD PTR [BX]      ; load first item
    ADD  BX, 2              ; move to next
    DEC  CX
CALC:
    FIADD WORD PTR [BX]     ; add
    ADD  BX, 2              ; move to next
    DEC  CX                 ; decrement counter
    JCXZ OUTPUT             ; check if done

    FISUB WORD PTR [BX]     ; subtract
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIMUL WORD PTR [BX]     ; multiply
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIDIV WORD PTR [BX]     ; divide
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT

    FIEXP [BX]              ; exponent
    ADD  BX, 2
    DEC  CX
    JCXZ OUTPUT
    JMP CALC                ; start again

OUTPUT:
    RET 
WOMI ENDP

PRINT_FLT PROC
; print top of 8087 stack
; scaling: 14 digits, 4 decimal places
; input: BX = address of a TBYTE (BCD) output buffer
;       ST = value to display on top of 8087 stack  
    LEA   BX, BUFF                  ; set BX to BCD output buffer
    MOV   AH, 2
    MOV   WORD  PTR[BX], 10000      ; ten thousand (scale factor)
    FIMUL WORD  PTR[BX]             ; scale up by 10000
    FBSTP TBYTE PTR[BX]             ; store as BCD
    FWAIT                           ; sync 8088 and 8087
    TEST  BYTE  PTR[BX+9], 80H      ; check sign bit
    JE    PF_1                      ; 0, goto PF_1
    MOV   DL, '-'                   ; output '-'
    INT   21H
PF_1:
    ADD   BX, 8                     ; point to high byte
    MOV   CH, 7                     ; 14 digits before decimal point
    MOV   CL, 4                     ; 4 shifts (8 bytes / 2 = 4 = 1 nibble)
    MOV   DH, 2                     ; 2 times (8 bytes / 4)
PF_LOOP:
    MOV   DL, [BX]                  ; get BCD digits
    SHR   DL, CL                    ; move high digit to low nibble
    OR    DL, 30H                   ; convert to ASCII
    INT   21H
    MOV   DL, [BX]                  ; get byte again
    AND   DL, 0FH                   ; mask out high digit
    OR    DL, 30H                   ; convert to ASCII
    INT   21H                       ; output
    DEC   BX                        ; next byte
    DEC   CH                        ; decrement byte
    JG    PF_LOOP                   ; repeat if more bytes
    DEC   DH                        ; second time?
    JE    PF_DONE                   ; yes, done
    MOV   DL, '.'                   ; no, output decimal point
    INT   21H
    MOV   CH, 2                     ; 4 more digits after decimal point
    JMP   PF_LOOP                   ; go print digits
PF_DONE:
    MOV  DL, 0DH                    ; display newline CRLF
    MOV  AH, 2
    INT  21H
    MOV  DL, 0AH
    INT  21H
    RET 
PRINT_FLT ENDP

BUFF DT 0   ; output buffer for floating point digit string

_TEXT ENDS
END START

Resultado:

A>WOMI.COM
00000000000539.0000
-00000000000027.9136
-00000000001055.3569
00000000000256.0000
00000000000001.0000
-00000000000016.0000
-00000000000003.0000

A entrada é feita através de um PROC (x86 mais equivalente a uma função), com BX sendo um ponteiro para uma matriz de WORDs na memória e CX sendo o número de itens e retornando o resultado em ST.

* Nota: O código real para a função é 66.82 bytes. Obviamente, o código para escrever um número de ponto flutuante no console (código do livro de receitas) é de 83 bytes. O programa de teste e os dados são183215 bytes, tornando o .COM executável 305 380 bytes no total.


1
Isso é ótimo! Eu escrevi uma solução semelhante para o x86-64 (linux), mas ainda não joguei muito, o que provavelmente mudará muita lógica. Para o seu cálculo de expoente, mesmo que os testes apresentados não testem receber um expoente negativo, eu senti que era uma parte necessária da lógica do programa, especialmente porque é tão simples quanto pressionar 1 para st0 e fazer uma divisão entre st0 e st1 (pelo menos no x86, são duas instruções).
davey

Obrigado @davey - muito bom ponto! Atualizei o código para lidar com expoentes negativos e adicionei outro caso de teste para ele.
640 KB

2

APL (Dyalog Unicode) , 29 27 bytes SBCS

Função prefixo tácito anômalo. Observe que *é exponenciação no APL.

≢{⍎3↓⍕⌽⍵,¨⍨⍺⍴'+-×÷*''⍨'}⊢

Experimente online!

Como o APL é executado da direita para a esquerda, podemos apenas reverter a ordem dos argumentos das operações inseridas e reverter toda a expressão. O Postfix inverte argumentos. Depois de fazer uma mistura perfeita de números e operações, precisamos apenas reverter, nivelar e avaliar:

≢{}⊢ Chame a seguinte função com contagem e números reais como e :

'⍨' esse personagem

'+-×÷*',¨ acrescente cada um desses caracteres a isso; ["+⍨","-⍨","×⍨","÷⍨","*⍨"]

⍺⍴ usar o argumento esquerdo (contagem de números) para ciclicamente r eshape que

 marcha ré

 formatar como sequência plana

3↓solte três caracteres principais (um espaço e um símbolo e )

 executar como código APL


2

Japonês , 16 bytes

r@[XY]r"p+-*/"gZ

Experimente online!

Explicação:

r@                  #Reduce the input list:
       "p+-*/"      # The list of functions to apply (offset by one due to the behavior of Z)
              gZ    # Choose the one at the current index, wrapping
  [  ]r             # Apply that function to:
   X                #  The result of the previous step
    Y               #  and the current number
                    #Implicitly return the result of the final step

Ah, merda, eu estava apenas trabalhando nisso, tentando descobrir por que isso estava me dando resultados incorretos - eu tinha perdido a exponenciação! : \
Shaggy

1

c #, 238 , 202 bytes

double d(double[]a){Array.Reverse(a);var s=new Stack<double>(a);int i=0,j;while(s.Count>1){double l=s.Pop(),r=s.Pop();j=i++%5;s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l,r));}return s.Peek();}

Eu não vi nenhuma solução c #, então darei uma. Este é o meu primeiro codegolf. Comecei a escrever em c # "há dois meses" (embora eu conheça Java até certo ponto).

Ele usa Stack

Experimente online!

Casos não testados e de teste

using System;
using System.Collections.Generic;

class M 
{
    double d(double[]a) {
        Array.Reverse(a);
        var s = new Stack<double>(a);
        int i=0,j;
        while (s.Count>1)
        {
            double l=s.Pop(),r=s.Pop();
            j=i++%5;
            s.Push(j==0?l+r:j==1?l-r:j==2?l*r:j==3?l/r:Math.Pow(l, r));
        }
        return s.Peek();
    }

    public static void Main()
    {
        int[][] a = new int[][]{
            new int[]{1,2,3,4,5},
            new int[]{5,12,23,2,4,4,2,6,7},
            new int[]{-8,50,3,3,-123,4,17,99,13},
            new int[]{2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
            new int[]{1,0,1,0,1,0},
            new int[]{-9,-8,-1},
            new int[]{0,-3},
            new int[]{-99}
        };

        for (int i = 0; i < a.Length; i++)
        {
            Console.WriteLine(new M().d(Array.ConvertAll(a[i], e => Convert.ToDouble(e))));
        }
        Console.ReadKey();
    }
}

Resultado:

0
539
-1055,35694384628
256
1
-16
-3
-99

Olá, e bem-vindo ao PPCG! Este pode ser um bom tópico para analisar: Dicas para jogar golfe em código em C # . Algumas coisas que podem ser aplicadas no seu código: spaces ( a, Double.Parse-> a,Double.Parse; while (s.Count-> while(s.Count; Pow(l, r)-> Pow(l,r)). Além disso, você pode remover int na frente do j=e colocá-lo atrás do int i=0,j;. Ótima primeira resposta, porém, e mais uma vez bem-vinda. :)
Kevin Cruijssen

@KevinCruijssen Hi! Ty! Os espaços foram removidos ej foi movido como você sugeriu :)
display_name

1

PHP, 206 , 198 , 197 bytes

function f($a){while(count($a)>1){$l=array_shift($a);$r=array_shift($a);array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));}return array_pop($a);}

Experimente online!

Ungolfed

<?php

function f($a)
{
    while(count($a)>1)
    {
        $l = array_shift($a); $r = array_shift($a);
        array_unshift($a,($j=$i++%5)==0?($l+$r):($j==1?($l-$r):($j==2?($l*$r):($j==3?($l/$r):(pow($l,$r))))));
    }
    return array_pop($a);
}

echo f([1,2,3,4,5])."\n";
echo f([5,12,23,2,4,4,2,6,7])."\n";
echo f([-8,50,3,3,-123,4,17,99,13])."\n";
echo f([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])."\n";
echo f([1,0,1,0,1,0])."\n";
echo f([-9,-8,-1])."\n";
echo f([0,-3])."\n";
echo f([-99])."\n";

Em PHP, lógica semelhante à minha resposta c # ( 202 bytes ) :).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.