Один плохой троичный оператор заслуживает другого

18

Сегодняшний Daily WTF цитирует следующую строку кода ...

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

Напишите некоторый код, который принимает целочисленное значение с именем FailSafe и возвращает ту же строку, что приведенный выше код будет производить из того же целочисленного значения.

  • Задача состоит в том, чтобы переписать эту строку, чтобы «стандартный» код был бесплатным, включая любой код, который загружает целочисленное значение и выводит строку. Считается только код, который выполняет вышеуказанное преобразование из целого числа в строку.
  • Вы можете использовать другое имя для «FailSafe», если хотите, если выбранный вами идентификатор имеет ту же оценку в гольфе.
  • Нет вызова внешних ресурсов для выполнения поиска.
  • Применяются нормальные правила игры в гольф.
billpg
источник
Разрешено ли хранить FailSafe в другой переменной (например, f=FailSafeили что-то в этом роде)?
ProgramFOX
@ProgramFOX Это хорошо, но это назначение включено в счет. Только шаблон, который приведет вас к точке, где есть переменная с именем FailSafe, свободен.
billpg
Не могли бы вы, пожалуйста, просто напечатать код для нас? Или задача понять проблему?
Джон Дворжак
3
@JanDvorak Я не уверен, что смогу ...
billpg
2
Я надеюсь , что это: pastebin.com/jzXt4fsp приятнее читать
eithed

Ответы:

5

Рубин, 210 символов

Похоже на решение @Jan Dvorak, но более функционально и немного короче.

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 символов

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

Код принимает значение в переменной FailSafeи помещает результат в стек (т. Е. Выводит строку, если запускается как отдельная программа). Вы можете проверить код онлайн .

Код в основном генерирует массив всех 16 возможных результатов, выбирает сообщение об ошибке в зависимости от четырех младших битов FailSafe. Затем внешний ifобрабатывает нулевой регистр.

Говард
источник
Я думаю orвместо того, ifчтобы спасти вас .. Но я признаю, что я не пытался расшифровать оригинальный код.
Питер Тейлор
4

Rebol / Red: 208 символов

Я не так заинтересован в этом, как согласиться с тем, что вложенные троичные операторы раздражают ... и упоминание, что это на самом деле хороший пример для CASE Rebol / Red . Это связано с SWITCH и действительно помогает сгладить такие вещи:

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

Существует вариант с именем CASE / ALL, который фактически выполняет все условия, но значение по умолчанию просто останавливается после первого истинного.

Я буду "гольфить" это немного до 208:

x: func [y] [y <(f: FailSafe) и ++ y] добавьте регистр [x 0 ["Зоны обнаружения, находящиеся в заданном состоянии"] x 1 ["Плохая видимость"] x 3 ["Инициализация"] y 7 ["Плохая конфигурация"] f> 0 ["Неизвестно"] 1 ["Нет технических аварий"]] ";

Доктор Ребму
источник
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

Объяснение:

  • {...}FailSafe : генерировать строки
    • ⍵=0:⊂'No technical alarms': 0 дело
    • 0=16|⍵:⊂'Unknown': Unknown case (FailSafe не 0, но первые четыре бита)
    • 'Detection zones staying in a given state' 'Bad visibility' 'Initialization' 'Bad configuration'/⍨⌽⍵⊤⍨4/2: получить младшие 4 бита в аргументе ( ⍵⊤⍨4/2), reverse ( ) и выбрать строки для битов, которые включены ( /⍨).
  • '; '∘,¨: добавить '; 'в начало каждой возвращаемой строки,
  • ⊃,/: объединить все строки вместе,
  • 2↓: и удалите первые два символа (потому что есть дополнительный '; 'в передней.)
Мэринус
источник
Сохраните два байта, изменив ⊃,/на .
Адам
3

Рубин, 183 символа

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

Еще одно решение Ruby, но немного короче других. Это единственное выражение, которое использует константу FailSafe(в Ruby все идентификаторы в верхнем регистре являются константами) для создания выходной строки.

Ventero
источник
в ruby ​​вы должны объявить константу (как FailSafe) перед использованием. И вы код поднятьuninitialized constant FailSafe
4
@ Зелёный Поскольку вопрос гласит: «Напишите некоторый код, который принимает целочисленное значение с именем FailSafe», - поэтому мой код (как и все остальные ответы здесь) предполагает, что FailSafeон уже определен. Когда вы захотите запустить код, вы должны сначала определить константу самостоятельно.
Вентеро
2

JavaScript, 197 195 символов

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'

отформатирован:

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

Может быть дополнительно уменьшено с помощью выражений функций ES6 или Coffeescript.

Берги
источник
что если FailSafe 18? (на самом деле исходный код вызова рассматривает только младшие 4 бита, поэтому неизвестный случай фактически никогда не обнаруживается!) Поэтому вопрос в том, должны ли мы на самом деле заботиться об этом или предоставить «фиксированный» алгоритм.
blabla999
@ blabla999: он вернется, "Bad visibility"потому что установлен 2-битный, а остальные 4 младших бита отсутствуют. UnknownСлучай происходит , когда ни один из нижних 4 бит не установлен, но FailSafeэто != 0- так же , как в исходном коде (попробуйте 16). Должны ли мы «исправить» это, вы должны спросить у ОП (в комментарии к вопросу), а не у меня…
Берги
ты прав - я тупой Я так запутался из-за этого куска кода. Простите за это.
blabla999
2

Рубин, 213 символов

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

Это будет прекрасно работать в теле функции ( def transform failSafe; ...; end). Его также можно использовать как одно выражение (заключить в скобки, так как точка с запятой / новая строка имеет самый низкий приоритет) или как последовательность операторов с последним выражением ( e.join"; "), используемым в выражении.

Джон дворак
источник
Я добавлю правило, чтобы разрешить другое имя.
billpg
e+=["Initialization"]if f&4>3Я хочу это в Python.
Julıʇǝɥʇuʎs
@ Ты не впечатлен []||=?
Джон Дворжак
Не уверен, что он делает ... Также: since FailSafe must be a constant in RubyХа. Отношение Питона больше похоже на «Да, вы можете что-то сломать, но не ждите, что я
наведу порядок
1
@ ɐɔıʇǝɥʇuʎs ||=это как, +=но с ||- a ||= bэквивалентно a = a || b. Обычно это используется по умолчанию для переменной, когда она ложная.
Аарон Дюфур
1

VBScript, 204 234 232 символа

(edit: улучшил счет на 2, используя array () вместо split (). 232 сейчас.)

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

(редактировать: забыл "неизвестную" часть. 234 символов сейчас.)

f = отказоустойчивый: для b = 0 до 3: s = s & split (",; зоны обнаружения остаются в заданном состоянии ;; плохая видимость ,,; инициализация ,,,;; плохая конфигурация", ",") (f и 2 ^ b): следующее: split («Нет технических аварийных сигналов, неизвестно», & mid (s, 3), «,») (2+ (f = 0) + (len (s) = 0))

(оригинал, 230)

для b = 0 до 3: s = s & split (",; Зоны обнаружения, находящиеся в данном состоянии ,; Плохая видимость ,,; Инициализация ,,,,; Плохая конфигурация", ",") (FailSafe и 2 ^ b): далее : массив (средний (s, 3), «Нет технических аварий») (- (len (s) = 0))

Конечно, это всего лишь часть сценария. чтобы проверить это, попробуйте что-то вроде этого:

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
источник
Я тоже забыл Неизвестный случай ;-)
blabla999
@ blabla999 Действительно. Исправлена. Благодарность!
JesterBLUE
1

Smalltalk, 243 персонажа

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

отформатирован для удобства чтения:

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

Спасибо Берги, за указание на ошибку в первой версии.

Это порождает идею: если я сопоставлю значение FailSafe с 6-битной маской (отображение 0 -> 16 и больше-15 -> 32), я смогу избавиться от финальных тестов. Отображение на 6-битную маску m можно выполнить с помощью:

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

то есть m будет 16 для нулевого FailSafe и 32 для значений за пределами. Затем выберите и соберите строки, как указано выше. Это дает новый код:

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

(Я также заменил asStringWith: на joinWithAll:, который является псевдонимом).

Хотя это кажется хорошей идеей, у нее одинаковое количество символов - вздох. Может быть, какой-нибудь другой язык программирования с более плотными именами операторов будет лучше!

Я мог бы сохранить несколько символов, не используя временную переменную для m, но пересчитав ее в цикле и не используя буквальный массив для строкового вектора, чтобы получить счетчик чуть меньше 240 символов.

Наконец, маска m также может быть вычислена m:={32},(1 to: 16) at:(FailSafe+1 min:17), что может быть короче в APL. Затем поменяйте две последние строки в векторе.

PS: первая версия предполагает, что FailSafe неотрицательна, как некоторые другие решения здесь. Второй может иметь дело с чем угодно, даже с нулем или другими не числами.

blabla999
источник
2
Как насчет Unknownконфигурации?
Берги
ой извините - я должен это исправить.
blabla999
0

CoffeeScript, 161 160 221 символ

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'
Райан Кеннеди
источник
Что случилось с Unknownи No technical alarms?
Берги
3
Ой дерьмо. Я должен был быть подозрительным, когда я обыграл ответ GolfScript ...
Райан Кеннеди
Как всегда, я забыл о крайних случаях ...
Райан Кеннеди
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

Изменить: лучший вход

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 символов

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

С шаблоном кода, чтобы он работал:

#!/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
источник
Перечитайте код: нет проверки границ.
Titanofold
0

Java 275 символов (не считая ненужных пробелов)

    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);
Джефф Григг
источник