Trasforma una matrice in un problema di matematica


35

Dato un elenco non vuoto di numeri interi non negativi, considerare di riscriverlo come un problema aritmetico in cui:

  • Un segno più ( +) viene inserito tra coppie di numeri che aumentano da sinistra a destra (ovvero dall'inizio dell'elenco alla fine).
  • Un segno meno ( -) viene inserito tra coppie di numeri che diminuiscono da sinistra a destra.
  • Un segno di moltiplicazione ( *) viene inserito tra coppie di numeri uguali.

Detto in altro modo: qualsiasi elenco secondario a,bdiventa a+bif a<b, a-bif a>be a*bif a==b.

Ad esempio, l'elenco

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

diventerebbe l'espressione

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

che valuta 75 .

Scrivi un programma o una funzione che contiene tale elenco e lo valuta, stampando o restituendo il risultato.

  • L'ordine delle operazioni è importante. Le moltiplicazioni devono essere eseguite prima di qualsiasi aggiunta o sottrazione.
  • Se l'elenco di input ha un numero, dovrebbe essere quello a cui valuta. ad esempio [64]dovrebbe dare 64.
  • L'utilizzo di evalo execo simili costrutti è permesso.

Ecco alcuni esempi aggiuntivi:

[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

Vince il codice più breve in byte. Tiebreaker è la risposta precedente.


5
Per quanto riguarda "l'ordine delle operazioni", potrebbe essere utile affermare esplicitamente che l'addizione e la sottrazione sono associative di sinistra e hanno la stessa precedenza.
Martin Ender,

Risposte:


15

Python 2, 63 byte

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

Costruisce evalla stringa di espressione. Il simbolo aritmetico viene scelto confrontando il numero precedente pcon quello attuale x. Il simbolo viene aggiunto seguito dal numero corrente.

Il primo numero viene gestito con un trucco intelligente da Sp3000. Il valore iniziale di pè impostato su una stringa, che è maggiore di qualsiasi numero e quindi causa un -prima del primo numero. Tuttavia, sviene inizializzato print-allo stesso tempo e fa iniziare il risultato con print--(grazie a xsot per aver salvato 2 byte inizializzando con print.)


Penso che puoi muoverti printnella stringa e usare execinvece di eval.
xsot,

13

Pyth, 31 26 19 17 16 15 byte

Le espressioni con *non verranno valutate online, ma teoricamente funzionerebbero.

2 byte grazie a Maltysen.

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

Suite di test (con valutazione).

Gli altri casi (senza valutazione).

Storia

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

Perché la moltiplicazione non funziona online? Se non sei sicuro che funzioni, potrebbe essere meglio testare un po 'di più prima di rispondere.
Calvin's Hobbies,

Perché roba di sicurezza (la valutazione funziona solo per +e -online)
Leaky Nun,

@HelkaHomba Non ho ancora avuto la possibilità di provarlo offline, ma dovrebbe funzionare. L'interprete online utilizza l' --safeinterruttore, che sostituisce evalcon ast.literal_eval.
Dennis,

Ok, abbastanza giusto.
Calvin's Hobbies,

Confermato, funziona con l'interprete offline.
Dennis,

12

Gelatina , 18 16 15 14 byte

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

Non utilizza valutazione integrata. Provalo online! o verifica tutti i casi di test .

Come funziona

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.


1
Ben fatto. Dovrei aggiungere Python evalcome un atomo ...
Dennis,

9
Ti ho giocato a golf. : P
Dennis,

Ben fatto, il tuo turno!
Leaky Nun,

9

MATL , 12 byte

Y'^l6MdZSh*s

Questo utilizza l'idea molto bella di @ aditsu sulla codifica run-length.

Provalo online!

Spiegazione

       % 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 aveva appena scritto qualcosa di simile. RLE funziona bene per questo
Suever

@Vue che vedo MrGreen
Luis Mendo il

7

CJam, 20

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

Provalo online

Spiegazione:

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 riceve un elenco di espressioni separato da virgole e restituisce il valore dell'ultima.

Test

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
È il peggior abuso dell'operatore virgola che ricordo di aver visto su questo sito ...
Neil,



3

R, 92 byte

Probabilmente c'è ancora del buon golf che si può fare qui.

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.

Sono riuscito a salvare solo un byte usando un approccio di indicizzazione
JayCe


2

TI-BASIC, 146 byte

Lo formatterò bene quando non sul cellulare. Il sonno mi sfugge, quindi hai capito. Godere.

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 caratteri

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

3
Non dovrebbe essere una funzione e aun parametro?
edc65,

Questo non è valido così com'è.
Rɪᴋᴇʀ

@ edc65, sì, dovrebbe. Ma in effetti è stato contato (61 specificato, ma la lunghezza del codice reale era 59), ho appena copiato male un nuovo codice (la modifica dovrebbe essere a[i+1]...a[i+1]=> a[++i]...a[i]- 2 caratteri più brevi, ma ho erroneamente sostituito l'intero rilascio del codice a=>).
Qwertiy,

@ EᴀsᴛᴇʀʟʏIʀᴋ, è solo una pasta sbagliata. Vedi il commento sopra e modifica la cronologia per maggiori dettagli.
Qwertiy,

@Qwertiy va bene bene. Bella risposta tra ..
Rɪᴋᴇʀ

1

Java, 384 byte

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

Ungolfed prova 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;
}

1
Alcuni golf rapidi: int a=l.length, &&=> &, mettere il int i=0sulla stessa "linea" come int n=l[0],m.
Leaky Nun,

In 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;, puoi semplicemente sostituirlo con il contenuto all'interno del elseblocco.
Leaky Nun,

1

Javascript ES6, 79 caratteri

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

1

Perl, 49 byte

48 byte codice + 1 per -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

Gli appunti

Ho imparato qui che puoi catturare un lookahead in PCRE, anche se è un po 'poco intuitivo ( (?=(\d+))invece di((?=\d+)) ). Ha senso dopo aver letto, dato che si catturerebbe una corrispondenza di lunghezza zero (il lookahead) con quest'ultima, e invece catturerebbe la corrispondenza con la prima).

Grazie a @ninjalj per aver salvato 8 byte!


@LeakyNun Non so mai esattamente cosa contare per quello, non riesco a trovare il meta post rilevante, sono felice di aumentare il conteggio, ma ho pensato che dato che puoi correre -egratis, aggiungendo pche è -pestato +1 ? Si aggiornerà per ora, ma se potessi trovare una fonte che potrei citare / link per andare avanti, sarebbe fantastico!
Dom Hastings,

3
@DomHastings 1 è corretto, per il motivo che dici + questo meta post
Sp3000

Grazie @ Sp3000! Non sono riuscito a trovare quel post per la mia vita! @LeakyNun meta post per +1 come da commento di Sp3000
Dom Hastings

Invece di utilizzare gli operatori condizionali concatenati, è possibile utilizzare l'operatore astronave per selezionare da un elenco: $&.qw(* - +)[$&<=>$1]nella parte sostitutiva s///dell'operatore.
ninjalj,

@ninjalj Certo! fantastico, grazie! -8 con quello!
Dom Hastings,

1

In realtà, 30 byte

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

Sfortunatamente, perché l'Eval ( comando ) valuta solo valori letterali su TIO, questo programma non funziona su TIO.

Spiegazione:

;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 byte

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

Provalo online!

L'algoritmo è simile a quello di questa risposta , ma me ne sono reso conto solo dopo aver codificato la mia risposta. Molto meglio della mia risposta originale che stava usando eval(parse).

Sfrutta appieno le operazioni vettorializzate di R - esegue *prima l' operazione utilizzando rle(x)$values ^ rle(x)$lenghtse dot-products questo vettore con sign( diff( rle(x)$values ) )(predetto con 1).


1

05AB1E (legacy) , 17 16 15 byte

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

-2 byte grazie a @Emigna .

Provalo online o verifica tutti i casi di test .

Spiegazione:

ü                  # 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

1
Grazie all'indicizzazione modulare, è possibile rimuovere >spostandosi +alla fine della stringa.
Emigna,

@Emigna Non sono sicuro di come mi sia perso .. Grazie!
Kevin Cruijssen,

1
È possibile salvare un altro byte rimuovendo Će ¨, se si utilizza al ‚ζposto diø
Emigna il

@Emigna Oh, ora che è intelligente! Grazie. Sapevo che l'allegato era un po 'strano, ma non sapevo come risolverlo. ‚ζè una perfetta alternativa alternativa, poiché lo spazio è ignorato nell'eval. Grazie ancora. :)
Kevin Cruijssen il

0

PHP, 103 byte

Sfida ordinata. Questo è diventato più lungo del previsto. Penso che usare array_mapo simili non migliorerà il conteggio dei byte, poiché le funzioni anonime sono ancora costose in PHP.

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

Viene eseguito dalla riga di comando, richiederà un elenco separato da virgole, come:

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

0

PowerShell v2 +, 62 byte

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

Accetta input come argomenti della riga di comando separati da spazio, che vengono convertiti in array automatico $args. Esaminiamo ogni elemento, usando la variabile helper $oogni iterazione per ricordare quale era la nostra voce precedente. Usiamo una stringa indicizzato per estrarre l'operatore appropriato, fatto eseguendo matematica sui valori booleani implicitamente-convertiti (ad esempio, se la voce precedente è più piccolo, le []restituisce 1+2*0modo '*+-'[1]intende la +è selezionato).

Le stringhe concatenate vengono lasciate sulla tubazione. Raccogliamo tutti questi frammenti insieme (ad esempio, 3-, 1+, 4-, etc.) con -joinun'operazione, concatenate sul numero finale (implicitamente convertito a stringa), e pipe a iex(alias per Invoke-Expressione simile eval).


Una preoccupazione è che se il chiamante ha già dato $ o valore (diciamo $ o = 999), l'espressione in questa voce non calcolerà il valore corretto. È necessario aggiungere un'inizializzazione di $ o a questa soluzione.
Bevo,

@Bevo Questo deve essere uno script completo, eseguito tramite la riga di comando e non una funzione o tramite la shell interattiva. La stragrande maggioranza delle mie osservazioni è in quanto tale, poiché in tale scenario non ci sono variabili predefinite di cui preoccuparsi e quindi il codice può essere un po 'più breve.
AdmBorkBork


0

Japt -x , 21 19 byte

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

Provalo


Spiegazione

                        :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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.