50
\$\begingroup\$

Do While False

At work today one of my colleagues was describing the use-case for do while(false). The person he was talking to thought that this was silly and that simple if statements would be much better. We then proceeded to waste half of our day discussing the best manner to write something equivalent to:

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

This is an idiom which is found in c quite often. Your program should produce the same output as the below pseudo-code depending on the conditions.

do
{
   result += "A";

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

   result += "C"

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

   result += "E";

}
while(false);

print(result);

Therefore the input could be:

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

and the output should be:

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

This is code-golf so answers will be judged on bytes. Standard loopholes are banned.

Yes this is a simple one, but hopefully we will see some creative answers, I'm hoping the simplicity will encourage people to use languages they are less confident with.

\$\endgroup\$
9
  • \$\begingroup\$ Does the output have to be uppercase, or is lowercase also permitted? \$\endgroup\$
    – Adnan
    Feb 18, 2016 at 19:56
  • 8
    \$\begingroup\$ As an aside for the debate with your coworker, it seems to me you could accomplish the same thing using a method with return result in place of break. Then you get the bonuses of re-usability and simplifying the calling code, too. But perhaps I'm missing something. \$\endgroup\$
    – jpmc26
    Feb 21, 2016 at 7:18
  • 3
    \$\begingroup\$ I didn't know this was an idiom in C... \$\endgroup\$
    – user541686
    Feb 21, 2016 at 10:45
  • 5
    \$\begingroup\$ @Mehrdad some folks do this instead of goto because using goto is bad form :) \$\endgroup\$
    – Seth
    Feb 21, 2016 at 22:53
  • 3
    \$\begingroup\$ The only time I have ever used do{}while(false) is inside macros. A simple if does not suffice, because it interacts badly with elses around that may be present. Without a macro you may as well remove the do and while. \$\endgroup\$
    – nwp
    Feb 22, 2016 at 11:56

57 Answers 57

1
2
1
\$\begingroup\$

Japt, 19 bytes

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

Test it online!

Fun fact: This would be 16 bytes if it weren't for a bug:

"A{U?"B:C{V?"D:E
\$\endgroup\$
4
  • \$\begingroup\$ Bugs are the worst :| \$\endgroup\$ Feb 18, 2016 at 20:01
  • 2
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Lemme see if I can dig out an older version that didn't have this bug. Then the 16 bytes would be legit. \$\endgroup\$ Feb 18, 2016 at 20:02
  • 1
    \$\begingroup\$ What's the bug? \$\endgroup\$ Mar 22, 2016 at 15:13
  • \$\begingroup\$ @CalculatorFeline I believe nested strings like that don't transpile for some reason. \$\endgroup\$ Sep 7, 2016 at 2:24
1
\$\begingroup\$

Kotlin, 50 bytes

It is interesting what one can do with string templates.

{a,b->"A${if(a)"B" else "C${if(b)"D" else "E"}"}"}

Try Here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Those quotations... shivers \$\endgroup\$
    – seequ
    Feb 19, 2016 at 23:55
  • \$\begingroup\$ Oh my god, the quotes actually match? ... \$\endgroup\$
    – cat
    Feb 20, 2016 at 10:48
1
\$\begingroup\$

Mouse-2002, 23 bytes

??"A"["B"|"C"["D"|"E"]]

Switches on two inputs, which each should be either 0 for false or anything else for true.

Ungolfed, as a function:

#Y,?,?;

$Y 1% a: 2% b:
  "A"
  a [
    "B"
  |
    "C"
    b [
      "D"
    |
      "E"
    ]
  ]
$

Brackets just test if the top of the stack is true, and | is else.

This is a translation of @Cᴏɴᴏʀ O'Bʀɪᴇɴ's ES6 answer.

\$\endgroup\$
2
  • \$\begingroup\$ Feature-request: These mentions actual should show up in my inbox >-< \$\endgroup\$ Feb 19, 2016 at 17:41
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ I know, right? \$\endgroup\$
    – cat
    Feb 19, 2016 at 17:47
1
\$\begingroup\$

PHP 4.1, 19 bytes

I was expecting it to be harder, but well. It was really fun!

<?=A,$A?B:C.($B^t);

This expects 2 parameters/values, passed as strings over POST/GET/SESSION/COOKIE... The key A will have the first value, the key B will have the 2nd.
The result will be sent to STDOUT.

\$\endgroup\$
1
\$\begingroup\$

DUP, 29 bytes

['A,^['B,]['C,$['D,]['E,]?]?]

Try it here!

Anonymous lambda. Usage:

1 0['A,^['B,]['C,$['D,]['E,]?]?]!

Explanation

[                           ] {lambda}
 'A,                          {output A}
    ^                         {check if arg1 is truthy}
     [   ][               ]?  {conditional}
      'B,                     {if so, output B}
           'C,                {otherwise, output C...}
              $               {...and check if arg2 is truthy}
               [   ][   ]?    {conditional}
                'D,           {if so, output D}
                     'E,      {otherwise, output E}
\$\endgroup\$
1
\$\begingroup\$

><> (Fish), 30 bytes

"A"o$1+.
"<"DC"v"CE
o "B"|>oo;

This code uses the two variables (using the initial stack) to move the pointer to (C2, C1+1) You can try it here

\$\endgroup\$
1
\$\begingroup\$

Perl, 19 + 1 (-p switch) = 20 bytes

$ perl -pe '$_=l.$_^-su;s/B./B/'
00
ACE
01
ACD
10
AB
11
AB

Uses string XOR and a bareword with leading hyphen. Ungolfed:

$_ = ('l' . $_) ^ '-su';
s/B./B/;
\$\endgroup\$
1
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 18 chars / 23 bytes

`A⏜î?⍘B:`C⏜í?⍘D:⍘E

Try it here (Firefox only).

It's pretty much a fusion of conditional statements.

Note: basically takes all code up to an optional , interprets the code, and replaces that block in the code with the result. This is the first time I've used this in a submission, but it works quite well. Self-modifying code FTW!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ This might be the most ASCII I've seen in an ESMin program \$\endgroup\$
    – Downgoat
    Feb 23, 2016 at 21:57
1
\$\begingroup\$

QBIC, 39 34 bytes

EDIT: Found out that QBasic (and by extension QBIC) doesn't need an =1 to test if an input is true, so removed those.

_!_!~a_>?@AB._X]~b_>?@ACD._E?@ACE.

Original answer:

_!_!~a=1_>?@AB._X]~b=1_>?@ACD._X]?@ACE.

Takes two numerical inputs and tests these in straight-forward IF's. No fancy OR logic and array indexes here, unfortunately.

\$\endgroup\$
2
1
\$\begingroup\$

C, 42 bytes (long version); 31 (short version)

The existing submissions seem inconsistent with regards to whether the variables must be named C1 and C2, and whether actually printing the results is required, so I've done a long and short version.

This approach takes advantage of the fact that most of the possibilities for each index differ by only one bit.

Long version:

char s[4]={65,67-C1,69*!C1&69-C2};puts(s);

Short version:

char s[4]={65,67-a,69*!a&69-b};
\$\endgroup\$
1
\$\begingroup\$

ForceLang,124 bytes

def f io.readnum()
set w io.write
set g goto
w "A"
if f
g L
w "C"
if f
g M
w "E"
g N
label L
w "B"
g N
label M
w "D"
label N
\$\endgroup\$
1
\$\begingroup\$

D, 35 bytes

(int a,int b)=>a?"AB":"AC"+"ED"[b];

Hey, look, D has lambdas.

Hey, look, D is JavaScript, but longer. :^(

Copied verbatim from Conor's ES6 answer. c:

\$\endgroup\$
2
  • \$\begingroup\$ @Cᴏɴᴏʀ O'Bʀɪᴇɴ here's your ping c: \$\endgroup\$
    – cat
    Mar 23, 2016 at 2:58
  • 1
    \$\begingroup\$ 25 \$\endgroup\$
    – ASCII-only
    Aug 9, 2018 at 11:15
1
\$\begingroup\$

Go, 120 bytes

func w(b bool,d bool)(r string){
for i:=true;i;i=!i{
r+="A"
if b{r+="B"
break}
r+="C"
if d{r+="D"
break}
r+="E"}
return}

Go has only one loop structure, for, but you can simulate a do-while loop with for i := true; i; i = expr.

Edit: It also happens that Go's switch statement is flexible enough to replicate this.

switch {
case true:
    r += "A"
    if b {
        r += "B"
        break
    }
    r += "C"
    if d {
        r += "D"
        break
    }
    r += "E"
}
\$\endgroup\$
1
  • \$\begingroup\$ I miss my ternary operator :( \$\endgroup\$
    – cat
    Mar 23, 2016 at 2:02
1
\$\begingroup\$

FALSE, 16 bytes

$"A"'C+,~['E+,]?

Input values are on the stack (first C2 then C1), false is 0 and true is -1 (this is normal in FALSE)

\$\endgroup\$
0
1
\$\begingroup\$

SMBF, 39 bytes

Each _ represents a null literal \x00 and is used for readability. I've successfully tested it for all test cases. except the third, because I haven't found a way to test that input on my interpreter, since I'd need stdin to be \x00\x01. I know it works, though, because I used the exact same method for testing C2 as I did for testing C1.

<.<,[<]<<.[>]>[<<<]<<<<,[<]<<.DE__BC__A

Explanation:

<.          print A
<,          read C1
[<]         if true, move left one
<<.         move left 2 and print (C if false, B if true)
[>]>        move to C1
[<<<]       if true, our output is done, so move all the way left, so further code is NOP
<<<<,       move left 4 and read C2
[<]         if true, move left one
<<.         move left 2 and print (E if false, D if true)
DE_ BC_ A   data on the tape

I think this will do the same for the same byte count, reusing B and C by adding 2 to each:

<.<,[<]<<.[>]>[<<]<<++<++>>,[<]<<.BC__A
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Now I look at this and think "what was I doing, I could just increment A"... it might not be shorter, but I should've tried that first... \$\endgroup\$
    – mbomb007
    Feb 19, 2016 at 18:51
  • \$\begingroup\$ Try decrementing the inputs. Then you can nullterminate correctly. \$\endgroup\$ Mar 22, 2016 at 15:15
1
\$\begingroup\$

Hexagony, 28 26 25 bytes

A;?.));?~..>);@</E"+;@}/>

-2 bytes by moving up the printing of AB

-1 byte by incrementing to C instead

Try it online!

Expanded:

   A ; ? . 
  ) ) ; ? ~ 
 . . > . ; @ 
< / E " + ; @ 
 } / > . . . 
  . . . . . 
   . . . .


Uses the value of the second input to get the last char, removing the need for another costly branch:

"E" + (-1*C2)


Credit to @JoKing
Alternatively I could have also just subtracted the value which doesn't save any bytes though:

"E" - C2
\$\endgroup\$
2
  • \$\begingroup\$ Instead of negating, you could just change the + to a -. This doesn't actually save any bytes though \$\endgroup\$
    – Jo King
    Aug 9, 2018 at 13:31
  • \$\begingroup\$ @JoKing i don't know how I didn't notice that \$\endgroup\$
    – Adyrem
    Aug 9, 2018 at 13:32
0
\$\begingroup\$

CJam, 25 bytes

'Aq~[{'C\['E'D]=}{;'B}]=~

Try it online

Not the best way to do it, but it works.

\$\endgroup\$
0
\$\begingroup\$

Jolf, 16 bytes

+'A?j'B+'C."DE"J

Simple. Try this one here!

Aother one, using that other Pyth answer's approach:

11 characters, 18 UTF-8 bytes. You can try this one here.

~T."૎્««"Ιj
          ^-- that's a capital Iota, converting input to binary
\$\endgroup\$
0
\$\begingroup\$

Brainbash, 43 bytes

----[>+<----]>++.>#{<+.>}-{<++.+>#-{<+>}<.}

Brainbash is BF with two tapes and more stuff. We're only using one this time. Let's take a look:

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

This sets the first cell to A and outputs it.

>#

This move to the next cell and takes numeric input

{<+.>}

This is an if statement. If the numeric input is one, then we'll increment the previous cell and output it, outting B.

-

This transforms 1 to 0 (falsey) and 0 to 255. It's effectively a boolean NOT as far as the next if statement is concerned.

{<++.

If the current bit, output a C.

+>#

Change it do a D and take some input

-

"Negate it"

{<+>}

If it was a zero, output an increment and return to input cell.

<.}

Move to destination cell and out it.


I could use the "heat death of the universe" to save two bytes, using >+[+[<]>>+<+]>, but that didn't complete in the online interpreter, which can be found in the link in the header.

\$\endgroup\$
6
  • \$\begingroup\$ Why does the "heat death of the universe" take until the heat death of the universe? \$\endgroup\$ Mar 22, 2016 at 15:16
  • \$\begingroup\$ @CatsAreFluffy Because the Brainbash interpreter does not optimize the code. \$\endgroup\$ Mar 22, 2016 at 16:51
  • \$\begingroup\$ How does the "heat death of the universe" code work, anyway? \$\endgroup\$ Mar 22, 2016 at 18:31
  • \$\begingroup\$ @CatsAreFluffy it uses one of the constant generators found on esolangs wiki page "brainfuck constants" \$\endgroup\$ Mar 22, 2016 at 18:38
  • \$\begingroup\$ The 15-long one doesn't work either? How sad. \$\endgroup\$ Mar 22, 2016 at 18:42
0
\$\begingroup\$

MATLAB, 31 28 bytes

@(x,y)[65,67-x,~x*(69-y),'']

This anonymous function will match all the test cases. The first input is condition 1 and the second input is condition 2. The string will be returned.

The function also works with Octave. You can try it online here.

Simply create the anonymous function by running the command above, then call the function. Running this for example:

ans(0,1)

Will return:

ACD 
\$\endgroup\$
0
\$\begingroup\$

C, 54 bytes

Since the story started with a loop, I decided to stick to that. Not the shortest of solutions; but certainly one of the more obscure ones.

Function f takes two integer parameters as input (1 = true, 0 = false), and outputs AB, ACD or ACE to stdout.

f(a,b){for(int x=64;~putchar(++x)<<a&4;x+=x&2?!b:!a);}
\$\endgroup\$
0
\$\begingroup\$

Nustack, 27 bytes

a"AB"*"AC"b{"E"}{"D"}if + |

Thanks to Morgan Thrapp and her Python answer for giving me the inspiration for this one.

Explanation:

a"AB"* /* Repeat "AB" 0 or 1 times, depending on if a is #t or #f. The result ("" or "AB") is put on the stack */
"AC" /* Put "AC" on the stack */
b{"E"}{"D"}if /* If b is true, push "E", else push "D" */
+ /* Concatenate the top two strings on the stack, push the result ("ACE" or "ACD") */
| /* Right now the stack looks like (x y). If x is truthy (not empty), keep x, else keep y */
\$\endgroup\$
0
\$\begingroup\$

Javascript, 43 Bytes

A different (more intuitive?) way to do it in JS. The name parseInt is not inductive of Code Golfing :P

"A"+["CE","CD","B","B"][parseInt(x+""+y,2)]

Test:

var cases = ["00","01","10","11"];
    
for (i=0;i<4;i++) {
   var x = cases[i][0];
   var y = cases[i][1];
   document.write("A"+["CE","CD","B","B"][parseInt(x+""+y,2)]+"<br>")
}

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Try +`0b${x}${y}` instead of parseInt \$\endgroup\$ Mar 22, 2016 at 6:45
0
\$\begingroup\$

Ruby, 31 bytes

Anonymous function; assign to a variable to test its output.

->x,y{?A+(x ??B:?C+(y ??D:?E))}
\$\endgroup\$
0
\$\begingroup\$

SmileBASIC, 32 bytes

INPUT A,B?"A"+"CB"[A]+"ED"[B]*!A
\$\endgroup\$
0
\$\begingroup\$

C++, 57 52 bytes

[](auto c,auto&s){s="AC";c[0]?--s[1],s:s+='E'-c[1];}

First argument should be an indexable collection (vector, array, etc) of conditions, and second argument is the string to write to.

Assumes that the runtime character set has B and C contiguous, and D and E also contiguous (both are true for common codings such as ASCII and EBCDIC).

Demo

auto const f = [](auto c,auto&s){s="AC";c[0]?--s[1],s:s+='E'-c[1];};

#include<array>
#include<iostream>
#include<string>
int main()
{
    std::string s;

    for (bool c1: {true, false})
        for (bool c2: {true, false})
            f(std::array{c1, c2}, s),std::cout << s << '\n';
}
\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 54 bytes

I had orignally planned on using emit for this, but realized that direct string output was shorter (61 vs 54 bytes)

: f if ." AB" else if ." ACD" else ." ACE" then then ;

Try it online!

Explanation

If C1 is true, it prints AB, otherwise it prints ACD if C2 is true, and ACE if C2 is false

Code Explanation

: f                \ start a new word definition
   if              \ if c1 is true
      ." AB"       \ print "AB"
   else            \ if c1 is false
      if           \ if c2 is true
         ." ACD"   \ print "ACD"
      else         \ if c2 is false
         ." ACE"   \ print "ACE"
      then         \ end the inner if
   then            \ end the outer if
;                  \ end the word defintion
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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