Ternary-If-Konverter

18

In Java / .NET / C / JavaScript / etc. Sie können ternary-ifs verwenden, um if-Anweisungen zu verkürzen.

Zum Beispiel (in Java):

// there is a String `s` and an int `i`
if(i<0)s="Neg";else if(i>0)s="Pos";else s="Neut";

Kann mit einem ternären gekürzt werden, wenn:

s=i<0?"Neg":i>0?"Pos":"Neut";

Herausforderung:

Eingabe: Ein reguläres if-else (mit Verschachtelung möglich), das eine einzelne Variable festlegt.

Ausgabe: Das konvertierte ternäre If.

Herausforderungsregeln:

  • Sie können davon ausgehen, dass alle if-else-Fälle ohne eckige Klammern möglich sind (daher hat jeder if / else-if / else-Block einen einzigen Körper).
  • Sie können davon ausgehen, dass es keine Leerzeichen, Tabulatoren oder Zeilenumbrüche gibt, mit Ausnahme eines einzelnen Leerzeichens nach jedem else(einschließlich at else if).
  • Sie können davon ausgehen, dass die verwendeten Variablennamen immer nur Kleinbuchstaben sind ( [a-z]).
  • Die Werte für die Variablen können folgende sein:
    • Strings (ohne Leerzeichen / Tabs / new-Linien), die durch doppelte Anführungszeichen gesetzt wird (dh "Test", "SomeString", "Example_string", etc.). Sie können davon ausgehen, dass die Zeichenfolgen niemals die Teilzeichenfolgen ifoder elseLeerzeichen, Tabulatoren, Zeilenumbrüche, Anführungszeichen oder das Zeichen enthalten =. Es kann die Zeichen enthalten ><(){}[];?:!&|, liegt jedoch nur im druckbaren ASCII-Bereich ( ['!' (33), '~' (126)]).
    • Integers (dh 0, 123, -55, etc.)
    • Dezimalzahlen (dh 0.0, 0.123, -55.55, etc.)
  • Die Werte werden niemals gemischt. Alle zugewiesenen Variablen sind also Ganzzahlen, und nicht einige sind Ganzzahlen und einige sind Zeichenfolgen.
  • Die Bedingungen in Klammern können die folgenden Zeichen enthalten =<>!+-/*%&|[], a-z, 0-9. Sie können davon ausgehen, dass es keine inneren Klammern gibt, und Sie können auch davon ausgehen, dass keine (verwirrenden) Felder mit mehr als einem Zeichen verwendet werden (wie if(if<0)).
  • Sie können davon ausgehen, dass es keine Abkürzungen wie i*=10statt gibt i=i*10.
  • Sie müssen keine baumelnden elseFälle bearbeiten , sodass alle ifmit einem gepaart werden können else. Dh if(a)if(b)r=0;else r=1;kein möglicher Eingabefall. if(a)if(b)r=0;else r=1;else r=2;oder if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;sind es aber.
  • I / O ist flexibel. Eingabe und Ausgabe können eine Zeichenfolge, eine Liste von Zeichen sein, die von STDIN gelesen, an STDOUT ausgegeben werden usw. Ihr Anruf.
  • Alle Ternaries werden eine richtige Assoziativität haben, wie es der Standard in den meisten Sprachen ist ( aber nicht zum Beispiel in PHP ).

Allgemeine Regeln:

  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
    Lassen Sie sich von Code-Golf-Sprachen nicht davon abhalten, Antworten mit Nicht-Codegolf-Sprachen zu veröffentlichen. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Antwort zu finden.
  • Für Ihre Antwort gelten Standardregeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methoden mit den richtigen Parametern und vollständige Programme vom Rückgabetyp verwenden. Ihr Anruf.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu.
  • Fügen Sie nach Möglichkeit auch eine Erklärung hinzu.

Testfälle:

Input:   if(i<0)s="Neg";else if(i>0)s="Pos";else s="Neut";
Output:  s=i<0?"Neg":i>0?"Pos":"Neut";

Input:   if(i%2<1)r=10;else r=20;
Output:  r=i%2<1?10:20;

Input:   if(n<10)if(m<0)i=0;else i=10;else if(m<0)i=-1;else i=1;
Output:  i=n<10?m<0?0:10:m<0?-1:1;

Input:   if(i==1)i=0.0;else i=0.25;
Output:  i=i==1?0.0:0.25;

Input:   if(!a)if(b)r=0;else r=1;else r=2;
Output:  r=!a?b?0:1:2;

Input:   if(a)if(b)r=0;else r=1;else if(c)r=2;else r=3;
Output:  r=a?b?0:1:c?2:3;

Input:   if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;
Output:  r=a&&b?0:a&&!b?1:-1;

Input:   if(i[0]>0)if(j>0)if(q>0)r="q";else r="j";else r="i";else r="other";
Output:  r=i[0]>0?j>0?q>0?"q":"j":"i":"other";

Input:   if(i>0)r="i";else if(j>0)r="j";else if(q>0)r="q";else r="other";
Output:  r=i>0?"i":j>0?"j":q>0?"q":"other";

Input:   if(a>0)if(a<2)x="one";else if(a<3)x="two";else if(a<4)x="three";else x="other";else x="other";
Output:  x=a>0?a<2?"one":a<3?"two":a<4?"three":"other":"other";

Input:   if(b[0]<=b[1])q=5;else if(b[0]==null)q=0;else q=-10;
Output:  q=b[0]<=b[1]?5:b[0]==null?0:-10;
Kevin Cruijssen
quelle
Technisch gesehen ist in F # if ... then ... elseder ternäre Operator. Wenn Sie also schreiben, wäre let result = if 10 > 100 then 99 else -99der Wert von . result-99
Ciaran_McCarthy
1
@Ciaran_McCarthy Ich würde davon ausgehen, dass dies für die meisten, wenn nicht alle funktionalen Lernsprachen der Fall ist, die standardmäßig bedingte Ausdrücke haben. Clojure, Scala und Haskell sind gleich.
Carcigenicate
@tsh Ups .. Ich sollte spät abends nach einem Arbeitstag keine Testfälle hinzufügen .. Behoben.
Kevin Cruijssen
2
Der JavaScript Compressor Closure Compiler eignet sich hervorragend für alle diese Testfälle. Was, wenn die gegebenen Eingaben genommen werden, nur die erwarteten Ausgaben erzeugen würde. Aber es scheint, dass ich es nicht als Antwort behaupten kann. Darum möchte ich hier einen Kommentar abgeben.
Dienstag,

Antworten:

5

Retina 0.8.2 , 32 Bytes

+r`if.(.*?)\)(.=)
$2$1?
;.{6}=
:

Probieren Sie es online! Erläuterung:

r`if.(.*?)\)(.=)
$2$1?

Behandeln Sie eine ifunmittelbar vor einer Zuordnung, indem Sie die Zuordnung vor der Bedingung verschieben und eine hinzufügen ?. Die Bühne ist von rechts nach links abgeglichen, um sicherzustellen, \)dass wir der Aufgabe am nächsten kommen, während sichergestellt wird, dass wir nicht versehentlich übereinstimmen else.

+

Wiederholen Sie den Vorgang, um sich um verschachtelte ifs zu kümmern .

;.{6}=
:

Verbleibende Zuordnungen werden elsedurch ;else ?=a ersetzt :.

Neil
quelle
@nwellnhof Danke für den Hinweis; Ich dachte, ich würde ein Byte abschlagen, weil es bei den Testfällen funktionierte.
Neil
6

Python 2 , 126 121 120 114 100 Bytes

lambda s:findall(' (.=)',s)[0]+sub('if.(.*?)\)(.=)?',r'\1?',sub('.{5} (.=)?',':',s))
from re import*

Probieren Sie es online!


Gerettet:

  • -1 Byte, danke an Kevin Cruijssen
TFeld
quelle
@ KevinCruijssen Danke :)
TFeld
1
Warum steht die Funktionsdefinition vor dem Import?
Skyler
@Skyler Es ist eigentlich egal, aber es ist einfacher, die Zuordnung auf diese Weise in den Header zu setzen
Jo King
6

Perl 5 -p, 50 49 48 Bytes

s/if.(.*?)\)(.=)/\2\1?/g;s/.if./?/g;s/;.{6}=/:/g

Probieren Sie es online!

Die 48-Byte-Version ist von Neils Retina-Antwort inspiriert.

Erläuterung

# Replace "if(e1)if(e2)x=" with "x=e1)if(e2?"
s/if.(.*?)\)(.=)/\2\1?/g;
# Replace ")if(" with "?"
s/.if./?/g;
# Replace ";else x=" with ":"
s/;.{6}=/:/g

Alte 49-Byte-Lösung

s/.{5} (.=)?/:/g;s/if.(.*?)\)(.=)?/\1?/g;$_=$2.$_
nwellnhof
quelle
3

Ruby , 72 71 Bytes

->s{$a=$2while s.gsub!(/if.(.*?)\)(.=)?(.*?);\w* (.=)?/,'\1?\3:');$a+s}

Probieren Sie es online!

GB
quelle
Entweder ;elseoder else kann sein .{5}, ein Byte zu speichern.
Kevin Cruijssen
1
Danke, ich habe etwas anderes mit dem gleichen Effekt gefunden.
GB
3

Java (JDK) , 119 bis 116 Byte

Fast völlig reine Regex-Lösung, gehackt und ein bisschen verändert von ein paar anderen Antworten.

-3 Bytes dank mehr Regex-Trick von Kevin

s->s.replaceAll(".*(.=).*","$1$0").replaceAll("if.(.*?)\\)","$1?").replaceAll("([ ?]).=","$1").replace(";else ",":")

Probieren Sie es online!

Erläuterung

s->                                         // Lambda function taking a String
   s.replaceAll(".*(.=).*","$1$0")          // Find assigned variable and append to start of String
    .replaceAll("if.(.*?)\\)","$1?")        // Replace any 'if' statements with their condition
                                            // followed by '?'
    .replaceAll("([? ]).=","$1")            // Remove all assignments after a '?' or space
    .replace(";else ",":");                 // Simple replace (no regex) to remove 'else' statements
Luke Stevens
quelle
1
Ich mag das, was ".*(.=).*","$1$0"du benutzt hast, es ist 1 Byte kürzer als das, was "^(.*)(.=)","$2$1"ich mir vorgestellt habe. :) Wie auch immer, können Sie 2 Bytes speichern Wechsel if\\(auf if.und ein zusätzliches Byte Wechsel (\\?| )zu ([? ]). Probieren Sie es online 116 Bytes .
Kevin Cruijssen
@ KevinCruijssen Prost! Ich habe so lange versucht, die Regex zu reduzieren, ich kann nicht glauben, dass ich das verpasst habe!
Luke Stevens
3

Kakoune v2018.09.04 , 43 38 37 Bytes

xs\w=(?!=)<ret>d<a-h>Psif.<ret>df);r?xs;else<space><ret>c:<esc>

Erläuterung:

Kakoune ist ein auf Mehrfachauswahl basierender, modaler Editor, der von Vim inspiriert wurde.

  1. x wähle die ganze Zeile aus

  2. s... <ret>filtern Sie die Auswahl mit dem regulären Ausdruck \w=(?!=), der allen Variablenzuweisungen und nicht den ==Vergleichen entspricht

  3. d lösche jede Auswahl und füge ihren Inhalt in das Standardregister ein

  4. <a-h> Erweitern Sie alle Auswahlen bis zum Anfang ihrer Zeile

  5. P Fügen Sie den Inhalt des Standardregisters vor jeder Auswahl ein

  6. s... <ret>filtern Sie die Auswahl mit dem regulären Ausdruckif.

  7. d lösche jede Auswahl

  8. f Erweitern Sie jede Auswahl vorwärts zur nächsten )

  9. ; Reduzieren Sie jede Auswahl auf ihren Cursor

  10. r Ersetzen Sie jedes Zeichen jeder Auswahl durch ?

  11. x wähle die ganze Zeile aus

  12. s... <ret>filtern Sie die Auswahl mit;else<space>

  13. c... <esc>löschen Sie jede Auswahl und ersetzen Sie sie durch:

Animation des Codes an einem Testfall:

Code in Aktion

Vaelus
quelle
1
Hmm, ich habe noch nie von Kakoune gehört. Ich denke, es gibt keinen Online-Compiler dafür? Wenn nicht, könnten Sie vielleicht einige Screenshots einiger der Testfälle hinzufügen, damit ich überprüfen kann, ob es wie beabsichtigt funktioniert? Wenn dies Ihre Sprache ist, können Sie Dennis im talk.tryitonline.net-Chat kontaktieren , um ihn zu fragen, ob er sie zu TIO hinzufügen kann .
Kevin Cruijssen
1
@ KevinCruijssen Ich habe ein GIF von einem der Testfälle hinzugefügt. Es funktioniert bei allen, aber es ist nicht trivial, die Gifs zu erstellen.
Vaelus
Danke für die Erklärung und gif, +1 von mir. :) Immer schön, etwas über eine neue Sprache zu lernen.
Kevin Cruijssen
2

Sauber , 386 375 216 196 189 Bytes

Schau ma, kein Regex!

import StdEnv,Data.List
?[_,'=':b]= $b
?b= $b
$['if(':s]#(h,[_:t])=span((<>)')')s
=h++['?': ?t]
$[';else ':s]=[':': ?s]
$[a:b]|b>[]=[a: $b]=b
@s=hd[[v,e: $s]\\['else ',v,e=:'=':_]<-tails s]

Probieren Sie es online!

Οurous
quelle
1

JavaScript (Node.js) , 80 Byte

s=>(p=s.replace(/(?:if.(.*?)\)|;.*? )(.=)?/g,(_,t,v)=>(V=v||V,t)?t+'?':':'),V+p)

Probieren Sie es online!

Dank Kevin Cruijssen konnten 2 Bytes eingespart werden.

tsh
quelle
if\(kann sein if.und ;else kann sein ;.{5}, 2 Bytes zu sparen
Kevin Cruijssen