C ++ 11, 7441.68126105 6997.65434833 5198.16107651
Weitere Updates
Ich mochte die Ellipsen von Perl so sehr, dass ich sie in C ++ 11 ausprobieren musste. Ich habe die rohe Zeichenfolge verwendet, um Bytes dorthin zu schieben, aber für eine Weile bekam ich eine leichte Diskrepanz mit der erwarteten Punktzahl und dem generierten Code. Es stellt sich heraus, dass Sie kein rohes 0x0d (Carriage Return) setzen können, da g ++ dies in 0x0a (New Line) konvertiert. Ich bin mir ehrlich gesagt nicht sicher, wie legitim diese generierte Quelle ist, aber sie wird auf einigen meiner Maschinen kompiliert und funktioniert.
Ich habe auch einen anderen Algorithmus ausprobiert, Adaptive Dimensional Search, nachdem der GA ins Stocken geraten zu sein schien, nur um zu versuchen, das lokale Minimum abzubauen und vielleicht Glück zu haben und in einen anderen Brunnen zu fallen.
Damit liefert C ++ 11 ein überraschend konkurrenzfähiges Ergebnis (weitaus besser, als ich ursprünglich vermutet hätte) ... Ich bin ziemlich überrascht, dass dies mit fstream als einzigem Include möglich ist.
Text (ja, die Zeilenumbrüche befinden sich in der eigentlichen Quelle ... ich könnte sie wahrscheinlich entfernen):
#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;}
Diese Antwort kombiniert mehrere Ansätze aus früheren Antworten, die ich unten erläutern werde. Leider musste ich das Programm etwas golfen, um in 944 949 Zeichen (laut wc -c
) zu passen , so dass es nicht mehr wie C ++ aussieht (entschuldigt, wenn Dies verstößt gegen die Regeln der Herausforderung. Ich werde in Kürze versuchen, einige Verbesserungen vorzunehmen. Das habe ich anfangs nicht geplant, deshalb ist es immer noch nicht völlig unkenntlich und es gibt immer noch jede Menge tief hängende Früchte.
Aktualisierte Ergebnisse
Nur den genetischen Algorithmus länger laufen zu lassen, hat zu einem etwas besseren Ergebnis geführt; Angesichts der Tatsache, dass sich die Konvergenz erheblich verlangsamt hat, würde ich sagen, dass diese spezielle Methode wahrscheinlich das Beste ist (oder ich bin in ein tiefes lokales Minimum gefallen). Ich habe das endgültige Programm noch ein wenig weiter ausgearbeitet, um ein paar Rechtecke mehr zusammenzudrücken (der Generator bleibt derselbe, außer dass die maximale Genomgröße erhöht wurde).
Das Implementieren des Crossovers zwischen Individuen wird helfen, wenn das Problem ein tiefes lokales Minimum ist, aber da es für eine Weile im selben Bereich bleibt, denke ich, dass dies in etwa so gut ist, wie es für die Anzahl der Rechtecke geht.
#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;}
Voronoi Version, 7331.92407536, 989 Zeichen
Ich habe die Voronoi-Idee von Marco13 mit meinem GA-Code verwendet. Das hat tatsächlich nicht so gut funktioniert, wie ich gehofft hatte. Ich konnte nur ein paar Punkte mehr einpressen als Rechtecke. Ich denke, die potenziell unzusammenhängende Natur der Rechtecke aufgrund von Überlappungen hilft der Partitur ein bisschen. Ungeachtet dessen gefällt mir die Art und Weise, wie dies deutlich besser aussieht, trotz der ähnlichen Punktzahl wie bei meinem ersten Eintrag.
#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;}
Alte Ergebnisse, 7441.68126105, 944 Zeichen
#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; }
Ähnlich wie bei einigen anderen Einträgen zeichnet das Programm nur überlappende Rechtecke. Es verwendet binäres PPM, da das Format einfach ist (die Ausgabe ist a.ppm
, aber ich habe eine PNG-Version hochgeladen, da SE das PPM nicht mochte) und es ist vollständig deterministisch.
Erläuterung
Das Erzeugen des PPM nahm einen guten Teil des Boilerplate-Codes in Anspruch, was bedeutete, dass ich selbst nach einigem Golfen nicht zu viele Rechtecke haben konnte. Hier können wahrscheinlich noch ein paar mehr eingedrückt werden, um die Punktzahl weiter zu verbessern.
Die wahre Magie ist die Liste der Rechtecke. Ähnlich wie bei Wolfgang verwendete ich einen genetischen Algorithmus, um diese zu finden. Tatsächlich ist die Implementierung weitgehend unvollständig, da eine Rekombination zwischen Individuen noch nicht erfolgt, aber dennoch eine Mutation auftritt und die turnierartige Rangfolge nach Fitness die besten Organismen in der nächsten Runde behält. Elitismus wird auch verwendet, da eine Kopie des besten Individuums aus der letzten Runde in der nächsten Runde aufbewahrt wird, sodass der am besten geeignete Organismus immer mindestens so fit ist wie in der vorherigen Runde.
Ich habe mir den Code von Wolfgang seit meinem gestrigen Start nicht mehr so genau angesehen, aber anscheinend lässt er auch die Farbe variieren, was möglicherweise den Unterschied zwischen den Werten erklärt.
Um den Suchraum kleiner zu halten, habe ich nur die Rechteckposition betrachtet. Die Farbe wird anhand des kanalweisen Durchschnitts der sichtbaren Pixel aus diesem Rechteck berechnet, da wir das Ausgangsbild haben (ich glaube, wir können für dieses bestimmte Rechteck nichts Besseres tun, da dies den Quadratabstand minimiert).
Ich werde in den nächsten Änderungen ein Github-Repository erstellen, wenn ich weiter daran arbeite, aber der (Single-File-) Code befindet sich derzeit im Pastebin . Kompilieren Sie es im C ++ 11-Modus (Randnotiz: Es ist mir ziemlich peinlich, wie unordentlich es selbst für einen Einzelgänger ist).
Sie benötigen auch ein P3 PPM-Bild der Sternennacht, das ORIGINAL.ppm
für diese Funktion benannt ist . Sie können die Datei von diesem GitHub Gist herunterladen .
pip unistall PIL
, dannpip install pillow
) zu verwenden und die erste Zeile in zu ändernfrom PIL import Image
.