「Do While False」イディオム


47

偽りながら

今日の仕事では、同僚の1人がdo while(false)のユースケースを説明していました。彼が話していた人は、これはばかげていて、単純なifステートメントがはるかに優れていると思っていました。その後、私たちは一日の半分を無駄にして、次のようなものを書くための最良の方法について話し合いました。

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
これがCのイディオムだとは知らなかった
...-Mehrdad

5
@Mehrdad一部の人々は、代わりにgoto使用するのgotoが悪いのでこれを行います:)
セス

2
私が今まで使ったのdo{}while(false)はマクロ内だけです。単純なifものでは十分ではありませんelse。存在する可能性のあるs と相互作用するためです。マクロがなければ、doand も削除できますwhile
NWP

回答:


19

Python 3、31

xnorのおかげで1バイト節約されました。

ES6から1バイトだけ離れています。:/愚かな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ʀɪᴇɴ私は何かがPythonを抑制しなければならないことを知っていました。PEPをできるだけ早く提出します。
モーガンスラップ


9
λ同義語を作成するPEP lambdaは素晴らしいでしょう:)
ロバートグラント

13

JavaScriptのES6、30の 26 25バイト

2つの入力を取る単純な匿名関数。呼び出す変数に割り当てます。 更新:インデックスの時流に飛びましょう。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アトキン

@JAtkin本当に!
コナーオブライエン



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
]

この解決策、実際にはwhileループから抜け出すことに基づいていることに注意する価値があると思います。



7

NTFJ、110バイト

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

より読みやすい:

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

それは確かに楽しかったです。入力として2文字(または)を使用してここ試してみてください01

ETHProductionのメソッドを使用して0、1(文字)をビットに変換すると、これがより簡単になります。

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

これが上記の方法です。193(##~~~~~#@)を押して、それを|トップ入力値(この場合、最初の文字コード、48または49)でNANDします()。これにより、1の場合は254、0の場合は255が########@得られます。255()でNANDすると、入力に応じて0または1ビットが得られます。

~#~~~~~#@*

Aすべての入力がで始まるため、これはを出力しAます。印刷時にを*ポップするAため、スタックは以前の状態から変更されません。

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

ケース1:最初のビットはで1(内部のコードをアクティブにします。~#~~~~#~@*を出力しB########@^255 をプッシュして、コード内のその位置にジャンプします。これでプログラムは終了し、終了します。

ケース2:最初のビットは0です。(にスキップし)、コードを続行します。

~#~~~~##@*

C次の文字であるため、これはを出力します。

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

これにより、2番目の入力がビットに変換されます。

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

2番目のビットが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.

2つの連続した行に入力します。


3
ああ、ピスマスター、このプログラムの方法を私たちに知らせてください。;)
コナーオブライエン

5

CJam、15 16 17バイト

'Ali'B'C'Eli-+?

オンラインでお試しください!

@randomraのおかげで1バイトオフ、@ Dennisのおかげで1バイトオフ

説明:

'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バイト(UTF-8では3バイト)および«1バイト(UTF-8では2バイト)としてカウントします。両方wcと、これは 19バイトであることに同意します。
デニス

4

C、76バイト

私は名前を変更c1するcc2Cして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:

非ゴルフ

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

それは文字列リテラルを宣言する本当にばかげた方法ではありませんか?
タモグナチョードリー

@TamoghnaChowdhuryの並べ替え。文字列リテラルは書き込み可能ではありません。これは、文字列リテラル「A」で初期化される配列です。「A」は最初の2バイトのみを設定するため、残りは静的期間のオブジェクトのルール(この場合は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);}

2つのパラメーターで入力を取得します。パラメーターは0または1(まあ、bmust)でなければならず、stdoutに出力します。

セットaのいずれかに0x42410x454341または0x444341。文字列として印刷される場合、リトルエンディアンASCIIシステムでは、必要な出力が得られます。


4

R41 39 37バイト

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

オンラインでお試しください!

RではTRUE、数値として使用しようとするとそれぞれFALSE強制され1、強制さ0れます。私たちは、インデックスにこれらの数字を変換することができ12および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

これらの値は、インデックスにリストを使用しているACDACEAB正しい出力を生成します。

JayCeのおかげで2バイト節約されました。

代わりに、ifステートメントを含むバージョンを好む場合、41バイトには次のようになります。

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

オンラインでお試しください!



@JayCeありがとう、答えを更新しました!
rturnbull

3

Mathematica、35 30バイト

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

とても簡単です。匿名関数。



3

JavaScript、38バイト

区切り文字なし0または/の1代わりに使用しますfalsetrue

_=>"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には正式な入力がないように見えるため、YOU SET US UP代わりに最初の2つの値を0または1に変更してください。

説明

これは、可能なすべての出力を説明する条件文の集まりです。なぜ、あなたは尋ねるかもしれませんか?まあ、ArnoldCには実際には文字列の理解がありません。文字列を連結することさえできません!その結果、もっと...効率の悪い...メソッドに頼らなければなりません。


Er、aがtrueの場合、「ABD」/「ABE」ではなく「AB」になります。これにより、コードが短くなります!
トビー・スペイト

3

Java、28バイト

多くの答えと同じ定型句。タイプはBiFunction<Boolean,Boolean, String>です。

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

私はそれがほぼ2年だった(c,d)->ことを知っていますがc->d->、を使用するときまで1バイトでゴルフすることができますjava.util.function.Function<Boolean, java.util.function.Function<Boolean, String>>
ケビンクルーイッセン

2

Pyth、21バイト

@c"ACE ACD AB AB"diz2

ここで試してみてください!

C1が最初に来る間、入力はtrue / falseではなく0または1として取得されます。

説明

結果が4つしかないという事実を使用します。入力をバイナリとして解釈し、ベース10に変換し、これを使用してルックアップ文字列から正しい結果を選択することにより機能します。

@c "ACE ACD AB AB" diz2#z =入力

                  iz2#バイナリ入力を基数10に変換
 c "ACE ACD AB AB" d#スペースで文字列を分割
@#インデックスの要素を取得

2

Y、20バイト

最初の入力が1つの場合、1つの入力のみが取得されます。この動作は許可されていると思います。ここで試してみてください!

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

ゴルフをしていない:

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

説明:

'B'A

これは、文字をプッシュしB、その後Aスタックに。

jh M

これは、1つの入力を受け取り、それをインクリメントし、ポップし、その数のセクションに移動します。

ケース1: j1 = 0。これはもっと面白いものです。r$スタックを反転し、値をポップし、'C'E文字CとをプッシュしEます。対応する数値に@変換Eし、2番目の入力を減算して、文字に再変換します。rスタックを元に戻します。次に、プログラムはCリンクを確認して次のリンクに移動しp、スタックを出力します。

ケース2:プログラムは最後のリンクに移動しますがp、これは単にスタック全体を印刷します。


2

PowerShell、40バイト

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

入力によってインデックス付けされた入れ子配列。PowerShellでは、$true/ 1$false/ 0は実質的に同等です(非常に緩やかな型キャストのおかげです)。そのため、2要素配列にうまくインデックス付けされます。これは、PowerShellが取得する3項に非常に近いものであり、ゴルフで何度も使用しています。

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

Vitsy、26バイト

改行で区切られたSTDINを介して1または0として入力を期待します。

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

実際、このチャレンジ中にifステートメントに重大な問題を発見しました。D:これは壊れたバージョンで投稿されていますが、問題なく動作します。(問題を修正した後、これを更新します)if / ifnotの修正でVitsyを更新したことに注意してください。この変更は利点を与えるものではなく、明確化するだけです。

説明:

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バイト

0false、1true として解釈します。

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つしかないため、次のような3つの文字列のいずれかを選択できます。

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

2バイトのHerman Lに感謝

デモ

#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);}
ハーマンL

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

-p22 + 1 = 23バイトを必要とする代替ソリューション:

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

say-<>?AB:-<>?ACD:ACE 2バイト短くなります。
-nwellnhof

1

05AB1E23 20バイト

コード:

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

オンラインでお試しください!


1
これはおそらく05AB1Eの古代のバージョンであるが、それは今14バイトになりますi„ABë„AC69I-çJ オンラインそれを試してみたり、すべてのテストケースを確認してください
ケビンCruijssen

1
@KevinCruijssenいいね!これは確かに05AB1Eの古代バージョンです。この言語はここで約3か月前のものでした(暗黙の入力すらありませんでした)。
アドナン

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ʀɪᴇɴLemmeは、このバグのない古いバージョンを掘り下げることができるかどうかを確認します。その場合、16バイトが正当です。
ETHproductions

1
バグは何ですか?
電卓

@CalculatorFelineそのようなネストされた文字列は、何らかの理由でトランスパイルしないと信じています。
ETHproductions
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.