はじめに
なんだかズンドコキヨシてのがあるみたいで。
Delphi で書かれたものもあるのですが、
僕なりに書いてみたいと思います 1。
コード
こんな感じ。Delphi 10.4 Sydney で書いたコンソールアプリケーションです。
{$APPTYPE CONSOLE}
const
a: array [0..1] of string = ('ズン', 'ドコ');
begin
Randomize;
var l := MaxInt;
repeat
var v := Random(2);
Write(a[v]);
l := (l shl 1) or v;
until (l and $1F) = $01;
Writeln('キ・ヨ・シ!');
end.
ちょっと短く書くとこう。
{$APPTYPE CONSOLE}
const
a: array [0..1] of string = ('ズン', 'ドコ');
begin
Randomize;
var l := MaxInt;
repeat
l := (l shl 1) or Random(2);
Write(a[l and 1]);
until (l and $1F) = $01;
Writeln('キ・ヨ・シ!');
end.
説明
特に難しい事はやっていません。
- 変数
l
を MAXINT で初期化。0xFFFFFFFF (0b11111111111111111111111111111111) になっている。 - 変数
l
を左シフトしてズンドコの結果 (ランダム) を最下位ビットに格納。 - 最下位ビットを見て
ズン (0)
,ドコ (1)
を表示。 - 変数
l
と 0x1F (0b11111) の and (5 ワード分) を取って、結果が0x01 (0b00001 = ズン(0)ズン(0)ズン(0)ズン(0)ドコ(1))
ならループを抜ける。 -
キ・ヨ・シ!
を表示してプログラム終了。
もうひとつ
System.Types
を uses してもいいのなら、次のような記述も可能です。
{$APPTYPE CONSOLE}
uses
System.Types;
begin
Randomize;
var l := MaxInt;
repeat
l := (l shl 1) or Random(2);
Write(TStringDynArray.Create('ズン', 'ドコ')[l and 1]);
until (l and $1F) = $01;
Writeln('キ・ヨ・シ!');
end.
さらにもうひとつ
System.SysUtils
を uses してもいいのなら、次のような記述も可能です。
{$APPTYPE CONSOLE}
uses
System.SysUtils;
begin
Randomize;
var l := MaxInt;
repeat
l := (l shl 1) or Random(2);
Write('ズン,ドコ'.Split([','])[l and 1]);
until (l and $1F) = $01;
Writeln('キ・ヨ・シ!');
end.
一行だと 160 文字にできます。
uses SysUtils;begin Randomize;var l:=MaxInt;repeat l:=(l shl 1)or Random(2);Write('ズン,ドコ'.Split([','])[l and 1]);until(l and 31)=1;Write('キ・ヨ・シ!')end.
さらにさらにもうひとつ
動的配列をインライン変数宣言する記述も可能です。
{$APPTYPE CONSOLE}
begin
Randomize;
var a := ['ズン', 'ドコ'];
var l := MaxInt;
repeat
l := (l shl 1) or Random(2);
Write(a[l and 1]);
until (l and $1F) = $01;
Writeln('キ・ヨ・シ!');
end.
上記コードを
- 改行を含めた不要なホワイトスペースを抜く
- 16進値は短くなるのであれば 10進値に変更
- 演算子の優先順位により不要な
()
を除去 - end. 前のセミコロンを抜く
あれやこれやで一行にし、
-
{$APPTYPE CONSOLE}
を抜く -
Writeln()
をWrite()
にする - (
Randomize()
を抜く)
様々なインチキを施せば、
begin Randomize;var l:=1;var a:=['ズン','ドコ'];repeat l:=l shl 1 or Random(2);Write(a[l and 1]);until l and 31=1;Write('キ・ヨ・シ!')end.
140 文字で納まるようです (Randomize を抜いて 130 文字)。僕が単独で思いついた短いコードはここまでです。
See also:
短いコードの変遷
パクりパクられ...いえいえ、インスパイアの歴史です (w
作者 | 長さ 2 | 説明 |
---|---|---|
@pik | 167 | 初版 |
@ht_deko | 160 | Split() を使った手法 |
@fujitanozomu | 147 | 160文字版のズンドコ逆転、シフト演算を乗算に |
@ht_deko | 140 | 動的配列をインライン変数で定義 |
@ht_deko | 133 | 140文字版に147文字版のロジックを適用 |
@ht_deko | 132 | 133文字版のビットフラグを見直し |
@pik | 130 | 演算順序の変更による空白の除去、 空文のセミコロン除去 |
@ht_deko | 129 | 132文字版に130文字版のロジックを適用 |
@fujitanozomu | 125 | ビットフラグの見直し |
@pik | 122 | 125文字版の動的配列を Copy() で置き換え |
@fujitanozomu | 120 | 122文字版の Copy() の引数を変更、 Index=1 と Index=0 が同じ事を利用 |
※ この記事と @pik さんの記事、双方のコメント欄にコードがあります。
※ 他言語持ってきて「こんなに短く書けるぜ~」って言うのは野暮なのでやめておきましょう。
おわりに
元々は自作関数の課題だったみたいで、僕が書いたコードは関数でない時点で論外なのかもしれません。
そもそも、Delphi (Pascal) だと結果を返さないルーチンは手続きであり関数ではないのですが、課題のズンドコは何を返したのでしょうね。
See also: