Verwandle ein Array in ein mathematisches Problem


35

Wenn Sie eine nicht leere Liste nichtnegativer Ganzzahlen angeben, sollten Sie das Umschreiben als ein arithmetisches Problem betrachten, bei dem Folgendes zutrifft:

  • Ein Pluszeichen ( +) wird zwischen Zahlenpaaren eingefügt, die von links nach rechts (vom Anfang der Liste bis zum Ende) zunehmen.
  • Ein Minuszeichen ( -) wird zwischen Zahlenpaaren eingefügt, die von links nach rechts abnehmen.
  • Ein Multiplikationszeichen ( *) wird zwischen Zahlenpaaren eingefügt, die gleich sind.

Anders gesagt: Jede Unterliste a,bwird zu a+bif a<b, a-bif a>bund a*bif a==b.

Zum Beispiel die Liste

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

würde der Ausdruck werden

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

die auswertet zu 75 .

Schreiben Sie ein Programm oder eine Funktion, die eine solche Liste aufnimmt und auswertet und das Ergebnis druckt oder zurückgibt.

  • Die Reihenfolge der Operationen ist wichtig. Multiplikationen sollten vor jeder Addition oder Subtraktion durchgeführt werden.
  • Wenn die Eingabeliste eine Nummer hat, sollte dies der Wert sein, zu dem sie ausgewertet wird. zB [64]soll geben 64.
  • Die Verwendung von evaloder execähnlichen Konstrukten ist erlaubt.

Hier sind einige zusätzliche Beispiele:

[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

Der kürzeste Code in Bytes gewinnt. Tiebreaker ist frühere Antwort.


5
In Bezug auf "Reihenfolge der Operationen" kann es sinnvoll sein, explizit anzugeben, dass Addition und Subtraktion linksassoziativ sind und den gleichen Vorrang haben.
Martin Ender

Antworten:


15

Python 2, 63 Bytes

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

Konstruiert und evals den Ausdrucksstring. Das arithmetische Symbol wird durch Vergleichen der vorherigen pmit der aktuellen Nummer ausgewählt x. Das Symbol wird gefolgt von der aktuellen Nummer angehängt.

Die erste Zahl wird mit einem cleveren Trick von Sp3000 gehandhabt. Der Anfangswert von pwird auf eine Zeichenfolge festgelegt, die größer als eine beliebige Zahl ist und daher ein -vor der ersten Zahl verursacht. Aber swird initialisiert print-zugleich, die das Ergebnis Start mit macht print--(zum Speichern von 2 Bytes durch Initialisierung mit dank xsot print.)


Ich denke, Sie können printin die Zeichenfolge bewegen und execanstelle von verwenden eval.
Xsot

13

Pyth, 31 26 19 17 16 15 Bytes

Ausdrücke mit *werden nicht online ausgewertet, funktionieren aber theoretisch.

2 Bytes dank Maltysen.

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

Testsuite (mit Auswertung).

Die anderen Fälle (ohne Bewertung).

Geschichte

  • 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

Warum funktioniert die Multiplikation online nicht? Wenn Sie sich nicht sicher sind, ob es funktioniert, testen Sie es am besten, bevor Sie antworten.
Calvins Hobbys

Weil Sicherheitskram (Evaluierung funktioniert nur für +und -online)
Undichte Nonne

@HelkaHomba Ich hatte noch keine Chance, es offline zu versuchen, aber es sollte funktionieren. Das Online - Interpreter verwendet den --safeSchalter, der ersetzt evalmit ast.literal_eval.
Dennis

OK Fair genug.
Calvins Hobbys

Bestätigt, dies funktioniert mit dem Offline-Interpreter.
Dennis

12

Jelly , 18 16 15 14 Bytes

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

Verwendet kein eingebautes eval. Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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
Schön gemacht. Ich sollte Pythons evalals Atom hinzufügen ...
Dennis

9
Ich habe dich übertroffen. : P
Dennis

Schön gemacht, du bist dran!
Undichte Nonne

9

MATL , 12 Bytes

Y'^l6MdZSh*s

Hierbei wird @ aditsus sehr schöne Idee der Lauflängencodierung verwendet.

Probieren Sie es online!

Erläuterung

       % 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 hatte gerade etwas Ähnliches geschrieben. RLE funktioniert gut dafür
Suever

@ Immer wenn ich sehe :-D
Luis Mendo

7

CJam, 20

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

Probieren Sie es online aus

Erläuterung:

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 empfängt eine durch Kommas getrennte Liste von Ausdrücken und gibt den Wert des letzten zurück.

Prüfung

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
Das ist der schlimmste Missbrauch des Komma-Operators, an den ich mich erinnern kann ...
Neil



3

R, 92 Bytes

Hier kann man wahrscheinlich noch ein bisschen Golf spielen.

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.

Ich habe es geschafft, nur ein Byte mit einem Indexierungsansatz
JayCe


2

TI-BASIC, 146 Bytes

Ich werde es schön formatieren, wenn nicht auf dem Handy. Der Schlaf entgeht mir, also bekommst du das. Genießen.

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 Zeichen

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

3
Sollte das nicht eine Funktion und aein Parameter sein?
edc65

Dies ist ungültig wie es ist.
12.

@ edc65, ja, das sollte es. Tatsächlich wurde es aber gezählt (61 angegeben, aber die tatsächliche Codelänge betrug 59). Ich habe nur einen neuen Code schlecht kopiert (die Bearbeitung sollte a[i+1]...a[i+1]=> a[++i]...a[i]- 2 Zeichen kürzer sein, aber ich habe fälschlicherweise das Löschen des gesamten Codes ersetzt a=>).
Qwertiy

@ EᴀsᴀIᴛᴇʀʟʏ, es ist nur eine falsche Paste. Siehe Kommentar oben und Änderungsverlauf für weitere Details.
Qwertiy

@Qwertiy okay cool. Schöne Antwort übrigens
Rɪᴋᴇʀ

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

Ungolfed online versuchen

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
Einige schnelle Golf spielt: int a=l.length, &&=> &, setzen die int i=0auf der gleichen „Linie“ , wie int n=l[0],m.
Undichte Nonne

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;können Sie dies einfach durch den Inhalt innerhalb des elseBlocks ersetzen .
Undichte Nonne

1

Javascript ES6, 79 Zeichen

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

1

Perl, 49 Bytes

48 Byte Code + 1 für -p

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

Verwendung

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

Anmerkungen

Ich habe hier erfahren, dass Sie einen Lookahead in PCRE erfassen können, obwohl dies ( (?=(\d+))anstelle von ((?=\d+))) ein wenig unintuitiv ist . Nach dem Lesen ist dies jedoch sinnvoll, da Sie mit letzterem eine Übereinstimmung mit der Länge Null (den Lookahead) erfassen und stattdessen die Übereinstimmung mit erstem erfassen würden.

Vielen Dank an @ninjalj für das Speichern von 8 Bytes!


@LeakyNun Ich weiß nie genau, was ich dafür zählen soll. Ich kann den relevanten Meta-Post nicht finden. Ich bin froh, die Zählung zu erhöhen, aber ich dachte, da du -ekostenlos pdamit laufen kannst und ein Making-It -pe+1 gab ? Wird vorerst aktualisiert, aber wenn Sie eine Quelle finden könnten, die ich zitieren / verlinken könnte, wäre das großartig!
Dom Hastings

3
@DomHastings 1 ist korrekt, aus dem Grund, den Sie sagen, + dieser Meta-Post
Sp3000

Vielen Dank @ Sp3000! Ich konnte diesen Beitrag für mein Leben nicht finden! @LeakyNun Meta-Post für +1 laut Kommentar von Sp3000
Dom Hastings

Anstatt verkettete Bedingungsoperatoren zu verwenden, können Sie den Raumschiffoperator verwenden, um aus einer Liste auszuwählen: $&.qw(* - +)[$&<=>$1]im Ersatzteil des s///Operators.
Ninjalj

Natürlich! super danke -8 damit!
Dom Hastings

1

Eigentlich 30 Bytes

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

Leider funktioniert dieses Programm unter TIO nicht , da der Befehl eval ( ) nur Literale unter TIO auswertet.

Erläuterung:

;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

Probieren Sie es online!

Der Algorithmus ähnelt dem dieser Antwort , aber ich habe ihn erst erkannt, nachdem ich meine Antwort codiert habe. Viel besser als meine ursprüngliche Antwort eval(parse).

Nutzt die vektorisierten Operationen von R voll aus - *Verwendet die Operation zuerst rle(x)$values ^ rle(x)$lenghtsund punktiert diesen Vektor mit sign( diff( rle(x)$values ) )(vorangestellt mit 1).


1

05AB1E (Legacy) , 17 16 15 Byte

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

-2 Bytes dank @Emigna .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

ü                  # 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
Aufgrund der modularen Indizierung können Sie entfernen, >indem Sie +an das Ende der Zeichenfolge verschieben.
Emigna

@Emigna Nicht sicher, wie ich das verpasst habe .. Danke!
Kevin Cruijssen

1
Sie können ein weiteres Byte speichern, indem Sie Ćund entfernen ¨, wenn Sie ‚ζanstelle vonø
Emigna

@Emigna Oh, das ist doch schlau! Vielen Dank. Ich wusste, dass der Anhang ein bisschen seltsam war, wusste aber nicht, wie ich ihn beheben sollte. ‚ζist eine perfekte Alternative, da der Raum in der Auswertung ignoriert wird. Danke noch einmal. :)
Kevin Cruijssen

0

PHP, 103 Bytes

Ordentliche Herausforderung. Das wurde länger als erwartet. Ich denke, mit array_mapo.ä. wird die Anzahl der Bytes nicht verbessert, da anonyme Funktionen in PHP immer noch teuer sind.

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

Wird über die Befehlszeile ausgeführt und fordert zur Eingabe einer durch Kommas getrennten Liste auf, z.

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

Nimmt Eingaben als durch Leerzeichen getrennte Befehlszeilenargumente an, die in ein automatisches Array konvertiert werden $args. Wir durchlaufen jedes Element und verwenden die Hilfsvariable für $ojede Iteration, um uns daran zu erinnern, was unser vorheriger Eintrag war. Wir verwenden eine indizierte Zeichenfolge, um den entsprechenden Operator zu ermitteln, indem wir die implizit konvertierten Booleschen Werte berechnen (wenn der vorherige Eintrag kleiner ist, bedeutet die []Auswertung, 1+2*0dass '*+-'[1]der +ausgewählte ausgewählt ist).

Die verketteten Zeichenfolgen verbleiben in der Pipeline. Wir sammeln alle diese Schnipsel zusammen ( zum Beispiel 3-, 1+, 4-, etc.) mit einem -joinBetrieb, verketten auf der Endzahl (implizit in einem String konvertiert), und eine Pipe an iex(alias für Invoke-Expressionund ähnliche eval).


Es besteht die Sorge, dass der Ausdruck in diesem Eintrag nicht den richtigen Wert berechnet, wenn der Aufrufer bereits einen Wert von $ o angegeben hat (z. B. $ o = 999). Zu dieser Lösung muss eine Initialisierung von $ o hinzugefügt werden.
Bevo

@Bevo Dies ist ein vollständiges Skript, das über die Befehlszeile und nicht über eine Funktion oder über die interaktive Shell ausgeführt wird. Die überwiegende Mehrheit meiner Einsendungen ist als solche zu bezeichnen, da in einem solchen Szenario keine vordefinierten Variablen zu befürchten sind und der Code daher möglicherweise etwas kürzer ist.
AdmBorkBork


0

Japt -x , 21 bis 19 Bytes

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

Versuch es


Erläuterung

                        :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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.