Un mauvais opérateur ternaire en mérite un autre

18

Le Daily WTF d'aujourd'hui cite la ligne de code suivante ...

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')))))))))))))))

Écrivez du code qui prend une valeur entière nommée FailSafe et renvoie la même chaîne que le code ci-dessus produirait à partir de la même valeur entière.

  • Le défi est de réécrire cette ligne, donc le code "passe-partout" est gratuit, y compris tout code qui charge une valeur entière et sort la chaîne. Seul le code qui effectue la transformation ci-dessus d'un entier à une chaîne compte.
  • Vous pouvez utiliser un nom différent de "FailSafe" si vous le souhaitez, tant que votre identifiant choisi a le même score de golf.
  • Aucun appel de ressources externes pour effectuer la recherche.
  • Les règles normales du code-golf s'appliquent.
billpg
la source
Sommes-nous autorisés à stocker FailSafe dans une autre variable (par exemple, f=FailSafeou quelque chose comme ça)?
ProgramFOX
@ProgramFOX C'est bien, mais cette affectation est incluse dans le décompte. Seul le passe-partout qui vous mène au point où il y a une variable nommée FailSafe est libre.
billpg
Pourriez-vous s'il vous plaît imprimer le code pour nous? Ou est le défi de comprendre le défi?
John Dvorak
3
@JanDvorak Je ne suis pas sûr de pouvoir ...
billpg
2
J'espère que cela: pastebin.com/jzXt4fsp est plus agréable à lire
eithed

Réponses:

5

Ruby, 210 caractères

Similaire à la solution de @Jan Dvorak mais un peu plus fonctionnel et un peu plus court.

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
la source
5

GolfScript, 167 caractères

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

Le code prend la valeur en variable FailSafeet pousse le résultat sur la pile (c'est-à-dire, affiche la chaîne si elle est exécutée en tant que programme autonome). Vous pouvez tester le code en ligne .

Le code génère essentiellement un tableau des 16 résultats possibles, sélectionne le message d'erreur en fonction des quatre bits les plus bas de FailSafe. Le plus à l'extérieur ifgère alors le cas zéro.

Howard
la source
Je pense orqu'au lieu de ifvous sauver la .. Mais j'avoue que je n'ai pas essayé de déchiffrer le code d'origine.
Peter Taylor
4

Rebol / Red: 208 caractères

Je ne suis pas aussi intéressé par le golf comme ce que les opérateurs en acceptant de ternaires imbriqués sont ennuyeux ... et mentionner c'est en fait une belle instance pour de Rebol / Red CASE . Il est lié à SWITCH et aide vraiment à aplatir des choses comme ça:

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"]
] "; "

Il existe une variante appelée CASE / ALL qui exécutera toutes les conditions, mais la valeur par défaut s'arrête juste après la première vraie.

Je vais "jouer au golf" un peu à 208:

x: func [y] [y <(f: FailSafe) et ++ y] ajoutent le cas [x 0 ["Zones de détection restant dans un état donné"] x 1 ["Mauvaise visibilité"] x 3 ["Initialisation"] y 7 ["Mauvaise configuration"] f> 0 ["Inconnu"] 1 ["Aucune alarme technique"]] ""; "

Dr. Rebmu
la source
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

Explication:

  • {... }FailSafe: générer les chaînes
    • ⍵=0:⊂'No technical alarms': le 0cas
    • 0=16|⍵:⊂'Unknown': le Unknowncas (FailSafe n'est pas 0 mais les quatre premiers bits le sont)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: obtenez les 4 bits les plus bas dans l'argument ( ⍵⊤⍨4/2), reverse ( ), et sélectionnez les chaînes pour les bits qui sont sur ( /⍨).
  • '; '∘,¨: ajouter '; 'au début de chaque chaîne retournée,
  • ⊃,/: joindre toutes les chaînes ensemble,
  • 2↓: et supprimez les deux premiers caractères (car il y a un extra '; 'à l'avant.)
marinus
la source
Enregistrez deux octets en changeant ⊃,/pour .
Adám
3

Ruby, 183 caractères

[(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]]-[""]]*"; "

Encore une autre solution Ruby, mais un peu plus courte que les autres. Il s'agit d'une expression unique qui utilise la constante FailSafe(dans Ruby, tous les identificateurs en majuscules sont des constantes) pour créer la chaîne de sortie.

Ventero
la source
en rubis, vous devez déclarer constant (comme FailSafe) avant d'utiliser. Et vous augmentez le codeuninitialized constant FailSafe
4
@ Зелёный Comme l'indique la question: "Écrivez du code qui prend une valeur entière nommée FailSafe" - donc mon code (comme toutes les autres réponses ici) suppose qu'il FailSafeest déjà défini. Lorsque vous souhaitez exécuter le code, vous devez d'abord définir la constante vous-même.
Ventero
2

JavaScript, 197 195 caractères

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'

formaté:

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';

Pourrait être encore réduit en utilisant les expressions de fonction ES6 ou Coffeescript.

Bergi
la source
que faire si FailSafe a 18 ans? (en fait, le code de défi d'origine ne regarde que les 4 bits inférieurs, donc le cas inconnu n'est en fait jamais détecté!) La question est donc de savoir si nous devons en prendre soin ou fournir un algorithme "fixe".
blabla999
@ blabla999: Il reviendra "Bad visibility"car le 2 bits est défini et aucun des 4 autres bits inférieurs. Le Unknowncas se produit lorsqu'aucun des 4 bits inférieurs n'est défini, mais l' FailSafeest != 0- tout comme dans le code d'origine (essayez avec 16). Si nous devons "corriger" cela, vous devriez demander au PO (dans un commentaire sur la question), pas moi…
Bergi
tu as raison - moi stupide. Je suis tellement confus par ce morceau de code. Désolé.
blabla999
2

Ruby, 213 caractères

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"; "

Cela fonctionnera très bien dans un corps de fonction ( def transform failSafe; ...; end). Il peut également être utilisé comme une expression unique (envelopper entre parenthèses car un point-virgule / nouvelle ligne a la priorité la plus basse) ou comme une séquence d'instructions avec la dernière expression ( e.join"; ") utilisée dans une expression.

John Dvorak
la source
J'ajouterai une règle pour autoriser un nom différent.
billpg
e+=["Initialization"]if f&4>3Je veux cela en Python.
ɐɔıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs n'êtes-vous pas impressionné par []||=?
John Dvorak
Je ne sais pas trop ce que ça fait ... Aussi: since FailSafe must be a constant in RubyHuh. L'attitude de Python ressemble plus à "Ouais, tu peux casser des trucs, mais ne t'attends pas à ce que je nettoie le bordel"
ɐɔıʇǝɥʇuʎs
1
@ ɐɔıʇǝɥʇuʎs ||=est comme +=mais avec ||- a ||= best équivalent à a = a || b. Il est couramment utilisé pour définir une variable par défaut lorsqu'elle est fausse.
Aaron Dufour
1

VBScript, 204 234 232 caractères

(edit: amélioration du score de 2 en utilisant array () au lieu de split (). 232 maintenant.)

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))

(modifier: oublié la partie "inconnu". 234 caractères maintenant.)

f = sécurité intégrée: pour b = 0à 3: s = s & split (",; Zones de détection restant dans un état donné ;; Mauvaise visibilité ,,; Initialisation ,,,,; Mauvaise configuration", ",") (f et 2 ^ b): suivant: split ("Pas d'alarmes techniques, Inconnu", & mid (s, 3), ",") (2+ (f = 0) + (len (s) = 0))

(original, 230)

pour b = 0à 3: s = s & split (",; Zones de détection restant dans un état donné ,; Mauvaise visibilité ,,; Initialisation ,,,,; Mauvaise configuration", ",") (FailSafe et 2 ^ b): suivant : tableau (mid (s, 3), "Aucune alarme technique") (- (len (s) = 0))

Bien sûr, ce n'est qu'une partie d'un script. pour le tester, essayez quelque chose comme ceci:

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
la source
moi aussi oublié le cas inconnu ;-)
blabla999
@ blabla999 En effet. Fixé. Merci!
JesterBLUE
1

Smalltalk, 243 caractères

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']     

formaté pour la lisibilité:

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']

Merci à Bergi pour avoir signalé le bug de la première version.

Cela soulève une idée: si je mappe la valeur FailSafe dans un masque 6 bits (mappage 0 -> 16 et supérieur à 15 -> 32), je peux me débarrasser des tests finaux. La mise en correspondance avec le masque 6 bits m peut être effectuée avec:

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

c'est-à-dire que m sera 16 pour un FailSafe zéro et 32 ​​pour les valeurs hors limites. Ensuite, sélectionnez et collectez les chaînes comme ci-dessus. Cela donne le nouveau code:

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:'; '

(J'ai également remplacé asStringWith: par joinWithAll :, qui est un alias).

Bien que cela semble être une bonne idée, cela a le même nombre de caractères - soupir. Peut-être qu'un autre langage de programmation avec des noms d'opérateurs plus denses obtient de meilleurs résultats ici!

Je pourrais enregistrer quelques caractères en n'utilisant pas de variable temporaire pour m, mais en la recalculant dans la boucle et en n'utilisant pas de tableau littéral pour le vecteur chaîne, pour obtenir un nombre légèrement inférieur à 240 caractères.

Enfin, le masque m pourrait également être calculé par m:={32},(1 to: 16) at:(FailSafe+1 min:17), ce qui pourrait être plus court en APL. Échangez ensuite les deux dernières chaînes du vecteur.

PS: La première version suppose que FailSafe n'est pas négatif, comme le font d'autres solutions ici. Le second peut traiter n'importe quoi, même nul ou autre non-nombre.

blabla999
la source
2
Et la Unknownconfiguration?
Bergi
aïe désolé - je dois le réparer.
blabla999
0

CoffeeScript, 161 160 221 caractères

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
la source
Qu'est-il arrivé à Unknownet No technical alarms?
Bergi
3
Oh merde. J'aurais dû me méfier quand j'ai battu la réponse GolfScript ...
Ryan Kennedy
Comme toujours, j'ai oublié les cas de bord ...
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

Modifier: meilleure entrée

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
la source
0

Perl, 208 197 caractères

$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'

Avec code passe-partout pour le faire fonctionner:

#!/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
la source
Relisez le code: il n'y a pas de vérification des limites.
titanofold
0

Java 275 caractères (sans compter les espaces blancs inutiles )

    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
la source