Mathematik ist Tatsache. Programmierung geht nicht

176

In der Mathematik bedeutet ein Ausrufezeichen !oft Fakultät und kommt nach dem Argument.

Bei der Programmierung bedeutet ein Ausrufezeichen !oft Negation und steht vor dem Argument.

Für diese Herausforderung wenden wir diese Operationen nur auf Null und Eins an.

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

Nehmen Sie eine Folge von null oder mehr !, gefolgt von 0oder 1, gefolgt von null oder mehr !( /!*[01]!*/).
Beispielsweise kann die Eingabe !!!0!!!!oder !!!1oder !0!!oder 0!oder sein1 .

Das !'s vor dem 0oder 1sind Negationen und das !' s nach sind Fakultäten.

Fakultät hat höhere Priorität als Negation, daher werden Fakultäten immer zuerst angewendet.
Zum Beispiel !!!0!!!!wirklich bedeutet !!!(0!!!!), oder noch besser !(!(!((((0!)!)!)!))).

Die resultierende Anwendung aller Fakultäten und Negationen ausgeben. Die Ausgabe wird immer 0oder sein 1.

Testfälle

0 -> 0
1 -> 1
0! -> 1
1! -> 1
!0 -> 1
!1 -> 0
!0! -> 0
!1! -> 0
0!! -> 1
1!! -> 1
!!0 -> 0
!!1 -> 1
!0!! -> 0
!!!1 -> 0
!!!0!!!! -> 0
!!!1!!!! -> 0

Der kürzeste Code in Bytes gewinnt.

Calvins Hobbys
quelle
18
Aber 0! = 1! Was nützt es also, mehrere Fakultäten zu behandeln?
Boboquack
30
@ Boboquack Weil das die Herausforderung ist.
Calvins Hobbys
11
<? = '1'; ... korrigiere 75% der Zeit in PHP.
Aslum
10
Ich kann mich hier irren, kann aber keine Zahl mit Fakultäten angeben, nachdem sie einfach entfernt und durch 1 ersetzt wurde. Wie 0 !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 etc
Albert Renshaw
2
@ AlbertRenshaw Das ist richtig.
Calvins Hobbys

Antworten:

43

Mathematica, 25 17 Bytes

Input[]/.!x_:>1-x

Nimmt Eingaben von einer Benutzereingabeaufforderung entgegen. Übernimmt die Notebook-Umgebung von Mathematica für implizites Drucken. Um es zu einem Befehlszeilenskript Print[...]zu machen, schließen Sie es ein oder machen Sie es zu einer argumentlosen Funktion (die dann Eingaben von der Eingabeaufforderung entgegennimmt) &.

Mathematica verfügt über beide erforderlichen Operatoren (mit der erforderlichen Priorität), sodass wir die Eingabe nur "auswerten" können (was automatisch von ausgeführt wird Input[]), der Operator für die logische Negation jedoch nicht für ganze Zahlen funktioniert (sodass er nicht ausgewertet wird). Wenn !xdas Ergebnis einen Rest enthält, ersetzen wir diesen durch 1-x.

Ein paar lustige Fakten zur Bewertung:

  1. Mathematica hat tatsächlich auch den doppelten Fakultätsoperator !!, der berechnet n*(n-2)*(n-4)*..., aber auf angewendet 0oder 1immer noch gegeben wird 1, sodass es keine Rolle spielt, 0!!!!!als was tatsächlich analysiert wird ((0!!)!!)!.
  2. Obwohl Mathematica verlässt !0und nicht !1ausgewertet ist, weiß es, dass dies !selbstinvers ist, sodass es automatisch alle Führungspaare aufhebt !. Nachdem das ToExpressionsind wir immer mit einem von links 0, 1, !0, !1.
Martin Ender
quelle
3
Seit wann ist ein REPL-Snippet standardmäßig erlaubt?
LegionMammal978
2
@ LegionMammal978 Anscheinend seit Dezember 2015, aber ich vergesse es immer wieder. Um fair zu sein, es ist kein "Snippet", bei dem nicht angenommen wird, dass die Eingabe bereits irgendwo im Speicher gespeichert ist. Und vorausgesetzt, die Notebook-Umgebung unterscheidet sich nicht wesentlich von einer Sprache mit impliziter Ausgabe.
Martin Ender
Nur neugierig, könnte ein Meta-Link zur Verfügung gestellt werden? (Der Versuch, dort Informationen zu finden, ist stressig, ein weiteres Problem des SE Q & A-Formats ...)
LegionMammal978
@ LegionMammal978 steht schon in der Antwort.
Martin Ender
Reine ksh-Lösung x=${x/[01]!*/1};echo $(($x))- nicht erlaubt, eine richtige Antwort zu posten :(
DarkHeart
28

[Bash] + Unix-Dienstprogramme, 21 17 Bytes

sed s/.!!*$/1/|bc

Dies muss in einer Datei gespeichert und als Programm ausgeführt werden. Wenn Sie versuchen, den Befehl direkt über die Befehlszeile einzugeben, funktioniert er nicht, weil !! wird erweitert, da die Ersetzung des Verlaufs im interaktiven Modus von bash aktiviert ist. (Alternativ können Sie die Protokollersetzung mit deaktivierenset +H .)

Testfall läuft:

for x in 0 1 '0!' '1!' '!0' '!1' '!0!' '!1!' '0!!' '1!!' '!!0' '!!1' '!0!!' '!!!1' '!!!0!!!!' '!!!1!!!!'; do ./excl <<<"$x"; done

0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
Mitchell Spector
quelle
Die alte Version funktioniert, das tut man nicht
Cows quaken
Ich habe den TIO-Link verwendet
Kühe quaken
@KritixiLithos Es hat gut funktioniert, als ich es auf meiner Linux-Box ausprobiert habe. Das Problem bestand anscheinend darin, dass TIO am Ende der simulierten Eingabezeile eine neue Zeile benötigt. Es ist eine verwirrende Situation, also habe ich den TIO-Link entfernt. Wenn Sie es dort ausprobieren möchten, klicken Sie erneut auf den folgenden Link (stellen Sie jedoch sicher, dass Sie am Ende der Eingabe eine neue Zeile einfügen, wenn Sie die Eingabe ändern, um sie zu testen): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ /…
Mitchell Spector
2
Aber was ist, wenn jemand gelaufen ist mkdir -p 's/.!!'{bunch,of,different,directories}\$/1? Dann erhalten Sie Pathname Expansion und Sed versucht, Verzeichnisse wie Dateien zu lesen, anstatt die Standardeingabe zu lesen, und gibt nichts aus! :)
Wildcard
1
@Wildcard Ich stimme vollkommen zu. In Produktionsskripten verwende ich in solchen Situationen immer Anführungszeichen. (In diesem Fall würde ich das Argument tatsächlich in doppelte Anführungszeichen setzen, anstatt nur das * zu umgehen. Es ist einfacher zu lesen als die Verwendung von Backslashes und vermeidet die Möglichkeit, ein Sonderzeichen zu verpassen.)
Mitchell Spector,
22

Retina , 20 15 14 Bytes

Danke an Leo für das Speichern von 1 Byte.

0!
1
!!

^1|!0

Probieren Sie es online!

Erläuterung

0!
1

Biegen Sie 0!in 1. Andere Trailing !s sind uns egal , die resultierende Zahl ist dieselbe, als hätten wir alle Fakultäten angewendet.

!!

Negationspaare aufheben. Dies kann auch einige Fakultäten aufheben, aber das ist irrelevant.

^1|!0

Zählen Sie die Anzahl der Übereinstimmungen dieser Regex, die entweder 1oder ist 0und das gewünschte Ergebnis liefert.

Martin Ender
quelle
Alternative Lösung für das gleiche bytecount: \d.+...
Kühe quaken
@KritixiLithos Hat einen Weg gefunden, dies zu vermeiden.
Martin Ender
Sie können die ^vor!0
Leo
17

Schmutz , 14 12 9 Bytes

e`\0!~\!_

Probieren Sie es online!

Erläuterung

Dies vergleicht die Eingabe mit einem Muster und druckt 1für Übereinstimmung und 0für keine Übereinstimmung.

e`\0!~\!_
e`         Match entire input against this pattern:
    !      not
  \0       a sole 0
     ~     xor
      \!   exclamation mark
        _  followed by this pattern matched recursively.

Die Idee ist dies. Wenn die Eingabe mit einer Ziffer beginnt, \!_schlägt der rekursive Teil immer fehl und ist \0!erfolgreich , es sei denn, wir haben einen einzigen 0. Ihr xor ist erfolgreich, es sei denn, die Eingabe ist eine einzelne 0. Beginnt die Eingabe mit einem !, ist dies \0!immer erfolgreich und ist \!_erfolgreich, wenn die rekursive Übereinstimmung erfolgreich ist. Ihr xor ist genau dann erfolgreich, wenn die rekursive Übereinstimmung fehlschlägt und sie somit negiert.

Zgarb
quelle
16

Brainfuck, 85 72 (84) Bytes

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]<+.

numerisch zurückgeben oder

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]-[-----<+>]<--.

für ASCII-Text. > kann auch vorangestellt werden, um Speicherumbrüche zu vermeiden.

Probieren Sie es online!


Loops over the input.
On 1, ends.
On "!", toggles bool a stored as 0 or 255.
On "0", toggles if there is no trailing bit, then ends.

Memory labels  | BOOL | INPUT | FLAG |

,                   first input 
[                     # loop on INPUT
  >-[-----<->]<++     subtract 49 == "1"

  [                     # case not "1"
    >++++[-<++++>]      add 16 since 49 take 16 == "!"

    +                   set FLAG
    <                   move to INPUT
    [                     # case "0"
      [+],                clear and new INPUT
      [                     # case "0!"
        [-]>-<              clear INPUT and FLAG
      ]
    ]
  ]

  >                   move to FLAG
  [                     # case "!" or "0" without tail
    <<+[-->]>[<]        not the BOOL
    ,                   take new input
    >-                  clear FLAG
  ]
  <                   move to INPUT
]

+.                    return 0 or 1

Oder ersetzen Sie für eine Textantwort die letzte Zeile durch

-[-----<+>]<--.       add 49 for "0" or "1" conversion and return
Rupert Gräber
quelle
14

Brainfuck - Weg zu vielen Bytes (232 Bytes)

Offensichtlich die falsche Sprache für das Gewinnen im Codegolf. Hauptsächlich bemerkte ich einen Mangel an jemandem, der diesen Esolang benutzte. Es gibt einen guten Online-Dolmetscher für Interpeter, oder Sie können mit diesem bf visualizer beobachten, was das Programm macht .

>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.
CodyCode
quelle
3
Du verrückter Mann!!
Almo
Liebe es, kannst du das in malbolge tun? XD
Stefan Nolde
Information: Es gibt unten zu viel kürzere Lösungen.
user202729
14

Python, -44- 42 Bytes

2 Bytes gespart dank Zgarb!

lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2

Schritt für Schritt:

  1. x[-1]!='0'
    wenn xEnde mit 1oder !xnicht am Ende mit 0dem faktoriellen Teil muss Wert haben 1, sonst0
  2. ^len(x.rstrip('!'))%2
    das Eigentum von xor als "bedingtes Nicht" ausnutzen. Die Bedingung ist in diesem Fall, wenn die Länge des Anfangs !s ungerade ist. Jedoch,.rstrip entfernt nicht die Anzahl von der Saite , so dass die Länge berechnet , indem 1 versetzt ist, damit der Zustand invertiert wird
  3. Der Versatz von 1 in Schritt 2 wird korrigiert, indem !=zu ==in Schritt 1 gewechselt wird. Zgarb schlug vor, einen Differenzvergleichsoperator zu verwenden, anstatt eine andere Inversion anzuwenden, wodurch 2 Bytes eingespart werden.

Probieren Sie es online!

busukxuan
quelle
Scheitert an einer Eingabe von !!0; es kehrt gerade zurück 1.
Value Ink
@ValueInk sollte jetzt funktionieren
busukxuan
1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2vermeidet die zusätzliche Inversion.
Zgarb
15
Durchgestrichen
3
Ich denke, er gibt an, dass ein durchgestrichenes 44 in der verwendeten Schriftart nicht durchgestrichen aussieht ... :) Der durchgestrichene Teil überlappt sich mit dem horizontalen Teil der 4er.
JeffC
13

JavaScript (ES6), 43 41 29 Bytes

s=>+eval(s.replace(/.!+$/,1))

Non-Regex-Methode ( 41 31 Bytes)

Unten ist mein erster Ansatz. Es ist etwas interessanter, aber auch nach einer signifikanten Optimierung von Neil (10 Bytes gespart) noch deutlich länger .

f=([c,...s])=>1/c?c|s>'':1-f(s)

Testfälle

Arnauld
quelle
Ich kann nur 10 Byte aus dem Nicht-regex Methode speichern, so dass es immer noch zu lang: f=([c,...s])=>1/c?c|s>'':1-f(s).
Neil
@Neil Da es sowieso viel besser ist als mein erster Versuch, habe ich mir erlaubt, Ihren Vorschlag einzubeziehen.
Arnauld
Ha, ich hatte die gleiche Idee, aber du hast es besser gespielt. :)
Devsman
11

Gelee , 5 Bytes

VeMḂ$

Probieren Sie es online!

Monadische Funktion, die einen String erwartet. Eingänge mit führenden !s verursachen a1 auf dem Weg nach STDOUT gedruckt wird. Die von mir angegebene TIO-Verknüpfung ist also ein Testkabel, das die Eingabe-Ausgabe-Paare unter der ersten Ausgabezeile druckt.

Wie?

VeMḂ$ - Monadic link: string
V     - eval the string
          - the implicit input of 0 causes !...! to evaluate to 1 (which gets printed),
          - the result is the evaluation of the rest: "0"=0; "0!"=1; "1"=1; "1!"=1; ...
 e    - exists in?
    $ - last two links as a monad:
  M   -     Maximal indexes - the "0" and "1" characters are greater than "!",
                            - so this results in a list of one item [i] where
                            - i is the 1-based index of the 0 or 1 character.
   Ḃ  -     %2 (vectorises) - [i%2], so a 0 if we need to logically negate and a 1 if not
                            - hence we check equality with e rather than inequality.
Jonathan Allan
quelle
10

05AB1E , 9 Bytes

Code:

.V¹'!ÜgG_

Verwendet die CP-1252- Codierung. Probieren Sie es online! oder Überprüfen Sie alle Testfälle!

Erläuterung:

.V         # Evaluate the input as 05AB1E code. This computes the factorial part.
   '!Ü     # Remove trailing exclamation marks..
  ¹        # ..from the first input
      g    # Get the length of the resulting string
       G   # Do the following length - 1 times:
        _  #   Negate the number
Adnan
quelle
10

Retina , 13 Bytes

Ein etwas seltsamer Ansatz, aber er ist kurz und funktioniert.

0$
!1
!!

^\d

Mit den ersten beiden Zeilen ersetzen wir eine Endung 0mit !1: Mit dieser Ersetzung wissen wir jetzt, dass der Teil unserer Zeichenfolge ab der Ziffer gleich 1 ist.

Entfernen Sie in den nächsten beiden Zeilen die folgenden Paare !: Die doppelte Negation löscht sich von selbst, und wir haben die Fakultät bereits im vorherigen Schritt berücksichtigt.

Die letzte Zeile muss mit einer Ziffer am Anfang der Zeichenfolge übereinstimmen und die Anzahl der Übereinstimmungen zurückgeben: Wenn alle Negationen beseitigt sind, werden wir eine Übereinstimmung finden (und wie wir bereits sagten, ist dies gleich 1), wenn es noch eine gibt Eine Negation, die nicht passt.

Probieren Sie es online!

Löwe
quelle
1
Wäre die letzte Ziffer nicht unbedingt immer eine 1? In diesem Fall könnten Sie 1eher als verwenden \d.
1
@ ais523 nein, da der erste Teil nur eine Endung 0 ersetzt, 0!bleibt die Eingabe zum Beispiel bis zur letzten Zeile unverändert
Leo
1
Wirklich schöne Lösung, nette Arbeit! :)
Martin Ender
10

Ruby, 12 + 1 = 39 24 15 13 Bytes

Verwendet die -nFlagge. Danke an @GB für -9 Bytes!

p~/!*$|0$/%2
Wert Tinte
quelle
Da Sie nur die Länge prüfen, können Sie die nachfolgende Null löschen, anstatt zuerst "! 0" und danach eine einzelne Null zu prüfen.
GB
@GB das ist eine wunderbare idee! Ich fand jedoch eine Lösung, die noch kürzer ist, indem ich meinen regulären Ausdruck änderte, um nach der Position 0 oder dem Zeilenende zu suchen
Value Ink
Dann können Sie einfach prüfen, ob ein '!' oder Null oder Zeilenende: p ~ /! + $ | 0 $ | $ /% 2 ist nur 14 Byte.
GB
Und dann könnte "0 $ | $" zu "0? $" Werden, um ein weiteres Byte zu speichern.
GB
1
Besser noch !*$ist kürzer um zwei!
Value Ink
9

Perl , 20 Bytes

19 Byte Code + -pFlag.

s/\d!+/1/;$_=0+eval

Probieren Sie es online!

Perl Negation kehrt undefoder 1, damit ich 0+das Ergebnis numerify 0+undefkehrt 0. Abgesehen davon gibt es nicht viel über den Code zu sagen.

Dada
quelle
2
Gerade genau das geschrieben. Habe eine +1.
Primo
@primo Freut mich zu sehen, dass ich ausnahmsweise nicht 20 Bytes hinter dir bin! Danke :)
Dada
9

C 68 62 61 53 Bytes

c;e(char*a){for(c=1;*a<34;a++)c^=1;c=a[1]?c:*a&1^!c;}

Noch ein paar Bytes mit einigem Missbrauch rausgedrückt

Probieren Sie es online!

Ahemone
quelle
1
Ich denke du kannst das intaus der Funktion entfernen und du kannst das *a==33auf ändern *a<34.
Kühe quaken
Leider *a%2ist kürzer als*a-48
Kühe quaken
Danke für den Tipp. Ich konnte auch ein anderes Zeichen eliminieren, indem ich die Klammern um die Rückgabe entfernte und es zuwies.
Ahemone
Ich bin mir ziemlich sicher for(;*a<34;a++), for(;*a++<34;)dass man 1 Byte sparen kann
Albert Renshaw
Leider nicht, da die bedingte Anweisung immer ausgeführt wird und daher der Zeiger für die Rückgabe-Dereferenzierung zu weit nach vorne verschoben wird.
Ahemone
6

Perl 6 , 32 28 23 Bytes

{m/(\!)*(1|0.)*/.sum%2}

Wie es funktioniert

{                     }  # A lambda.
{m/            /      }  # Match the lambda argument against the regex:
   (\!)*                 #   Zero or more `!`.
                         #     (First capture will be an array with one element per negation).
        (1|0.)*          #   A `1`, or a `0` and another character, zero or more times.
                         #     (Second capture will be a one-element array if the factorial
                         #     part evaluates to 1, and an empty array otherwise.)
                .sum     # Add the lengths of the two captures,
                    %2   # and return that sum modulo 2.
smls
quelle
6

Haskell , 39 Bytes

f('!':b)="10"!!read[f b]
f[a]=a
f _='1'

Definiert eine Funktion f, die eine Zeichenfolge akzeptiert und ein Zeichen zurückgibt. Probieren Sie es online!

Erläuterung

Es gibt drei Fälle: Die Eingabe beginnt mit !, die Eingabe hat die Länge 1 und alles andere.

f('!':b)=    -- If input has head '!' and tail b,
 "10"!!      -- we index into the string "10"
  read[f b]  -- using f b converted to int. This essentially inverts f b.
f[a]=        -- If input has only one character, we know it's a digit,
 a           -- so we can just return it.
f _=         -- In all other cases, we know the input is a digit followed by !s,
 '1'         -- so we can return '1'.
Zgarb
quelle
Schalten von String in Integer als Rückgabetyp: f('!':b)=[1,0]!!f b;f"0"=0;f _=1.
nimi
6

Befunge, 24 Bytes

~"!"-:#v_$1+
*+2%!.@>0~`

Probieren Sie es online!

Dies beginnt mit dem Zählen der Anzahl der !von stdin gelesenen Zeichen. Das erste Zeichen, das nicht a ist, ist !entweder a 0oder 1, aber beim Testen auf haben !wir 33 subtrahiert, was entweder 15 oder 16 ergibt. Dann lesen wir ein weiteres Zeichen, das entweder a !oder EOF ist, und vergleiche, ob das kleiner als 0 ist (dh EOF).

Aus diesen drei Datenpunkten - der Ausrufezahl ( c ), dem Ziffernwert ( d ) und der Dateiende-Bedingung ( e ) - können wir das Ergebnis wie folgt berechnen:

!((c + d*e) % 2)

Das Multiplizieren des Ziffernwerts mit der Dateiendebedingung bedeutet, dass er auf Null konvertiert wird, wenn auf die Ziffer ein folgt !, wodurch ihm der gleiche Modulo-2-Wert wie ein 1(der in 16 konvertiert wurde) gegeben wird. Bevor Sie jedoch das Modulo 2 anwenden, fügen Sie die anfängliche Ausrufezahl hinzu, wodurch das Modulo 2-Ergebnis effektiv so oft umgeschaltet wird, wie !Präfixe vorhanden waren. Und schließlich wir nicht das Ergebnis , da unsere Ausgangswerte für 0und 1ist das Gegenteil von dem, was wir brauchen.

Sehen Sie sich den Code genauer an:

~                Read a character from stdin.
 "!"-            Subtract 33 (ASCII for '!').
     :  _        Make a duplicate and check if zero (i.e. is it a '!').
         $1+     If so, drop the duplicate, increment a counter, and repeat.
       v         Otherwise move to the second line, leaving the digit value on the stack.
       >0~`      Read one more character and check if less than 0 (i.e. EOF).
*                Multiple by the digit value, making it zero if not followed by EOF.
 +               Add to the exclamation count.
  2%             Modulo 2 the result.
    !            Then not that value.
     .@          And finally write to stdout and exit.
James Holderness
quelle
6

Haskell , 27 Bytes

f('!':b)=1-f b
f"0"=0
f _=1

Probieren Sie es online!

Jede führende !Zeile ergänzt die Ausgabe für den Rest des Ausdrucks, und zwar als 1-. Wir drehen weiter, bis wir eine Ziffer erreicht haben. Wenn der Rest gerade ist "0", ist das Ergebnis 0. Andernfalls ist es ein 1oder gefolgt von einem oder mehreren !, sodass das Ergebnis 1 ist.

xnor
quelle
5

Ruby, 22 21 20 Bytes

->s{(s=~/!*$|0$/)%2}

Erläuterung:

  • Erster Fall, ich habe ein '!' am ende entferne sie und erhalte length modulo 2.
  • Zweiter Fall, kein '!', Wenn das letzte Zeichen Null ist, dann entferne es, erhalte Länge Modulo 2
  • Wenn das letzte Zeichen 1 ist, kehren Sie zum ersten Fall zurück

(-1 Byte, das die Idee von @Value Ink stiehlt)

GB
quelle
Genial, ich habe mir dieses Puzzle 10 Minuten lang angesehen, hatte aber nicht viel Zeit und vergaß es dann. Jetzt entdeckte es wieder in aktiven Fragen und freute sich über einen so schönen Ansatz.
Akostadinov
4

Gelee , 8 Bytes

œr”!LḂ=V

Probieren Sie es online!

Dies ist eine Funktion (monadischer Link), die ein Argument akzeptiert und über ihren Rückgabewert zurückgibt. (Als Nebeneffekt schreibt es auch oft Junk auf die Standardausgabe, aber das interessiert uns nicht.)

Erläuterung

œr”!LḂ=V
œr”!      Take {the input}, with all trailing ! deleted
    L     Take the length of this
     Ḃ    Take the parity of that length
      =   Return 0 if unequal, 1 if equal to:
       V    the value of {the input} when eval'ed as a niladic Jelly program

Beachten Sie zunächst, dass die Eingabe immer aus einer Anzahl von Zeichen besteht !, gefolgt von einer Ziffer, gefolgt von einer weiteren !. Wenn Sie das abschließende Zeichen löschen !und die Länge übernehmen, erhalten Sie eine Zahl plus der Anzahl der führenden Zeichen !im Programm. Wenn Sie die Parität davon nehmen, wird 0 zurückgegeben, wenn es eine ungerade Zahl gab !, oder 1, wenn es eine gerade Zahl gab !. Das Vergleichen mit 0 ist eine "Nicht" -Funktion, während das Vergleichen mit 1 die Identitätsfunktion ist; Dadurch wird œr”!LḂ=der !Teil der Frage "Führende Operatoren als NICHT-Operatoren behandeln" effektiv implementiert .

Was die zweite Hälfte angeht, !ist die Behandlung von Fakultäten eine Fakultätsoperation in Jelly. Wenn das Programm also keine Führungslinie hat !, können wir das Problem direkt mit simple eval( V) lösen . Wenn das Programm über eine führende Stelle verfügt !, werden diese so interpretiert, dass sie die Fakultät 0 annehmen (möglicherweise mehrmals), was einen Rückgabewert von 1 ergibt, der auf der Standardausgabe ausgegeben und verworfen wird, sobald eine Ziffer angezeigt wird. Daher haben sie keinen Einfluss auf den Rückgabewert der Funktion, die ich der Frage unterbreitet habe.


quelle
Sehr schöne und gute Erklärung.
ElPedro
4

Python, 38 Bytes

lambda s:(s[1::2]>s[::2])^ord(s[-1])%2

TryItOnline!

Eine unbenannte Funktion, die eine Eingabezeichenfolge verwendet sund eine Ganzzahl 0oder zurückgibt 1.

s[1::2] ist ein Teil der Eingabezeichenfolge, der bei Index 1 beginnt und eine Schrittgröße von zwei hat:
'Like this' -> 'ieti'

s[::2] ist ähnlich, beginnt jedoch mit dem Standardindex 0:
'Like this' -> 'Lk hs'

Der Test (s[1::2]>s[::2])prüft, ob der auf 0 basierende Index des '0'oder '1'ungerade ist, dh ob wir ergänzen müssen.
Dies funktioniert, weil die Reihenfolge der Zeichenfolgen lexikografisch mit einer nicht leeren Zeichenfolge überprüft wird, die größer als die leere Zeichenfolge ist, und mit der ASCII-Reihenfolge '1'>'0'>'!'. Dies ist ein Byte kürzer als das einfachere s.index(max(s))%2.

Das ord(s[-1])%2prüft, ob das letzte Zeichen kein '0'(für eine gültige Eingabe) ist, und führt zu einer Ganzzahl (wobei dieselbe Länge (s[-1]!='0')einen Booleschen Wert zurückgeben würde).
Dies funktioniert, weil das letzte Zeichen der Eingabe s[-1]a '0'ist '1'oder '!'ASCII-Codepunkte 48, 49 und 33 aufweist, die 0, 1 und 1 Modulo 2 sind.

Das ^führt dann eine bitweise Exklusiv- oder Operation für die beiden obigen Werte durch und gibt eine Ganzzahl zurück, da eine Eingabe, die rechte, eine Ganzzahl ist. Wenn die linke wahr ist, wird das Komplement der rechten zurückgegeben, wenn die linke falsch ist, wird die rechte nach Bedarf zurückgegeben.

Jonathan Allan
quelle
4

Java 7, 105 82 81 Bytes

int a(char[]a){int b=0,c=0;for(;a[b++]<34;c^=1);return(b<a.length?1:a[b-1]&1)^c;}

Probieren Sie es online!

Alte reguläre Lösung

int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}
Sack
quelle
2
c^=1ist super schlau. Das ist ein unbenutzter Operator, falls ich jemals einen gesehen habe.
Addison Crump
3

CJam , 12 11 Bytes

r_W='0=!\~;

Probieren Sie es online! Testsuite (druckt eine 1für jeden richtigen Testfall).

r      e# Read input.
_W='0= e# Duplicate and check whether the string ends in '0'. This is the
       e# only case in which the factorial part results in 0.
!      e# Negate this to get the actual result of the factorial part.
\      e# Swap with the input.
~      e# Evalute the input as CJam code. The leading `!` will apply the logical
       e# negations to the factorial result. The 0 or 1 will then push a junk value
       e# which is potentially negated a few times as well, by the factorials.
;      e# Discard the junk value.
Martin Ender
quelle
3

Haskell , 67 65 Bytes

f s|foldr(\_->not)(last s`elem`"1!")$fst.span(<'0')$s="1"|1<3="0"

Probieren Sie es online! Verwendungszweck:f "!!!0!!!!"

Zwei Bytes dank @nimi gespeichert.

Laikoni
quelle
3

Brainfuck, 115 Bytes

>,[->++++[<-------->-]<[--------------->,[<[-]+>-]<<[->-[>+<+]>[-<+>]<<]>>++++++[-<++++++++>]<.>>+<]>-[<<+>,>[-]]<]

Probieren Sie es online!

Ungolfed:

% 0: inverter count
% 1: result
% 2: if/else flag; tmpspace in inner loop 0

>1,[
    ->2++++[<-------->-]<1 subtract 33 (!)
    [ 
        % we've reached the number
        ---------------
        % now it's either 0 or 1

        % check next char; If it's not 0 then it's '!'
        % 0! = 1! = 1!...! so we only need to determine if at least one ! exists
        >2,
                [<[-]+>-]<1

        % apply inversions
        <0
        [->1
            % invert cell 1 once each iteration
                       % cell 1 is 0 or 1
            -          % cell 1 is 255 or 1
            [>+<+]     % cell 1 is 0; cell 2 is 1 iff cell 1 should be 1
            >2[-<+>]<1 % cell 1 is 1 or 0
        <0]

        % print result
        >1>++++++[-<++++++++>]<1.

        >>2+< % tape={0 r 0 1}
    ]
    >2-[ % we haven't seen the number yet
        <<0+>1,>2 % add to inverter count
        [-]
    ]<1
]
Strahl
quelle
2

Batch, 62 Bytes

@set/ps=
@set s=%s:0!=1%
@set s=%s:!!=%
@cmd/cset/a%s:1!=1%

Übernimmt die Eingabe für STDIN. Batch versteht die führenden !s für diese Herausforderung tatsächlich richtig, aber die nachfolgenden !s müssen behandelt werden, was drei Schritte umfasst:

  • Wechseln Sie 0!zu1
  • Löschen Sie Paare von !!(dies ist auch für das !!s vor der Ziffer sicher )
  • Löschen Sie alle verbleibenden Trailing !(die jetzt erst nach einem sein können 1)
Neil
quelle
2

IBM / Lotus Notes-Formel - 77 Byte

@Eval(@Left(a;@If(@Like(a;"%1%");"1";"0"))+@If(@Ends(a;"!");"1";@Right(a;1)))

Es gibt kein TIO für Notes Formula, daher wird unten ein Screenshot aller Testfälle angezeigt:

Alle Testfälle

Wie es funktioniert

@Eval() wertet einen String als Ausdruck aus

Zuerst prüfen wir, ob die Eingabezeichenfolge in Feld (Eingabe) oder aenthält, und nehmen alle Zeichen links von der Zeichenfolge, bei der es sich um eine Zeichenfolge handelt . Es ist uns egal, wie viele. werde mich darum kümmern.10!@Eval()

Als nächstes prüfen wir, ob sich !am Ende der Zeichenfolge ein befindet. Wenn dies der Fall ist, hängen wir 1an die !Zeichenfolge an ( 0!und 1!beide sind 1 - es spielt keine Rolle, wie viele !Zeichen sich am Ende befinden), andernfalls hängen wir das letzte Zeichen unverändert an, da es kein a ist !und entweder a 1oder a sein kann 0.

Wir haben jetzt eine Zeichenkette mit den führenden Inversionen und einer Zahl, die definiert ist, ob Fakultätszeichen vorhanden sind, damit wir diese mit Feeds versehen @Eval()und die obigen Ergebnisse erhalten können.

ElPedro
quelle
2

sed, 36 33 31 bytes

Pure sed, keine bc / shell utils. Funktioniert mit GNU sed <4.3; 33 Bytes unter BSD und GNU 4.3+.

s/.!!*$/1/
:
s/!0/1/
s/!1/0/
t

Einfach genug, wenn Sie sich auskennen sed; kommentiert für diejenigen, die nicht sind:

# Since 0! == 1! == 1 and factorial has precedence, just collapse any trailing "!" 
s/.!!*$/1/
# Define an anonymous label
:
# Invert 0 if needed
s/!0/1/
# Invert 1 if needed
s/!1/0/
# If a change was made, go back to the anonymous label.
t

Prüfung:

% cat 109248.sed
s/.!!*$/1/
:l
s/!0/1/
s/!1/0/
tl
% wc -c 109248.sed
      33 109248.sed
% cat cases
0
1
0!
1!
!0
!1
!0!
!1!
0!!
1!!
!!0
!!1
!0!!
!!!1
!!!0!!!!
!!!1!!!!
% sed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
% gsed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
%
Kevin
quelle
In einigen (allen?) Versionen von IIRC sedkönnen Sie die Nullzeichenfolge als Labelnamen verwenden. Wenn Sie das hier zum Laufen bringen, sparen Sie zwei Bytes. Eigentlich bin ich mir nicht sicher, ob das Etikett überhaupt gebraucht wird. Sofern ich nichts übersehen habe, ist die erste Zeile idempotent, sodass Sie möglicherweise zum Programmstart zurückkehren können, anstatt ein Etikett zu benötigen.
@ ais523 Das dachte ich mir auch, aber offensichtlich funktioniert es in BSD-Versionen nicht. Auf der Manpage steht "Wenn keine Beschriftung angegeben ist, verzweige zum Ende des Skripts", und selbst das funktionierte nicht, als ich es versuchte.
Kevin
GNU sed erlaubt es, dass ein Label einfach ist :(eher ein Bug, der als Feature angesehen wird). In diesem Fall können sowohl das tals auch das b! Befehle springen an die Position des Etiketts. Außerdem muss ein sed-Code für mindestens eine Version von sed funktionieren, ähnlich wie in anderen Sprachen, sodass Sie keinen Code erstellen müssen, der auch für BSD funktioniert.
Seshoumara
2

PHP 7.1, 58 55 54 37 35 Bytes

Anmerkung: Verwendet die IBM-850-Codierung

echo!!$argn[-1]^strspn($argn,~Ì)%2;

Laufen Sie wie folgt:

echo '!!!0!!!!' | php -nR 'echo!!$argn[-1]^strspn($argn,~Ì)%2;';echo
> 0

Erläuterung

echo
  strspn($a=$argv[1],~Ì) # Count the number of leading exclamation marks.
  % 2                    # Make 0 (even) or 1 (odd).
  ^ !!$a[-1];            # Negate with factorial part (truthy value of the 
                         # last char):
                         # - "0" is considered falsy.
                         # - "1" or "!" is considered truthy.

Optimierungen

  • 3 Byte mit IBM-850-Codierung gespeichert
  • Ein Byte wurde gespeichert, indem der reguläre Ausdruck leicht geändert wurde
  • 17 Bytes gespeichert, neue Version ohne lange Funktionsnamen und Rückkehr
  • 2 Bytes gespart mit -R(was $argnverfügbar macht )
aross
quelle
1

Bohne , 24 Bytes

Hexdump:

00000000 26 4a c1 53 a0 17 53 d0 80 a0 5d 20 80 0a a1 80  &JÁS .SÐ. ] ..¡.
00000010 81 00 25 3a ae a1 ab 24                          ..%:®¡«$
00000018

Entsprechendes JavaScript:

+eval(a.replace(/.!+$/,1))

Entschuldige, dass du auf die Zehen getreten bist, Arnauld .

Erläuterung:

Übernimmt die erste Eingabezeile als unformatierten String aund ersetzt eine beliebige Ziffer gefolgt von einer oder mehreren !durch 1, sodass der Rest evalvon JavaScript verarbeitet werden kann.

Probieren Sie die Demo oder die Testsuite aus

Patrick Roberts
quelle