C ++ 11, 7441,68126105 6997,65434833 5198,16 7651
Больше обновлений
Мне очень понравились эллипсы из Perl, и мне пришлось попробовать их в C ++ 11. Я использовал необработанную строку, чтобы вставить туда байты, но какое-то время я получал небольшое расхождение с ожидаемым результатом и сгенерированным кодом. Оказывается, что вы на самом деле не можете поместить необработанный 0x0d (возврат каретки), так как g ++ преобразует это в 0x0a (новая строка). Честно говоря, я не уверен, насколько легитимен этот сгенерированный источник, но он компилируется и работает на нескольких моих машинах.
Я также опробовал другой алгоритм, адаптивный поиск размеров после того, как GA выглядел так, как будто он застопорился, просто чтобы попытаться откорректировать локальный минимум и, возможно, получить удачу и попасть в другую скважину.
При этом 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 символов
Я использовал « Идею Вороного» от Marco13 с моим кодом GA. На самом деле это не сработало так, как я надеялся. Я мог только втиснуть в несколько больше точек, чем прямоугольники. Я думаю, что потенциально непересекающаяся природа прямоугольников из-за перекрытия помогает баллу немного. Несмотря на это, мне на самом деле нравится, как это выглядит значительно лучше, несмотря на результат, аналогичный моему первому заявлению.
#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; }
Как и некоторые другие записи, программа просто рисует перекрывающиеся прямоугольники. Он использует двоичный PPM, поскольку формат прост (вывод есть a.ppm
, но я загрузил версию png, поскольку SE не понравился PPM), и он полностью детерминирован.
объяснение
Генерация PPM потребовала много кода, что означало, что у меня не может быть слишком много прямоугольников даже после небольшого количества игры в гольф. Еще несколько, вероятно, можно сжать здесь, чтобы улучшить счет дальше.
Настоящая магия - это список прямоугольников. Подобно ответу Вольфганга, я использовал генетический алгоритм, чтобы найти их. На самом деле реализация в значительной степени неполная, поскольку рекомбинация между людьми еще не происходит, но мутации все же происходят, и рейтинг в турнирном стиле по физической пригодности сохраняет лучшие организмы в следующем раунде. Элитарность также используется, поскольку копия лучшего человека из последнего раунда сохраняется в следующем раунде, поэтому наиболее подходящий организм всегда, по крайней мере, такой же, как и в предыдущем раунде.
Я не слишком внимательно присматривался к коду Вольфганга с тех пор, как начал его вчера, но похоже, что он также позволяет изменять цвет, что может объяснить разницу в баллах.
Чтобы уменьшить пространство поиска, я смотрел только на положение прямоугольника; цвет рассчитывается по среднему значению для каждого канала видимых пикселей из этого прямоугольника, поскольку у нас есть исходное изображение (я не думаю, что мы можем добиться большего успеха для этого конкретного прямоугольника, поскольку это минимизирует квадратное расстояние).
Я оставлю репозиторий github в следующих нескольких изменениях, если буду продолжать над ним работать, но пока (однофайловый) код находится на pastebin . Скомпилируйте его в режиме C ++ 11 (примечание, я довольно смущен тем, насколько грязно это даже для одного раза).
Вам также понадобится изображение звездной ночи P3 PPM, названное так, ORIGINAL.ppm
чтобы это работало. Вы можете скачать файл из этого GitHub Gist .
pip unistall PIL
, затемpip install pillow
) и изменить первую строку наfrom PIL import Image
.