Идиома «Делай пока ложно»


47

Делать пока ложно

Сегодня на работе один из моих коллег описывал вариант использования для do while (false). Человек, с которым он разговаривал, думал, что это глупо и так просто, если заявления будут намного лучше. Затем мы потратили впустую половину нашего дня, обсуждая лучший способ написать что-то эквивалентное:

do
{
   //some code that should always execute...

   if ( condition )
   {
      //do some stuff
      break;
   }

   //some code that should execute if condition is not true

   if ( condition2 )
   {
       //do some more stuff
       break;
   }

   //further code that should not execute if condition or condition2 are true

}
while(false);

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

do
{
   result += "A";

   if ( C1)
   {
      result += "B";
      break;
   }

   result += "C"

   if ( C2 )
   {
       result += "D";
       break;
   }

   result += "E";

}
while(false);

print(result);

Поэтому вход может быть:

1. C1 = true, C2 = true
2. C1 = true, C2 = false
3. C1 = false, C2 = true
4. C1 = false, C2 = false

и вывод должен быть:

1. "AB"
2. "AB"
3. "ACD"
4. "ACE"

Это код-гольф, поэтому ответы будут оцениваться по байтам. Стандартные лазейки запрещены.

Да, это простой вопрос, но, надеюсь, мы увидим креативные ответы. Надеюсь, простота побудит людей использовать языки, в которых они менее уверены.


Должен ли вывод быть прописным или строчным?
Аднан

7
В дополнение к дискуссии с вашим коллегой, мне кажется, вы могли бы сделать то же самое, используя метод return resultвместо break. Тогда вы получаете бонусы за повторное использование и упрощение кода вызова. Но, возможно, я что-то упустил.
jpmc26

3
Я не знал, что это была идиома в Си ...
Мердад

5
@Mehrdad некоторые люди делают это вместо того, чтобы gotoиспользовать gotoэто плохо :)
Сет

2
Единственное время, которое я когда-либо использовал do{}while(false), было внутри макросов. Простого ifнедостаточно, потому что оно плохо взаимодействует elseс окружающими, которые могут присутствовать. Без макроса вы можете также удалить doи while.
NWP

Ответы:


19

Python 3, 31

Сохранено 1 байт благодаря xnor.

Только один байт от ES6. : / Глупый Python и его длинный анонимный синтаксис функции.

Ура для одного лайнера!

lambda x,y:x*"AB"or"AC"+"ED"[y]

Тестовые случаи:

assert f(1, 1) == "AB"
assert f(1, 0) == "AB"
assert f(0, 1) == "ACD"
assert f(0, 0) == "ACE"

7
Если вы сделаете новый заказ x*"AB", вы можете сэкономить место после.
xnor

2
Извините, ваш длинный анонимный синтаксис функции будет смертью Python: P
Конор О'Брайен

5
@ CᴏɴᴏʀO'Bʀɪᴇɴ Я знал, что что-то должно сдерживать Питона. Я отправлю ПКП как можно скорее.
Морган Трепп


9
PEP, чтобы сделать λсинонимом, lambdaбыло бы здорово :)
Роберт Грант

13

JavaScript ES6, 30 26 25 байт

Простая анонимная функция, принимающая два входа. Назначьте переменную для вызова. Обновление : давайте поскакаем на индекс победителя. Это экономит 4 байта. Я обеспечил себе преимущество над Python . Сохранение байта путем каррирования функции; звоните как (...)(a)(b). Спасибо, Патрик Робертс!

a=>b=>a?"AB":"AC"+"ED"[b]

Старая, оригинальная версия, 30 байтов (включена, чтобы не раствориться в ответе Python (;):

(a,b)=>"A"+(a?"B":b?"CD":"CE")

Это не так умно ...
theonlygusti

15
@theonlygusti Это код-гольф, а не конкурс популярности. Кроме того, зачем использовать ненужные байты, если есть более краткое решение?
Конор О'Брайен

Мне нравится ваш выбор носа:b?
J Atkin

@JAtkin Действительно!
Конор О'Брайен

4
Вы можете сохранить байт с помощью карри
Патрик Робертс


9

Haskell, 28 байт

x#y|x="AB"|y="ACD"|1<2="ACE"

Пример использования: False # True-> "ACD".

Использование входных значений непосредственно в качестве охранников.


9

MATL , 15 17 байт

?'AB'}'AC'69i-h

Входы есть 0или 1на отдельных строках. В качестве альтернативы, 0может быть заменена F(MATL - х false) и 1от T(MATL - х true).

Попробуйте онлайн!

?           % if C1 (implicit input)
  'AB'      %   push 'AB'
}           % else
  'AC'      %   push 'AC'
  69        %   push 69 ('E')
  i-        %   subtract input. If 1 gives 'D', if 0 leaves 'E'
  h         %   concatenate horizontally
            % end if (implicit)

8

Brainfuck, 65 байт

Это предполагает, что C1 и C2 вводятся как необработанные 0 или 1 байт. например

echo -en '\x00\x01' | bf foo.bf

Golfed:

++++++++[>++++++++<-]>+.+>+>,[<-<.>>-]<[<+.+>>,[<-<.>>-]<[<+.>-]]

Ungolfed:

                                      Tape
                                      _0
++++++++[>++++++++<-]>+.+  print A    0 _B
>+>,                       read C1    0 B 1 _0  or  0 B 1 _1
[<-<.>>-]<                 print B    0 B _0 0  or  0 B _1 0
[<+.+>>                    print C    0 D 1 _0
    ,                      read C2    0 D 1 _0  or  0 D 1 _1
    [<-<.>>-]<             print D    0 D _0 0  or  0 D _1 0
    [<+.>-]                print E    0 D _0    or  0 E _0
]

Я считаю , что стоит отметить , что это решение является на самом деле основано на разрушении из в то время как петли.



7

NTFJ , 110 байт

##~~~~~#@|########@|~#~~~~~#@*(~#~~~~#~@*########@^)~#~~~~##@*##~~~~~#@|########@|(~#~~~#~~@*):~||(~#~~~#~#@*)

Более читабельно:

##~~~~~#@|########@|~#~~~~~#@*(~#~~~~#~@*########@^)~#~~~~##@*##~~~~~#@|########@|(~#~~~#~~@*
):~||(~#~~~#~#@*)

Это было конечно интересно. Попробуйте здесь , используя два символа ( 0или 1) в качестве ввода.

Используя метод ETHProduction для преобразования в 0, 1 (символы) в биты, это становится проще.

##~~~~~#@|########@|

Это указанный метод. Нажатие 193 ( ##~~~~~#@), NANDing его ( |) с верхним значением ввода (в этом случае, первый код символа, 48 или 49). Это дает 254 для 1 и 255 для 0. NANDE с 255 ( ########@) возвращает 0 или 1 бит в соответствии с входом.

~#~~~~~#@*

Это печатает A, так как весь ввод начинается с A. *появляется Aпри печати, поэтому стопка остается неизменной по сравнению с предыдущим состоянием.

(~#~~~~#~@*########@^)

Случай 1: первый бит 1, и (активирует код внутри. ~#~~~~#~@*печатает B, ########@^нажимает 255 и переходит на эту позицию в коде. Это конец программы, она заканчивается.

Случай 2: первый бит есть 0. (пропускает )и код продолжается.

~#~~~~##@*

Это печатает C, потому что это следующий символ.

##~~~~~#@|########@|

Это преобразует наш второй вход в немного.

(~#~~~#~~@*)

Если наш второй бит равен 1, мы приступаем к печати E.

:~||

Это NAND представление булева отрицания нашего бита: A NAND (0 NAND A) = NOT A.

(~#~~~#~#@*)

Это теперь активируется, если бит был 0, и печатает E.


5

Pyth, 16 байт

+\A?Q\B+\C?E\D\E

Тестирование

Триад!

Объяснение:

+\A              Start with an A
?Q\B             If the first variable is true, add a B and break.
+\C              Otherwise, add a C and
?E\D             If the second variable is true, add a D and break.
\E               Otherwise, add a E and finish.

Ввод на двух последовательных строках.


3
О, pythmaster, расскажи нам о путях этой программы. ;)
Конор О'Брайен

5

CJam, 15 16 17 байт

'Ali'B'C'Eli-+?

Попробуйте онлайн!

Один байт благодаря @randomra, а один байт благодаря @Dennis

Объяснение:

'A                  e# push "A"
  li                e# read first input as an integer
    'B              e# push "B" 
      'C            e# push "C"
        'E          e# push "E"
          li-       e# leave "E" or change to "D" according to second input
             +      e# concatenate "C" with "E" or "D"
              ?     e# select "B" or "C..." according to first input

Старая версия (16 байт):

'Ali'B{'C'Eli-}?

Объяснение:

'A                  e# push character "A"
               ?    e# if-then-else
  li                e# read first input as an integer. Condition for if
    'B              e# push character "B" if first input is true
      {       }     e# execute this if first input is false
       'C           e# push character "C"
         'E         e# push character "E"
           li       e# read second input as an integer
             -      e# subtract: transform "E" to "D" if second input is true
                    e# implicitly display stack contents

5
Наши хорошие друзья Али и Эли!
Конор О'Брайен

5

Pyth, 13 символов, 19 байтов

.HC@"૎્««"iQ2

Принимает данные в форме [a, b]

объяснение

               - autoassign Q = eval(input())
           iQ2 -    from_base(Q, 2) - convert to an int
   @"૎્««"    -   "૎્««"[^]
  C            -  ord(^)
.H             - hex(^)

Попробуй здесь

Или используйте набор тестов


2
По крайней мере, в UTF-8 это весит 19 байт.
Деннис

1
bytesizematters использует полностью составленный способ подсчета байтов, который не соответствует (и не может ) соответствовать фактической кодировке. Он считает квадратные вещи как 2 байта каждый (3 байта в UTF-8) и «как 1 байт каждый (2 байта в UTF-8). Как wcи в этом согласны , что это 19 байт.
Деннис

4

C, 76 байтов

Я переименовал c1в c, c2чтобы Cи resultчтобы r. C программисты идут на крайности, чтобы избежать goto. Если у вас когда-нибудь есть проблум с абсурдным синтаксисом в C, скорее всего, это потому, что вы не использовали goto.

char r[4]="A";if(c){r[1]=66;goto e;}r[1]=67;if(C){r[2]=68;goto e;}r[2]=69;e:

Ungolfed

char r[4] = "A";
if(c1){
    r[1] = 'B';
    goto end;
}
r[1] = 'C';
if(c2){
    r[2] = 'D';
    goto end;
}
r[2] = 'E';
end:

Вы можете начать с char r[4]="A";? Мой C ржавый.
LarsH

Разве это не действительно нелепый способ объявления строкового литерала?
Тамогна Чоудхури

@ ТамогнаChowdhury Вроде. Строковые литералы не доступны для записи. Это массив, который затем инициализируется строковым литералом "A". Поскольку «A» устанавливает только первые два байта, остаток инициализируется в соответствии с правилами для объектов статической длительности (в данном случае 0). [C99 6.7.8 / 22]
Рэй

1
Вы можете сэкономить 22 байта, изменив список инициализации на "AC"и заменив все с r[1]=67на r[2]=69;наr[2]=c2?68:69;
Рэй

4

C, 41 байт

Я не уверен, требует ли вопрос программы, функции или фрагмента кода.
Вот функция:

f(a,b){a=a?16961:4473665|b<<16;puts(&a);}

Он получает входные данные в виде двух параметров, которые должны быть 0 или 1 (ну, bобязательно), и печатает в стандартный вывод.

Наборы aк одному из 0x4241, 0x454341или 0x444341. При печати в виде строки в системе ASCII с прямым порядком байтов выдает требуемый вывод.


4

R , 41 39 37 байт

pryr::f(c("ACD","ACE","AB")[1+a+a^b])

Попробуйте онлайн!

В R, TRUEи FALSEпринуждают к 1и , 0соответственно , при попытке использовать их как числа. Мы можем преобразовать эти числа индексов 1, 2и 3по формуле 1+a+a^b.

  a  |   b  | 1+a+a^b
TRUE | TRUE | 1+1+1^1 = 3
TRUE | FALSE| 1+1+1^0 = 3
FALSE| TRUE | 1+0+0^1 = 1
FALSE| FALSE| 1+0+0^0 = 2

Эти значения затем используются для индекса списка ACD, ACE, ABчтобы дать правильный вывод.

Сохранено два байта благодаря JayCe.

Если вместо этого вы предпочитаете версию с ifоператором, для 41 байта есть следующее:

pryr::f(`if`(a,"AB",`if`(b,"ACD","ACE")))

Попробуйте онлайн!



@JayCe Спасибо, я обновил ответ!
rturnbull


3

Сетчатка, 22 байта

1.+
AB
.+1
ACD
.+0
ACE

Попробуйте онлайн


1
retina.tryitonline.net/… . Добавьте префикс ^с m`, чтобы он работал для многострочного ввода, что не является обязательным для вопроса, но облегчает тестирование.
Цифровая травма

Я думаю, что вы можете сэкономить 3 байта, удалив пространство между двумя входами.
CalculatorFeline

3

JavaScript, 38 байт

Используйте без разделителя 0или 1вместо false/true

_=>"ACE ACD AB AB".split` `[+('0b'+_)]

1
Вы можете использовать split` ` вместоsplit(" ")
andlrc

Вы также можете использовать +('0b'+prompt())вместоparseInt(prompt(),2)
andlrc


3

ArnoldC , 423 байта

IT'S SHOWTIME
HEY CHRISTMAS TREE a
YOU SET US UP 0
HEY CHRISTMAS TREE b
YOU SET US UP 0
BECAUSE I'M GOING TO SAY PLEASE a
BECAUSE I'M GOING TO SAY PLEASE b
TALK TO THE HAND "ABD"
BULLSHIT
TALK TO THE HAND "ABE"
YOU HAVE NO RESPECT FOR LOGIC
BULLSHIT
BECAUSE I'M GOING TO SAY PLEASE b
TALK TO THE HAND "ACD"
BULLSHIT
TALK TO THE HAND "ACE"
YOU HAVE NO RESPECT FOR LOGIC
YOU HAVE NO RESPECT FOR LOGIC
YOU HAVE BEEN TERMINATED

Поскольку ArnoldC, кажется, не имеет формального ввода, просто измените первые 2 YOU SET US UPзначения на 0 или 1.

объяснение

Это всего лишь куча условных операторов, которые учитывают все возможные результаты. Почему, спросите вы? Ну, у ArnoldC на самом деле нет понимания строк. Он даже не может объединять строки! В результате мы вынуждены прибегнуть к более ... неэффективному ... методу.


Э-э, вывод должен быть "AB", если a истинно, а не "ABD" / "ABE". Это должно сделать ваш код короче!
Тоби Спейт

3

Java, 28 байт

Тот же самый шаблон, как много ответов. Тип есть BiFunction<Boolean,Boolean, String>.

(c,d)->c?"AB":d?"ACD":"ACE"

Я знаю, что это было почти два года, но (c,d)->может быть в гольфе на 1 байт, c->d->когда вы используете java.util.function.Function<Boolean, java.util.function.Function<Boolean, String>>.
Кевин Круйссен

2

Pyth, 21 байт

@c"ACE ACD AB AB"diz2

Попробуй это здесь!

Ввод принимается как 0 или 1 вместо true / false, пока C1 идет первым.

объяснение

Просто используя тот факт, что есть только 4 возможных результата. Работает, интерпретируя входные данные как двоичные, преобразовывая их в базу 10 и используя это для выбора правильного результата из строки поиска.

@c "ACE ACD AB AB" diz2 # z = вход

                  iz2 # Преобразование двоичного ввода в базу 10
 c "ACE ACD AB AB" d # Расщепленная строка в пробелах
@ # Получить элемент по индексу

2

Y , 20 байтов

В случае, если первый вход один, берется только один вход. Я предполагаю, что такое поведение разрешено. Попробуй это здесь!

'B'AjhMr$'C'E@j-#rCp

Ungolfed:

'B'A jh M
   r$ 'C 'E@ j - # r
 C p

Разъяснение:

'B'A

Это толкает символы Bзатем Aв стек.

jh M

Это берет один вход, увеличивает его, выталкивает и перемещает на это количество секций.

Случай 1: j1 = 0. Это более интересный. r$переворачивает стек и выводит значение, 'C'Eтолкает символы Cи E. @преобразует Eв числовой аналог, вычитает из него второй вход и преобразовывает его в символ. rне переворачивает стек. Затем программа видит C-ссылку и переходит к следующей ссылке pи печатает стек.

Случай 2: программа переходит к последней ссылке p, которая просто печатает весь стек.


2

PowerShell, 40 байт

param($x,$y)(("ACE","ACD")[$y],"AB")[$x]

Вложенные массивы индексируются вводом. В PowerShell $true/ 1и $false/ 0практически эквивалентны (благодаря очень свободному приведению типов), так что они хорошо индексируются в двухэлементный массив. Это действительно так близко к троице, как PowerShell, и я много раз использовал его в гольфе.

Примеры

PS C:\Tools\Scripts\golfing> .\do-while-false.ps1 1 1
AB

PS C:\Tools\Scripts\golfing> .\do-while-false.ps1 1 0
AB

PS C:\Tools\Scripts\golfing> .\do-while-false.ps1 0 1
ACD

PS C:\Tools\Scripts\golfing> .\do-while-false.ps1 0 0
ACE


2

Витси , 26 байт

Ожидает входные данные как 1 с или 0 через STDIN с разделителем новой строки.

W([1m;]'DCA'W(Zr1+rZ
'BA'Z

Я действительно обнаружил серьезную проблему с утверждениями if во время этого вызова. D: Это опубликовано с неработающей версией, но работает просто отлично. (Я обновлю это после того, как исправлю проблему) Обратите внимание, что я обновил Vitsy с исправлением if / ifnot. Это изменение не дает мне никакого преимущества, только разъяснение.

Объяснение:

W([1m;]'DCA'W(Zr1+rZ
W                      Get one line from STDIN (evaluate it, if possible)
 ([1m;]                If not zero, go to the first index of lines of code (next line)
                       and then end execution.
       'DCA'           Push character literals "ACD" to the stack.
            W          Get another (the second) line from STDIN.
             (         If not zero, 
do the next instruction.
              Z        Output all of the stack.
               r1+r    Reverse the stack, add one (will error out on input 0, 1), reverse.
                   Z   Output everything in the stack.

'BA'Z
'BA'                   Push character literals "AB" to the stack.
    Z                  Output everything in the stack.

Попробуйте онлайн!


2

пчелиный воск , 26 байт

Интерпретация 0как ложь, 1как правда.

E`<
D`d"`C`~<
_T~T~`A`"b`B

Выход:

julia> beeswax("codegolfdowhile.bswx",0,0.0,Int(20000))
i1
i1
AB
Program finished!

julia> beeswax("codegolfdowhile.bswx",0,0.0,Int(20000))
i1
i0
AB
Program finished!

julia> beeswax("codegolfdowhile.bswx",0,0.0,Int(20000))
i0
i1
ACD
Program finished!

julia> beeswax("codegolfdowhile.bswx",0,0.0,Int(20000))
i0
i0
ACE
Program finished!

Клонируйте моего переводчика пчелиного воска из моего хранилища Github .


Я уверен, что вам не нужны цитаты.
подземный

@undergroundmonorail: Хорошо, я обновлю свое решение. Благодарю.
ML

2

C, 47 45 байтов

Так как есть только 3 различных результата, мы можем выбрать одну из трех строк следующим образом:

char*f(c,d){return"AB\0 ACE\0ACD"+(!c<<d+2);}

Спасибо Herman L за 2 байта

демонстрация

#include<stdio.h>
int main()
{
    printf("%s\n%s\n%s\n%s\n",
           f(1,1),
           f(1,0),
           f(0,1),
           f(0,0));
}

1
-2 байта:char*f(c,d){return"AB\0 ACE\0ACD"+(!c<<d+2);}
Герман Л

ссылка на TIO PLS
только ASCII

1

Perl, 23 байта

say<>>0?AB:<>>0?ACD:ACE

Требуется -E| -M5.010помечает и принимает ввод как 1 и 0:

$ perl -E'say<>>0?AB:<>>0?ACD:ACE' <<< $'0\n0'
ACE
$ perl -E'say<>>0?AB:<>>0?ACD:ACE' <<< $'0\n1'
ACD
$ perl -E'say<>>0?AB:<>>0?ACD:ACE' <<< $'1\n0'
AB

Альтернативное решение, которое требует -pи составляет 22 + 1 = 23 байта:

$_=/^1/?AB:/1/?ACD:ACE
perl -pe'$_=/^1/?AB:/1/?ACD:ACE' <<< '0 1'

say-<>?AB:-<>?ACD:ACEна два байта короче.
nwellnhof

1

05AB1E , 23 20 байт

Код:

Ii"AB"?q}"AC"?69I-ç?

Попробуйте онлайн!


1
Вероятно, это древняя версия 05AB1E, но теперь она может занимать 14 байт: i„ABë„AC69I-çJ попробуйте ее в Интернете или проверьте все контрольные примеры .
Кевин Круйссен

1
@KevinCruijssen Отлично! Это действительно древняя версия 05AB1E. Языку здесь было около трех месяцев (у него даже не было неявного ввода).
Аднан

1
Да, я действительно уже запутался в руководстве I. ; p
Кевин Круйссен

1

Japt, 19 байт

"A{U?'B:'C+(V?'D:'E

Проверьте это онлайн!

Интересный факт: это было бы 16 байтов, если бы не ошибка:

"A{U?"B:C{V?"D:E

Ошибки самые худшие: |
Конор О'Брайен

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Давай посмотрим, смогу ли я найти более старую версию, в которой не было этой ошибки. Тогда 16 байтов будут законными.
ETHproductions

1
В чем ошибка?
CalculatorFeline

@CalculatorFeline Я думаю, что подобные вложенные строки по какой-то причине не переносятся.
ETHпродукция
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.