Zubehör nachträglich!

10

Diese Herausforderung ist inspiriert von Mathematik ist Tatsache. Programmierung ist nicht .


Die mathematische Notation für eine Fakultät oder eine Tatsache ist ein Ausrufezeichen !. Das Ausrufezeichen ist auch notin vielen Programmiersprachen ein gängiges Symbol .

Herausforderung:

Nehmen Sie eine Zeichenfolge mit Ziffern und Zeichen: + !Geben Sie als Eingabe und Ausgabe Folgendes ein:

Alles vor einem Ausrufezeichen sollte als mathematischer Ausdruck ausgewertet 2+2werden 4.

Alles nach einem einzelnen Ausrufezeichen sollte als Zubehör an das angehängt werden, was sich davor befindet. Also: 2+2!5sollte geben 45, weil 2+2=4, und 5ist ein Zubehör. 2+2!5+5sollte geben 410.

Da !bedeutet auch not, dass alles, was nachträglich kein Zubehör ist, nicht angehängt werden sollte. Also 2+2!!5sollte geben 4, da 5ist kein Zubehör. Nun not(not(true))==true, so 2+2!!!5geben soll 45. 2+2!!5!5+5sollte geben : 410, weil 2+2=4dann gefolgt von einer Fakultät und !5!5+5. Das erste 5ist keine Tatsache, sondern 5+5steht nach einem weiteren Ausrufezeichen und ist daher wieder eine Tatsache.

Erläuterungen:

  • Die Ausrufezeichen befinden sich +auf keiner Seite neben a.
  • Es wird keine Führung +für Zahlen geben (es ist 5nicht so +5).
  • Sie können optional eine führende Null einfügen, wenn dies das Ergebnis des Ausdrucks vor der ersten ist !. Beide 4und 04werden als Ausgabe für Eingabe akzeptiert:0+0!4

Zusammenfassung: Bewerten Sie jede Summe (Behandlung !als Trennzeichen). Verwerfen Sie dann alle Zahlen, die nach einer geraden Zahl von !(ab dem Beginn der Zeichenfolge) erscheinen. Dann entfernen Sie alle !.

Testfälle:

!
   <- Empty string

5
5

12!
12

!87
87

!!5
   <- Empty string

5+5!2+2
104

5+5!!2+2
10

1!2!3!4!5!6!7!8!9
12468

10+10!!2+2!!3+3!4+4
208

2!!3!5
25

2!!3!5!7
25

10!!!!!!!5
105

Dies ist also gewinnt der kürzeste Code in Bytes (in jeder Sprache)! Erklärungen sind ausdrücklich erwünscht!

Stewie Griffin
quelle
ähm ... sagen wir, wir haben 2 !! 3! 5 hier ist oder ist 5 kein Zubehör von 3?
Officialaimm
3
@officialaimm Es ist 25(siehe hinzugefügten Testfall). Noch wichtiger ist, 2!!3!5!7würde immer noch geben 25, weil es eine gerade Anzahl von !links von der gibt 7(so dass Sie nicht nur den Lauf direkt vor der Zahl zählen, sondern alle !links davon).
Martin Ender
Kann die Ausgabe eine Mathematica sein Row?
Ngenisis
Ähm ... also hat diese Herausforderung eigentlich nichts mit Fakultäten zu tun?
DLosc

Antworten:

5

Netzhaut , 35 31 29 Bytes

4 Bytes wurden gespart, indem Sie sich von ETH-Produktionen inspirieren ließen .

Vielen Dank an Leo für das Speichern von weiteren 2 Bytes.

\d+|\+
$*
1+
$.&
1`!

!\d*!?

Probieren Sie es online aus!

Martin Ender
quelle
Sie können einige Bytes in den letzten Zeilen wie diesen
Leo
1
@ Leo Das ist wirklich ordentlich, danke. :)
Martin Ender
5

JavaScript (ES6), 58 56 Byte

Dank Martin Ender zwei Bytes gespeichert .

let f =
x=>x.replace(/[^!]+/g,eval).replace(/!(\d*)!?\d*/g,"$1")
<input value="2+2!5+5" oninput="try{O.value=f(value)}catch(e){}"><br>
<input id=O value="410" disabled>

Könnte irgendwie verbessert werden ...

ETH-Produktionen
quelle
Gute Verwendung des Funktionsarguments zu replace.
Neil
@ Neil Danke, aber ich habe einen besseren Weg gefunden :-)
ETHproductions
Ihr Code-Snippet gibt mir die falsche Antwort 1+1!5. Ich denke du hast evaldas bisschen vor dem vergessen !.
Wert Tinte
@ValueInk Ah verdammt, ich glaube nicht, dass es einen einfachen Weg gibt, das zu beheben.
ETHproductions
2

Gelee , 16 Bytes

ṣ”!µḢW;m2$VṾ$L¡€

Probieren Sie es online aus!

Erläuterung

Die wichtigste Beobachtung hier ist, dass wir die Schritte "außer Betrieb" ausführen können; Anstatt die Summen zu bewerten und diejenigen zu ignorieren, die wir nicht mögen, können wir die Summen an ungültigen Positionen ignorieren und dann den Rest bewerten.

ṣ”!µḢW;m2$VṾ$L¡€
ṣ”!                Split input on '!'
   µ               Set as the new default for missing arguments
    Ḣ              Take the first element, removing it from the default
     W;  $         Cons with
       m2            every odd-numbered element of {the tail of the !-split input}
               €   For each remaining element
          VṾ$      Evaluate and de-evaluate it
             L¡      a number of times equal to its length

Wenn Sie eine Summe wie "10+10"bewerten, wird sie zu einer Zahl ausgewertet, z. B. 20zu einer Zeichenfolge "20". Das Wiederholen dieses Vorgangs hat keine zusätzlichen Auswirkungen (es ist idempotent). Daher bewerten wir effektiv jedes Element der Zeichenfolge mit Ausnahme der Nullzeichenfolge, die nicht bewertet wird, da sie eine Länge von Null hat.


quelle
Das ist ein großartiger Trick, um jeden Gegenstand bedingt zu bewerten. Könnten Sie irgendwie das logische UND jedes Gegenstands und seinen abwertbaren Wert nehmen? (Ich nehme an, die leere Zeichenfolge ist in Jelly
falsch
@ETHproductions: Jellys tacitness macht es unwahrscheinlich, dass dies Bytes sparen würde; Wenn möglich, sollte derselbe Wert nicht zweimal verwendet werden. Wenn Sie einen Wert wiederverwenden möchten, müssen Sie normalerweise mindestens einen zusätzlichen Wert µeingeben (und µfunktionieren nicht in einer Schleife, was bedeutet, dass Sie etwas benötigen noch ausführlicher). Ich habe es geschafft, es zum Laufen zu bringen ṣ”!µḢW;m2$ȧVṾ$$€, aber es ist nicht kürzer (und hat die charakteristische Ansammlung von Dollarzeichen, die auftreten können, wenn Sie Jelly an den Rand seiner Fähigkeit bringen, Kontrollstrukturen zu verschachteln.)
2

Gelee , 18 Bytes

ṣ”!µḊm2;@ḢW$LÐfVṾ€

Probieren Sie es online aus!

Wie?

ṣ”!µḊm2;@ḢW$LÐfVṾ€ - Main link: string
ṣ”!                - split on '!' characters
   µ               - monadic chain separation (call that x)      e.g. ['1+1','0+0','0+0','0+0','','1+0','','','']
    Ḋ              - dequeue x (all but the leftmost entry of x) e.g.       ['0+0','0+0','0+0','','1+0','','','']
     m2            - modulo 2 index into that result             e.g.       ['0+0',      '0+0',   '1+0',   '']
           $       - last two links as a monad
         Ḣ         -     head x (the leftmost entry of x)        e.g.  '1+1'
          W        -     wrap                                    e.g. ['1+1']
       ;@          - concatenate with reversed arguments         e.g. ['1+1','0+0',      '0+0',   '1+0',   '']
             Ðf    - filter keep:
            L      -     length (keep that have non-zero length) e.g. ['1+1','0+0',      '0+0',   '1+0']
               V   - eval as jelly code (vectorises)             e.g. [  2,    0,          0,       1]
                      Yes, addition is just + and decimal numbers are just strings of digits in Jelly believe it or not!
                Ṿ€ - uneval €ach (creates a string from each one)e.g. [ '2',  '0',        '0'     ,'1']
                      without the € it would uneval the list and hence yield commas too)
                   - implicit print (prints the resulting list [of characters and possibly
                      lists of characters] as if it were all one string.)
Jonathan Allan
quelle
Ich denke nicht, dass dies für Literal 0+0in der Mitte der Eingabe funktioniert (an einem Ort, an dem es nicht verworfen wird). es erzeugt die Nullzeichenfolge, obwohl es eine Ziffer 0 erzeugen sollte.
Ah, stimmt - ich muss zu einer längeren Lösung übergehen :(
Jonathan Allan
Sollte repariert werden (möglicherweise jetzt golffähig).
Jonathan Allan
1

Ruby , 58 56 + 1 = 59 57 Bytes

Verwendet die -pFlagge. -2 Bytes von Tutleman .

i=0;$_=' '+$_;gsub(/!?([^!]*)/){eval$1if(2>i+=1)||i%2<1}

Probieren Sie es online aus! (Eine zusätzliche Codezeile wurde hinzugefügt, damit alle Eingabezeilen verwendet und die Ausgabe in verschiedenen Zeilen gedruckt werden.)

Wert Tinte
quelle
Ich denke, Sie können die Klammern fallen lassen eval$1, nein?
Tutleman
@ Tutleman huh. Ich weiß nicht, welches Problem ich hatte, das mich dazu brachte, die Parens hinzuzufügen (sie waren nicht vorhanden, als ich anfing, das Programm zu schreiben), aber es scheint, dass ich sie wirklich fallen lassen kann.
Wert Tinte
0

Stapel, 192 184 Bytes

@echo off
set/ps=
call:c . "%s:!=" "%"
echo(%s%
exit/b
:c
set s=
if not %2=="" set/as=%2
:l
shift
shift
if "%1"=="" exit/b
if %1=="" goto l
set/at=%1
set s=%s%%t%
goto l

Es ist unpraktisch, mit den leeren Zeichenfolgen umgehen zu müssen.

Neil
quelle
0

Pip , 18 Bytes

Ich denke, das ist das kürzeste, was es gibt ... obwohl ich das auch vor ungefähr drei Iterationen gesagt habe.

{VaX++v%2+!v}Ma^'!

Übernimmt die Eingabe als Befehlszeilenargument. Probieren Sie es online aus!

Erläuterung

                    a is 1st cmdline arg; global variable v is -1 (implicit)
              a^'!  Split a on !
{           }M      Map this function to the resulting list (note that inside function,
                    a is the function arg):
    ++v              Increment v (so that v tracks the 0-based index of the current
                     element)
       %2            We want to keep the elements where v%2 is 1...
         +!v         ... and also v=0, where v%2 is 0, but adding !v makes it 1
  aX                 String-multiply the argument by the above quantity (turning elements
                     we don't want into empty string)
 V                   Eval it (eval'ing empty string gives nil, but that's okay because
                     nil doesn't output anything)
                    Autoprint the resulting list, concatenated together (implicit)
DLosc
quelle
0

R 95 Bytes

function(x)for(e in strsplit(gsub('!([^!]*)![^!]*','\\1!',x),'!')[[1]])cat(eval(parse(text=e)))

Es gibt wahrscheinlich Raum für Verbesserungen, aber im Moment ist es das Beste, was ich mir einfallen lassen kann.

Robert Hacken
quelle