18
\$\begingroup\$

Today's Daily WTF quotes the following line of code...

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

Write some code that takes an integer value named FailSafe and returns the same string that the above code would produce from the same integer value.

  • The challenge is to rewrite that line, so "boilerplate" code is free, including any code that loads an integer value and outputs the string. Only the code that performs the above transformation from an integer to a string counts.
  • You may use a different name to "FailSafe" if you wish, as long as your chosen identifier has the same golf score.
  • No calling external resources to perform the lookup.
  • Normal code-golf rules apply.
\$\endgroup\$
9
  • \$\begingroup\$ Are we allowed to store FailSafe in another variable (for example, f=FailSafe or something like that)? \$\endgroup\$
    – ProgramFOX
    Jul 8, 2014 at 10:52
  • \$\begingroup\$ @ProgramFOX That's fine, but that assignment is included in the count. Only the boilerplate that leads you the point where there's a variable named FailSafe is free. \$\endgroup\$
    – billpg
    Jul 8, 2014 at 10:54
  • \$\begingroup\$ Could you please pretty-print the code for us? Or is the challenge to understand the challenge? \$\endgroup\$ Jul 8, 2014 at 10:56
  • 3
    \$\begingroup\$ @JanDvorak I'm not sure I can... \$\endgroup\$
    – billpg
    Jul 8, 2014 at 11:14
  • 2
    \$\begingroup\$ I hope this: pastebin.com/jzXt4fsp is nicer to read \$\endgroup\$
    – eithed
    Jul 8, 2014 at 11:22

13 Answers 13

5
\$\begingroup\$

Ruby, 210 characters

Similar to @Jan Dvorak's solution but a bit more functional and a bit shorter.

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"; "
\$\endgroup\$
5
\$\begingroup\$

GolfScript, 167 characters

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

The code assumes the value in variable FailSafe and pushes the result on the stack (i.e. output the string if run as standalone program). You can test the code online.

The code basically generates an array of all 16 possible outcomes, selects the error message depending on the four lowest bits of FailSafe. The outermost if then handles the zero case.

\$\endgroup\$
1
  • \$\begingroup\$ I think or instead of if would save you the .. But I admit that I haven't tried to decipher the original code. \$\endgroup\$ Jul 8, 2014 at 15:13
4
\$\begingroup\$

Rebol/Red: 208 chars

I'm not as interested in golfing this as in agreeing that nested ternary operators are annoying...and mentioning this is actually a nice instance for Rebol/Red's CASE. It's related to SWITCH and really helps flatten things like this out:

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

There's a variant called CASE/ALL that will actually run all the conditions, but the default just stops after the first true one.

I'll "golf" it a little to 208:

x: func[y][y < (f: FailSafe) and ++ y]append case[x 0["Detection zones staying in a given state"]x 1["Bad visibility"]x 3["Initialization"]y 7["Bad configuration"]f > 0["Unknown"]1["No technical alarms"]]"; "

\$\endgroup\$
4
\$\begingroup\$

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

Explanation:

  • {...}FailSafe: generate the strings
    • ⍵=0:⊂'No technical alarms': the 0 case
    • 0=16|⍵:⊂'Unknown': the Unknown case (FailSafe is not 0 but the first four bits are)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: get the lowest 4 bits in the argument (⍵⊤⍨4/2), reverse (), and select the strings for the bits that are on (/⍨).
  • '; '∘,¨: add '; ' to the front of each returned string,
  • ⊃,/: join all the strings together,
  • 2↓: and remove the first two characters (because there's an extra '; ' at the front.)
\$\endgroup\$
1
  • \$\begingroup\$ Save two bytes by changing ⊃,/ to . \$\endgroup\$
    – Adám
    May 29, 2017 at 11:46
3
\$\begingroup\$

Ruby, 183 characters

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

Yet another Ruby solution, but a bit shorter than the others. This is a single expression that uses the constant FailSafe (in Ruby, all uppercase identifiers are constants) to create the output string.

\$\endgroup\$
2
  • \$\begingroup\$ in ruby you should declare constant (like FailSafe) before using. And you code raise uninitialized constant FailSafe \$\endgroup\$
    – user13426
    Jul 8, 2014 at 18:40
  • 4
    \$\begingroup\$ @Зелёный As the question states: "Write some code that takes an integer value named FailSafe" - so my code (like all other answers here) assumes FailSafe is already defined. When you want to run the code, you'll have to define the constant yourself first. \$\endgroup\$
    – Ventero
    Jul 8, 2014 at 19:04
2
\$\begingroup\$

JavaScript, 197195 characters

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'

formatted:

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

Could be further reduced by using ES6 or Coffeescript function expressions.

\$\endgroup\$
3
  • \$\begingroup\$ what if FailSafe is 18? (actually, the original challenge code does only look at the lower 4 bits, so the Unknown case is actually never detected!) So the question is, if we should actually care for it or provide a "fixed" algorithm. \$\endgroup\$
    – blabla999
    Jul 9, 2014 at 13:18
  • \$\begingroup\$ @blabla999: It will return "Bad visibility" because the 2-bit is set and none of the other lower 4 bits. The Unknown case happens when none of the lower 4 bits is set, but FailSafe is != 0 - just as in the original code(try with 16). Whether we should "fix" this you should ask the OP (in a comment on the question), not me… \$\endgroup\$
    – Bergi
    Jul 9, 2014 at 13:24
  • \$\begingroup\$ you'r right - me stupid. I got so confused by that piece of code. Sorry for that. \$\endgroup\$
    – blabla999
    Jul 9, 2014 at 20:53
2
\$\begingroup\$

Ruby, 213 characters

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

This will work just fine wrapped in a function body (def transform failSafe; ...; end). It can also be used as a single expression (wrap in parentheses because a semicolon/newline has the lowest priority) or as a sequence of statements with the last expression (e.join"; ") used within an expression.

\$\endgroup\$
7
  • \$\begingroup\$ I'll add a rule to allow a different name. \$\endgroup\$
    – billpg
    Jul 8, 2014 at 13:05
  • \$\begingroup\$ e+=["Initialization"]if f&4>3 I want this in Python. \$\endgroup\$ Jul 8, 2014 at 14:04
  • \$\begingroup\$ @ɐɔıʇǝɥʇuʎs are you not impressed by []||=? \$\endgroup\$ Jul 8, 2014 at 14:34
  • \$\begingroup\$ Not sure what it does... Also: since FailSafe must be a constant in Ruby Huh. Python's attitude is more like "Yeah, you can break stuff, but don't expect me to clean up the mess" \$\endgroup\$ Jul 8, 2014 at 14:43
  • 1
    \$\begingroup\$ @ɐɔıʇǝɥʇuʎs ||= is like += but with || - a ||= b is equivalent to a = a || b. It is commonly used to default a variable when it is falsy. \$\endgroup\$ Jul 8, 2014 at 15:04
1
\$\begingroup\$

VBScript, 204 234 232 characters

(edit: improved score by 2 by using array() instead of 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: forgot the "unknown" part. 234 chars 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:split("No technical alarms,Unknown,"&mid(s,3),",")(2+(f=0)+(len(s)=0))

(original, 230)

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

Of course, this is just part of a script. to test it, try something like this:

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))
\$\endgroup\$
2
  • \$\begingroup\$ me too forgot the Unknown case ;-) \$\endgroup\$
    – blabla999
    Jul 9, 2014 at 11:38
  • \$\begingroup\$ @blabla999 Indeed. Fixed. Thanks! \$\endgroup\$
    – JesterBLUE
    Jul 9, 2014 at 12:41
1
\$\begingroup\$

Smalltalk, 243 characters

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

formatted for readability:

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

Thanks to Bergi, for pointing to the bug in the first version.

This brings up an idea: if I map the FailSafe value into a 6-bit mask, (mapping 0 -> 16 and greater-than-15 -> 32), I can get rid of the final tests. The mapping to the 6bit mask m can be done with:

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

that is, m will be 16 for a zero FailSafe, and 32 for out-of-bounds values. Then select and collect strings as above. This gives the new 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:'; '

(I also replaced asStringWith: by joinWithAll:, which is an alias).

Although this seems to be a nice idea, this has the same character count - sigh. Maybe some other programming language with denser operator names scores better here!

I could save a few chars by not using a temporary variable for m, but recompute it in the loop and by not using a literal array for the string vector, to get a count slighty below 240 chars.

Finally, the mask m could also be computed by m:={32},(1 to: 16) at:(FailSafe+1 min:17), which might be shorter in APL. Then exchange the last two strings in the vector.

PS: The first version assumes FailSafe is non-negative, like some other solutions here do. The second can deal with anything, even nil or other non-numbers.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ What about the Unknown configuration? \$\endgroup\$
    – Bergi
    Jul 8, 2014 at 18:10
  • \$\begingroup\$ ouch sorry - I have to fix it. \$\endgroup\$
    – blabla999
    Jul 9, 2014 at 10:31
0
\$\begingroup\$

CoffeeScript, 161 160 221 chars

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'
\$\endgroup\$
3
  • \$\begingroup\$ What happened to Unknown and No technical alarms? \$\endgroup\$
    – Bergi
    Jul 8, 2014 at 18:09
  • 3
    \$\begingroup\$ Aw crap. I should have been suspicious when I beat the GolfScript answer... \$\endgroup\$ Jul 8, 2014 at 18:11
  • \$\begingroup\$ As always, I forgot the edge cases... \$\endgroup\$ Jul 8, 2014 at 18:16
0
\$\begingroup\$

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

Edit: Better Entry

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
\$\endgroup\$
0
\$\begingroup\$

Perl, 208 197 Characters

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

With boilerplate code to make it work:

#!/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'
}
\$\endgroup\$
1
  • \$\begingroup\$ Reread the code: There isn't a bounds check. \$\endgroup\$
    – titanofold
    Jul 9, 2014 at 12:48
0
\$\begingroup\$

Java 275 characters (not counting unnecessary white space)

    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);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.