Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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.
share|improve this question
    
Are we allowed to store FailSafe in another variable (for example, f=FailSafe or something like that)? –  ProgramFOX Jul 8 at 10:52
    
@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. –  billpg Jul 8 at 10:54
    
Could you please pretty-print the code for us? Or is the challenge to understand the challenge? –  Jan Dvorak Jul 8 at 10:56
2  
@JanDvorak I'm not sure I can... –  billpg Jul 8 at 11:14
2  
I hope this: pastebin.com/jzXt4fsp is nicer to read –  eithedog Jul 8 at 11:22
show 4 more comments

13 Answers 13

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"; "
share|improve this answer
add comment

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.

share|improve this answer
    
I think or instead of if would save you the .. But I admit that I haven't tried to decipher the original code. –  Peter Taylor Jul 8 at 15:13
add comment

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

share|improve this answer
add comment

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.

share|improve this answer
    
in ruby you should declare constant (like FailSafe) before using. And you code raise uninitialized constant FailSafe –  Зелёный Jul 8 at 18:40
4  
@Зелёный 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. –  Ventero Jul 8 at 19:04
add comment

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.)
share|improve this answer
add comment

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.

share|improve this answer
    
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. –  blabla999 Jul 9 at 13:18
    
@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… –  Bergi Jul 9 at 13:24
    
you'r right - me stupid. I got so confused by that piece of code. Sorry for that. –  blabla999 Jul 9 at 20:53
add comment

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.

share|improve this answer
    
I'll add a rule to allow a different name. –  billpg Jul 8 at 13:05
    
e+=["Initialization"]if f&4>3 I want this in Python. –  ɐɔıʇǝɥʇuʎs Jul 8 at 14:04
    
@ɐɔıʇǝɥʇuʎs are you not impressed by []||=? –  Jan Dvorak Jul 8 at 14:34
    
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" –  ɐɔıʇǝɥʇuʎs Jul 8 at 14:43
1  
@ɐɔıʇǝɥʇ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. –  Aaron Dufour Jul 8 at 15:04
show 2 more comments

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))
share|improve this answer
    
me too forgot the Unknown case ;-) –  blabla999 Jul 9 at 11:38
    
@blabla999 Indeed. Fixed. Thanks! –  JesterBLUE Jul 9 at 12:41
add comment

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.

share|improve this answer
2  
What about the Unknown configuration? –  Bergi Jul 8 at 18:10
    
ouch sorry - I have to fix it. –  blabla999 Jul 9 at 10:31
add comment

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'
share|improve this answer
    
What happened to Unknown and No technical alarms? –  Bergi Jul 8 at 18:09
3  
Aw crap. I should have been suspicious when I beat the GolfScript answer... –  Ryan Muller Jul 8 at 18:11
    
As always, I forgot the edge cases... –  Ryan Muller Jul 8 at 18:16
add comment

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
share|improve this answer
add comment

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'
}
share|improve this answer
    
Reread the code: There isn't a bounds check. –  titanofold Jul 9 at 12:48
add comment

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);
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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