47
\$\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\$
  • \$\begingroup\$ Does the output have to be uppercase, or is lowercase also permitted? \$\endgroup\$ – Adnan Feb 18 '16 at 19:56
  • 7
    \$\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 '16 at 7:18
  • 3
    \$\begingroup\$ I didn't know this was an idiom in C... \$\endgroup\$ – Mehrdad Feb 21 '16 at 10:45
  • 5
    \$\begingroup\$ @Mehrdad some folks do this instead of goto because using goto is bad form :) \$\endgroup\$ – Seth Feb 21 '16 at 22:53
  • 2
    \$\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 '16 at 11:56

57 Answers 57

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\$
  • 1
    \$\begingroup\$ Those quotations... shivers \$\endgroup\$ – seequ Feb 19 '16 at 23:55
  • \$\begingroup\$ Oh my god, the quotes actually match? ... \$\endgroup\$ – cat Feb 20 '16 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\$
  • \$\begingroup\$ Feature-request: These mentions actual should show up in my inbox >-< \$\endgroup\$ – Conor O'Brien Feb 19 '16 at 17:41
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ I know, right? \$\endgroup\$ – cat Feb 19 '16 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\$

Jelly, 14 bytes

Ḥoị“ACD“AB“ACE

This expects the Booleans (1 or 0) as separate command-line arguments. Try it online!

How it works

Ḥoị“ACD“AB“ACE  Main link. Left input: C1. Right input: C2.

Ḥ               Double C1. Yields 2 or 0.
 o              Logical OR with C2.
                2o1 and 2o0 yield 2. 0o1 and 0o0 yield 1 and 0, resp.
   “ACD“AB“ACE  Yield ['ACD', 'AB', 'ACE'].
  ị             Retrieve the string at the corresponding index.
\$\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\$
  • 2
    \$\begingroup\$ This might be the most ASCII I've seen in an ESMin program \$\endgroup\$ – Downgoat Feb 23 '16 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\$
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\$
  • \$\begingroup\$ @Cᴏɴᴏʀ O'Bʀɪᴇɴ here's your ping c: \$\endgroup\$ – cat Mar 23 '16 at 2:58
  • 1
    \$\begingroup\$ 25 \$\endgroup\$ – ASCII-only Aug 9 '18 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\$
  • \$\begingroup\$ I miss my ternary operator :( \$\endgroup\$ – cat Mar 23 '16 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\$
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\$
  • 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 '16 at 18:51
  • \$\begingroup\$ Try decrementing the inputs. Then you can nullterminate correctly. \$\endgroup\$ – CalculatorFeline Mar 22 '16 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\$
  • \$\begingroup\$ Instead of negating, you could just change the + to a -. This doesn't actually save any bytes though \$\endgroup\$ – Jo King Aug 9 '18 at 13:31
  • \$\begingroup\$ @JoKing i don't know how I didn't notice that \$\endgroup\$ – Adyrem Aug 9 '18 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\$
  • \$\begingroup\$ Why does the "heat death of the universe" take until the heat death of the universe? \$\endgroup\$ – CalculatorFeline Mar 22 '16 at 15:16
  • \$\begingroup\$ @CatsAreFluffy Because the Brainbash interpreter does not optimize the code. \$\endgroup\$ – Conor O'Brien Mar 22 '16 at 16:51
  • \$\begingroup\$ How does the "heat death of the universe" code work, anyway? \$\endgroup\$ – CalculatorFeline Mar 22 '16 at 18:31
  • \$\begingroup\$ @CatsAreFluffy it uses one of the constant generators found on esolangs wiki page "brainfuck constants" \$\endgroup\$ – Conor O'Brien Mar 22 '16 at 18:38
  • \$\begingroup\$ The 15-long one doesn't work either? How sad. \$\endgroup\$ – CalculatorFeline Mar 22 '16 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
    \$\begingroup\$ Try +`0b${x}${y}` instead of parseInt \$\endgroup\$ – Not that Charles Mar 22 '16 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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