Um operador ternário ruim merece outro


18

O Daily WTF de hoje cita a seguinte linha 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')))))))))))))))

Escreva um código que use um valor inteiro chamado FailSafe e retorne a mesma string que o código acima produziria do mesmo valor inteiro.

  • O desafio é reescrever essa linha, para que o código "clichê" seja gratuito, incluindo qualquer código que carrega um valor inteiro e gera a string. Somente o código que executa a transformação acima de um número inteiro para uma seqüência de caracteres conta.
  • Você pode usar um nome diferente para "FailSafe", se desejar, desde que o identificador escolhido tenha a mesma pontuação de golfe.
  • Não é necessário chamar recursos externos para executar a pesquisa.
  • Aplicam-se regras normais de código-golfe.

Temos permissão para armazenar o FailSafe em outra variável (por exemplo, f=FailSafeou algo assim)?
ProgramFOX

@ProgramFOX Tudo bem, mas essa tarefa está incluída na contagem. Somente o padrão que leva ao ponto em que há uma variável chamada FailSafe é gratuito.
billpg

Você poderia imprimir o código para nós? Ou é o desafio de entender o desafio?
John Dvorak

3
@JanDvorak Não tenho a certeza que posso ...
billpg

2
Espero que isto: pastebin.com/jzXt4fsp seja mais agradável de ler
eithed

Respostas:


5

Ruby, 210 caracteres

Semelhante à solução de @Jan Dvorak, mas um pouco mais funcional e um pouco mais curta.

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

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

O código assume o valor na variável FailSafee envia o resultado para a pilha (ou seja, gera a string se for executado como um programa independente). Você pode testar o código online .

O código basicamente gera uma matriz de todos os 16 resultados possíveis, seleciona a mensagem de erro dependendo dos quatro bits mais baixos de FailSafe. O mais externo iflida com o caso zero.


Eu acho que ao orinvés de ifte poupar .. Mas admito que não tentei decifrar o código original.
Peter Taylor

4

Rebol / Vermelho: 208 caracteres

Não estou tão interessado em jogar golfe quanto em concordar que os operadores ternários aninhados são irritantes ... e mencionar que esse é realmente um bom exemplo para o CASE da Rebol / Red . Está relacionado ao SWITCH e realmente ajuda a achatar coisas como estas:

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

Há uma variante chamada CASE / ALL que realmente executa todas as condições, mas o padrão para após a primeira verdadeira.

Vou "jogar golfe" um pouco para 208:

x: func [y] [y <(f: FailSafe) e ++ y] anexam maiúsculas e minúsculas [x 0 ["Zonas de detecção que permanecem em um determinado estado"] x 1 ["Má visibilidade"] x 3 ["Inicialização"] y 7 ["Configuração incorreta"] f> 0 ["Desconhecido"] 1 ["Sem alarmes técnicos"]] ";"


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

Explicação:

  • {... }FailSafe: gera as strings
    • ⍵=0:⊂'No technical alarms': o 0caso
    • 0=16|⍵:⊂'Unknown': o Unknowncaso (FailSafe não é 0, mas os quatro primeiros bits são)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: obtenha os 4 bits mais baixos no argumento ( ⍵⊤⍨4/2), reverse ( ) e selecione as strings dos bits que estão em ( /⍨).
  • '; '∘,¨: adicione '; 'à frente de cada sequência retornada,
  • ⊃,/: junte todas as cordas,
  • 2↓: e remova os dois primeiros caracteres (porque há um extra '; 'na frente).

Salve dois bytes alterando ⊃,/para .
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]]-[""]]*"; "

Mais uma solução Ruby, mas um pouco menor que as outras. Essa é uma expressão única que usa a constante FailSafe(em Ruby, todos os identificadores em maiúsculas são constantes) para criar a sequência de saída.


em ruby, você deve declarar constante (like FailSafe) antes de usar. E você codifica raiseuninitialized constant FailSafe

4
@ Зелёный Como a pergunta indica: "Escreva um código que aceite um valor inteiro chamado FailSafe" - então meu código (como todas as outras respostas aqui) assume que FailSafejá está definido. Quando você deseja executar o código, primeiro precisa definir a constante.
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'

formatado:

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

Pode ser reduzido ainda mais usando as expressões de função ES6 ou Coffeescript.


e se o FailSafe for 18? (na verdade, o código de desafio original olha apenas para os 4 bits inferiores, portanto o caso Desconhecido nunca é detectado!) Portanto, a questão é: se devemos realmente cuidar dele ou fornecer um algoritmo "fixo".
precisa saber é o seguinte

@ blabla999: Ele retornará "Bad visibility"porque os 2 bits estão definidos e nenhum dos outros 4 bits inferiores. O Unknowncaso acontece quando nenhum dos 4 bits inferiores está definido, mas FailSafeé != 0- assim como no código original (tente com 16). Se devemos "consertar" isso você deve perguntar ao OP (em um comentário sobre a questão), não me ...
Bergi

você está certo - eu sou estúpido. Fiquei tão confuso com esse pedaço de código. Desculpe por isso.
precisa saber é o seguinte

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

Isso funcionará perfeitamente dentro de um corpo de função ( def transform failSafe; ...; end). Também pode ser usado como uma expressão única (entre parênteses, porque um ponto-e-vírgula / nova linha tem a menor prioridade) ou como uma sequência de instruções com a última expressão ( e.join"; ") usada em uma expressão.


Vou adicionar uma regra para permitir um nome diferente.
billpg

e+=["Initialization"]if f&4>3Eu quero isso em Python.
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs você não está impressionado []||=?
John Dvorak

Não tenho certeza do que faz ... Também: since FailSafe must be a constant in RubyHuh. A atitude do Python é mais como "Sim, você pode quebrar coisas, mas não espere que eu
arrume

1
@ ɐɔıʇǝɥʇuʎs ||=é como +=mas com ||- a ||= bé equivalente a a = a || b. É comumente usado para usar como padrão uma variável quando ela é falsa.
Aaron Dufour

1

VBScript, 204 234 232 caracteres

(editar: pontuação aprimorada em 2 usando array () em vez de split (). 232 agora.)

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: esqueceu a parte "desconhecida". 234 caracteres agora.)

f = à prova de falhas: para b = 0 a 3: s = s & split (";; Zonas de detecção que permanecem em um determinado estado ;; Visibilidade ruim ,,; Inicialização ,,,,; Configuração incorreta", ",") (f e 2 ^ b): próximo: divisão ("Sem alarmes técnicos, desconhecido", & médio (s, 3), ",") (2+ (f = 0) + (len (s) = 0))

(original, 230)

para b = 0 a 3: s = s & split (";; Zonas de detecção que permanecem em um determinado estado ;; Visibilidade ruim ,,; Inicialização ,,,,; Configuração incorreta", ",") (FailSafe e 2 ^ b): próximo : matriz (médio (s, 3), "Sem alarmes técnicos") (- (len (s) = 0))

Claro, isso é apenas parte de um script. para testá-lo, tente algo como isto:

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

eu também esqueceu o caso Desconhecido ;-)
blabla999

@ blabla999 De fato. Fixo. Obrigado!
precisa saber é o seguinte

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

formatado para facilitar a leitura:

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

Obrigado a Bergi, por apontar o bug na primeira versão.

Isso traz uma idéia: se eu mapear o valor do FailSafe em uma máscara de 6 bits (mapeamento de 0 -> 16 e maior que 15 -> 32), posso me livrar dos testes finais. O mapeamento para a máscara de 6 bits m pode ser feito com:

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

isto é, m será 16 para um FailSafe zero e 32 para valores fora dos limites. Em seguida, selecione e colete as strings como acima. Isso fornece o novo 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:'; '

(Também substituí asStringWith: por joinWithAll :, que é um alias).

Embora essa pareça uma boa idéia, ela tem o mesmo número de caracteres - suspiro. Talvez alguma outra linguagem de programação com nomes de operadores mais densos seja melhor aqui!

Eu poderia salvar alguns caracteres não usando uma variável temporária para m, mas recalculá-la no loop e não usando uma matriz literal para o vetor string, para obter uma contagem ligeiramente abaixo de 240 caracteres.

Finalmente, a máscara m também pode ser calculada por m:={32},(1 to: 16) at:(FailSafe+1 min:17) , o que pode ser menor no APL. Troque as duas últimas cadeias no vetor.

PS: A primeira versão assume que o FailSafe não é negativo, como algumas outras soluções aqui. O segundo pode lidar com qualquer coisa, até nulo ou outros não-números.


2
E a Unknownconfiguração?
Bergi 08/07/2014

ai desculpe - eu tenho que consertar isso.
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'

O que aconteceu com Unknowne No technical alarms?
Bergi 08/07/19

3
Aw porcaria. Eu deveria ter suspeitado quando bati na resposta do GolfScript ...
Ryan Kennedy

Como sempre, eu esqueci os casos de ponta ...
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: Melhor 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

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'

Com o código padrão para fazê-lo funcionar:

#!/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'
}

Releia o código: não há uma verificação de limites.
titanofold

0

Caracteres Java 275 (sem contar espaço em branco desnecessário )

    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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.