Konwerter trójskładnikowy

18

W Javie / .NET / C / JavaScript / itp. możesz użyć trójskładnikowych ifs, aby skrócić instrukcje if.

Na przykład (w Javie):

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

Można skrócić trójskładnikiem, jeśli:

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

Wyzwanie:

Dane wejściowe: regularny if-else (możliwe z zagnieżdżaniem), który ustawia jedną zmienną.

Dane wyjściowe: skonwertowane trójskładnikowe-jeśli.

Zasady konkursu:

  • Możesz założyć, że wszystkie przypadki if-else są możliwe bez nawiasów kwadratowych (więc każdy blok if / else-if / else ma jedną treść).
  • Możesz założyć, że nie będzie żadnych spacji, tabulatorów ani nowych wierszy, z wyjątkiem pojedynczego spacji po każdym else(w tym at else if).
  • Możesz założyć, że używane nazwy zmiennych są zawsze pojedynczymi małymi literami ( [a-z]).
  • Wartości podane zmiennym mogą być jedną z:
    • Struny (bez spacji / tabs / nowe-lines), które zostaną otoczone cudzysłowami (czyli "Test", "SomeString", "Example_string", itd.). Możesz założyć, że ciągi nigdy nie będą zawierać podłańcuchów ifani elseteż nie będą zawierać spacji, tabulatorów, znaków nowej linii, (znaków zmiany znaczenia) podwójnych cudzysłowów ani znaku =. Może zawierać znaki ><(){}[];?:!&|, ale będzie tylko w zakresie do wydruku ASCII ( ['!' (33), '~' (126)]).
    • Całkowitymi (czyli 0, 123, -55, itd.)
    • Dziesiętnych (czyli 0.0, 0.123, -55.55, itd.)
  • Wartości nigdy się nie zmieszają. Zatem wszystkie przypisane zmienne są liczbami całkowitymi, a nie niektóre są liczbami całkowitymi, a niektóre są łańcuchami.
  • Warunki w nawiasie może zawierać następujące znaki =<>!+-/*%&|[], a-z, 0-9. Możesz założyć, że nie będzie żadnych wewnętrznych nawiasów, a także możesz założyć, że nie będzie żadnych (mylących) pól więcej niż jednego znaku (jak if(if<0)).
  • Możesz założyć, że nie będzie żadnych skrótów takich jak i*=10zamiast i=i*10.
  • Nie będziesz musiał zajmować się wiszącymi elsesprawami, więc wszystko ifmożna połączyć z else. Tj. if(a)if(b)r=0;else r=1;Nie jest możliwym przypadkiem wejściowym. if(a)if(b)r=0;else r=1;else r=2;lub if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;są jednak.
  • I / O jest elastyczny. Dane wejściowe i wyjściowe mogą być ciągiem znaków, listą znaków, odczytanymi ze STDIN, wyjściowymi do STDOUT itp. Twoje połączenie.
  • Wszystkie trójskładniki będą miały odpowiednie skojarzenie, co jest standardem w większości języków ( ale nie na przykład w PHP ).

Główne zasady:

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie pozwól, aby języki gry w golfa zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania.
  • Do odpowiedzi mają zastosowanie standardowe reguły , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami i zwracanymi typami, pełnych programów. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem swojego kodu.
  • Jeśli to możliwe, dodaj wyjaśnienie.

Przypadki testowe:

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
źródło
Technicznie rzecz biorąc, w języku F # if ... then ... elsewystępuje operator trójskładnikowy. Więc jeśli napiszesz, let result = if 10 > 100 then 99 else -99to wartość resultbędzie -99.
Ciaran_McCarthy
1
@Ciaran_McCarthy Spodziewałbym się, że tak będzie w przypadku większości, jeśli nie wszystkich funkcjonalnych języków lean, które domyślnie mają wyrażenia warunkowe. Clojure, Scala i Haskell są takie same.
Carcigenicate,
@tsh Ups .. Nie powinienem dodawać przypadków testowych późnym wieczorem po dniu pracy. Naprawiono.
Kevin Cruijssen
2
Kompilator JavaScript do zamykania kompresorów działa doskonale na wszystkich tych testach. Które przy przyjmowaniu danych wejściowych wygenerowałyby oczekiwane wyniki. Ale wydaje się, że nie mogę twierdzić, że jest to odpowiedź. Chciałbym więc tutaj skomentować.
tsh,

Odpowiedzi:

5

Retina 0.8.2 , 32 bajty

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

Wypróbuj online! Wyjaśnienie:

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

Obsługuj ifbezpośrednio przed zadaniem, przenosząc zadanie przed warunkiem i dołączając ?. Etap jest dopasowywany od prawej do lewej, aby upewnić się, że otrzymamy najbliższe zadanie, a jednocześnie \)gwarantuje, że nie dopasujemy się elseprzez pomyłkę.

+

Powtórz etap, aby zająć się zagnieżdżonymi if.

;.{6}=
:

Wszelkie pozostałe zadania są elses więc wymienić ;else ?=z :.

Neil
źródło
@nwellnhof Dziękujemy za zwrócenie na to uwagi; Myślałem, że gram w golfa, bo zadziałało to na testach.
Neil,
6

Python 2 , 126 121 120 114 100 bajtów

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

Wypróbuj online!


Zapisano:

  • -1 bajt, dzięki Kevin Cruijssen
TFeld
źródło
@KevinCruijssen Thanks :)
TFeld
1
Dlaczego definicja funkcji jest przed importem?
Skyler,
@Skyler To nie ma znaczenia, ale łatwiej jest w ten sposób umieścić zadanie w nagłówku
Jo King,
6

Perl 5- p, 50 49 48 bajtów

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

Wypróbuj online!

Wersja 48-bajtowa jest inspirowana odpowiedzią Neila na Retinę.

Wyjaśnienie

# 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

Stare 49 bajtowe rozwiązanie

s/.{5} (.=)?/:/g;s/if.(.*?)\)(.=)?/\1?/g;$_=$2.$_
nwellnhof
źródło
3

Rubin , 72 71 bajtów

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

Wypróbuj online!

GB
źródło
Albo ;elsealbo else można .{5}zapisać bajt.
Kevin Cruijssen
1
Dzięki, znalazłem coś innego z tym samym efektem.
GB
3

Java (JDK) , 119 116 bajtów

Prawie całkowicie czyste rozwiązanie wyrażenia regularnego, posiekane i zmienione nieco z kilku innych odpowiedzi.

-3 bajty dzięki dodatkowej sztuczce wyrażeń regularnych od Kevina

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

Wypróbuj online!

Wyjaśnienie

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
źródło
1
Podoba mi się ten, ".*(.=).*","$1$0"którego używałeś, jest o 1 bajt krótszy niż "^(.*)(.=)","$2$1"miałem na myśli. :) W każdym razie możesz zapisać 2 bajty if\\(na if.i dodatkowy bajt (\\?| )na ([? ]). Wypróbuj online 116 bajtów .
Kevin Cruijssen
@KevinCruijssen Cheers! Spędziłem tak długo, próbując zmniejszyć regex, nie mogę uwierzyć, że to przegapiłem!
Luke Stevens,
3

Kakoune v2018.09.04 , 43 38 37 bajtów

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

Wyjaśnienie:

Kakoune to edytor modalny oparty na wielu selekcjach, zainspirowany przez Vima.

  1. x wybierz całą linię

  2. s... <ret>filtruj zaznaczenie za pomocą wyrażenia regularnego \w=(?!=), które pasuje do wszystkich przypisań zmiennych i nie pasuje do ==porównań

  3. d usuń każdy wybór i umieść jego zawartość w rejestrze domyślnym

  4. <a-h> rozciągnij wszystkie zaznaczenia na początek ich linii

  5. P wklej zawartość rejestru domyślnego przed każdym wyborem

  6. s... <ret>filtruj zaznaczenie za pomocą wyrażenia regularnegoif.

  7. d usuń każdy wybór

  8. f przedłużyć każdy wybór do następnego )

  9. ; zmniejsz każdy wybór do jego kursora

  10. r zamień każdy znak każdego wyboru na ?

  11. x wybierz całą linię

  12. s... <ret>filtruj zaznaczenie za pomocą;else<space>

  13. c... <esc>wyczyść każdy wybór i zastąp go:

animacja kodu na przypadku testowym:

Kod w akcji

Vaelus
źródło
1
Hmm, nigdy wcześniej nie słyszałem o Kakoune. Myślę, że nie ma dla niego żadnego kompilatora online? Jeśli nie, czy możesz dodać zrzuty ekranu z niektórych przypadków testowych, aby sprawdzić, czy działają zgodnie z przeznaczeniem? Ponadto, jeśli jest to Twój język, możesz skontaktować się z Dennisem na czacie talk.tryitonline.net, aby zapytać, czy mógłby dodać go do TIO .
Kevin Cruijssen
1
@KevinCruijssen Dodałem gif jednego z przypadków testowych. Działa na wszystkich, ale tworzenie gifów nie jest trywialne.
Vaelus,
Dzięki za wyjaśnienie i gif, +1 ode mnie. :) Zawsze miło jest dowiedzieć się o nowym języku.
Kevin Cruijssen
2

Czysty , 386 375 216 196 189 bajtów

Spójrz, nie ma wyrażeń regularnych!

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]

Wypróbuj online!

Obrzydliwe
źródło
1

JavaScript (Node.js) , 80 bajtów

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

Wypróbuj online!

Dzięki Kevinowi Cruijssenowi zaoszczędzono 2 bajty.

tsh
źródło
if\(można if.i ;else można ;.{5}zaoszczędzić 2 bajty
Kevin Cruijssen,