Transforme uma matriz em um problema de matemática


35

Dada uma lista não vazia de números inteiros não negativos, considere reescrevê-la como um problema aritmético em que:

  • Um sinal de adição ( +) é inserido entre pares de números que aumentam da esquerda para a direita (também conhecido como do início da lista ao final).
  • Um sinal de menos ( -) é inserido entre pares de números que diminuem da esquerda para a direita.
  • Um sinal de multiplicação ( *) é inserido entre pares de números iguais.

Dito de outra maneira: qualquer sub-lista se a,btorna a+bse a<b, a-bse a>be a*bse a==b.

Por exemplo, a lista

[12, 0, 7, 7, 29, 10, 2, 2, 1]

se tornaria a expressão

12 - 0 + 7*7 + 29 - 10 - 2*2 - 1

que avalia como 75 .

Escreva um programa ou função que inclua essa lista e a avalie, imprimindo ou retornando o resultado.

  • A ordem das operações é importante. Multiplicações devem ser feitas antes de qualquer adição ou subtração.
  • Se a lista de entrada tiver um número, deve ser o que ela avalia. por exemplo, [64]deve dar 64.
  • O uso de evalou execou construções semelhantes é permitido.

Aqui estão alguns exemplos adicionais:

[list]
expression
value

[0]
0
0

[1]
1
1

[78557] 
78557
78557

[0,0]
0*0
0

[1,1]
1*1
1

[2,2]
2*2
4

[0,1]
0+1
1

[1,0]
1-0
1

[1,2]
1+2
3

[2,1]
2-1
1

[15,4,4]
15-4*4
-1

[9,8,1]
9-8-1
0

[4,2,2,4]
4-2*2+4
4

[10,9,9,12]
10-9*9+12
-59

[1,1,2,2,3,3]
1*1+2*2+3*3
14

[5,5,4,4,3,3]
5*5-4*4-3*3
0

[3,1,4,1,5,9,2,6,5,3,5,9]
3-1+4-1+5+9-2+6-5-3+5+9
29

[7637,388,389,388,387,12,0,0,34,35,35,27,27,2]
7637-388+389-388-387-12-0*0+34+35*35-27*27-2
7379

O código mais curto em bytes vence. O desempatador é a resposta anterior.


5
Em relação à "ordem das operações importa", pode ser bom afirmar explicitamente que adição e subtração são associativas à esquerda e têm a mesma precedência.
— Martin Ender

Respostas:


15

Python 2, 63 bytes

p=s='print-'
for x in input():s+='*+-'[cmp(x,p)]+`x`;p=x
exec s

Constrói evales a string de expressão. O símbolo aritmético é escolhido comparando o número anterior pao atual x. O símbolo é anexado seguido pelo número atual.

O primeiro número é tratado com um truque inteligente do Sp3000. O valor inicial de pé definido como uma sequência, que é maior que qualquer número e, portanto, causa a -antes do primeiro número. Mas, sé inicializado ao print-mesmo tempo em que inicia o resultado print--(graças ao xsot por salvar 2 bytes ao inicializar com print.)


Eu acho que você pode passar printpara a string e usar em execvez de eval.
— xsot

13

Pitão, 31 26 19 17 16 15 bytes

Expressões com *não serão avaliadas on-line, mas teoricamente funcionariam.

2 bytes graças a Maltysen.

vsm+@"*-+"._-~k

Conjunto de testes (com avaliação).

Os outros casos (sem avaliação).

História

  • 31 bytes: M+G@"*-+"->GH<GHv+sgMC,JsMQtJ\x60e
  • 26 bytes: M+G@"*-+"->GH<GHv+sgVQtQ\x60e
  • 19 bytes: vtssVm@"*-+"->Zd<~Z
  • 17 bytes: vtssVm@"*-+"._-~Z
  • 16 bytes: vssVm@"*-+"._-~k
  • 15 bytes: vsm+@"*-+"._-~k

Por que a multiplicação não funciona online? Se não tiver certeza de que funciona, talvez seja melhor testar um pouco mais antes de responder.
— Passatempos de Calvin

Porque material de segurança (avaliação só funciona para +e -on-line)
— Leaky Nun

@HelkaHomba Ainda não tive a chance de experimentá-lo offline, mas deve funcionar. O intérprete online usa o --safeswitch, que substitui evalpor ast.literal_eval.
— Dennis

Ok, é justo.
— Calvin's Hobbies

Confirmado, isso funciona com o intérprete offline.
— Dennis

12

Geléia , 18 16 15 14 bytes

I0;ð1g×⁹⁸œṗP€S

Não usa avaliação interna. Experimente online! ou verifique todos os casos de teste .

Como funciona

I0;ð1g×⁹⁸œṗP€S  Main link. Input: A (list)

I               Increments; compute the deltas of all adjacent items of A.
 0;             Prepend a 0.
   ð            Begin a new, dyadic chain.
                Left argument: D (0 plus deltas). Right argument: A
    1g          Compute the GCD of 1 and each item in D.
                This yields 1 for non-negative items, -1 for negative ones.
      ×⁹        Multiply each 1 or -1 with the corresponding item of A.
                This negates every item in A that follows a - sign.
        ⁸œṗ     Partition the result by D. This splits at occurrences of non-zero
                values of D, grouping items with identical absolute value.
           P€   Take the product of each group.
             S  Sum; add the results.


11
Bem feito. Devo acrescentar Python evalcomo um átomo ...
— Dennis

9
Eu superava você. : P
— Dennis

Muito bem, é a sua vez!
— Freira vazada

9

MATL , 12 bytes

Y'^l6MdZSh*s

Isso usa a ótima idéia do @ aditsu de codificação em tamanho de execução.

Experimente online!

Explicação

       % Take input vector implicitly
Y'     % RLE. Produces two vectors: values and lengths
^      % Rise each value to the number of consecutive times it appears. This
       % realizes the product of consecutive equal values
l      % Push 1
6M     % Push vector of values again
d      % Consecutive differences
ZS     % Sign function. Gives 1 or -1 (no 0 in this case)
h      % Concatenate horizontally with previous 1
*      % Multiply. This gives plus or minus depending on increasing character
s      % Sum of vector. This realizes the additions or subtractions
       % Display implicitly

Haha tinha acabado de escrever algo semelhante. RLE funciona bem para isso
— Suever

@Suever I see :-D
— Luis Mendo

7

CJam, 20

q~e`{~_W-g\:W@#*}%:+

Experimente online

Explicação:

q~       read and evaluate the input (array of numbers)
e`       RLE encode, obtaining [count number] pairs
{…}%     map each pair
  ~_     dump the count and number on the stack, and duplicate the number
  W-     subtract the previous number (W is initially -1 by default)
  g      get the sign of the result
  \      swap with the other copy of the number
  :W     store it in W (for next iteration)
  @#     bring the count to the top, and raise the number to that power
  *      multiply with the sign
:+       add all the results together

7

JavaScript (ES6), 54

p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

eval recebe uma lista de expressões separadas por vírgula e retorna o valor da última.

Teste

f=p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

t=p=>(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

function Test() {
  var a=I.value.match(/\d+/g).map(x=>+x) // convert input to a numeric array
  
  var x=f(a),y=t(a)
  O.textContent='Value '+x+'\n(no eval '+y+')'
}  

Test()
#I { width:80%}
<input value='12, 0, 7, 7, 29, 10, 2, 2, 1' id=I>
<button onclick='Test()'>Test</button>
<pre id=O></pre>


4
Essa é a pior abuso do operador vírgula que eu me lembro de ver neste site ...
— Neil



3

R, 92 bytes

Provavelmente ainda há algum bom golfe que pode ser feito aqui.

eval(parse(t=paste(i<-scan(),c(ifelse(d<-diff(i),ifelse(d>0,"+","-"),"*"),""),collapse="")))

Ungolfed:

i = scan()                # Read list from stdin
d = diff(i)               # Calculate difference between each element of list
s = ifelse(d,             # If d!=0
             ifelse(d>0,  # And if d>1
                    "+",  # Return plus
                    "-"), # Else return minus
             "*")         # Else (i.e. d==0) return multiply.
s = c(s,"")               # Pad the list s with an empty string, so it's the same
                          # length as i
p = paste(i,s,collapse="")# Paste the elements of i and s into one long string.
eval(parse(t=p))          # Evaluate the string as a language object.

I conseguiu salvar apenas um byte usando uma abordagem de indexação
— Jayce


2

TI-BASIC, 146 bytes

Vou formatá-lo bem quando não estiver em dispositivos móveis. O sono me escapa, então você entende isso. Apreciar.

Prompt L₁
"(→Str1
For(A,1,dim(L₁
{0,1→L₂
{0,L₁(A→L₃
LinReg(ax+b) L₁,L₃,Y₁
Equ►String(Y₁,Str2
sub(Str2,1,-1+inString(Str2,"X→Str2
If A>1
Then
L₁(A-1
2+(Ans>L₁(A))-(Ans<L₁(A
Str1+sub("+*-",Ans,1→Str1
End
Str1+Str2→Str2
End
expr(Str1

2

Javascript ES6, 64 62 caracteres

a=>eval(a.map((x,i)=>x+('*+-'[x<a[++i]|(x>a[i])*2])).join``+1)

3
Isso não deveria ser uma função e aum parâmetro?
— edc65

Isso é inválido como está.
— Rɪᴋᴇʀ

@ edc65, sim, deveria. Mas, na verdade, foi contado (61 especificado, mas o tamanho real do código era 59), apenas copiei mal um novo código (a edição deve ser a[i+1]...a[i+1]=> a[++i]...a[i]- 2 caracteres mais curta, mas substitui por engano toda a remoção do código a=>).
— Qwertiy

@ EᴀsᴛᴇʀʟʏIʀᴋ, é apenas uma pasta errada. Veja o comentário acima e edite o histórico para obter mais detalhes.
— Qwertiy

@Qwertiy okay cool. Resposta agradável btw .. #
— 31416 Re:

1

Java, 384 bytes

int s(int[]l){int n=l[0],m;for(int i=0;i<l.length-1;i++)if(l[i]<l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;}else if(l[i]>l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n-=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n-=m;}else{m=l[i];while(i<l.length-1&&l[i]==l[i+1])m*=l[i++];n+=m;}return n;}

Tentativa sem golfe online

int s(int[] l)
{
    int n=l[0], m;

    for(int i=0; i<l.length-1; i++)
    {
        if(l[i] < l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n += l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n += m;
            }
        }
        else if(l[i] > l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n -= l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n -= m;
            }
        }
        else
        {
            m = l[i];
            while(i<l.length-1 && l[i]==l[i+1]) m *= l[i++];
            n += m;
        }
    }

    return n;
}

11
Alguns campos de golfe rápidas: int a=l.length, &&=> &, coloque o int i=0na mesma "linha" como int n=l[0],m.
— Leaky Nun

Em if(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;, você pode simplesmente substituir isso pelo conteúdo dentro do elsebloco.
— Leaky Nun

1

Javascript ES6, 79 caracteres

a=>eval(`${a}`.replace(/(\d+),(?=(\d+))/g,(m,a,b)=>a+('*+-'[+a<+b|(+a>+b)*2])))

1

Perl, 49 bytes

Código de 48 bytes + 1 para -p

s/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval

Uso

perl -pe 's/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval' <<< '12 0 7 7 29 10 2 2 1'
75

Notas

Aprendi aqui que você pode capturar um lookahead no PCRE, embora seja um pouco pouco intuitivo (em (?=(\d+))vez de ((?=\d+))). No entanto, faz sentido depois de ler, pois você capturaria uma correspondência de comprimento zero (a cabeça de impressão) com a segunda e, em vez disso, capturaria a correspondência com a primeira.

Obrigado a @ninjalj por salvar 8 bytes!


@LeakyNun Eu nunca sei exatamente o que contar para isso, eu não posso encontrar o post meta relevante, estou feliz de bater a contagem, mas eu pensei que desde que você pode executar com -egratuitamente, adicionando um ptornando- -pese um ? Será atualizado por enquanto, mas se você encontrar uma fonte que eu possa citar / vincular para daqui para frente, isso seria incrível!
— Dom Hastings

3
@DomHastings 1 está correto, pela razão de você dizer + este post meta
— SP3000

Obrigado @ Sp3000! Não consegui encontrar esse post para a minha vida! Meta postagem do @LeakyNun para +1, conforme comentário de Sp3000
— Dom Hastings

Em vez de usar operadores condicionais em cadeia, você pode usar o operador de nave espacial para selecionar em uma lista: $&.qw(* - +)[$&<=>$1]na parte de substituição do s///operador.
— Njalj

@ninjalj Claro! incrível, obrigado! -8 com isso!
— Dom Hastings

1

Na verdade, 30 bytes

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡

Infelizmente, como o ≡comando eval ( ) avalia apenas literais no TIO, esse programa não funciona no TIO.

Explicação:

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡
;                               duplicate input
 2@V                            overlapping sublists of length <= 2
    pXdX                        discard first and last element (length-1 sublists)
        `i-su"+*-"E`M           map: for each pair of elements
         i-su                     flatten, subtract, sign, increment (results in a 0 if b < a, 1 if b == a, and 2 if b > a)
             "+*-"E               select the correct operation
                     ' @o       put a space at the beginning of the list to pad it properly
                         ♀+     pairwise addition (since addition is not defined for strings and integers, this just zips the lists and flattens the result into a single flat list)
                           εj   join with empty string
                             ≡  eval

1

R , 120 44 bytes

r=rle(scan());c(1,sign(diff(r$v)))%*%r$v^r$l

Experimente online!

O algoritmo é semelhante ao desta resposta , mas só o percebi depois de codificar minha resposta. Muito melhor do que minha resposta original que estava usando eval(parse).

Alavanca totalmente as operações vetorizadas de R - faz a *operação primeiro usando rle(x)$values ^ rle(x)$lenghtse pontilha produtos com esse vetor sign( diff( rle(x)$values ) )(previsto com 1).


1

05AB1E (herdado) , 17 16 15 bytes

ü.S…*-+sè‚ζJJ.E

-2 bytes graças a @Emigna .

Experimente online ou verifique todos os casos de teste .

Explicação:

ü                  # Pair-wise loop over the (implicit) input-list
                   #  i.e. [12,0,7,7] → [[12,0],[0,7],[7,7]]
 .S                # Calculate the signum of the pair (-1 for a<b; 0 for a==b; 1 for a>b)
                   #  i.e. [[12,0],[0,7],[7,7]] → [1,-1,0]
   …*-+sè          # Index over "*-+" (with wrap-around)
                   #  i.e. [1,-1,0] → ['-','+','*']
         ‚ζ        # Zip the two lists together (appending the operands to the numbers)
                   #  i.e. [12,0,7,7] and ['-','+','*','+']
                   #   → [[12,'-'],[0,'+'],[7,'*'],[7,' ']]
           JJ      # Join them together
                   #  [[12,'-'],[0,'+'],[7,'*'],[7,' ']] → '12-0+7*7 '
             .E    # Evaluate as Python code
                   #  i.e. '12-0+7*7' → 61

11
Devido à indexação modular, você pode remover >movendo +para o final da string.
— Emigna

@ Emigna Não sei como eu perdi isso .. Obrigado!
— Kevin Cruijssen 23/08/19

11
Você pode salvar outro byte, removendo Će ¨, se você usar ‚ζem vez deø
— Emigna

@ Emigna Oh, agora isso é inteligente! Obrigado. Eu sabia que o anexo era um pouco estranho, mas não sabia como consertá-lo. ‚ζé uma alternativa alternativa perfeita, pois o espaço é ignorado na avaliação. Obrigado novamente. :)
— Kevin Cruijssen 23/08/18

0

PHP, 103 bytes

Desafio puro. Isso ficou mais do que o esperado. Eu acho que usar array_mapou similar não melhorará a contagem de bytes, pois as funções anônimas ainda são caras no PHP.

foreach(fgetcsv(STDIN)as$v)(0<=$p?$o.=$p.('*-+'[($p>$v)+2*($p<$v)]):_)&&$p=$v;echo eval("return$o$v;");

Executa a partir da linha de comando, solicitará uma lista separada por vírgula, como:

php array_to_math.php
12, 0, 7, 7, 29, 10, 2, 2, 1

0

PowerShell v2 +, 62 bytes

-join($args|%{"$o"+'*+-'[($o-lt$_)+2*($o-gt$_)];$o=$_})+$o|iex

Recebe entrada como argumentos de linha de comando separados por espaço, que são convertidos em matriz automática $args. Nós iteramos através de cada elemento, usando a variável helper em $ocada iteração para lembrar qual era a nossa entrada anterior. Usamos uma string indexada para obter o operador apropriado, efetuando cálculos nos valores booleanos convertidos implicitamente (por exemplo, se a entrada anterior for menor, a []avaliação é feita de 1+2*0forma que '*+-'[1]o +selecionado).

As seqüências concatenadas são deixadas no pipeline. Recolhemos todos esses fragmentos em conjunto (por exemplo, 3-, 1+, 4-, etc.) com uma -joinoperação, concatenar sobre o número final (convertidas, implicitamente, a cadeia de caracteres), e inseri-lo em iex(nome alternativo para Invoke-Expressione semelhantes a eval).


Uma preocupação é que, se o chamador já forneceu $ oa valor (digamos $ o = 999), a expressão nesta entrada não calculará o valor correto. Uma inicialização de $ o precisa ser adicionada a esta solução.
— Bevo

@Bevo Pretende-se que seja um script completo, executado através da linha de comando, e não uma função ou através do shell interativo. A grande maioria dos meus envios é assim, pois, nesse cenário, não há variáveis ​​predefinidas para se preocupar e, portanto, o código pode ser um pouco mais curto.
— AdmBorkBork 14/08


0

Japonês -x , 21 19 bytes

änJ f mÎí*Uò¦ ®ÎpZÊ

Tente


Explicação

                        :Implicit input of array U
  J                     :Prepend -1
än                      :Get deltas
    f                   :Filter (remove 0s)
      m                 :Map
       Î                : Signs
        í               :Interleave
          U             :  Original input
           ò            :  Partition on
            ¦           :   Inequality
              ®         :  Map each sub-array Z
               Î        :    Get first element
                p       :    Raise to the power of
                 ZÊ     :     Length of Z
         *              :Reduce each pair of elements by multiplcation
                        :Implicitly reduce by addition and output
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.