Ідіома "Робити помилкову"


47

Робіть у той час як помилковим

Сьогодні на роботі один з моїх колег описував приклад використання для доки (помилково). Людина, з якою він розмовляв, думав, що це дурне і просте, якщо твердження будуть набагато кращими. Тоді ми переходили витрачати половину дня, обговорюючи найкращий спосіб написати щось еквівалентне:

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не достатньо, оскільки він погано взаємодіє з elses навколо, що може бути присутнім. Без макросу ви також можете видалити doі while.
nwp

Відповіді:


19

Пітон 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
Вибачте, вашим довгим анонімним синтаксисом функції стане смерть пітона: P
Conor O'Brien

5
@ CᴏɴᴏʀO'Bʀɪᴇɴ Я знав, що щось повинно стримувати Python. Я надішлю як можна швидше PEP.
Морган Трапп


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 Це гольф-код, а не популярність. Крім того, навіщо байти сміття розумні, якщо є більш стисле рішення?
Conor O'Brien

Мені подобається твій вибір носа:b?
J Atkin,

@JAtkin Дійсно!
Conor O'Brien

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

Гольф:

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

Безголівки:

                                      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 його ( |) з верхнім вхідним значенням (у цьому випадку перший char код, 48 або 49). Це дає 254 для 1 і 255 для 0. NANDing з 255 ( ########@) дає 0 або 1 біт відповідно до вхідних даних.

~#~~~~~#@*

Це друкує A, оскільки все введення починається з A. *виводиться під Aчас друку, тому стек не змінюється від попереднього стану.

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

Випадок 1: перший біт є 1і (активує код всередині. ~#~~~~#~@*друкує Bта ########@^натискає 255 і переходить на цю позицію в коді. Це, як кінець програми, закінчується.

Випадок 2: перший біт є 0. (пропускає до )і код продовжується.

~#~~~~##@*

Це друкує а C, тому що це наступний символ.

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

Це перетворює наш другий вхід на трохи.

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

Якщо наш другий біт дорівнює 1, переходимо до друку анкети E.

:~||

Це NAND уявлення булева заперечення нашого біта: A NAND (0 NAND A) = NOT A.

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

Це тепер активується, якщо біт був 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
О пітмейстере, розкажіть нам про способи цієї програми. ;)
Conor O'Brien

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
Наші добрі друзі Алі та Елі!
Conor O'Brien

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. Якщо у вас колись виникає проблема з абсурдним синтаксисом на С, це, швидше за все, тому, що ви цього не використовували 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:

Безумовно

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

Хіба це не дуже смішний спосіб декларування String буквалом?
Tamoghna Chowdhury

@TamoghnaChowdhury Сорт. Строкові літерали не підлягають запису. Це масив, який потім ініціалізується літеральним рядком "A". Оскільки "A" встановлює лише перші два байти, решта ініціалізується за правилами для об'єктів статичної тривалості (так 0 у цьому випадку). [C99 6.7.8 / 22]
Промінь

1
Ви можете заощадити 22 байт, змінюючи список ініціалізації "AC"і замінити все від r[1]=67до r[2]=69;зr[2]=c2?68:69;
Ray

4

C, 41 байт

Я не впевнений, чи потребує питання програма, функція або фрагмент коду.
Ось функція:

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

Він отримує вхід у двох параметрах, який повинен бути 0 або 1 (ну, bобов'язково), і друкує до stdout.

Набори 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

Математика, 35 30 байт

If[#,"AB",If[#2,"ACD","ACE"]]&

Дуже просто. Анонімна функція.


3

Сітківка, 22 байти

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

Спробуйте в Інтернеті


1
retina.tryitonline.net / ... . Префікс ^з m`, щоб він працював для багаторядкового введення, що не потрібно для питання, але полегшує тестування.
Digital Trauma

Я думаю, ви можете зберегти 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 насправді не має чіткого розуміння. Він навіть не може об'єднати рядки! Як результат, ми повинні вдатися до більш ... неефективного ... методу.


Er, вихід повинен бути "AB", якщо a є правдою, а не "ABD" / "ABE". Це повинно скоротити ваш код!
Toby Speight

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

Безголівки:

'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відміняє стек. Потім програма бачить С-посилання і переходить до наступного посилання pта друкує стек.

Випадок 2: програма переходить до останнього посилання p, яке просто виводить весь стек.


2

PowerShell, 40 байт

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

Вкладені масиви, індексовані введенням. У PowerShell $true/ 1та $false/ 0практично еквівалентні (завдяки дуже розпущеному типуcasting), так що вони добре індексуються у двоелементний масив. Це насправді наближається до потрійного, як отримує 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 байт

Очікує введення як 1s або 0s через STDIN з розділенням нового рядка.

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

Я фактично виявив серйозну проблему, якщо заяви під час цього виклику. Д: Це розміщено зі зламаною версією, але це працює просто чудово. (Я оновлю це після усунення проблеми) Зауважте, що я оновив 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

Клопи найгірші: |
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Lemme подивіться, чи можу я викопати старішу версію, в якій не було цієї помилки. Тоді 16 байт було б законним.
ETHproductions

1
Що за помилка?
CalculatorFeline

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