Convertisseur ternaire

18

En Java / .NET / C / JavaScript / etc. vous pouvez utiliser les ifs ternaires pour raccourcir les instructions if.

Par exemple (en Java):

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

Peut être raccourci avec un ternaire si:

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

Défi:

Entrée: un if-else régulier (possible avec l'imbrication) qui définit une seule variable.

Sortie: le ternaire converti.

Règles du défi:

  • Vous pouvez supposer que tous les cas if-else sont possibles sans crochets (donc chaque bloc if / else-if / else a un seul corps).
  • Vous pouvez supposer qu'il n'y aura pas d'espaces, de tabulations ou de nouvelles lignes, à l'exception d'un seul espace après chacun else(y compris at else if).
  • Vous pouvez supposer que les noms de variables utilisés sont toujours une seule lettre minuscule ( [a-z]).
  • Les valeurs données aux variables peuvent être l'une des suivantes:
    • Cordes (sans espaces / onglets / nouvelles-lignes), qui seront entourés par des guillemets doubles (c. -à "Test", "SomeString", "Example_string", etc.). Vous pouvez supposer que les chaînes ne contiendront jamais les sous-chaînes ifou else, ni les espaces, les tabulations, les retours à la ligne, les guillemets (échappés) ou le caractère =. Il peut contenir les caractères ><(){}[];?:!&|, mais sera uniquement dans la plage ASCII imprimable ( ['!' (33), '~' (126)]).
    • Entiers (c. -à- 0, 123, -55, etc.)
    • (C. -à- Décimales 0.0, 0.123, -55.55, etc.)
  • Les valeurs ne seront jamais mélangées. Ainsi, toutes les variables attribuées sont des entiers, et non certaines sont des entiers et certaines sont des chaînes.
  • Les conditions à l' intérieur des parenthèses peuvent contenir les caractères suivants =<>!+-/*%&|[], a-z, 0-9. Vous pouvez supposer qu'il n'y aura pas de parenthèses internes, et vous pouvez également supposer qu'il n'y aura pas de champs (confus) de plus d'un caractère utilisés (comme if(if<0)).
  • Vous pouvez supposer qu'il n'y aura pas de raccourcis comme i*=10au lieu de i=i*10.
  • Vous n'aurez pas à gérer de elsecas pendants , donc tout ifpeut être associé à un else. Ce if(a)if(b)r=0;else r=1;n'est pas un cas d'entrée possible. if(a)if(b)r=0;else r=1;else r=2;ou if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;sont cependant.
  • Les E / S sont flexibles. L'entrée et la sortie peuvent être une chaîne, une liste de caractères, lues depuis STDIN, sorties vers STDOUT, etc. Votre appel.
  • Tous les ternaires auront une bonne associativité, comme c'est le standard dans la plupart des langues ( mais pas par exemple en PHP ).

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, fonctions / méthode avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • Veuillez également ajouter une explication si possible.

Cas de test:

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
la source
Techniquement, en F # if ... then ... elseest l'opérateur ternaire. Donc, si vous écrivez, let result = if 10 > 100 then 99 else -99la valeur de resultserait -99.
Ciaran_McCarthy
1
@Ciaran_McCarthy Je m'attendrais à ce que ce soit le cas pour la plupart, sinon tous les langages penchés fonctionnels qui ont des expressions conditionnelles par défaut. Clojure, Scala et Haskell sont les mêmes.
Carcigenicate
@tsh Oups .. Je ne devrais pas ajouter de cas de test tard dans la soirée après une journée de travail .. Corrigé.
Kevin Cruijssen
2
Le compilateur de fermeture de compresseur JavaScript fonctionne très bien sur tous ces tests. Ce qui, en prenant les entrées données, ne ferait que générer les sorties attendues. Mais il semble que je ne puisse pas le prétendre comme réponse. Je voudrais donc commenter ici.
tsh

Réponses:

5

Retina 0.8.2 , 32 octets

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

Essayez-le en ligne! Explication:

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

Traitez un ifimmédiatement avant une affectation en déplaçant l'affectation avant la condition et en ajoutant a ?. L'étape est mise en correspondance de droite à gauche pour garantir que nous obtenons le plus proche de l'affectation, tandis que la \)garantit que nous ne correspondons pas elsepar erreur.

+

Répétez l'étape pour prendre soin des ifs imbriqués .

;.{6}=
:

Toutes les affectations restantes sont elses donc remplacez le ;else ?=par un :.

Neil
la source
@nwellnhof Merci d'avoir signalé cela; Je pensais que je jouais un octet là-bas parce que cela fonctionnait sur les cas de test.
Neil
6

Python 2 , 126 121 120 114 114 100 octets

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

Essayez-le en ligne!


Enregistré:

  • -1 octet, merci à Kevin Cruijssen
TFeld
la source
@KevinCruijssen Merci :)
TFeld
1
Pourquoi la définition de la fonction est-elle avant l'importation?
Skyler
@Skyler Cela n'a pas vraiment d'importance, mais il est plus facile de mettre l'affectation dans l'en-tête de cette façon
Jo King
6

Perl 5 -p, 50 49 48 octets

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

Essayez-le en ligne!

La version 48 octets est inspirée de la réponse de Neil's Retina.

Explication

# 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

Ancienne solution de 49 octets

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

Rubis , 72 71 octets

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

Essayez-le en ligne!

GB
la source
Soit ;elseou else peut être .{5}pour enregistrer un octet.
Kevin Cruijssen
1
Merci, j'ai trouvé quelque chose de différent avec le même effet.
GB
3

Java (JDK) , 119116 octets

Solution de regex presque entièrement pure, hachée et changée un peu par rapport à quelques autres réponses.

-3 octets grâce à la supercherie regex de Kevin

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

Essayez-le en ligne!

Explication

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
la source
1
J'aime le que ".*(.=).*","$1$0"vous avez utilisé, c'est 1 octet de moins que ce "^(.*)(.=)","$2$1"que j'avais en tête. :) Quoi qu'il en soit, vous pouvez enregistrer 2 octets en changeant if\\(en if.et un octet supplémentaire en changeant (\\?| )en ([? ]). Essayez-le en ligne 116 octets .
Kevin Cruijssen
@KevinCruijssen Cheers! J'ai passé tellement de temps à essayer de réduire le regex, je ne peux pas croire que j'ai raté ça!
Luke Stevens
3

Kakoune v2018.09.04 , 43 38 37 octets

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

Explication:

Kakoune est un éditeur modal basé sur une sélection multiple, inspiré de Vim.

  1. x sélectionner toute la ligne

  2. s... <ret>filtre la sélection avec l'expression régulière \w=(?!=), qui correspond à toutes les affectations de variables et ne correspond pas aux ==comparaisons

  3. d supprimer chaque sélection et mettre son contenu dans le registre par défaut

  4. <a-h> étendre toutes les sélections au début de leur ligne

  5. P collez le contenu du registre par défaut avant chaque sélection

  6. s... <ret>filtrer la sélection avec l'expression régulièreif.

  7. d supprimer chaque sélection

  8. f étendre chaque sélection à la suivante )

  9. ; réduire chaque sélection à son curseur

  10. r remplacer chaque caractère de chaque sélection par ?

  11. x sélectionner toute la ligne

  12. s... <ret>filtrer la sélection avec;else<space>

  13. c... <esc>effacer chaque sélection et la remplacer par:

animation du code sur un cas de test:

Code en action

Vaelus
la source
1
Hmm, je n'ai jamais entendu parler de Kakoune auparavant. Je suppose qu'il n'y a pas de compilateur en ligne pour cela? Sinon, pourriez-vous peut-être ajouter des captures d'écran de certains des cas de test afin que je puisse vérifier que cela fonctionne comme prévu? De plus, si c'est votre langue, vous pouvez contacter Dennis dans le chat talk.tryitonline.net pour lui demander s'il peut l'ajouter à TIO .
Kevin Cruijssen
1
@KevinCruijssen J'ai ajouté un gif de l'un des cas de test. Cela fonctionne sur chacun d'eux, mais rendre les gifs n'est pas anodin.
Vaelus
Merci pour l'explication et le gif, +1 de ma part. :) Toujours agréable d'apprendre une nouvelle langue.
Kevin Cruijssen
2

Propre , 386 375 216 196 189 189 octets

Regardez ma, pas de 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]

Essayez-le en ligne!

Οurous
la source
1

JavaScript (Node.js) , 80 octets

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

Essayez-le en ligne!

Merci à Kevin Cruijssen, 2 octets enregistrés.

tsh
la source
if\(peut être if.et ;else peut être ;.{5}d'économiser 2 octets
Kevin Cruijssen