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