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.