Un operador ternario malo merece otro

18

El Daily WTF de hoy cita la siguiente línea de código ...

FailSafe==0?'No technical alarms':((FailSafe&1)!=0&&(FailSafe&2)!=0&&(FailSafe&4)!=0&&(FailSafe&8)!=0?'Detection zones staying in a given state; Bad visibility;
Initialization; Bad configuration':((FailSafe&1)!=0&&(FailSafe&2)!=0&&(FailSafe&4)!=0?'Detection zones staying in a given state; Bad visibility; Initialization':
((FailSafe&1)!=0&&(FailSafe&2)!=0&&(FailSafe&8)!=0?'Detection zones staying in a given state; Bad visibility; Bad configuration':((FailSafe&1)!=0&&(FailSafe&4)!=0&&
(FailSafe&8)!=0?'Detection zones staying in a given state; Initialization; Bad configuration':((FailSafe&2)!=0&&(FailSafe&4)!=0&&(FailSafe&8)!=0?'Bad visibility;
Initialization; Bad configuration':((FailSafe&1)!=0&&(FailSafe&2)!=0?'Detection zones staying in a given state; Bad visibility':((FailSafe&1)!=0&&(FailSafe&4)!=0?'Detection 
zones staying in a given state; Initialization':((FailSafe&1)!=0&&(FailSafe&8)!=0?'Detection zones staying in a given state; Bad configuration':((FailSafe&2)!=0&&
(FailSafe&4)!=0?'Bad visibility; Initialization':((FailSafe&2)!=0&&(FailSafe&8)!=0?'Bad visibility; Bad configuration':((FailSafe&4)!=0&&(FailSafe&8)!=0?'Initialization; Bad 
configuration':((FailSafe&1)!=0?'Detection zones staying in a given state':((FailSafe&2)!=0?'Bad visibility':((FailSafe&4)!=0?'Initialization':((FailSafe&8)!=0?'Bad 
configuration':'Unknown')))))))))))))))

Escriba un código que tome un valor entero llamado FailSafe y devuelva la misma cadena que produciría el código anterior a partir del mismo valor entero.

  • El desafío es reescribir esa línea, de modo que el código "repetitivo" sea gratuito, incluido cualquier código que cargue un valor entero y genere la cadena. Solo cuenta el código que realiza la transformación anterior de un entero a una cadena.
  • Puede usar un nombre diferente para "FailSafe" si lo desea, siempre que su identificador elegido tenga el mismo puntaje de golf.
  • No se requieren recursos externos para realizar la búsqueda.
  • Se aplican las reglas normales de código de golf.
billpg
fuente
¿Se nos permite almacenar FailSafe en otra variable (por ejemplo, f=FailSafeo algo así)?
ProgramFOX
@ProgramFOX Está bien, pero esa asignación está incluida en el recuento. Solo la placa repetitiva que te lleva al punto donde hay una variable llamada FailSafe es gratuita.
billpg
¿Podrías imprimir el código por nosotros? ¿O es el desafío entender el desafío?
John Dvorak
3
@ JanDvorak No estoy seguro de poder ...
billpg
2
Espero que esto: pastebin.com/jzXt4fsp sea ​​más agradable de leer
publicado el

Respuestas:

5

Ruby, 210 caracteres.

Similar a la solución de @Jan Dvorak pero un poco más funcional y un poco más corta.

f=FailSafe
e=[f&1,f&2,f&4,f&8,1-f].zip(["Detection zones staying in a given state","Bad visibility","Initialization","Bad configuration","No technical alarms"]).map{|a,b|a>0&&b}-[!0]
e[0]||="Unknown"
e.join"; "
Howard
fuente
5

GolfScript, 167 caracteres

FailSafe.15&["Unknown"][""]"Bad configuration
Initialization
Bad visibility
Detection zones staying in a given state"
n/{`{n+1$+}+%}/1>+=n%"; "*"No technical alarms"if

El código asume el valor en variable FailSafey empuja el resultado en la pila (es decir, genera la cadena si se ejecuta como programa independiente). Puede probar el código en línea .

El código básicamente genera una matriz de los 16 resultados posibles, selecciona el mensaje de error en función de los cuatro bits más bajos de FailSafe . El más externo ifentonces maneja el caso cero.

Howard
fuente
Creo que en orlugar de ifsalvarte el .. Pero admito que no he intentado descifrar el código original.
Peter Taylor
4

Rebol / Rojo: 208 caracteres

No estoy tan interesado en jugar golf como en aceptar que los operadores ternarios anidados son molestos ... y mencionar que en realidad es una buena instancia para CASO de Rebol / Red . Está relacionado con SWITCH y realmente ayuda a aplanar cosas como esta:

f: FailSafe
append case [
    0 < f and 1 ["Detection zones staying in a given state"]
    1 < f and 2 ["Bad visibility"]
    3 < f and 4 ["Initialization"]
    7 < f and 8 ["Bad configuration"]
    f > 0 ["Unknown"]
    true ["No technical alarms"]
] "; "

Hay una variante llamada CASE / ALL que realmente ejecutará todas las condiciones, pero la predeterminada solo se detiene después de la primera verdadera.

Lo "golfé" un poco a 208:

x: func [y] [y <(f: FailSafe) y ++ y] agregan mayúsculas y minúsculas [x 0 ["Zonas de detección que permanecen en un estado dado"] x 1 ["Mala visibilidad"] x 3 ["Inicialización"] y 7 ["Configuración incorrecta"] f> 0 ["Desconocido"] 1 ["Sin alarmas técnicas"]] ";"

Dr. Rebmu
fuente
4

APL (172)

2↓⊃,/'; '∘,¨{⍵=0:⊂'No technical alarms'⋄0=16|⍵:⊂'Unknown'⋄'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2}FailSafe

Explicación:

  • {...}FailSafe : generar las cadenas
    • ⍵=0:⊂'No technical alarms': el 0 caso
    • 0=16|⍵:⊂'Unknown': el Unknown caso (FailSafe no es 0 pero los primeros cuatro bits sí lo son)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: obtenga los 4 bits más bajos en el argumento ( ⍵⊤⍨4/2), reverse ( ), y seleccione las cadenas para los bits que están en ( /⍨).
  • '; '∘,¨: agregar '; ' al frente de cada cadena devuelta,
  • ⊃,/: une todas las cuerdas juntas,
  • 2↓: y elimine los dos primeros caracteres (porque hay un extra '; 'en el frente).
marinus
fuente
Ahorre dos bytes cambiando ⊃,/a .
Adám
3

Ruby, 183 caracteres

[(f=FailSafe)<1?"No technical alarms":f&15<1?:Unknown:["Detection zones staying in a given state"*f[0],"Bad visibility"*f[1],"Initialization"*f[2],"Bad configuration"*f[3]]-[""]]*"; "

Otra solución más de Ruby, pero un poco más corta que las otras. Esta es una expresión única que usa la constante FailSafe(en Ruby, todos los identificadores en mayúsculas son constantes) para crear la cadena de salida.

Ventero
fuente
en ruby ​​debes declarar constante (like FailSafe) antes de usar. Y tu código subeuninitialized constant FailSafe
44
@ Зелёный Como dice la pregunta: "Escriba un código que tome un valor entero llamado FailSafe", por lo que mi código (como todas las otras respuestas aquí) supone FailSafeque ya está definido. Cuando desee ejecutar el código, primero deberá definir la constante usted mismo.
Ventero
2

JavaScript, 197 195 caracteres

FailSafe?['Detection zones staying in a given state','Bad visibility','Initialization','Bad configuration'].filter(function(_,i){return FailSafe&1<<i}).join('; ')||'Unknown':'No technical alarms'

formateado:

FailSafe
  ? [ 'Detection zones staying in a given state',
      'Bad visibility',
      'Initialization',
      'Bad configuration'
    ].filter(function(_, i) {
      return FailSafe & 1<<i;
    }).join('; ') || 'Unknown'
  : 'No technical alarms';

Podría reducirse aún más mediante el uso de expresiones de función ES6 o Coffeescript.

Bergi
fuente
¿Qué pasa si FailSafe tiene 18 años? (en realidad, el código de desafío original solo mira los 4 bits inferiores, por lo que el caso desconocido en realidad nunca se detecta). Entonces la pregunta es si realmente deberíamos cuidarlo o proporcionar un algoritmo "fijo".
blabla999
@ blabla999: Volverá "Bad visibility"porque el 2 bits está configurado y ninguno de los otros 4 bits más bajos. El Unknowncaso ocurre cuando ninguno de los 4 bits inferiores está configurado, pero FailSafees != 0así, como en el código original (intente con 16). Si deberíamos "arreglar" esto, debería preguntarle al OP (en un comentario sobre la pregunta), no a mí ...
Bergi
tienes razón, yo estúpido. Me confundí mucho con ese código. Lo siento por eso.
blabla999
2

Ruby, 213 caracteres

f=failSafe
e=f&1>0?["Detection zones staying in a given state"]:[]
e+=["Bad visibility"]if f&2>1
e+=["Initialization"]if f&4>3
e+=["Bad configuration"]if f&8>7
e[0]||=f>0?"Unknown":"No technical alarms"
e.join"; "

Esto funcionará bien envuelto en un cuerpo de función ( def transform failSafe; ...; end). También se puede usar como una sola expresión (entre paréntesis porque un punto y coma / nueva línea tiene la prioridad más baja) o como una secuencia de declaraciones con la última expresión ( e.join"; ") utilizada dentro de una expresión.

John Dvorak
fuente
Agregaré una regla para permitir un nombre diferente.
billpg
e+=["Initialization"]if f&4>3Quiero esto en Python.
Publicado el
@ ɐɔıʇǝɥʇuʎs ¿no te impresiona []||=?
John Dvorak
No estoy seguro de lo que hace ... También: since FailSafe must be a constant in RubyHuh. La actitud de Python es más como "Sí, se puede romper cosas, pero no espere que yo a limpiar el lío"
ɐɔıʇǝɥʇuʎs
1
@ ɐɔıʇǝɥʇuʎs ||=es como +=pero con ||- a ||= bes equivalente a a = a || b. Se usa comúnmente para predeterminar una variable cuando es falsa.
Aaron Dufour
1

VBScript, 204 234 232 caracteres

(editar: puntuación mejorada en 2 usando array () en lugar de split (). 232 ahora.)

f=failsafe:for b=0to 3:s=s&split(",; Detection zones staying in a given state,; Bad visibility,,; Initialization,,,,; Bad configuration",",")(f and 2^b):next:array("No technical alarms","Unknown",mid(s,3))(2+(f=0)+(len(s)=0))

(editar: olvidé la parte "desconocida". 234 caracteres ahora).

f = failsafe: for b = 0to 3: s = s & split (",; Zonas de detección que permanecen en un estado dado ,; Mala visibilidad ,,; Inicialización ,,,,; Mala configuración", ",") (f y 2 ^ b): siguiente: división ("Sin alarmas técnicas, Desconocido", y medio (s, 3), ",") (2+ (f = 0) + (len (s) = 0))

(original, 230)

para b = 0 a 3: s = s & split (",; Zonas de detección que permanecen en un estado dado ;; Mala visibilidad ,,; Inicialización ,,,,; Mala configuración", ",") (FailSafe y 2 ^ b): siguiente : array (mid (s, 3), "Sin alarmas técnicas") (- (len (s) = 0))

Por supuesto, esto es solo parte de un guión. para probarlo, intente algo como esto:

FailSafe=cint(inputbox("Please enter Failsafe as an integer"))
f=failsafe:for b=0to 3:s=s&split(",; Detection zones staying in a given state,; Bad visibility,,; Initialization,,,,; Bad configuration",",")(f and 2^b):next
msgbox array("No technical alarms","Unknown",mid(s,3))(2+(f=0)+(len(s)=0))
JesterBLUE
fuente
yo también olvidé el caso Desconocido ;-)
blabla999
@ blabla999 De hecho. Fijo. ¡Gracias!
JesterBLUE
1

Smalltalk, 243 caracteres

FailSave>15ifTrue:'Unknown'ifFalse:[((((1to:4)select:[:b|FailSafe isBitSet:b])collect:[:b|#('Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration')at:b])asStringWith:'; ')ifEmpty:'No technical alarms']     

formateado para facilitar la lectura:

FailSafe > 15 
    ifTrue:'Unknown'
    ifFalse:[
        ((((1 to:4)
            select:[:b | FailSafe isBitSet:b ])
                collect:[:b| 
                    #( 'Detection zones staying in a given state'
                       'Bad visibility'
                       'Initialization'
                       'Bad configuration') at:b ]
                    ) asStringWith:'; ')
                        ifEmpty:'No technical alarms']

Gracias a Bergi, por señalar el error en la primera versión.

Esto trae una idea: si mapeo el valor FailSafe en una máscara de 6 bits (mapeo 0 -> 16 y mayor que 15 -> 32), puedo deshacerme de las pruebas finales. La asignación a la máscara m de 6 bits se puede hacer con:

m := {16},(1 to: 15) at:FailSafe+1 ifAbsent:32.

es decir, m será 16 para un FailSafe cero y 32 para valores fuera de límites. Luego seleccione y recolecte cadenas como se indica arriba. Esto le da el nuevo código:

m := {16},(1 to:15) at:FailSafe+1 ifAbsent:32.
(((1 to:6) select:[:b | m isBitSet:b ])
        collect:[:b| 
            #( 'Detection zones staying in a given state'
               'Bad visibility'
               'Initialization'
               'Bad configuration'
               'No technical alarms'        
               'Unknown') at:b ]
               ) joinWithAll:'; '

(También reemplacé asStringWith: por joinWithAll :, que es un alias).

Aunque esto parece ser una buena idea, tiene el mismo número de personajes: suspiro. ¡Tal vez algún otro lenguaje de programación con nombres de operadores más densos tenga mejores puntajes aquí!

Podría guardar algunos caracteres al no usar una variable temporal para m, pero volver a calcularlo en el bucle y al no usar una matriz literal para el vector de cadena, para obtener un recuento ligeramente inferior a 240 caracteres.

Finalmente, la máscara m también podría ser calculada por m:={32},(1 to: 16) at:(FailSafe+1 min:17), que podría ser más corta en APL. Luego intercambie las dos últimas cadenas en el vector.

PD: La primera versión supone que FailSafe no es negativo, como algunas otras soluciones aquí. El segundo puede tratar con cualquier cosa, incluso nulo u otros no números.

blabla999
fuente
2
¿Qué pasa con la Unknownconfiguración?
Bergi
ouch lo siento, tengo que arreglarlo.
blabla999
0

CoffeeScript, 161 160 221 caracteres

F = FailSafe;F<16 and (F and [0..3].filter((i)->(1<<i)&F).map((i)->(['Detection zones staying in a given state','Bad visibility','Initialization','Bad configuration'])[i]).join('; ') or 'No technical alarms') or 'Unknown'
Ryan Kennedy
fuente
¿Qué pasó con Unknowny No technical alarms?
Bergi
3
Aw mierda. Debería haber sospechado cuando superaba la respuesta de GolfScript ...
Ryan Kennedy
Como siempre, olvidé los casos extremos ...
Ryan Kennedy
0

VB.net

Function StateText(f As FailFlag) As String
  If f=0 Then Return "No Technical Alarm"
  Dim t=""
  If f.HasFlag(f1) Then t &= "Detection zones staying in a given state; "
  If f.HasFlag(f2) Then t &= "Bad visibility; "
  If f.HasFlag(f4) Then t &= "Initialization; "
  If f.HasFlag(f8) Then t &= "Bad configuration; "
  Return If( t<>"", t.TrimEnd("; "),"Unknown")
End Function

<Flags>
Enum FailFlag
  f1 = 1
  f2 = 2
  f4 = 4
  f8 = 8
End Enum

Editar: Mejor entrada

Function StateText(f As FailFlag) As String
  If f = 0 Then Return "No Technical Alarm"
  Dim t = String.Join("; ",
            From e In [Enum].GetValues(GetType(FailFlag))
            Where f.HasFlag(e)
            Select [Enum].GetName(GetType(FailFlag), e).Replace("_", " "))
  Return If( t<>"", t,"Unknown")
End Function

<Flags>
Enum FailFlag
  Detection_zones_staying_in_a_given_state = 1
  Bad_visibility = 2
  Initialization = 4
  Bad_configuration = 8
End Enum
Adam Speight
fuente
0

Perl, 208 197 caracteres

$f=$FailSafe;%m=(1,'Detection zones staying in a given state',2,'Bad visibility',4,'Initialization',8,'Bad configuration');($f?join'; ',@m{map{$f&$_?$_:()}1,2,4,8}:'No technical alarms')||'Unknown'

Con código repetitivo para que funcione:

#!/usr/bin/env perl
$FailSafe=17;
print failmsg() . "\n";

sub failmsg {
$f=$FailSafe;%m=(1,'Detection zones staying in a given state',2,'Bad visibility',4,'Initialization',8,'Bad configuration');($f?join'; ',@m{map{$f&$_?$_:()}1,2,4,8}:'No technical alarms')||'Unknown'
}
Titanofold
fuente
Vuelva a leer el código: no hay una verificación de límites.
titanofold
0

Java 275 caracteres (sin contar espacios en blanco innecesarios )

    String s = "";
    int b = 1;
    for (String m : new String[]{"Detection zones staying in a given state; ","Bad visibility; ", "Initialization; ", "Bad configuration; "}) {
        if ((FailSafe & b) != 0) s = s + m;
        b <<= 1;
    }
    return (s.length() == 0) ? (FailSafe == 0) ? "No technical alarms" : "Unknown" : s.substring(0, s.length() - 2);
Jeff Grigg
fuente