フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: 先制 hello, world
DEKO
管理者
投稿数: 2691
先制 hello, world
on: 2015/09/27 19:01 Sun

[先制 hello, world]
https://codeiq.jp/q/2074

とりあえず Pascal (fpc) での解説を。”負けにくい事” を最初に考える事にしました。そうなると、preemptive "hello, world" という文字は可能な限り取り除く必要があります。考え付いたのは以下の三種類。

[IBM->HAL 方式]
{攻撃/防御コード}BEGIN FOR PCHAR(@ARGC)^IN'qsffnqujwf!#ifmmp-!xpsme#'DO WRITE(CHAR(ARGC-1))END.

 
これは以前、細川さんが「第7回デスマコロシアム」で書かれたコードを応用したものです (Delphi では通らないコードです)。
http://delphimaniacs.blogspot.jp/2014/12/codeiq-pascal.html
但し、お題に 半角SP (0×20)w (0×78) が含まれるため、最大でも 7 文字しかスライドできません。あと長い。

[すべて大文字で記述]
{攻撃/防御コード}BEGIN WRITE(LOWERCASE('PREEMPTIVE "HELLO, WORLD"'))END.

 
シンプルに。Pascal の予約語等の識別子は大文字小文字を区別しませんので。
メリットとしてはその短さです。コードが短ければ短いほどヒットする確率は低くなりますし、その分攻撃コードを増やす事が出来ます。

[すべてコントロールコードで記述]
{攻撃/防御コード}BEGIN WRITE(^0^2^%^%^-^0^4^)^6^%^`#$22^(^%^,^,^/#$2C^`^7^/^2^,^$#$22)END.

 
僕が最終的に選択したのはコレです。メリットとしては文字種が意表をついたものである点と、文字種が比較的少なくて済む点があります。コントロールコードの文字列は以下のような関数で変換する事が出来ます。

function StringToControlCode(s: string; IsHexadecimal: Boolean = False): string;
const
FMTSTR: array [Boolean] of string = ('#%d', '#$%x');
SLIDEVALUE: array [Boolean] of Int16 = (-$40, $40);
var
C: Char;
B: UInt16;
begin
for C in S do
begin
B := Ord(C);
case B of
$00..$21, $3B..$3E,
$60..$7F:
result := result + Format('^%s', [Char(B + SLIDEVALUE[B < $60])]);
else
result := result + Format(FMTSTR[IsHexadecimal], [ B ]);
end;
end;
end;

 
解りやすく書くと…

function StringToControlCode(s: string; IsHexadecimal: Boolean = False): string;
var
C: Char;
begin
for C in S do
begin
case Ord(C) of
$00..$21, $3B..$3E:
result := result + Format('^%s', [Char(Ord(C) + $40)]);
$60..$7F:
result := result + Format('^%s', [Char(Ord(C) - $40)]);
else
if IsHexadecimal then
result := result + Format('#%d', [Ord(C)])
else
result := result + Format('#$%x', [Ord(C)]);
end;
end;
end;

 
こうなります。

最終的な順位は19位でしたが、真ん中よりちょっと上を目標としていましたのでまずまずの結果でした。
http://nabetani.sakura.ne.jp/codeiq/prehewo/all.html

See Also:
[Delphi で ^ は "べき乗" の演算子ではないけれど?]
http://ht-deko.com/ft1210.html#121019_01

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/27 19:18 Sun

Pascal でのブロックコメントは { } の他に (* *) がありますが、/* */ を使う言語に対してアドバンテージがないので使うのを見送りました。

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/27 20:39 Sun

Pascal (fpc) を殺すのは簡単です。
「begin と end がなければ始まらないし終わらない」
この一言に尽きます (w

ちなみに Pascal (fpc) での最短コードは以下のようになると思われます。

begin write('preemptive "hello, world"')end.

 
これでは素の PHP とかに瞬殺されてしまいますね (^^;A

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/27 20:54 Sun

対 BF は捨てました。
. を最初に書かれてしまうと、Pascal では最低一文字はヒットしてしまいます (Pascal はプログラムの終端として . が必要) が、これを防ぐ方法がありません。「実行くんで 0×00-0x1F を出力したら制御文字が表示される」とかだったらまだ対策のしようもあったのでしょうけれど。

See Also:
[実行くん]
https://codeiq.jp/tools/sandbox/

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/27 21:48 Sun

防御コードですが、使用されている文字をソートしてカウントし、幾つかを先頭に配置します。

{^(任意)}

 
僕のコードでは ^ がよく使われていますからこれは先頭に。

攻撃コードはフィーリングです (w
"先制 hello, world" は毎回結果の変わる 変則 Hit&Blow みたいなものなので勘が頼りです。様々な言語を広く知っている方なら攻撃コードにセンスがあるのでしょうが、僕はあまりセンスがなかったようです (^^;A

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/27 21:54 Sun

最終的に僕が提出したコードがコレです。

 {^\$2("l}BEGIN WRITE(^0^2^%^%^-^0^4^)^6^%^`#$22^(^%^,^,^/#$2C^`^7^/^2^,^$#$22)END.

 
この方針で行くのなら、攻撃コードをもうちょい練るべきだったと思いました。
"l (小文字 L)" は素の preemptive "hello, world" 殺しです。e か l を最初の方に入れておけば 3 ヒットします。Pascal では二文字目までに e を含めるのが難しいので l を入れてみました。

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/29 19:44 Tue

細川さんの回答です。
https://gist.github.com/freeonterminate/06bad6ab91d0d73d2c5c

DEKO
管理者
投稿数: 2691
Re: 先制 hello, world
on: 2015/09/30 18:25 Wed

結果論としては、

 (*-20",l^*)BEGIN WRITE(^0^2^%^%^-^0^4^)^6^%^`#$22^(^%^,^,^/#$2C^`^7^/^2^,^$#$22)END.

 
このようなコードだと 10 位以内に入れたようです (65 / 1 / 15)。

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.036 sec.