Convertidor ternario si

18

En Java / .NET / C / JavaScript / etc. puedes usar ternary-ifs para acortar sentencias if.

Por ejemplo (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";

Se puede acortar con un ternario si:

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

Desafío:

Entrada: Un if-else regular (posible con anidamiento) que establece una sola variable.

Salida: El ternario convertido si.

Reglas de desafío:

  • Puede suponer que todos los casos if-else son posibles sin corchetes (por lo que cada bloque if / else-if / else tiene un solo cuerpo).
  • Puede suponer que no habrá espacios, pestañas o nuevas líneas, excepto un solo espacio después de cada uno else(incluido en else if).
  • Puede suponer que los nombres de variables utilizados son siempre una letra minúscula ([a-z] ).
  • Los valores dados a las variables pueden ser uno de:
    • Cuerdas (sin espacios / tabs / nuevos líneas), que estará rodeado por comillas dobles (es decir "Test", "SomeString", "Example_string", etc.). Puede suponer que las cadenas nunca contendrán las subcadenas ifo que elsetampoco contendrán espacios, tabulaciones, líneas nuevas, comillas dobles (escapadas) o el carácter =. Puede contener los caracteres ><(){}[];?:!&|, pero solo estará en el rango ASCII imprimible ( ['!' (33), '~' (126)]).
    • Los enteros (es decir 0, 123, -55, etc.)
    • Decimales (es decir 0.0, 0.123, -55.55, etc.)
  • Los valores nunca se mezclarán. Entonces, todas las variables asignadas son enteros, y no algunas son enteras y algunas son cadenas.
  • Las condiciones dentro de paréntesis pueden contener los siguientes caracteres =<>!+-/*%&|[], a-z, 0-9. Puede suponer que no habrá paréntesis internos, y también puede suponer que no habrá campos (confusos) de más de un carácter utilizado (como if(if<0)).
  • Puede suponer que no habrá atajos como en i*=10lugar de i=i*10.
  • No tendrá que manejar elsecasos colgantes , por lo que todos ifse pueden combinar con un else. Es decir, if(a)if(b)r=0;else r=1;no es un posible caso de entrada. if(a)if(b)r=0;else r=1;else r=2;o if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;son sin embargo.
  • I / O es flexible. La entrada y salida puede ser una cadena, una lista de caracteres, leer desde STDIN, salir a STDOUT, etc. Su llamada.
  • Todos los ternaries tendrán una asociatividad correcta, como es el estándar en la mayoría de los lenguajes ( pero no en PHP, por ejemplo ).

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de código de golf lo desalienten de publicar respuestas con idiomas que no sean de código. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Se aplican reglas estándar para su respuesta, por lo que puede utilizar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, agregue una explicación si es posible.

Casos de prueba:

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
fuente
Técnicamente, en F # if ... then ... elsees el operador ternario. Entonces, si escribes, let result = if 10 > 100 then 99 else -99entonces el valor de resultsería -99.
Ciaran_McCarthy
1
@Ciaran_McCarthy Espero que ese sea el caso para la mayoría, si no para todos los lenguajes funcionales que tienen expresiones condicionales como predeterminadas. Clojure, Scala y Haskell son lo mismo.
Carcigenicate
@tsh Vaya ... No debería agregar casos de prueba a última hora de la tarde después de un día de trabajo ... Solucionado.
Kevin Cruijssen
2
El compilador de cierre de compresor de JavaScript funciona muy bien en todos estos casos de prueba. Que al tomar las entradas dadas solo generaría las salidas esperadas. Pero parece que no puedo reclamarlo como respuesta. Entonces me gustaría comentar aquí.
tsh

Respuestas:

5

Retina 0.8.2 , 32 bytes

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

Pruébalo en línea! Explicación:

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

Maneje una iftarea inmediatamente antes de una tarea moviéndola antes de la condición y agregando a ?. El escenario se combina de derecha a izquierda para garantizar que obtengamos el más cercano a la tarea, mientras que el\) que garantiza que no coincidamos elsepor error.

+

Repita la etapa para cuidar anidados if s .

;.{6}=
:

Cualquier asignación restante es elses, así que reemplácela ;else ?=con a :.

Neil
fuente
@nwellnhof Gracias por señalar eso; Pensé que estaba jugando a un byte porque funcionó en los casos de prueba.
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*

Pruébalo en línea!


Salvado:

  • -1 byte, gracias a Kevin Cruijssen
TFeld
fuente
@KevinCruijssen Gracias :)
TFeld
1
¿Por qué es la definición de la función antes de la importación?
Skyler
@Skyler En realidad no importa, pero es más fácil poner la tarea en el encabezado de esta manera
Jo King,
6

Perl 5 -p, 50 49 48 bytes

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

Pruébalo en línea!

La versión de 48 bytes está inspirada en la respuesta Retina de Neil.

Explicación

# 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

Solución antigua de 49 bytes

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

rubí , 72 71 bytes

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

Pruébalo en línea!

GB
fuente
Ya sea ;elseo else puede ser .{5}para salvar a un byte.
Kevin Cruijssen
1
Gracias, encontré algo diferente con el mismo efecto.
GB
3

Java (JDK) , 119 bytes

Solución regex casi completamente pura, picada y cambiada un poco de algunas de las otras respuestas.

-3 bytes gracias a algunos trucos de expresiones regulares de Kevin

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

Pruébalo en línea!

Explicación

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
fuente
1
Me gusta el ".*(.=).*","$1$0"que has usado, es 1 byte más corto que el "^(.*)(.=)","$2$1"que tenía en mente. :) De todos modos, puede guardar 2 bytes cambiando if\\(a if.y un byte adicional cambiando (\\?| )a ([? ]). Pruébelo en línea 116 bytes .
Kevin Cruijssen
@KevinCruijssen ¡Salud! Pasé tanto tiempo tratando de reducir la expresión regular, ¡no puedo creer que me haya perdido eso!
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>

Explicación:

Kakoune es un editor modal basado en selección múltiple, inspirado en Vim.

  1. x seleccione toda la línea

  2. s... <ret>filtra la selección con la expresión regular \w=(?!=), que coincide con todas las asignaciones de variables, y no coincide con las ==comparaciones

  3. d eliminar cada selección y poner su contenido en el registro predeterminado

  4. <a-h> extender todas las selecciones al comienzo de su línea

  5. P pegue el contenido del registro predeterminado antes de cada selección

  6. s... <ret>filtra la selección con la expresión regularif.

  7. d eliminar cada selección

  8. f extender cada selección hacia adelante a la siguiente )

  9. ; reducir cada selección a su cursor

  10. r reemplazar cada personaje de cada selección con ?

  11. x seleccione toda la línea

  12. s... <ret>filtrar la selección con;else<space>

  13. c... <esc>borre cada selección y reemplácela con:

Animación del código en un caso de prueba:

Código en acción

Vaelus
fuente
1
Hmm, nunca había oído hablar de Kakoune antes. ¿Supongo que no hay ningún compilador en línea para ello? Si no es así, ¿podría agregar algunas capturas de pantalla de algunos de los casos de prueba para que pueda verificar que funciona según lo previsto? Además, si este es su idioma, puede comunicarse con Dennis en el chat talk.tryitonline.net para preguntar si podría agregarlo a TIO .
Kevin Cruijssen
1
@KevinCruijssen Agregué un gif de uno de los casos de prueba. Funciona en todos ellos, pero hacer los gifs no es trivial.
Vaelus
Gracias por la explicación y gif, +1 de mi parte. :) Siempre es bueno aprender sobre un nuevo idioma.
Kevin Cruijssen
2

Limpio , 386 375 216 196 189 bytes

Mira ma, no 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]

Pruébalo en línea!

Οurous
fuente
1

JavaScript (Node.js) , 80 bytes

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

Pruébalo en línea!

Gracias a Kevin Cruijssen, 2 bytes guardados.

tsh
fuente
if\(puede ser if.y ;else puede ser ;.{5}para guardar 2 bytes
Kevin Cruijssen