Ein schlechter ternärer Operator verdient einen anderen

18

Die heutige Daily WTF zitiert die folgende Codezeile ...

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

Schreiben Sie einen Code, der einen ganzzahligen Wert mit dem Namen FailSafe annimmt und dieselbe Zeichenfolge zurückgibt, die der obige Code aus demselben ganzzahligen Wert erzeugen würde.

  • Die Herausforderung besteht darin, diese Zeile neu zu schreiben, sodass der Code "boilerplate" frei ist, einschließlich aller Codes, die einen ganzzahligen Wert laden und die Zeichenfolge ausgeben. Es zählt nur der Code, der die obige Umwandlung von einer Ganzzahl in eine Zeichenfolge ausführt.
  • Wenn Sie möchten, können Sie einen anderen Namen als "FailSafe" verwenden, sofern Ihre gewählte Kennung die gleiche Golfwertung aufweist.
  • Es werden keine externen Ressourcen aufgerufen, um die Suche durchzuführen.
  • Es gelten die normalen Code-Golf-Regeln.
billpg
quelle
Dürfen wir FailSafe in einer anderen Variablen speichern (zum Beispiel f=FailSafeoder so ähnlich)?
ProgramFOX
@ProgramFOX Das ist in Ordnung, aber diese Zuweisung ist in der Zählung enthalten. Nur das Boilerplate, das Sie zu dem Punkt führt, an dem es eine Variable namens FailSafe gibt, ist kostenlos.
billpg
Könnten Sie bitte den Code für uns ausdrucken? Oder ist die Herausforderung, die Herausforderung zu verstehen?
John Dvorak
3
@ JanDvorak Ich bin nicht sicher, ob ich kann ...
billpg
2
Ich hoffe das: pastebin.com/jzXt4fsp ist
besser

Antworten:

5

Ruby, 210 Zeichen

Ähnlich wie @Jan Dvoraks Lösung, jedoch etwas funktionaler und etwas kürzer.

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
quelle
5

GolfScript, 167 Zeichen

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

Der Code nimmt den Wert in Variable an FailSafeund überträgt das Ergebnis auf den Stack (dh er gibt den String aus, wenn er als eigenständiges Programm ausgeführt wird). Sie können den Code online testen .

Der Code generiert im Grunde ein Array aller 16 möglichen Ergebnisse, wählt die Fehlermeldung in Abhängigkeit von den vier niedrigsten Bits aus FailSafe. Der äußerste behandelt ifdann den Nullfall.

Howard
quelle
Ich denke oranstatt ifdir das zu sparen .. Aber ich gebe zu, dass ich nicht versucht habe, den Originalcode zu entschlüsseln.
Peter Taylor
4

Rebol / Rot: 208 Zeichen

Ich bin nicht so sehr am Golfen interessiert, als daran, zuzustimmen, dass verschachtelte ternäre Operatoren ärgerlich sind ... und dies zu erwähnen, ist eigentlich eine nette Instanz für Rebol / Reds CASE . Es ist mit SWITCH verwandt und hilft wirklich dabei, Dinge wie dieses zu reduzieren:

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

Es gibt eine Variante mit dem Namen CASE / ALL, die alle Bedingungen ausführt, die Standardeinstellung wird jedoch erst nach der ersten echten beendet.

Ich "golf" es ein wenig bis 208:

x: func [y] [y <(f: FailSafe) und ++ y] füge case [x 0 ["Erkennungszonen bleiben in einem bestimmten Zustand"] x 1 ["Schlechte Sichtbarkeit"] x 3 ["Initialisierung"] hinzu y 7 ["Bad configuration"] f> 0 ["Unknown"] 1 ["No technical alarms"]] ";"

Dr. Rebmu
quelle
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

Erläuterung:

  • {... }FailSafe: generiere die Strings
    • ⍵=0:⊂'No technical alarms': der 0Fall
    • 0=16|⍵:⊂'Unknown': der UnknownFall (FailSafe ist nicht 0, aber die ersten vier Bits sind)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: Holen Sie sich die niedrigsten 4 Bits in das Argument ( ⍵⊤⍨4/2), kehren Sie ( ) und wählen Sie die Zeichenfolgen für die Bits, die auf ( /⍨) sind.
  • '; '∘,¨: '; 'vor jeder zurückgegebenen Zeichenfolge einfügen,
  • ⊃,/: alle Saiten zusammenfügen,
  • 2↓: und entferne die ersten beiden Zeichen (weil '; 'vorne ein Extra ist .)
Marinus
quelle
Speicher zwei Bytes durch eine Änderung ⊃,/an .
Adám
3

Ruby, 183 Zeichen

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

Noch eine Ruby-Lösung, aber etwas kürzer als die anderen. Dies ist ein einzelner Ausdruck, der die Konstante verwendet FailSafe(in Ruby sind alle Großbuchstaben Konstanten), um die Ausgabezeichenfolge zu erstellen.

Ventero
quelle
In Ruby sollten Sie FailSafevor der Verwendung eine Konstante (like ) deklarieren . Und Sie Code erhöhenuninitialized constant FailSafe
4
@ Зелёный Wie die Frage besagt: "Schreiben Sie einen Code, der einen ganzzahligen Wert mit dem Namen FailSafe annimmt" - so geht mein Code (wie alle anderen Antworten hier) davon aus, dass er FailSafebereits definiert ist. Wenn Sie den Code ausführen möchten, müssen Sie zuerst die Konstante selbst definieren.
Ventero
2

JavaScript, 197 195 Zeichen

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'

formatiert:

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

Könnte durch die Verwendung von ES6- oder Coffeescript-Funktionsausdrücken weiter reduziert werden.

Bergi
quelle
Was ist, wenn FailSafe 18 ist? (Tatsächlich betrachtet der ursprüngliche Herausforderungscode nur die unteren 4 Bits, so dass der unbekannte Fall tatsächlich nie erkannt wird!) Die Frage ist also, ob wir uns tatsächlich darum kümmern oder einen "festen" Algorithmus bereitstellen sollten.
Blabla999
@ blabla999: Es wird zurückgegeben, "Bad visibility"da das 2-Bit gesetzt ist und keines der anderen unteren 4 Bits. Der UnknownFall geschieht , wenn keine der unteren 4 Bits gesetzt, sondern FailSafeist != 0- wie im ursprünglichen Code (versuchen Sie mit 16). Ob wir dies "beheben" sollten, sollten Sie dem OP (in einem Kommentar zu der Frage) fragen, nicht mir ...
Bergi
du hast recht - ich dumm. Dieser Code hat mich so verwirrt. Das tut mir leid.
Blabla999
2

Ruby, 213 Zeichen

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

Dies funktioniert einwandfrei in einem Funktionskörper ( def transform failSafe; ...; end). Es kann auch als einzelner Ausdruck (in Klammern eingeschlossen, da ein Semikolon / eine neue Zeile die niedrigste Priorität hat) oder als Folge von Anweisungen mit dem letzten Ausdruck ( e.join"; ") in einem Ausdruck verwendet werden.

John Dvorak
quelle
Ich werde eine Regel hinzufügen, um einen anderen Namen zuzulassen.
billpg
e+=["Initialization"]if f&4>3Ich möchte das in Python.
ɐɔıɐɔuʇǝɥʇs
@ ɐɔıɐɔuʇǝɥʇs bist du nicht beeindruckt von []||=?
John Dvorak
Nicht sicher, was es tut ... Also: since FailSafe must be a constant in RubyHuh. Pythons Haltung ist eher wie "Ja, du kannst Sachen zerbrechen, aber erwarte nicht, dass ich das Chaos aufräume"
ɐɔıʇǝɥʇuʎs
1
@ ɐɔıɐɔuʇǝɥʇs ||=ist wie, +=aber mit ||- a ||= bist äquivalent zu a = a || b. Es wird häufig verwendet, um eine Variable als Standard festzulegen, wenn sie falsch ist.
Aaron Dufour
1

VBScript, 204 234 232 Zeichen

(Bearbeiten: Verbesserte Punktzahl um 2 durch Verwendung von array () anstelle von split (). 232 now.)

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

(edit: vergaß den "unbekannten" Teil. 234 Zeichen jetzt.)

f = ausfallsicher: für b = 0 bis 3: s = s & split (",; Erkennungszonen bleiben in einem bestimmten Zustand; schlechte Sicht ,,; Initialisierung ,,,,; schlechte Konfiguration", ",") (f und 2 ^ b): next: split ("Keine technischen Alarme, Unbekannt," & mid (s, 3), ",") (2+ (f = 0) + (len (s) = 0))

(original, 230)

für b = 0 bis 3: s = s & split (",; Erkennungszonen bleiben in einem bestimmten Zustand; schlechte Sichtbarkeit ,,; Initialisierung ,,,,; schlechte Konfiguration", ",") (FailSafe und 2 ^ b): next : Array (Mitte (n, 3), "Keine technischen Alarme") (- (Länge (n) = 0))

Dies ist natürlich nur ein Teil eines Skripts. Versuchen Sie zum Testen Folgendes:

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
quelle
Ich vergaß auch den unbekannten Fall ;-)
blabla999
@ blabla999 In der Tat. Fest. Vielen Dank!
JesterBLUE
1

Smalltalk, 243 Zeichen

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

Zur besseren Lesbarkeit formatiert:

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

Vielen Dank an Bergi für den Hinweis auf den Fehler in der ersten Version.

Daraus ergibt sich eine Idee: Wenn ich den FailSafe-Wert einer 6-Bit-Maske zuordne (Zuordnung 0 -> 16 und größer als 15 -> 32), kann ich die endgültigen Tests loswerden. Die Abbildung auf die 6-Bit-Maske m kann erfolgen mit:

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

Das heißt, m ist 16 für einen FailSafe-Wert von Null und 32 für Werte außerhalb des zulässigen Bereichs. Dann wählen und sammeln Sie die Zeichenfolgen wie oben. Dies ergibt den neuen 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:'; '

(Ich habe auch asStringWith: durch joinWithAll: ersetzt, das ist ein Alias).

Obwohl dies eine nette Idee zu sein scheint, hat dies den gleichen Charakter - seufz. Vielleicht schneidet hier eine andere Programmiersprache mit dichteren Operatoren besser ab!

Ich könnte ein paar Zeichen sparen, indem ich keine temporäre Variable für m verwende, sondern sie in der Schleife neu berechne und kein literales Array für den Zeichenfolgenvektor verwende, um eine geringfügige Anzahl unter 240 Zeichen zu erhalten.

Schließlich könnte auch die Maske m berechnet werden m:={32},(1 to: 16) at:(FailSafe+1 min:17), die in APL kürzer sein könnte. Tauschen Sie dann die letzten beiden Zeichenfolgen im Vektor aus.

PS: In der ersten Version wird davon ausgegangen, dass FailSafe nicht negativ ist, wie dies bei einigen anderen Lösungen der Fall ist. Der zweite kann mit allem umgehen, auch mit Null oder anderen Nicht-Zahlen.

blabla999
quelle
2
Was ist mit der UnknownKonfiguration?
Bergi
autsch sorry - ich muss es reparieren.
Blabla999
0

CoffeeScript, 161 160 221 Zeichen

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
quelle
Was ist mit Unknownund passiert No technical alarms?
Bergi
3
Oh verdammt. Ich hätte misstrauisch sein sollen, als ich die GolfScript-Antwort geschlagen habe ...
Ryan Kennedy
Wie immer habe ich die Randfälle vergessen ...
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

Bearbeiten: Besserer Eintrag

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
quelle
0

Perl, 208 197 Zeichen

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

Mit Boilerplate-Code, damit es funktioniert:

#!/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
quelle
Lesen Sie den Code erneut: Es gibt keine Grenzüberprüfung.
Titanofold
0

Java 275 Zeichen (ohne unnötige Leerzeichen)

    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
quelle