Libraryless. Click here for Pure Java version (4762L/31K/104K).
1 | !752 |
2 | |
3 | static BWImage bw; |
4 | static ImageSurface imageSurface; |
5 | static Thread producer; |
6 | static Reproducing rp; |
7 | |
8 | !include #1000522 // image helper functions |
9 | |
10 | p {
|
11 | rp = new Reproducing; |
12 | bw = rp.bw = loadBWImage("#1004541");
|
13 | imageSurface = showImage(rp.bw.getBufferedImage()); |
14 | rp.imageSurfaceToUpdateWithBest = imageSurface; |
15 | |
16 | //showImage("Full Grab", descToImage(fullGrab(bw)));
|
17 | |
18 | produce(); |
19 | rp.reproduceOpenEnd(); |
20 | |
21 | while (rp.solved()) {
|
22 | rp.pivotLength = l(rp.bestDesc) - rp.pivotStep; |
23 | print("Trying pivot length " + rp.pivotLength);
|
24 | |
25 | produce(); |
26 | rp.reproduceOpenEnd(); |
27 | } |
28 | } |
29 | |
30 | static void produce() {
|
31 | cancelThread(producer); |
32 | producer = new Thread(r {
|
33 | // STRATEGY! |
34 | |
35 | rp.push(fullGrab(bw)); |
36 | int w = 1; |
37 | while licensed {
|
38 | rp.push(new RandomSolid().reproduce(bw)); |
39 | S best = rp.bestDesc; |
40 | if (best != null) |
41 | rp.push(varyFloat(best)); |
42 | if (w < rp.bw.getWidth()) |
43 | rp.push(hrepeat(bw, w++)); |
44 | } |
45 | }, "Producer"); |
46 | producer.start(); |
47 | } |
48 | |
49 | sclass Best {
|
50 | S desc; |
51 | double score; |
52 | BWImage image; |
53 | |
54 | *() {}
|
55 | *(S *desc, double *score, BWImage *image) {}
|
56 | |
57 | int l() { ret main.l(desc); }
|
58 | } |
59 | |
60 | sclass Reproducing {
|
61 | BWImage bw; // original |
62 | ImageSurface imageSurfaceToUpdateWithBest; |
63 | new LinkedBlockingQueue<S> newProducts; |
64 | int maxQueueLength = 10; |
65 | Best shortest100; |
66 | double bestScore; |
67 | volatile S bestDesc; |
68 | BWImage bestRendering; |
69 | int pivotLength = -1; // no length punishment at start |
70 | int pivotStep = 1; |
71 | int fullGrabLength; // length of full grab for reference |
72 | |
73 | void push(S product) {
|
74 | if (product == null) ret; |
75 | while (newProducts.size() >= maxQueueLength && mayRun()) |
76 | sleep(100); |
77 | newProducts.add(product); |
78 | } |
79 | |
80 | double formula(S desc, double pixelScore) {
|
81 | int lengthPunishment = pivotLength < 0 ? 0 |
82 | : max(0, l(desc)-pivotLength); |
83 | ret pixelScore-lengthPunishment; |
84 | } |
85 | |
86 | void reproduceOpenEnd() {
|
87 | bestDesc = null; |
88 | bestScore = 0; |
89 | bestRendering = null; |
90 | Renderer best = null; |
91 | fullGrabLength = l(fullGrab(bw)); |
92 | long lastPrint = 0, lastN = 0; |
93 | for (long ntry = 1; ; ntry++) {
|
94 | ping(); |
95 | long now = now(); |
96 | if (now >= lastPrint+1000) {
|
97 | long tps = (ntry-lastN)*1000/(now-lastPrint); |
98 | lastPrint = now; |
99 | lastN = ntry; |
100 | String s = "Try " + ntry + " (" + tps + "/s)";
|
101 | if (best == null) |
102 | System.out.println(s); |
103 | else {
|
104 | System.out.println("Best: " + bestDesc);
|
105 | System.out.println(s + ", score: " + formatDouble(bestScore, 2) + "%, l=" + l(bestDesc) + ", pivotL=" + pivotLength + "/" + fullGrabLength + (shortest100 == null ? "" : ", shortest100=" + shortest100.l())); |
106 | } |
107 | } |
108 | S desc; |
109 | try {
|
110 | desc = grabFromQueue(newProducts); |
111 | } catch e {
|
112 | print("Production failed: " + exceptionToStringShort(e));
|
113 | continue; |
114 | } |
115 | Renderer p; |
116 | try {
|
117 | p = makeRenderer(desc); |
118 | } catch {
|
119 | print("Can't unstructure: " + desc);
|
120 | continue; |
121 | } |
122 | |
123 | BWImage rendering = render(p, bw); |
124 | double pixelScore = 100*(1-diff(bw, rendering)); |
125 | double score = formula(desc, pixelScore); |
126 | |
127 | if (bestDesc == null || p != null && score > bestScore) {
|
128 | //System.out.println("New best! " + score);
|
129 | bestDesc = desc; |
130 | bestScore = score; |
131 | bestRendering = rendering; |
132 | best = p; |
133 | if (pixelScore >= 100 && (shortest100 == null || shortest100.l() > l(desc))) {
|
134 | shortest100 = new Best(desc, pixelScore, rendering); |
135 | saveTextFile(getProgramFile("shortest100.txt"), bw.getWidth() + " " + bw.getHeight() + " " + desc);
|
136 | } |
137 | imageSurface.setImage(bestRendering.getBufferedImage()); |
138 | } |
139 | |
140 | if (solved()) {
|
141 | print("Solved! l=" + l(bestDesc));
|
142 | print(bestDesc); |
143 | break; |
144 | } |
145 | } |
146 | } |
147 | |
148 | bool solved() {
|
149 | ret bestScore >= 100.0; |
150 | } |
151 | |
152 | BufferedImage descToImage(S desc) {
|
153 | try {
|
154 | ret makeRenderer(desc).render(bw.getWidth(), bw.getHeight()).getBufferedImage(); |
155 | } catch {
|
156 | fail(desc); |
157 | } |
158 | } |
159 | } |
160 | |
161 | static class FullGrab extends Renderer {
|
162 | int dw, dh; |
163 | byte[] data; |
164 | |
165 | BWImage render(int w, int h) {
|
166 | if (w != dw || h != dh) |
167 | fail("size: \*w*/ \*h*/ \*dw*/ \*dh*/");
|
168 | ret new BWImage(w, h, data); |
169 | } |
170 | } |
171 | |
172 | static class HRepeat extends Renderer {
|
173 | int width; |
174 | S inner; |
175 | |
176 | BWImage render(int w, int h) {
|
177 | BWImage img = new BWImage(w, h); |
178 | BWImage clip = makeRenderer(inner).render(width, h); |
179 | for (int x = 0; x < w; x += width) |
180 | copy(clip, 0, 0, img, x, 0, width, h); |
181 | ret img; |
182 | } |
183 | } |
184 | |
185 | static S fullGrab(BWImage img) {
|
186 | DynamicObject d = new DynamicObject("FullGrab");
|
187 | int w = img.getWidth(), h = img.getHeight(); |
188 | d.put("dw", w);
|
189 | d.put("dh", h);
|
190 | byte[] data = new byte[w*h]; |
191 | for (int y = 0; y < h; y++) |
192 | for (int x = 0; x < w; x++) |
193 | data[y*w+x] = img.getByte(x, y); |
194 | d.put("data", data);
|
195 | ret structure(d); |
196 | } |
197 | |
198 | static S hrepeat(BWImage img, int width) {
|
199 | int h = img.getHeight(); |
200 | BWImage clip = img.clip(0, 0, width, h); |
201 | ret structure(dynamicObject("HRepeat", "width", width, "inner", fullGrab(clip)));
|
202 | } |
203 | |
204 | static S varyFloat(S s) {
|
205 | L<S> tok = javaTok(s); |
206 | int i = tok.indexOf("f");
|
207 | if (i < 0) null; |
208 | float f = Float.parseFloat(unquote(tok.get(i+2))); |
209 | f = (float) (f+random(-0.1, 0.1)); |
210 | tok.set(i+2, quote(str(f))); |
211 | ret join(tok); |
212 | } |
213 | |
214 | static BWImage render(Renderer p, BWImage original) {
|
215 | ret p.render(original.getWidth(), original.getHeight()); |
216 | } |
217 | |
218 | static interface Reproducer {
|
219 | public S reproduce(BWImage original); |
220 | } |
221 | |
222 | static class Solid extends Renderer {
|
223 | float col; |
224 | |
225 | BWImage render(int w, int h) {
|
226 | ret new BWImage(w, h, col); |
227 | } |
228 | } |
229 | |
230 | static class RandomSolid implements Reproducer {
|
231 | int n = -1; |
232 | public S reproduce(BWImage original) {
|
233 | ++n; |
234 | DynamicObject p = new DynamicObject("Solid");
|
235 | if (n % 2 == 0) {
|
236 | p.put("col", randomBrightness());
|
237 | } else {
|
238 | p.put("col", probeRandomPixel(original));
|
239 | } |
240 | ret structure(p); |
241 | } |
242 | } |
243 | |
244 | static abstract class Renderer {
|
245 | abstract BWImage render(int w, int h); |
246 | } |
247 | |
248 | static Renderer makeRenderer(S desc) {
|
249 | ret (Renderer) unstructure(desc); |
250 | } |
251 | |
252 | static BufferedImage render(S fullDesc) {
|
253 | if (fullDesc == null) null; |
254 | new Matches m; |
255 | assertTrue(jmatchStart("* *", fullDesc, m));
|
256 | int w = m.psi(0), h = m.psi(1); |
257 | S desc = m.unq(2); |
258 | ret makeRenderer(desc).render(w, h).getBufferedImage(); |
259 | } |
260 | |
261 | static S shortest100() {
|
262 | ret loadTextFile(getProgramFile("shortest100.txt"));
|
263 | } |
264 | |
265 | static BufferedImage renderShortest100() {
|
266 | ret render(shortest100()); |
267 | } |
Began life as a copy of #1004545
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1004551 |
| Snippet name: | Reproduce Image 4 (with class Reproducing) |
| Eternal ID of this version: | #1004551/1 |
| Text MD5: | aab8ce0320808195f71e45d0d3ffe72c |
| Transpilation MD5: | f2dcafe1888ea6848cb4f49afbd564c5 |
| Author: | stefan |
| Category: | javax / a.i. |
| Type: | JavaX source code |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2016-08-21 02:15:43 |
| Source code size: | 6905 bytes / 267 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 881 / 1298 |
| Referenced in: | [show references] |