C ++ 11、7441.68126105 6997.65434833 5198.16107651
その他の更新
Perlの楕円がとても気に入ったので、C ++ 11で試してみました。生の文字列を使用してそこにバイトを押し込みましたが、しばらくの間、予想したスコアと生成されたコードとの間にわずかな矛盾が生じていました。g ++はこれを0x0a(改行)に変換するため、実際に生の0x0d(キャリッジリターン)を配置することはできません。私は正直、この生成されたソースがどれほど合法かはわかりませんが、私のマシンのいくつかでコンパイルして動作します。
また、GAが失速したように見えた後に別のアルゴリズム、Adaptive Dimensional Searchを試してみました。これは、ローカルミニマムを磨き、幸運を手に入れて別のウェルにたどり着くためです。
これにより、C ++ 11は驚くほど競争力のあるスコアを提供します(最初に推測したよりもはるかに優れています)... fstreamを唯一のインクルードとして使用してこれを行うことができるのはかなり驚きです。
テキスト(はい、改行は実際のソースにあります...削除できると思います):
#include <fstream>
#define U unsigned
int main(){
auto *d=reinterpret_cast<const U char*>(R"(<<gibberish>>)");
U a=320,b=386,n=*d++;
char m[a*b*3]{0};
for(U i=0;i<n;i++,d+=7){long x=2*d[0],y=2*d[1],w=2*d[2],h=2*d[3];
for(U r=0;r<a;r++){for(U c=0;c<b;c++){long u=c-x,v=r-y;
if((w*w*v*v+h*h*u*u)<=w*w*h*h){auto *p=m+3*(r*b+c);*p++=d[4];*p++=d[5];*p=d[6];}}}}
std::ofstream f{"e.ppm",std::ios::binary};f<<"P6\n386 320\n255\n";for(U i=0;i<a*b*3;i++){f<<m[i];}
return 0;}
Hexdump:
00000000: 2369 6e63 6c75 6465 203c 6673 7472 6561 #include <fstrea
00000010: 6d3e 0a23 6465 6669 6e65 2055 2075 6e73 m>.#define U uns
00000020: 6967 6e65 640a 696e 7420 6d61 696e 2829 igned.int main()
00000030: 7b0a 6175 746f 202a 643d 7265 696e 7465 {.auto *d=reinte
00000040: 7270 7265 745f 6361 7374 3c63 6f6e 7374 rpret_cast<const
00000050: 2055 2063 6861 722a 3e28 5222 2851 1274 U char*>(R"(Q.t
00000060: 5134 8c86 6c7f 2ea0 3638 4c8b c001 c126 Q4..l...68L....&
00000070: 6e84 9500 480b 2964 778f 0196 5c09 353d n...H.)dw...\.5=
00000080: 346f 476e 6433 4581 0f02 0509 9798 4d12 4oGnd3E.......M.
00000090: 0110 0362 7482 6300 4d1f 2631 645b 213d ...bt.c.M.&1d[!=
000000a0: 187e 835c 6f84 333d 2c3e 4f9d 71bb 1e22 .~.\o.3=,>O.q.."
000000b0: 2d3d 1f4f 0248 2424 235f 577e 1f71 8990 -=.O.H$$#_W~.q..
000000c0: b314 3a89 404a 5920 1202 0c23 242a 8e01 ..:.@JY ...#$*..
000000d0: 6d30 3645 7145 86b0 082c 3543 4d42 1f52 m06EqE...,5CMB.R
000000e0: 6879 7c7a 336d 1a37 4c82 b876 b606 3146 hy|z3m.7L..v..1F
000000f0: 70a1 015e 0b38 4b7f 0e46 a916 4360 8550 p..^.8K..F..C`.P
00000100: 1623 0930 407c bf13 6e73 4556 6252 9837 .#.0@|..nsEVbR.7
00000110: 4326 2c31 7d81 3303 2e3c 526c 4123 4b37 C&,1}.3..<RlA#K7
00000120: 4758 bd6f 8b0a 2d3c 6000 0006 1b2c 3a6b GX.o..-<`....,:k
00000130: a83a 134f 4254 6649 590e 174a 6986 3833 .:.OBTfIY..Ji.83
00000140: 0a29 3245 8695 1d27 583e 507f 963c 2b33 .)2E...'X>P..<+3
00000150: 2f3d 6fb6 191f 6752 5f63 b09e 5b0c 3239 /=o...gR_c..[.29
00000160: 4021 4b20 1941 5c87 ab18 1c1e 4a5f 8c35 @!K .A\.....J_.5
00000170: 9d19 311d 211e af4b 3327 4f64 986c 2712 ..1.!..K3'Od.l'.
00000180: 573b 4b73 b733 a718 5f76 9ca9 2919 2163 W;Ks.3.._v..).!c
00000190: 7e9e 8147 8914 8996 726b 1c17 1670 807b ~..G....rk...p.{
000001a0: 5038 930e 6279 94b0 351d 3086 9b8e ba40 P8..by..5.0....@
000001b0: c10e 3449 6721 4002 232f 394e 22a0 0e74 ..4Ig!@.#/9N"..t
000001c0: 2b2f 2c09 3d0e 1666 7e97 0570 2e05 526d +/,.=..f~..p..Rm
000001d0: 8a68 1e2f 0a40 5586 bf5d 150c 2022 2e5e .h./.@U..].. ".^
000001e0: 260e 4b3a 4a7d a368 3807 4c63 972b 5707 &.K:J}.h8.Lc.+W.
000001f0: 2e41 5a79 865e 3c06 2326 3927 9d0e 411d .AZy.^<.#&9'..A.
00000200: 211d c030 9b16 657f 9666 2434 0a5f 7592 !..0..e..f$4._u.
00000210: 873b 0a1d 8895 89a9 432e 0aa2 aa95 af1d .;......C.......
00000220: 1212 aab1 7c80 5833 162c 3758 834d 3117 ....|.X3.,7X.M1.
00000230: 718b 9579 2a06 163e 5381 8439 3b0c 5172 q..y*..>S..9;.Qr
00000240: 9d54 3a16 1538 4e73 8c4f 1f0e 8fa2 9ab0 .T:..8Ns.O......
00000250: 200b 07b8 a946 5e40 1e19 5971 9457 5028 ....F^@..Yq.WP(
00000260: 125b 779b bb49 1a07 a1ad a022 7b0a 421f .[w..I....."{.B.
00000270: 231f 585e 200f 5f77 8a41 5b0e 136a 8089 #.X^ ._w.A[..j..
00000280: 9ca0 9d01 5648 3a40 550c 0c9f a89e 7841 ....VH:@U.....xA
00000290: 2a19 566f 9429 2229 3b0a 5520 613d 3332 *.Vo.)");.U a=32
000002a0: 302c 623d 3338 362c 6e3d 2a64 2b2b 3b0a 0,b=386,n=*d++;.
000002b0: 6368 6172 206d 5b61 2a62 2a33 5d7b 307d char m[a*b*3]{0}
000002c0: 3b0a 666f 7228 5520 693d 303b 693c 6e3b ;.for(U i=0;i<n;
000002d0: 692b 2b2c 642b 3d37 297b 6c6f 6e67 2078 i++,d+=7){long x
000002e0: 3d32 2a64 5b30 5d2c 793d 322a 645b 315d =2*d[0],y=2*d[1]
000002f0: 2c77 3d32 2a64 5b32 5d2c 683d 322a 645b ,w=2*d[2],h=2*d[
00000300: 335d 3b0a 666f 7228 5520 723d 303b 723c 3];.for(U r=0;r<
00000310: 613b 722b 2b29 7b66 6f72 2855 2063 3d30 a;r++){for(U c=0
00000320: 3b63 3c62 3b63 2b2b 297b 6c6f 6e67 2075 ;c<b;c++){long u
00000330: 3d63 2d78 2c76 3d72 2d79 3b0a 6966 2828 =c-x,v=r-y;.if((
00000340: 772a 772a 762a 762b 682a 682a 752a 7529 w*w*v*v+h*h*u*u)
00000350: 3c3d 772a 772a 682a 6829 7b61 7574 6f20 <=w*w*h*h){auto
00000360: 2a70 3d6d 2b33 2a28 722a 622b 6329 3b2a *p=m+3*(r*b+c);*
00000370: 702b 2b3d 645b 345d 3b2a 702b 2b3d 645b p++=d[4];*p++=d[
00000380: 355d 3b2a 703d 645b 365d 3b7d 7d7d 7d0a 5];*p=d[6];}}}}.
00000390: 7374 643a 3a6f 6673 7472 6561 6d20 667b std::ofstream f{
000003a0: 2265 2e70 706d 222c 7374 643a 3a69 6f73 "e.ppm",std::ios
000003b0: 3a3a 6269 6e61 7279 7d3b 663c 3c22 5036 ::binary};f<<"P6
000003c0: 5c6e 3338 3620 3332 305c 6e32 3535 5c6e \n386 320\n255\n
000003d0: 223b 666f 7228 5520 693d 303b 693c 612a ";for(U i=0;i<a*
000003e0: 622a 333b 692b 2b29 7b66 3c3c 6d5b 695d b*3;i++){f<<m[i]
000003f0: 3b7d 0a72 6574 7572 6e20 303b 7d ;}.return 0;}
この回答は、以下で説明する以前の回答からのいくつかのアプローチを組み合わせていますが、残念ながら私はプログラムを944 949文字(に応じてwc -c
)に合うようにゴルフする必要がありましたので、もはやC ++のようには見えません(謝罪これはチャレンジのルールに反しているので、近々改善を試みます)。最初はこれを計画していなかったので、完全に判読することはできず、まだぶら下がっている果物がたくさんあります。
更新された結果
遺伝的アルゴリズムをより長く実行しただけで、わずかに良い結果が得られました。ただし、収束が大幅に遅くなっていることを考えると、この特定の方法はおそらく最高になり始めていると思います(または、ローカルの極小値に陥りました)。私は最終プログラムをもう少しゴルフして、さらに数個の長方形を絞り込みました(最大ゲノムサイズが増加したことを除き、ジェネレーターは同じままです)。
問題が極小の極小値である場合、個人間のクロスオーバーを実装すると役立ちますが、しばらく同じ範囲にとどまっていることを考えると、これは長方形の数と同じくらい良いと考え始めています。
#include <fstream>
#include <vector>
#define q operator
#define s struct
#define k return
using o=std::ofstream;using i=int;s C{unsigned char r,g,b;};void q<<(o &z,C &c){z<<c.r<<c.g<<c.b;}s R{i x,y,w,h;C c;};s P{P(i a,i b):w(a),h(b),p(w*h){}C &q()(i x,i y){k p[y*w+x];}i w,h;std::vector<C> p;};void q<<(o &z,P &p){z<<"P6\n"<<p.w<<" "<<p.h<<"\n255\n";for(i n=0;n<p.w*p.h;n++){z<<p.p[n];}}i main(){R a{0,0,386,320,{73,87,116}};P p(386,320);for(auto r:
{a
,{0,174,385,145,{48,56,65}}
,{0,33,322,201,{97,123,144}}
,{289,26,96,136,{152,167,153}}
,{114,62,225,128,{128,150,151}}
,{46,74,116,245,{33,38,36}}
,{150,17,224,63,{170,172,109}}
,{85,41,125,158,{70,94,122}}
,{125,197,260,37,{59,77,118}}
,{109,78,105,138,{111,132,145}}
,{76,94,309,33,{88,115,148}}
,{176,17,139,160,{86,111,148}}
,{213,228,172,35,{62,79,97}}
,{0,11,270,89,{75,94,130}}
}
){for(i x=0;x<r.w;x++){for(i y=0;y<r.h;y++){p(r.x+x,r.y+y)=r.c;}}}o f{"a.ppm",std::ios::binary};f<<p;k 0;}
ボロノイバージョン、7331.92407536、989文字
GAコードでMarco13のVoronoi Ideaを使用しました。これは私が期待していたほどうまく機能しませんでした。長方形よりも数ポイントだけ絞ることができました。重複による長方形の潜在的にばらばらな性質は、スコアを少し助けると思います。いずれにせよ、最初のエントリーと同様のスコアにもかかわらず、私は実際にこれがかなり良く見える方法が好きです。
#include <fstream>
#include <vector>
#define q operator
#define s struct
#define k return
using i=int;using o=std::ofstream;s C{unsigned char r,g,b;};void q<<(o &z,C &c){z<<c.r<<c.g<<c.b;}s P{i x,y;C c;P q-(P r){k {x-r.x,y-r.y,{0,0,0}};}i q*(P r){k x*r.x+y*r.y;}i q^(P r){P d=(*this-r);k d*d;}};s X{X(i a,i b):w(a),h(b),p(w*h){}C &q()(i x,i y){k p[y*w+x];}i w,h;std::vector<C> p;};void q<<(o &z,X &p){z<<"P6\n"<<p.w<<' '<<p.h<<"\n255\n";for(i n=0;n<p.w*p.h;n++){z<<p.p[n];}}i main(){P a{101,108,{72,89,122}};X p(386,320);for(i y=0;y<p.h;y++){for(i x=0;x<p.w;x++){P c(a),d{x,y,{0,0,0}};for(auto g:{a,{0,314,{48,56,58}},{182,135,{89,112,144}},{108,262,{34,39,41}},{357,221,{64,78,102}},{251,289,{50,60,75}},{129,161,{108,128,142}},{375,1,{83,104,137}},{44,161,{95,120,144}},{316,254,{53,65,85}},{47,161,{37,43,41}},{373,37,{159,167,121}},{313,138,{87,115,152}},{264,0,{71,88,130}},{314,141,{128,148,153}}}){i m=c^d;i n=g^d;if(n<m){c=g;}}p(x,y)=c.c;}}o f("v.ppm",std::ios::binary);f<<p;k 0;}
古い結果、7441.68126105、944文字
#include <iostream>
#include <fstream>
#include <vector>
#define q operator
#define s struct
#define k return
using o = std::ostream; using i = int; s C{i r;i g;i b;}; o &q<<(o &z,C &c){z<<(char)c.r<<(char)c.g<<(char)c.b;k z;} s R{i x;i y;i w;i h;C c;};s P{P(i a,i b):w(a),h(b){p.reserve(w*h);}C &q()(i x,i y){k p[y*w+x];}i w;i h;std::vector<C> p;}; o &q<<(o &z,P &p){z<<"P6\n"<<p.w<<" "<<p.h<<"\n255\n";for(i n=0;n<p.w*p.h;n++){z<<p.p[n];}k z;} i main() { R a{0,0,386,320,C{89,109,129}}; P p(386,320); for (auto r:
{
a
,{48,31,334,288,C{46,55,66}}
,{1,237,169,81,C{35,40,40}}
,{348,48,37,115,C{126,147,155}}
,{165,20,217,68,C{169,173,113}}
,{106,2,209,217,C{98,120,143}}
,{206,199,178,62,C{61,79,108}}
,{11,31,113,48,C{65,83,129}}
,{239,84,109,106,C{108,132,152}}
,{0,78,326,42,C{86,110,142}}
,{47,0,248,55,C{64,79,121}}
}
) { for(i dx=0;dx<r.w;dx++){for(i dy=0;dy<r.h;dy++){p(r.x+dx,r.y+dy)=r.c;}} } std::ofstream f("a.ppm"); f << p; k 0; }
他のエントリのいくつかと同様に、プログラムは重なり合った長方形を描くだけです。形式がシンプルであるため(出力はですがa.ppm
、SEはPPMを好まなかったため、pngバージョンをアップロードした)、完全に決定論的であるため、バイナリPPMを使用します。
説明
PPMの生成には、定型コードのかなりの部分が必要でした。つまり、少しゴルフをした後でも、あまり多くの長方形を作成することはできませんでした。スコアをさらに改善するために、ここでさらにいくつかを絞ることができます。
本当の魔法は長方形のリストです。Wolfgangの答えと同様に、私は遺伝的アルゴリズムを使用してこれらを見つけました。実際、個人間の組み換えはまだ起きていないため、実装はほとんど完了していませんが、突然変異はまだ起こり、フィットネスによるトーナメントスタイルのランキングは次のラウンドで最高の生物を保持します。最後のラウンドから最高の個人のコピーが次のラウンドに保持されるため、エリートも使用されます。そのため、最も適合した生物は常に前のラウンドと少なくとも同じ適合です。
Wolfgangのコードは昨日開始してからあまりよく見ていませんでしたが、彼も色を変えることができるようで、スコアの違いを説明できるかもしれません。
サーチスペースを小さく保つために、長方形の位置のみを見ました。ソース画像があるので、色はその長方形の可視ピクセルのチャネルごとの平均によって計算されます(平方距離を最小化するため、その特定の長方形についてこれ以上の改善はできないと思います)。
githubリポジトリの作業を続ける場合は、次の2、3の編集でgithubリポジトリを配置しますが、現時点では(単一ファイル)コードはpastebinにあります。C ++ 11モードでコンパイルします(補足ですが、1回限りの場合でも面倒だとはかなり恥ずかしく思います)。
またORIGINAL.ppm
、これを機能させるために命名された星空のP3 PPMイメージも必要です。このGitHub Gistからファイルをダウンロードできます。
pip unistall PIL
その後pip install pillow
)、最初の行をに変更することfrom PIL import Image
です。