1use std::str::FromStr;
2use std::hash::{DefaultHasher, Hash, Hasher};
3use peak_alloc::PeakAlloc;
4#[global_allocator]
5static PEAK: PeakAlloc = PeakAlloc;
6use strum::IntoEnumIterator;
7use std::panic;
8use std::panic::RefUnwindSafe;
9use std::collections::{BTreeSet, BTreeMap};
10use pathfinding::prelude::Matrix;
11use array_tool::vec::{Uniq, Join};
12use crate::cats::Colour::*;
13use crate::cats::GridCategory::*;
14use crate::cats::Direction::*;
15use crate::cats::Transformation::*;
16use crate::cats::*;
17use crate::examples::*;
18use crate::experiments::*;
19use crate::rules::*;
20use crate::grid::*;
22use crate::shape::*;
23use crate::cell::*;
24use crate::data::*;
25
26pub fn runner(data: &str, task_name: &str, experiment: &str, trans: &str, all: bool) {
27 let start = std::time::Instant::now();
29 let tdata = load_files(data);
30 let is_test = data == "test";
31 let mut cnt = 0;
32 let mut output: BTreeMap<String, Vec<OutputData>> = BTreeMap::new();
33 let mut cap_cats: BTreeMap<GridCategory, i32> = BTreeMap::new();
34 let mut cap_todo: BTreeMap<GridCategory, i32> = BTreeMap::new();
35 let mut rule_tasks: BTreeMap<usize, Vec<String>> = BTreeMap::new();
36 let mut done: BTreeSet<String> = BTreeSet::new();
37 let mut tries: usize = 0;
38 let mut cat_hash: BTreeMap<u64, usize> = BTreeMap::new();
39
40 for (file_name, data) in tdata.iter() {
42 let task = file_name.to_string();
43
44 if done.contains(&task) || (!task_name.is_empty() && task_name != "all" && task != task_name) {
46 continue;
47 }
48
49 let mut examples = Examples::new(data);
50
51 if examples.cat.contains(&OverlayInSame) || examples.cat.contains(&OverlayOutSame) {
53 examples = Examples::new_cons(data);
54 }
55 println!("{task}: {:?}", examples.cat);
56
57 let transform = if trans == "all" || trans == "NoTrans" {
58 NoTrans
59 } else if let Ok(tr) = Transformation::from_str(trans) {
60 examples = examples.transformation(tr);
61
62 tr
63 } else {
64 NoTrans
65 };
66
67 let mut hasher = DefaultHasher::new();
68 examples.cat.hash(&mut hasher);
69 let hash = hasher.finish();
70 *cat_hash.entry(hash).or_insert(0) += 1;
72
73 let rule = pass(all, &task, experiment, &examples, transform, is_test, &mut output, &mut cap_cats, &mut cap_todo, &mut done, &mut tries);
75
76 if done.contains(&task) {
77 if let Some(rule) = rule {
78 if rule != usize::MAX {
79 rule_tasks.entry(rule).or_default().push(task.clone());
80 }
81 }
82 }
83
84 if trans == "all" {
86 for transform in Transformation::iter() {
88 if transform == NoTrans || transform >= MirrorRowRotate90 { continue; }
89 let ex_copy = examples.transformation(transform);
92
93 let _rule = pass(all, &task, experiment, &ex_copy, transform, is_test, &mut output, &mut cap_cats, &mut cap_todo, &mut done, &mut tries);
94 }
95 }
96
97 cnt += 1;
98 }
99println!("Totals: {cap_cats:?}");
102
103 let cap_done: BTreeMap<GridCategory, i32> = cap_cats
104 .iter()
105 .map(|(cat, i)| {
106 if let Some(j) = cap_todo.get(cat) {
107 (*cat, *i - j)
108 } else {
109 (*cat, *i)
110 }
111 })
112 .collect();
113
114 if is_test {
115 create_output(true, &output);
116 }
117
118 println!("Complete: {cap_done:?}");
119 if rule_tasks.len() > 0 {
121 format(&rule_tasks);
122 println!("Generalisation Ratio: {:.4}", done.len() as f64 / rule_tasks.len() as f64);
123 }
124 println!("Done = {}, To Do = {}, tries = {tries}", done.len(), cnt - done.len());
125
126 let timing = start.elapsed().as_secs() as f64 + start.elapsed().subsec_millis() as f64 / 1000.0;
127
128 println!("Elapsed time: {timing} secs");
129 println!("Used memory : {:.2} Mb", PEAK.current_usage_as_mb());
130}
131
132fn pass(all: bool, task: &str, experiment: &str, examples: &Examples, trans: Transformation, is_test: bool, output: &mut BTreeMap<String, Vec<OutputData>>, cap_cats: &mut BTreeMap<GridCategory, i32>, cap_todo: &mut BTreeMap<GridCategory, i32>, done: &mut BTreeSet<String>, tries: &mut usize) -> Option<usize> {
133 let cat = &examples.cat;
134 let targets: Vec<Grid> = examples.tests.iter().map(|test| test.output.grid.clone()).collect();
135
136 let colour_diffs = examples.io_colour_diff();
139 let all_colour_diffs = examples.io_all_colour_diff();
140 let colour_common = examples.io_colour_common();
141
142 let gc = BlankIn;
143 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
145
146 let colour = examples.examples[0].output.grid.colour;
147
148 let func = &|ex: &Example| {
149 let odd = ex.cat.contains(&InOutSquareSameSizeOdd);
150 let mut grid;
151
152 if odd {
153 grid = ex.input.grid.clone();
155
156 for (r, c) in grid.cells.keys() {
157 if r % 2 == 0 || c % 2 == 0 || r == grid.cells.rows - 1 || c == grid.cells.columns - 1 {
158 grid.cells[(r,c)].colour = colour;
159 }
160 }
161 } else {
162 let sq = ex.cat.contains(&InOutSquareSameSize);
163
164 grid = ex.input.grid.do_circle(colour, sq);
165 }
166
167 grid
168 };
169
170 if let Some(rule) = run_experiment(task, 187, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
171
172 *cap_todo.entry(gc).or_insert(0) += 1;
173 }
174
175 let gc = BlackPatches;
176 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
178
179 let func = &|ex: &Example| {
182 if ex.input.black.is_empty() || !ex.input.grid.is_square() || ex.input.grid.size() < 16 * 16 {
183 return Grid::trivial();
184 }
185
186 fn pop_bp(grid: &Grid, black_patches: &Shapes, out: &mut Shapes) {
188 for bp in black_patches.shapes.iter() {
189 if grid.cells[(bp.orow,bp.ocol+bp.cells.columns-1)].colour != Black {
190 let sg = grid.subgrid(bp.orow, bp.cells.rows, bp.ocol, bp.cells.columns);
191 let ss = sg.to_shapes_coloured();
192
193 for s in ss.shapes.iter() {
194 let b = if s.orow == 0 {
195 if bp.orow + s.cells.rows >= grid.cells.rows || bp.ocol + s.cells.columns + 1 >= grid.cells.columns {
196 return;
197 }
198 let g = grid.subgrid(bp.orow, s.cells.rows, bp.ocol, s.cells.columns + 1);
199 g.as_shape().to_position(bp.orow, bp.ocol)
200 } else {
201 if bp.orow + s.orow + s.cells.rows >= grid.cells.rows || bp.ocol + s.cells.columns + s.cells.columns + 1 >= grid.cells.columns {
202 return;
203 }
204 let g = grid.subgrid(bp.orow + s.orow, s.cells.rows, bp.ocol + s.cells.columns, s.cells.columns + 1);
205
206 g.as_shape().to_position(bp.orow + s.orow, bp.ocol + s.cells.columns)
207 };
208
209 out.shapes.push(b);
210 }
211 } else {
212 out.shapes.push(bp.clone());
213 }
214 }
215 }
216
217 let mut grid = ex.input.grid.clone();
218 let bp_in = ex.input.black.clone();
219 let mut black_patches: Shapes = ex.input.black.clone_base();
220
221 pop_bp(&grid, &bp_in, &mut black_patches);
222
223 for it in 0 .. 4 { 'second:
225 for bp in black_patches.shapes.iter() {
226 let r1 = if bp.orow > 0 { bp.orow - 1 } else { bp.orow };
227 let r2 = if bp.orow + bp.cells.rows < grid.cells.rows { bp.orow + bp.cells.rows + 1 } else { bp.orow + bp.cells.rows };
228 let c1 = if bp.ocol > 0 { bp.ocol - 1 } else { bp.ocol };
229 let c2 = if bp.ocol + bp.cells.columns < grid.cells.columns { bp.ocol + bp.cells.columns + 1 } else { bp.ocol + bp.cells.columns };
230 let m = grid.cells.slice(r1 .. r2, c1 .. c2);
231
232 if let Ok(m) = m {
233 let s = Shape::new(bp.orow, bp.ocol, &m);
234let l = c2 - c1;
236 let fw = m.windows(l).next().unwrap();
237 let sc: Vec<_> = fw.iter().map(|c| c.colour).collect();
238 for w in grid.cells.windows(l) {
239 let fc: Vec<_> = w.iter().map(|c| c.colour).collect();
240 if sc == fc && (fw[0].row != w[0].row || fw[0].col != w[0].col) {
241 let patch = grid.get_patch(w[0].row, w[0].col, m.rows, m.columns);
242 if s.same_patch(&patch) {
244 let sor = if s.orow > 0 { s.orow - 1 } else { s.orow };
245 let soc = if s.ocol > 0 { s.ocol - 1 } else { s.ocol };
246
247 grid.fill_patch_mut(&patch, sor, soc);
248
249 continue 'second;
250 }
251 }
252 }
253 } else {
254 return Grid::trivial();
255 }
256 }
257 if it % 2 == 0 {
258 grid = ex.input.grid.rot_180();
259 let bp_in = black_patches.clone();
260 black_patches = grid.find_black_patches();
261 pop_bp(&grid, &bp_in, &mut black_patches);
262 } else {
263 grid = grid.rot_180();
264 }
265 if grid.full() {
266 break
267 }
268 }
269grid
272 };
273
274 if let Some(rule) = run_experiment(task, 292, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
275
276 let func = &|ex: &Example| {
277 if ex.input.black.is_empty() || !ex.input.grid.is_square() || ex.input.grid.size() < 20 * 20 {
278 return Grid::trivial();
279 }
280
281 let mut grid = ex.input.grid.clone();
282
283 grid.fill_border();
284
285 let mut pr = 0;
286 let mut pc = 0;
287 let mut lc = 0; loop {
290 let black = grid.find_black_patches();
291
292 if black.is_empty() || lc >= 10 {
293 break;
294 }
295
296 for p in black.shapes.iter() {
297 let ra = if p.ocol == 0 {
298 Vec::new()
299 } else if let Ok(xs) = grid.cells.slice(p.orow .. p.orow+p.cells.rows, p.ocol-1 .. p.ocol) {
300 let xa: Vec<_> = xs.values().map(|c| c.colour).collect();
301 if Colour::single_colour_vec(&xa) {
302 Vec::new()
303 } else {
304 xa
305 }
306
307 } else {
308 Vec::new()
309 };
310 let ca = if p.orow == 0 {
311 Vec::new()
312 } else if let Ok(ys) = grid.cells.slice(p.orow-1 .. p.orow, p.ocol .. p.ocol+p.cells.columns) {
313 let ya: Vec<_> = ys.values().map(|c| c.colour).collect();
314 if Colour::single_colour_vec(&ya) {
315 Vec::new()
316 } else {
317 ya
318 }
319 } else {
320 Vec::new()
321 };
322 if !ra.is_empty() && ra.len() >= ca.len() {
323 let (xo, yo) = grid.find_row_seq(p.orow, p.ocol, &ra, p.cells.columns);
324 if xo == usize::MAX && yo == usize::MAX || pr == xo && pc == yo {
325 return Grid::trivial();
326 }
327 for r in 0 .. p.cells.rows {
328 for c in 0 .. p.cells.columns {
329 if grid.cells[(p.orow+r,p.ocol+c)].colour == Black && xo+r < grid.cells.rows && yo+1+c < grid.cells.columns {
330 grid.cells[(p.orow+r,p.ocol+c)] = grid.cells[(xo+r,yo+1+c)].clone();
331 }
332 }
333 }
334
335 pr = xo;
336 pc = yo;
337 }
338 else if !ca.is_empty() {
339 let (xo, yo) = grid.find_col_seq(p.orow, p.ocol, &ca, p.cells.rows);
340 if xo == usize::MAX && yo == usize::MAX || pr == xo && pc == yo {
341 return Grid::trivial();
342 }
343 for r in 0 .. p.cells.rows {
344 for c in 0 .. p.cells.columns {
345 if grid.cells[(p.orow+r,p.ocol+c)].colour == Black && xo+1+r < grid.cells.rows && yo+c < grid.cells.columns {
346 grid.cells[(p.orow+r,p.ocol+c)] = grid.cells[(xo+1+r,yo+c)].clone();
347 }
348 }
349 }
350
351 pr = xo;
352 pc = yo;
353 } else {
354 return Grid::trivial();
355 }
356 }
357 lc += 1;
358 }
359grid
362 };
363
364 if let Some(rule) = run_experiment(task, 382, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
365
366 if !examples.examples[0].input.black.is_empty() && !examples.examples[0].output.shapes.shapes.is_empty() {
367 let mut ccm = examples.examples[0].output.grid.as_shape().cell_colour_cnt_map();
368 let bg = examples.examples[0].output.grid.cells[(0,0)].colour;
370 let border = examples.examples[0].output.shapes.shapes[0].colour;
371
372 ccm.remove(&bg);
373 ccm.remove(&border);
374
375 let func = |ex: &Example| {
376 if ccm.len() != 1 || !ex.input.black.shapes[0].is_square() {
377 return Grid::trivial();
378 }
379
380 let side = ex.input.black.shapes[0].cells.rows;
382 let Some((inner, _)) = ccm.first_key_value() else { todo!() };
383 let mut grid = ex.input.grid.clone();
384
385 for s in ex.input.black.shapes.iter() {
386 if s.orow == 0 || s.ocol == 0 {
387 return Grid::trivial();
388 }
389 if s.orow <= 2 || s.ocol <= 2 || s.orow >= grid.cells.rows - side - 2 || s.ocol >= grid.cells.columns - side - 2 {
390 grid.flood_fill_mut(s.orow, s.ocol, NoColour, border);
391 } else {
392 grid.flood_fill_mut(s.orow, s.ocol, NoColour, *inner);
393 }
394 }
395grid
398 };
399
400 if let Some(rule) = run_experiment(task, 418, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
401 }
402
403 let func = |ex: &Example| {
404 if colour_diffs.len() != 1 {
405 return Grid::trivial();
406 }
407 let colour = colour_diffs[0];
408 let g = &ex.input.grid;
409 let mut grid = g.clone();
410
411 grid.recolour_mut(Black, colour);
412
413 let shapes = grid.to_shapes_sq();
414
415 for s in shapes.shapes.iter() {
416 if s.is_pixel() && s.colour == colour {
417 grid.cells[(s.orow, s.ocol)].colour = Black;
418 }
419 }
420
421 grid
422 };
423
424 let (rs, cs) = examples.examples[0].output.grid.dimensions();
425
426 if let Some(rule) = run_experiment(task, 444, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
427
428 let func = |ex: &Example| {
429 if !ex.cat.contains(&NxNIn(15)) || !ex.cat.contains(&NxNOut(3)) || !colour_diffs.is_empty() {
430 return Grid::trivial();
431 }
432
433 let mut grid = Grid::new(rs, cs, ex.input.grid.colour);
434
435 for s in ex.input.black.shapes.iter() {
436 grid.cells[(s.orow / 5,s.ocol / 5)].colour = Black;
437 }
438grid
441 };
442
443 if let Some(rule) = run_experiment(task, 461, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
444
445 let func = |ex: &Example| {
446 if ex.input.shapes.shapes.is_empty() {
447 return Grid::trivial();
448 }
449
450 let mut shapes = ex.input.shapes.clone_base();
451
452 for s in ex.input.shapes.shapes.iter() {
453 let (dir,_) = s.has_arm(5);
454
455 if dir == Other {
456 let sn = s.recolour(Black, s.colour);
457
458 shapes.shapes.push(sn.clone());
459 }
460 }
461
462 for s in ex.input.shapes.shapes.iter() {
463 let (dir,len) = s.has_arm(5);
464
465 if dir == Other {
466 continue;
467 }
468
469 let sn = match dir {
470 Up => {
471 let s = s.subshape(len, s.cells.rows - len, 0, s.cells.columns);
472
473 if s.orow >= len {
474 s.to_position(s.orow - len, s.ocol)
475 } else {
476 return Grid::trivial();
477 }
478 },
479 Down => {
480 let s = s.subshape(0, s.cells.rows - len, 0, s.cells.columns);
481 s.to_position(s.orow + len, s.ocol)
482 },
483 Left => {
484 let s = s.subshape(0, s.cells.rows, len, s.cells.columns - len);
485 if s.ocol >= len {
486 s.to_position(s.orow, s.ocol - len)
487 } else {
488 return Grid::trivial();
489 }
490 },
491 Right => {
492 let s = s.subshape(0, s.cells.rows, 0, s.cells.columns - len);
493 s.to_position(s.orow, s.ocol + len)
494 },
495 _ => todo!(), };
497
498 shapes.shapes.push(sn.clone());
499 }
500
501 shapes.to_grid()
502 };
503
504 if let Some(rule) = run_experiment(task, 522, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
505
506 let func = |ex: &Example| {
508 if !ex.cat.contains(&OverlayInDiff) || !ex.cat.contains(&OverlayOutDiff) || ex.input.black.shapes.len() != 1 {
509 return Grid::trivial();
510 }
511
512 let g = &ex.input.grid;
513 let black = &ex.input.black.shapes[0];
514 let mut grid = ex.input.grid.clone();
515
516 for (r, c) in g.cells.keys() {
517 if g.cells[(r,c)].colour == Black {
518 if g.cells[(g.cells.rows - r - 1,c)].colour != Black {
519 grid.cells[(r,c)].colour = g.cells[(g.cells.rows - r - 1,c)].colour;
520 } else {
521 grid.cells[(r,c)].colour = g.cells[(r,g.cells.columns - c - 1)].colour;
522 }
523 }
524 }
525
526grid = grid.subgrid(black.orow, black.cells.rows, black.ocol, black.cells.columns);
528grid
531 };
532
533 if let Some(rule) = run_experiment(task, 551, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
534
535 if colour_diffs.len() == 2 {
536 for i in 0 .. 2 {
537 let func = |ex: &Example| {
538 if ex.input.shapes.shapes.is_empty() {
539 return Grid::trivial();
540 }
541 let mut shapes = ex.input.shapes.clone();
542 for s in ex.input.shapes.shapes.iter() {
545 let (dir, _) = s.has_arm(1);
546 let mut ns = if dir == Up || dir == Down {
547 let colour = colour_diffs[if i == 0 { 0 } else { 1 }];
548 s.mirrored_r().recolour(s.colour, colour)
549 } else if dir == Left || dir == Right {
550 let colour = colour_diffs[if i == 1 { 0 } else { 1 }];
551 s.mirrored_c().recolour(s.colour, colour)
552 } else {
553 s.clone()
554 };
555
556 match dir {
557 Left => ns.to_position_mut(s.orow, s.ocol + s.cells.columns + 1),
558 Right => if s.ocol > s.cells.columns {
559 ns.to_position_mut(s.orow, s.ocol - s.cells.columns - 1)
560 } else {
561 return Grid::trivial();
562 },
563 Down => if s.orow > s.cells.rows {
564 ns.to_position_mut(s.orow - s.cells.rows - 1, s.ocol)
565 } else {
566 return Grid::trivial();
567 },
568 Up => ns.to_position_mut(s.orow + s.cells.rows + 1, s.ocol),
569 _ => (),
570 }
571
572 shapes.shapes.push(ns);
573 }
574 shapes.trim_to_grid()
577 };
578
579 if let Some(rule) = run_experiment(task, 597, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
580 }
581 }
582
583 let func = |ex: &Example| {
585 if ex.input.shapes.shapes.is_empty() || colour_common.len() != 3 {
586 return Grid::trivial();
587 }
588 let mut colour_common = colour_common.clone();
589 let mut orig_colour = NoColour;
590
591 let (div_colour, mut shapes) = ex.input.grid.full_dim_split(&ex.input.shapes);
592
593 colour_common.retain(|&c| c != div_colour);
594
595 for s in shapes.shapes.iter_mut() {
596 if orig_colour == NoColour {
597 colour_common.retain(|&c| c != s.colour);
598 orig_colour = s.colour;
599 }
600
601 if colour_common.is_empty() {
602 return Grid::trivial();
603 }
604
605 if s.colour == div_colour {
606 break
607 }
608
609 s.recolour_mut(colour_common[0], orig_colour);
610 }
611
612 shapes.to_grid()
613 };
614
615 if let Some(rule) = run_experiment(task, 633, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
616
617 let func = |ex: &Example| {
618 if ex.input.shapes.shapes.is_empty() {
619 return Grid::trivial();
620 }
621
622 let mut cc = ex.input.shapes.colour_cnt();
623 let mut shapes = ex.input.shapes.clone_base();
624
625 for s in ex.input.shapes.shapes.iter() {
626 if !s.is_pixel() {
627 cc.remove(&s.colour);
628 }
629 }
630
631 for s in ex.input.shapes.shapes.iter() {
632 if !s.is_pixel() {
633 let mut ns = s.clone();
634 let bg_cnt = s.bg_count();
635 let colour: Vec<_> = cc.iter().filter(|&(&c,&s)|c != ns.colour && (s == if bg_cnt % 2 == 0 { bg_cnt / 2 } else { bg_cnt / 2 + 1})).collect();
636
637 if colour.len() != 1 {
638 return Grid::trivial();
639 }
640
641 let mut toddle = true;
643
644 for ((r, c), cell) in ns.cells.items_mut() {
645 if cell.colour == Black {
646 if r % 2 == 0 && c <= 1 {
648 toddle = false;
649 }
650 if toddle {
651 cell.colour = *colour[0].0;
652 }
653 toddle = !toddle;
654 }
655 }
656
657 shapes.shapes.push(ns);
658 }
659 }
660
661shapes.to_grid()
663 };
664
665 if let Some(rule) = run_experiment(task, 683, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
666
667 let func = |ex: &Example| {
668 if ex.input.shapes.shapes.is_empty() {
669 return Grid::trivial();
670 }
671
672 let mut shapes = ex.input.shapes.clone();
673
674 shapes.shapes.sort_by(|a, b| {
675 let (_, a_cc) = a.colour_cnt(true);
676 let (_, b_cc) = b.colour_cnt(true);
677
678 a_cc.cmp(&b_cc)
679 });
680
681 let mut pos = 0;
682
683 for s in shapes.shapes.iter_mut() {
684 if s.cells.rows > s.cells.columns {
685 s.to_position_mut(s.orow, pos);
686
687 pos += s.cells.columns + 1;
688 } else {
689 s.to_position_mut(pos, s.ocol);
690
691 pos += s.cells.rows + 1;
692 }
693 }
694
695 shapes.to_grid()
696 };
697
698 if let Some(rule) = run_experiment(task, 716, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
699
700 let func = |ex: &Example| {
701 if colour_diffs.len() != 1 {
702 return Grid::trivial();
703 }
704
705 ex.input.grid.rip(colour_diffs[0])
706 };
707
708 if let Some(rule) = run_experiment(task, 726, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
709
710 let func = |ex: &Example| {
711 let ss = ex.input.coloured_shapes.split_size(12);
712
713 if !colour_diffs.is_empty() && ss.shapes.len() < 2 {
714 return Grid::trivial();
715 }
716
717 let mut shapes = ex.input.coloured_shapes.clone_base();
718 let mut last_size = usize::MAX;
719
720 for s in ss.shapes.iter() {
721 if s.size() > 12 {
722 let s = s.shrink_border_n(3);
723
724 if s.size() == 0 || last_size != usize::MAX && last_size != s.size() {
725 return Grid::trivial();
726 }
727
728 if last_size == usize::MAX {
729 last_size = s.size();
730 }
731
732 shapes.shapes.push(s);
733 }
734 }
735 shapes.shapes.sort();
736let shape = shapes.majority_cell();
739
740 if shape.size() == 0 {
741 return Grid::trivial();
742 }
743
744 let (rrep, crep) = shapes.find_repeats();
745 let (rgap, cgap) = shapes.find_gaps();
746
747 shape.fit_chequer(rrep, crep, shapes.shapes[0].orow, shapes.shapes[0].ocol, rgap, cgap, ex.input.grid.cells.rows, ex.input.grid.cells.columns, &|s, _, _| s.clone()).to_grid()
748 };
749
750 if let Some(rule) = run_experiment(task, 768, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
751
752 let func = |ex: &Example| {
753 let pixels = ex.input.shapes.get_pixels();
754 let mut all_shapes = ex.input.shapes.clone();
755
756 if !colour_diffs.is_empty() || pixels.shapes.len() * 2 != all_shapes.shapes.len() {
757 return Grid::trivial();
758 }
759 let mut i = 0;
760
761 for ss in ex.input.shapes.shapes.iter() {
762 if !ss.is_pixel() {
763 let mut shapes = ss.get_joined();
764
765 for s in shapes.shapes.iter_mut() {
766 s.fill_centre_mut(pixels.shapes[i].colour);
767
768 all_shapes.shapes.push(s.clone());
769 }
770
771 i += 1;
772 }
773 }
774all_shapes.to_grid_transparent()
777 };
778
779 if let Some(rule) = run_experiment(task, 797, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
780
781 let func = |ex: &Example| {
782 if colour_diffs.len() != 1 || ex.input.shapes.len() < 2 {
783 return Grid::trivial();
784 }
785
786 let (rg, cg) = ex.input.shapes.find_gaps();
787 let ss = &ex.input.shapes.shapes;
788 let mut grid = ex.input.grid.clone();
789
790 for (r, c) in (ss[ss.len() - 1].orow + rg + 1 .. grid.cells.rows).step_by(rg + 1).zip((ss[ss.len() - 1].ocol + cg + 1 .. grid.cells.columns).step_by(cg + 1)) {
791 grid.cells[(r,c)].colour = colour_diffs[0];
792 }
793grid
796 };
797
798 if let Some(rule) = run_experiment(task, 816, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
799
800 let func = |ex: &Example| {
801 if ex.input.shapes.len() != 5 {
802 return Grid::trivial();
803 }
804 let in_shapes = ex.input.shapes.clone();
805 let rows = in_shapes.shapes[1].cells.rows;
806 let cols = in_shapes.shapes[1].cells.columns;
807 let (cr, cc) = in_shapes.shapes[0].mid_pixel();
808
809 let mut shapes = Shapes::new_sized(rows * 2, cols * 2);
810
811 for s in in_shapes.shapes.iter() {
812 if s.size() != ex.input.shapes.size() {
813 let ns = if s.orow < cr && s.ocol < cc {
814 s.to_position(0, 0)
815 } else if s.orow < cr && s.ocol >= cc {
816 s.to_position(0, cols)
817 } else if s.orow >= cr && s.ocol < cc {
818 s.to_position(rows, 0)
819 } else {
820 s.to_position(rows, cols)
821 };
822
823 shapes.shapes.push(ns);
824 }
825 }
826shapes.to_grid()
829 };
830
831 if let Some(rule) = run_experiment(task, 849, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
832
833 let func = |ex: &Example| {
834 if colour_diffs.len() != 1 {
835 return Grid::trivial();
836 }
837
838 let mut grid = ex.input.grid.clone();
839 let (min_r, min_c, max_r, max_c) = grid.corners();
840 let (r,c) = grid.centre_of_symmetry();
841
842 if r == 0 || c == 0 || r >= grid.cells.rows - 1 || c >= grid.cells.columns - 1 {
843 return Grid::trivial();
844 }
845
846 grid.cells[(r,c)].colour = colour_diffs[0];
847 grid.cells[(r-1,c-1)].colour = grid.cells[(min_r,min_c)].colour;
848 grid.cells[(r-1,c+1)].colour = grid.cells[(min_r,max_c)].colour;
849 grid.cells[(r+1,c-1)].colour = grid.cells[(max_r,min_c)].colour;
850 grid.cells[(r+1,c+1)].colour = grid.cells[(max_r,max_c)].colour;
851
852 grid
853 };
854
855 if let Some(rule) = run_experiment(task, 873, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
856
857 let out_csm = examples.colour_shape_map(true);
858 let cam = examples.colour_attachment_map(true);
859
860 let func = |ex: &Example| {
861 if all_colour_diffs.len() != 1 {
862 return Grid::trivial();
863 }
864 let (div_colour, mut shapes) = ex.input.grid.full_dim_split(&ex.input.shapes);
865
866 shapes.shapes.sort_by(|a, b| (a.ocol,a.orow).cmp(&(b.ocol,b.orow)));
867
868 let mut start = Shape::trivial();
869 let mut div = Shape::trivial();
870
871 for s in shapes.shapes.iter() {
872 if s.is_pixel() {
873 start = s.clone();
874 } else if s.cells.rows == ex.input.grid.cells.rows {
875 div = s.clone();
876 }
877 }
878
879 let mut new_shapes = Shapes::new_sized(ex.input.grid.cells.rows, div.ocol);
880 let mut r = 1;
881
882 if start.ocol <= div.ocol {
883 return Grid::trivial();
884 }
885
886 let mut c = start.ocol - div.ocol - 1;
887
888 start.to_position_mut(0, c);
889 new_shapes.shapes.push(start.clone());
890
891 for s in shapes.shapes.iter() {
892 if !s.is_pixel() && s.colour != div_colour {
893 if let Some(os) = out_csm.get(&s.colour) {
894 if let Some(left) = cam.get(&s.colour) {
895 let ns;
896
897 if *left {
898 ns = os.to_position(r, c);
899 c += os.cells.columns - 1;
900 } else {
901 if c < os.cells.columns - 1 {
902 return Grid::trivial();
903 }
904
905 c -= os.cells.columns - 1;
906 ns = os.to_position(r, c);
907 };
908
909 new_shapes.shapes.push(ns);
910 r += os.cells.rows;
911 }
912 }
913 }
914 }
915
916new_shapes.to_grid()
918 };
919
920 if let Some(rule) = run_experiment(task, 938, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
921
922 let func = |ex: &Example| {
923 if !all_colour_diffs.is_empty() {
924 return Grid::trivial();
925 }
926
927 let (div_colour, mut shapes) = ex.input.grid.full_dim_split(&ex.input.shapes);
928 let div = shapes.find_by_colour(div_colour);
929 let mut grid = ex.input.grid.clone();
930
931 for s in shapes.shapes.iter() {
933 if s.colour != div_colour {
934 if div.orow == ex.input.grid.cells.rows - 1 && div.cells.rows == 1 {
935 shapes.shapes.sort_by(|a, b| a.orow.cmp(&b.orow));
936 } else if div.ocol == ex.input.grid.cells.columns - 1 && div.cells.columns == 1 {
937 shapes.shapes.sort_by(|a, b| a.ocol.cmp(&b.ocol));
938 } else if div.orow == 0 && div.cells.rows == 1 {
939 shapes.shapes.sort_by(|a, b| b.orow.cmp(&a.orow));
940 } else {
941 shapes.shapes.sort_by(|a, b| b.ocol.cmp(&a.ocol));
942 }
943 break;
944 }
945 }
946
947 for s in shapes.shapes.iter() {
948 if s.colour != div_colour {
949 if div.orow == ex.input.grid.cells.rows - 1 && div.cells.rows == 1 {
950 for r in s.orow .. ex.input.grid.cells.rows - 1 {
951 for c in 0 .. s.cells.columns {
952 grid.cells[(r,c+s.ocol)].colour = s.colour;
953 }
954 }
955 } else if div.ocol == ex.input.grid.cells.columns - 1 && div.cells.columns == 1 {
956 for r in 0 .. s.cells.rows {
957 for c in s.ocol .. ex.input.grid.cells.columns - 1 {
958 grid.cells[(r+s.orow,c)].colour = s.colour;
959 }
960 }
961 } else if div.orow == 0 && div.cells.rows == 1 {
962 for r in (1 ..= s.orow).rev() {
963 for c in s.ocol .. s.ocol + s.cells.columns {
964 grid.cells[(r,c)].colour = s.colour;
965 }
966 }
967 } else {
968 for r in s.orow .. s.orow + s.cells.rows {
969 for c in (1 ..= s.ocol).rev() {
970 grid.cells[(r,c)].colour = s.colour;
971 }
972 }
973 }
974 }
975 }
976
977grid
979 };
980
981 if let Some(rule) = run_experiment(task, 999, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
982
983 let func = |ex: &Example| {
984 let mut shapes = ex.input.shapes.clone_base();
985
986 for s in ex.input.shapes.shapes.iter() {
987 for s2 in ex.input.shapes.shapes.iter() {
988 if s != s2 && s.container(&s2) {
989 let (s_r, _) = s.centre_of_exact();
990 let (s2_r, _) = s2.centre_of_exact();
991 shapes.shapes.push(s.clone());
992 shapes.shapes.push(s2.clone());
993
994 let sm = if s_r == s2_r {
995 let sm = s2.mirrored_c();
996
997 if sm.ocol + sm.cells.columns * 2 + 1 < s.ocol + s.cells.columns {
998 let extra = if s.cells.columns % 2 != 0 { 1 } else { 0 };
999 sm.to_position(sm.orow, s.ocol + s.cells.columns / 2 + extra)
1000 } else {
1001 sm.to_position(sm.orow, s.ocol + sm.cells.columns)
1002 }
1003 } else {
1004 let sm = s2.mirrored_r();
1005
1006 if sm.orow + sm.cells.rows * 2 + 1 < s.orow + s.cells.rows {
1007 let extra = if s.cells.rows % 2 != 0 { 1 } else { 0 };
1008 sm.to_position(s.orow + s.cells.rows / 2 + extra, sm.ocol)
1009 } else {
1010 sm.to_position(s.orow + sm.cells.rows, sm.ocol)
1011 }
1012 };
1013
1014 shapes.shapes.push(sm);
1015 }
1016 }
1017 }
1018
1019 shapes.to_grid()
1020 };
1021
1022 if let Some(rule) = run_experiment(task, 1040, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1023
1024 let func = |ex: &Example| {
1025 if !colour_diffs.is_empty() {
1026 return Grid::trivial();
1027 }
1028 let sc = ex.input.shapes.size_cnt();
1029 if sc.len() != 1 {
1030 return Grid::trivial();
1031 }
1032 let Some((_, n)) = sc.first_key_value() else { todo!() };
1033 if *n != 4 {
1035 return Grid::trivial();
1036 }
1037 let (rs, cs) = ex.input.shapes.shapes[0].dimensions();
1038 if rs != cs {
1039 return Grid::trivial();
1040 }
1041
1042 let mut shapes = Shapes::new_sized(rs * 2 + 1, cs * 2 + 1);
1043
1044 let corners = ex.input.shapes.all_corners();
1045
1046 let mut row = 0;
1047 let mut col = 0;
1048
1049 for (i, (r, c)) in corners.iter().enumerate() {
1050 let s = ex.input.shapes.nearest_shape(*r, *c);
1051
1052 shapes.shapes.push(s.to_position(row, col));
1053
1054 match i {
1055 0 => col = cs + 1,
1056 1 => row = rs + 1,
1057 2 => col = 0,
1058 3 => row = 0,
1059 _ => todo!(),
1060 }
1061 }
1062
1063 shapes.to_grid()
1064 };
1065
1066 if let Some(rule) = run_experiment(task, 1084, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1067
1068 let func = |ex: &Example| {
1069 if all_colour_diffs.len() != 1 {
1070 return Grid::trivial();
1071 }
1072 let sc = ex.input.shapes.size_cnt();
1073 if sc.len() != 2 || ex.input.shapes.shapes.len() < 3 || all_colour_diffs.len() != 1 {
1074 return Grid::trivial();
1075 }
1076
1077 let mut grid = Grid::new(2, 2, Black);
1078
1079 let corners = ex.input.shapes.all_corners();
1080
1081 for s in ex.input.shapes.shapes.iter() {
1082 if s.colour != all_colour_diffs[0] {
1083 match s.nearest_point_idx(&corners) {
1084 0 => grid.cells[(0,0)].colour = s.colour,
1085 1 => grid.cells[(0,1)].colour = s.colour,
1086 2 => grid.cells[(1,1)].colour = s.colour,
1087 3 => grid.cells[(1,0)].colour = s.colour,
1088 _ => todo!(),
1089 }
1090 }
1091 }
1092
1093grid
1095 };
1096
1097 if let Some(rule) = run_experiment(task, 1121, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1098
1099 let func = |ex: &Example| {
1100 if !colour_diffs.is_empty() {
1101 return Grid::trivial();
1102 }
1103
1104 let ccm = ex.input.shapes.shape_colour_cnt_map();
1105
1106 let mut grid = Grid::new(ex.input.grid.cells.rows, ex.input.grid.cells.columns, Black);
1107
1108 let mut box_tlr = 0;
1109 let mut box_tlc = 0;
1110
1111 for (col, sv) in ccm.iter() {
1112 if sv.len() == 1 {
1113 box_tlr = sv[0].orow;
1114 box_tlc = sv[0].ocol;
1115 let box_brr = box_tlr + sv[0].cells.rows;
1116 let box_brc = box_tlc + sv[0].cells.columns;
1117
1118 grid.fill_patch_coord_mut(box_tlr, box_tlc, box_brr - box_tlr, box_brc - box_tlc, *col);
1119 }
1120 }
1121
1122 for (col, sv) in ccm.iter() {
1123 if sv.len() > 1 {
1124 let (mut tlr, mut tlc, brr, brc) = Shapes::new_shapes(&sv).corners();
1125
1126 let rlen = brr - tlr - 1;
1127 let clen = brc - tlc - 1;
1128
1129 tlr = tlr.max(box_tlr);
1130 tlc = tlc.max(box_tlc);
1131
1132 if grid.cells.rows < tlr + rlen || grid.cells.columns < tlc + clen {
1133 return Grid::trivial();
1134 }
1135
1136 grid.fill_patch_coord_mut(tlr, tlc, rlen, clen, *col);
1137 }
1138 }
1139grid
1142 };
1143
1144 if let Some(rule) = run_experiment(task, 1168, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1145
1146 let func = |ex: &Example| {
1147 if ex.input.shapes.shapes.len() < 5 {
1148 return Grid::trivial();
1149 }
1150
1151 let mut shapes = ex.input.shapes.clone();
1152 let idx = &ex.input.shapes.shapes[0];
1153 let mut colour = NoColour;
1154
1155 for s in ex.input.shapes.shapes.iter() {
1156 if s.size() == 1 && s.orow < idx.cells.rows && s.ocol < idx.cells.columns {
1157 colour = s.colour;
1158 }
1159 }
1160
1161 for s in shapes.shapes.iter_mut() {
1162 if s.colour == colour && (s.orow >= idx.cells.rows || s.ocol >= idx.cells.columns) {
1163 s.force_recolour_mut(Black);
1164 }
1165 }
1166
1167 shapes.to_grid()
1168 };
1169
1170 if let Some(rule) = run_experiment(task, 1194, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1171
1172 let func = |ex: &Example| {
1173 let colours = Uniq::uniq(&colour_common, all_colour_diffs.clone());
1174 if ex.input.shapes.shapes.len() < 2 || colour_diffs.len() != 1 || colours.len() != 1 {
1175 return Grid::trivial();
1176 }
1177
1178 let (tlr, tlc, brr, brc) = ex.input.shapes.corners();
1179 let mut grid = ex.input.grid.clone();
1180
1181 grid.draw_mut(Down, 0, tlc, colours[0]);
1182 grid.draw_mut(Down, 0, brc - 1, colours[0]);
1183 grid.draw_mut(Right, tlr, 0, colours[0]);
1184 grid.draw_mut(Right, brr - 1, 0, colours[0]);
1185
1186 grid.flood_fill_mut(tlr + 1, tlc + 1, NoColour, colour_diffs[0]);
1187
1188grid
1190 };
1191
1192 if let Some(rule) = run_experiment(task, 1216, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1193
1194 if colour_diffs.len() == 1 {
1195 let mut gap = 0;
1196
1197 for (i, s) in examples.examples[0].output.shapes.shapes.iter().enumerate() {
1198 if i == 0 && s.colour == colour_diffs[0] {
1199 continue;
1200 } else if s.colour == colour_diffs[0] {
1201 gap = i;
1202 break;
1203 }
1204 }
1205
1206 let func = |ex: &Example| {
1207 if ex.input.shapes.shapes.len() < 2 || gap == 0 {
1208 return Grid::trivial();
1209 }
1210
1211 let mut shapes = ex.input.shapes.clone();
1212
1213 for (i, s) in shapes.shapes.iter_mut().enumerate() {
1214 if i % gap == 0 {
1215 s.force_recolour_mut(colour_diffs[0]);
1216 }
1217 }
1218
1219shapes.to_grid()
1221 };
1222
1223 if let Some(rule) = run_experiment(task, 1247, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1224 }
1225
1226 let func = |ex: &Example| {
1227 if ex.input.shapes.shapes.len() < 4 {
1228 return Grid::trivial();
1229 }
1230
1231 let mut grid = ex.input.grid.clone();
1232 let mut shapes: BTreeMap<Colour, Vec<&Shape>> = BTreeMap::new();
1233
1234 for s in ex.input.shapes.shapes.iter() {
1235 if s.size() != ex.input.grid.size() {
1236 shapes.entry(s.colour).and_modify(|sv| sv.push(s)).or_insert(vec![s]);
1237 }
1238 }
1239
1240 for (_colour, shapes) in shapes.iter() {
1241 let origins = Shapes::origins(shapes);
1242
1243 if origins.is_empty() {
1244 return Grid::trivial();
1245 }
1246
1247 for (i, (r, c)) in origins.iter().enumerate() {
1248 if !Shapes::contains_origin(shapes, *r, *c) {
1249 let posn = if i == 0 { 3 } else { i - 1 };
1250
1251 if posn >= shapes.len() {
1252 return Grid::trivial();
1253 }
1254
1255 let s = if posn % 2 == 0 {
1256 shapes[posn].mirrored_c()
1257 } else {
1258 shapes[posn].mirrored_r()
1259 };
1260
1261 let s = s.to_position(*r, *c);
1262
1263 grid.copy_shape_to_grid_mut(&s);
1264 }
1265 }
1266 }
1267grid
1269 };
1270
1271 if let Some(rule) = run_experiment(task, 1295, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1272
1273 let func = |ex: &Example| {
1274 if ex.input.shapes.shapes.len() < 10 || colour_common.len() < 5 {
1275 return Grid::trivial();
1276 }
1277
1278 let mut cc: BTreeMap<Colour, usize> = BTreeMap::new();
1279 let mut corners: Vec<Shape> = Vec::new();
1280
1281 for s in ex.input.shapes.shapes.iter() {
1282 if s.size() == 4 {
1283 *cc.entry(s.colour).or_insert(0) += 1;
1284 corners.push(s.clone());
1285 }
1286 }
1287
1288 let (_, max_col) = if let Some(col) = cc.iter().map(|(&c, &n)| (n, c)).max() {
1289 col
1290 } else {
1291 (0, NoColour)
1292 };
1293 let (_, min_col) = if let Some(col) = cc.iter().map(|(&c, &n)| (n, c)).min() {
1294 col
1295 } else {
1296 (0, NoColour)
1297 };
1298 let (tlr, tlc, brr, brc) = Shapes::vec_corners(&corners);
1299 let mut grid = ex.input.grid.clone();
1300
1301 if brr - tlr < 2 || brc - tlc < 2 || brr == tlr || brc == tlc || tlr == 0 || tlc == 0 || grid.cells.columns == brc || grid.cells.rows == brr {
1302 return Grid::trivial();
1303 }
1304
1305 let centre = Shape::new_sized_coloured_position(tlr, tlc, brr - tlr, brc - tlc, max_col);
1306 let scentre = Shape::new_sized_coloured_position(tlr + 1, tlc + 1, brr - tlr - 2, brc - tlc - 2, min_col);
1307 let left = Shape::new_sized_coloured_position(tlr, 0, brr - tlr, tlc, min_col);
1308 let right = Shape::new_sized_coloured_position(tlr, brc, brr - tlr, grid.cells.columns - brc, min_col);
1309 let up = Shape::new_sized_coloured_position(0, tlc, tlr, brc - tlc, min_col);
1310 let down = Shape::new_sized_coloured_position(brr, tlc, grid.cells.rows - brr, brc - tlc, min_col);
1311 grid.copy_shape_to_grid_mut(¢re);
1312 grid.copy_shape_to_grid_mut(&scentre);
1313 grid.copy_shape_to_grid_mut(&left);
1314 grid.copy_shape_to_grid_mut(&right);
1315 grid.copy_shape_to_grid_mut(&up);
1316 grid.copy_shape_to_grid_mut(&down);
1317
1318 for s in ex.input.shapes.shapes.iter() {
1319 if s.size() == 1 && grid.cells[(s.orow,s.ocol)].colour == min_col {
1320 if s.orow <= tlr && (s.orow == 0 || grid.cells[(s.orow-1,s.ocol)].colour == min_col) {
1322 grid.draw_bg_mut(Up, s.orow, s.ocol, s.colour, min_col);
1323 } else if s.orow >= brr && (s.orow == grid.cells.rows - 1 || grid.cells[(s.orow+1,s.ocol)].colour == min_col) {
1324 grid.draw_bg_mut(Down, s.orow, s.ocol, s.colour, min_col);
1325 } else if s.ocol <= tlc && (s.ocol == 0 || grid.cells[(s.orow,s.ocol-1)].colour == min_col) {
1326 grid.draw_bg_mut(Left, s.orow, s.ocol, s.colour, min_col);
1327 } else if s.ocol >= brc {
1328 grid.draw_bg_mut(Right, s.orow, s.ocol, s.colour, min_col);
1329 }
1330 }
1331 }
1332 grid
1333 };
1334
1335 if let Some(rule) = run_experiment(task, 1359, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1336
1337 let func = |ex: &Example| {
1338 if ex.input.shapes.shapes.len() < 5 || ex.input.coloured_shapes.shapes.len() != ex.input.shapes.shapes.len() {
1339 return Grid::trivial();
1340 }
1341
1342 let ccm = ex.input.shapes.shape_colour_cnt_map();
1343 let r = ccm.len();
1344 let c = if let Some(c) = ccm.iter().map(|(_,vs)| vs.len()).max() {
1345 c
1346 } else {
1347 0
1348 };
1349
1350 if c == 0 {
1351 return Grid::trivial();
1352 }
1353
1354 let mut grid = Grid::new(r, c, Black);
1355 let mut i = 0;
1356
1357 let mut cs: Vec<(usize, Colour)> = ccm.iter().map(|(colour,vs)| (vs.len(), *colour)).collect();
1358
1359 cs.sort_by(|a, b| b.cmp(a));
1360
1361 for (len, colour) in cs.iter() {
1362 for j in 0 .. *len {
1363 grid.cells[(i, c - len + j)].colour = *colour;
1364 }
1365
1366 i += 1;
1367 }
1368
1369grid
1371 };
1372
1373 if let Some(rule) = run_experiment(task, 1397, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1374
1375 let func = |ex: &Example| {
1376 if ex.input.coloured_shapes.shapes.len() < 2 {
1377 return Grid::trivial();
1378 }
1379 let mut posn = 0;
1380 let mut horizontal = true;
1381 let mut shapes = ex.input.coloured_shapes.clone();
1382
1383 for s in ex.input.coloured_shapes.shapes.iter() {
1384 if s.orow == 0 && s.cells.rows == ex.input.grid.cells.rows {
1385 horizontal = false;
1386 posn = s.ocol;
1387
1388 } else if s.ocol == 0 && s.cells.columns == ex.input.grid.cells.columns {
1389 horizontal = true;
1390 posn = s.orow;
1391 }
1392 }
1393
1394 for s in ex.input.coloured_shapes.shapes.iter() {
1395 if (s.orow != 0 || s.cells.rows != ex.input.grid.cells.rows) && (s.ocol != 0 || s.cells.columns != ex.input.grid.cells.columns) {
1396 let ccm = s.cell_colour_cnt_map();
1397
1398 if ccm.len() != 2 {
1399 return Grid::trivial();
1400 }
1401
1402 let colours: Vec<Colour> = ccm.iter().map(|(c, _)| *c).collect();
1403 shapes.shapes.push(s.toddle_colour(colours[0], colours[1]));
1404
1405 let s = if horizontal {
1406 if posn > s.orow {
1407 s.mirrored_r().to_position(posn + 2, s.ocol)
1408 } else {
1409 if posn < s.cells.rows + 1 {
1410 return Grid::trivial();
1411 }
1412
1413 s.mirrored_r().to_position(posn - 1 - s.cells.rows, s.ocol)
1414 }
1415 } else {
1416 if posn > s.ocol {
1417 s.mirrored_c().to_position(s.orow, posn + 2)
1418 } else {
1419 if posn < s.cells.columns + 1 {
1420 return Grid::trivial();
1421 }
1422
1423 s.mirrored_c().to_position(s.orow, posn - 1 - s.cells.columns)
1424 }
1425 };
1426
1427 shapes.shapes.push(s);
1428 }
1429 }
1430
1431shapes.to_grid()
1433 };
1434
1435 if let Some(rule) = run_experiment(task, 1459, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1436
1437 let func = |ex: &Example| {
1438 if ex.input.coloured_shapes.shapes.len() < 2 || all_colour_diffs.len() != 1 {
1439 return Grid::trivial();
1440 }
1441 let shapes = ex.input.grid.recolour(Black, NoColour).to_shapes();
1442 let mut shape = Shape::trivial();
1443 let mut bg = Shape::trivial();
1444 let mut pixel1 = Shape::trivial();
1445 let mut pixel2 = Shape::trivial();
1446
1447 for s in shapes.shapes.iter() {
1448 if s.size() == ex.input.grid.size() {
1449 continue;
1450 }
1451 if s.size() > 1 && s.colour != NoColour {
1452 shape = s.clone();
1453 } else if s.is_pixel() {
1454 if pixel1 == Shape::trivial() {
1455 pixel1 = s.clone();
1456 } else {
1457 pixel2 = s.clone();
1458 };
1459 } else if s.size() > 1 && s.colour == NoColour && s.colour_cnt(false).1 + 1 == s.size() {
1460 bg = s.clone();
1461 }
1462 }
1463 if pixel1.colour != pixel2.colour {
1464 return Grid::trivial();
1465 }
1466
1467 let mut grid = Grid::new(bg.cells.rows, bg.cells.columns, Black);
1468
1469 let (pixel, shape_pixel) = if pixel1.contained_by(&bg) {
1470 (&pixel1, pixel2)
1471 } else {
1472 (&pixel2, pixel1)
1473 };
1474
1475 if pixel.orow < bg.orow || pixel.ocol < bg.ocol {
1476 return Grid::trivial();
1477 }
1478
1479 let r = pixel.orow - bg.orow;
1480 let c = pixel.ocol - bg.ocol;
1481
1482 if shape_pixel.orow < shape.orow || shape_pixel.ocol < shape.ocol {
1483 return Grid::trivial();
1484 }
1485
1486 let sr = shape_pixel.orow - shape.orow;
1487 let sc = shape_pixel.ocol - shape.ocol;
1488
1489 if r < sr || c < sc {
1490 return Grid::trivial();
1491 }
1492
1493 grid.copy_shape_to_grid_position_mut(&shape, r - sr, c - sc);
1494 grid.copy_shape_to_grid_position_mut(&pixel, r, c);
1495
1496grid
1498 };
1499
1500 if let Some(rule) = run_experiment(task, 1524, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1501
1502 let (out_r, out_c) = examples.examples[0].output.grid.dimensions();
1503
1504 let func = |ex: &Example| {
1505 if ex.input.shapes.shapes.len() < 20 {
1506 return Grid::trivial();
1507 }
1508
1509 let mut cnt = 0;
1510 let mut ms = &Shape::trivial();
1511
1512 for s in ex.input.shapes.shapes.iter() {
1513 if s.size() > 4 {
1514 let (_, n) = if let Some(n) = s.cell_colour_cnt_map().pop_first() {
1515 n
1516 } else {
1517 (NoColour, 0)
1518 };
1519 if n > cnt {
1520 cnt = n;
1521 ms = &s;
1522 }
1523 }
1524 }
1525 let grid = Grid::new(out_r, out_c, ms.colour);
1526
1527grid
1529 };
1530
1531 if let Some(rule) = run_experiment(task, 1555, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1532
1533 let mut colour = NoColour;
1534
1535 for s in examples.examples[0].input.black.shapes.iter() {
1536 if s.is_square() {
1537 colour = examples.examples[0].output.grid.find_axis_colour(&s);
1538 }
1539 }
1540
1541 let func = |ex: &Example| {
1542 if ex.input.black.shapes.len() != 1 || colour == NoColour {
1543 return Grid::trivial();
1544 }
1545 let mut grid = ex.input.grid.clone();
1546 let patch = &ex.input.black.shapes[0];
1547
1548 for r in 0 .. grid.cells.rows {
1549 for c in patch.ocol .. patch.ocol + patch.cells.columns {
1550 if grid.cells[(r,c)].colour != colour {
1551 grid.cells[(r,c)].colour = Black;
1552 }
1553 }
1554 }
1555
1556 for c in 0 .. grid.cells.columns {
1557 for r in patch.orow .. patch.orow + patch.cells.rows {
1558 if grid.cells[(r,c)].colour != colour {
1559 grid.cells[(r,c)].colour = Black;
1560 }
1561 }
1562 }
1563
1564 grid
1565 };
1566
1567 if let Some(rule) = run_experiment(task, 1591, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1568
1569 let func = |ex: &Example| {
1570 if colour_diffs.len() != 1 {
1571 return Grid::trivial();
1572 }
1573
1574 let mut grid = ex.input.grid.clone();
1575
1576 for s in ex.input.shapes.shapes.iter() {
1577 grid.draw_mc_mut(Up, s.orow, s.ocol, s.colour);
1578 grid.draw_mc_mut(Down, s.orow, s.ocol, s.colour);
1579 grid.draw_mc_mut(Left, s.orow, s.ocol, s.colour);
1580 grid.draw_mc_mut(Right, s.orow, s.ocol, s.colour);
1581 }
1582
1583 for s in ex.input.shapes.shapes.iter() {
1584 grid.recolour_mut(s.colour + ToBlack, colour_diffs[0]);
1585 }
1586
1587grid
1589 };
1590
1591 if let Some(rule) = run_experiment(task, 1592, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1592
1593 let func = |ex: &Example| {
1594 if all_colour_diffs.len() != 1 {
1595 return Grid::trivial();
1596 }
1597
1598 let mut grid = ex.input.grid.clone();
1599
1600 for s in ex.input.shapes.shapes.iter() {
1601 if s.is_pixel() {
1602 let colour = ex.input.grid.shape_in_line(&s);
1603
1604 if colour != NoColour {
1605 grid.flood_fill_bg_mut(s.orow, s.ocol, NoColour, all_colour_diffs[0], s.colour);
1606 } else {
1607 grid.flood_fill_bg_mut(s.orow, s.ocol, NoColour, Black, s.colour);
1608 }
1609 }
1610 }
1611
1612grid
1614 };
1615
1616 if let Some(rule) = run_experiment(task, 1593, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1617
1618 let func = |ex: &Example| {
1619 if ex.input.shapes.shapes.len() < 6 {
1620 return Grid::trivial();
1621 }
1622
1623 let mut shapes = ex.input.shapes.clone_base();
1624
1625 for s in ex.input.shapes.shapes.iter() {
1626 if s.hollow() {
1627 let mut cc: BTreeMap<Colour, usize> = BTreeMap::new();
1628 let mut pix = Shape::trivial();
1629
1630 for s2 in ex.input.shapes.shapes.iter() {
1631 if s2.is_pixel() && s2.contained_by(&s) {
1632 *cc.entry(s2.colour).or_insert(0) += 1;
1633 pix = s2.clone();
1634 }
1635 }
1636 if let Some((_,c)) = cc.iter().map(|(k,v)| (v, k)).max() {
1637 let ss = s.flood_fill(pix.orow - s.orow, pix.ocol - s.ocol, NoColour, *c);
1638
1639 shapes.shapes.push(ss);
1640 }
1641 } else if !s.is_pixel() {
1642 shapes.shapes.push(s.clone());
1643 }
1644 }
1645
1646shapes.to_grid()
1648 };
1649
1650 if let Some(rule) = run_experiment(task, 1593, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1651
1652 let func = |ex: &Example| {
1653 let in_shapes = ex.input.coloured_shapes.clone();
1654 let mut shapes = in_shapes.clone();
1655 let mut cnt = usize::MAX;
1656 let mut del_shape = Shape::trivial();
1657
1658 for s in in_shapes.shapes.iter() {
1659 let n = s.pixels_in_shape();
1660
1661 if n == 0 {
1662 return Grid::trivial();
1663 }
1664
1665 if cnt > n {
1666 cnt = n;
1667 del_shape = s.clone();
1668 }
1669 }
1670
1671 shapes.shapes.retain(|s| *s != del_shape);
1672
1673 shapes.to_grid()
1674 };
1675
1676 if let Some(rule) = run_experiment(task, 1594, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1677
1678 let func = |ex: &Example| {
1679 if colour_diffs.len() != 1 {
1680 return Grid::trivial();
1681 }
1682
1683 let centres = ex.input.shapes.centre_of();
1684 let mut grid = ex.input.grid.clone();
1685 let mut pairs: Vec<(usize, usize)> = Vec::new();
1687
1688 for (r1, c1) in centres.keys() {
1689 for (r2, c2) in centres.keys() {
1690 if r1 != r2 && c1 != c2 {
1691 let l1 = (*r1 as isize - *r2 as isize).abs() as usize;
1692 let l2 = (*c1 as isize - *c2 as isize).abs() as usize;
1693
1694 if l1 == l2 && !pairs.contains(&(l1, l2)) {
1695 let dir = Grid::calc_direction(*r1, *c1, *r2, *c2);
1696 if dir != Other && !pairs.contains(&(l1, l2)) {
1697 let (r, c) = grid.skip_to(dir, *r1, *c1);
1698 grid.draw_term_mut(dir, r, c, colour_diffs[0]);
1699 }
1700 pairs.push((l1, l2));
1701 }
1702 }
1703 }
1704 }
1705
1706grid
1708 };
1709
1710 if let Some(rule) = run_experiment(task, 1595, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1711
1712 let func = |ex: &Example| {
1713 if colour_diffs.len() != 1 {
1714 return Grid::trivial();
1715 }
1716
1717 let mut grid = ex.input.grid.clone();
1718
1719 for s in ex.input.shapes.shapes.iter() {
1720 let (dir, r, c) = s.find_a_border_break();
1721
1722 grid.draw_term_mut(dir, r, c, colour_diffs[0]);
1723 grid.flood_fill_mut(s.orow + s.cells.rows / 2, s.ocol + s.cells.columns / 2, NoColour, colour_diffs[0]);
1724 }
1725
1726grid
1728 };
1729
1730 if let Some(rule) = run_experiment(task, 1596, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1731
1732 let func = |ex: &Example| {
1733 if all_colour_diffs.len() != 1 {
1734 return Grid::trivial();
1735 }
1736
1737 let mut grid = ex.input.shapes.biggest_shape().to_grid();
1738 let mut template = Shape::trivial();
1739 let mut idx = Shape::trivial();
1740
1741 for s in ex.input.coloured_shapes.shapes.iter() {
1742 if s.is_square() {
1743 template = s.to_origin();
1744 } else if s.dimensions() != grid.dimensions() {
1745 idx = s.clone();
1746 }
1747 }
1748
1749 for s in idx.to_grid().to_shapes_sq().shapes.iter() {
1750 if s.colour != grid.colour {
1751 let factor = grid.cells.rows as f64 / idx.cells.rows as f64 ;
1752
1753 template.recolour_mut(all_colour_diffs[0], grid.colour);
1754 template.to_position_mut((s.orow as f64 * factor) as usize, (s.ocol as f64 * factor) as usize);
1755 grid.copy_shape_to_grid_mut(&template);
1756 }
1757 }
1758
1759grid
1761 };
1762
1763 if let Some(rule) = run_experiment(task, 1597, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1764
1765 let func = |ex: &Example| {
1766 if all_colour_diffs.is_empty() || !ex.input.grid.is_square() {
1767 return Grid::trivial();
1768 }
1769
1770 let mut template = Shape::trivial();
1771
1772 for s in ex.input.shapes.shapes.iter() {
1773 if s.colour != Black && s.ocol != 0 {
1774 template = s.clone();
1775 }
1776 }
1777
1778 let bg = ex.input.grid.has_bg_grid_not_sq();
1779 let mut colour = NoColour;
1780 let mut shapes = ex.input.shapes.clone_base();
1781
1782 shapes.shapes.push(Shape::new_sized_coloured(ex.input.grid.cells.rows, ex.input.grid.cells.columns, bg));
1783
1784 for s in ex.input.shapes.shapes.iter() {
1785 if colour != s.colour && s.colour != Black && s.colour != template.colour {
1786 colour = s.colour;
1787 }
1788
1789 template.to_position_mut(s.orow, s.ocol);
1790 shapes.shapes.push(template.recolour(template.colour, colour));
1791
1792 }
1793
1794shapes.to_grid()
1796 };
1797
1798 if let Some(rule) = run_experiment(task, 1598, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1799
1800 let func = |ex: &Example| {
1801 if !all_colour_diffs.is_empty() {
1802 return Grid::trivial();
1803 }
1804
1805 let mut templates: Vec<Shape> = Vec::new();
1806
1807 for s in ex.input.coloured_shapes.shapes.iter() {
1808 if !s.is_pixel() {
1809 templates.push(s.clone());
1810 }
1811 }
1812
1813 if templates.is_empty() || templates[0].cells.rows != 1 || templates[0].cells.columns == 1 {
1814 return Grid::trivial();
1815 }
1816
1817 let mut shapes = ex.input.shapes.clone_base();
1818
1819 for s in ex.input.coloured_shapes.shapes.iter() {
1820 if templates.contains(s) {
1821 shapes.shapes.push(s.clone());
1822 } else {
1823 let mut c = 0;
1824 let mut template = Shape::trivial();
1825
1826 templates.iter().for_each(|t| {
1827 let cp = t.colour_position(s.colour);
1828
1829 if cp.len() > 0 {
1830 let (_, cc) = cp[0];
1831
1832 c = cc;
1833 template = t.clone();
1834 }
1835 });
1836
1837 let new_template = if s.ocol > c {
1838 template.to_position(s.orow, s.ocol - c)
1839 } else {
1840 let sc = c - s.ocol;
1841 let sub_temp = template.subshape(0, template.cells.rows, sc, template.cells.columns - sc);
1842 sub_temp.to_position(s.orow, 0)
1843 };
1844
1845 shapes.shapes.push(new_template);
1846 }
1847 }
1848
1849shapes.to_grid()
1851 };
1852
1853 if let Some(rule) = run_experiment(task, 1599, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1854
1855 let func = |ex: &Example| {
1856 if colour_diffs.len() != 1 || ex.input.shapes.shapes.len() < 4 {
1857 return Grid::trivial();
1858 }
1859
1860 let mut rv: BTreeSet<usize> = BTreeSet::new();
1861 let mut cv: BTreeSet<usize> = BTreeSet::new();
1862
1863 for s in ex.input.coloured_shapes.shapes.iter() {
1864 rv.insert(s.orow);
1865 cv.insert(s.ocol);
1866 }
1867
1868 let mut shapes = ex.input.shapes.clone();
1869 let mut template = ex.input.shapes.shapes[0].clone();
1870 let cts = ex.input.shapes.coords_to_shape();
1871
1872 for r in rv.iter() {
1873 for c in cv.iter() {
1874 if !cts.contains_key(&(*r, *c)) {
1875 template.recolour_mut(template.colour, colour_diffs[0]);
1876 template.to_position_mut(*r, *c);
1877
1878 shapes.shapes.push(template.clone());
1879 }
1880 }
1881 }
1882
1883shapes.to_grid()
1885 };
1886
1887 if let Some(rule) = run_experiment(task, 1600, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1888
1889 let func = |ex: &Example| {
1890 if !colour_diffs.is_empty() {
1892 return Grid::trivial();
1893 }
1894
1895 let mut pixels: Vec<Shape> = Vec::new();
1896 let mut horizontal: Vec<Shape> = Vec::new();
1897 let mut vertical: Vec<Shape> = Vec::new();
1898
1899 for s in ex.input.shapes.shapes.iter() {
1900 if s.is_pixel() {
1901 pixels.push(s.clone());
1902 } else if s.is_horizontal_line() {
1903 horizontal.push(s.clone());
1904 } else if s.is_vertical_line() {
1905 vertical.push(s.clone());
1906 }
1907 }
1908
1909 let mut pshapes: Vec<(Shape,Shape)> = Vec::new();
1910
1911 for s in ex.input.shapes.shapes.iter() {
1912 if !s.is_pixel() && !s.is_line() {
1913 for p in pixels.iter() {
1914 if p.contained_by(&s) {
1915 pshapes.push((p.clone(), s.clone()));
1916 }
1917 }
1918 }
1919 }
1920
1921 let mut shapes = ex.input.shapes.clone_base();
1922 let mut used: Vec<&Shape> = Vec::new();
1923
1924 for (p, s) in pshapes.iter() {
1925 for h in horizontal.iter() {
1926 if h.adjacent_r_or_c(&s) && !used.contains(&h) {
1927 let diff = (p.orow as isize - h.orow as isize).abs() as usize;
1928 let ms;
1929 let mp;
1930
1931 if h.above(&p) {
1932 ms = s.mirrored_r().to_position(s.orow + s.cells.rows + 1, s.ocol);
1933 mp = p.to_position(h.orow + diff, p.ocol);
1934 } else {
1935 if s.orow <= s.cells.rows || h.orow < diff {
1936 return Grid::trivial();
1937 }
1938
1939 ms = s.mirrored_r().to_position(s.orow - s.cells.rows - 1, s.ocol);
1940 mp = p.to_position(h.orow - diff, p.ocol);
1941 }
1942 shapes.shapes.push(s.clone());
1943 shapes.shapes.push(p.clone());
1944 shapes.shapes.push(ms);
1945 shapes.shapes.push(mp);
1946 shapes.shapes.push(h.clone());
1947
1948 used.push(h);
1949 }
1950 }
1951 for v in vertical.iter() {
1952 if v.adjacent_r_or_c(&s) && !used.contains(&v){
1953 let diff = (p.ocol as isize - v.ocol as isize).abs() as usize;
1954 let ms;
1955 let mp;
1956
1957 if v.left(&p) {
1958 ms = s.mirrored_c().to_position(s.orow, s.ocol + s.cells.columns + 1);
1959 mp = p.to_position(p.orow, v.ocol + diff);
1960 } else {
1961 if s.ocol <= s.cells.columns || v.ocol < diff {
1962 return Grid::trivial();
1963 }
1964
1965 ms = s.mirrored_c().to_position(s.orow, s.ocol - s.cells.columns - 1);
1966 mp = p.to_position(p.orow, v.ocol - diff);
1967 }
1968
1969 shapes.shapes.push(s.clone());
1970 shapes.shapes.push(p.clone());
1971 shapes.shapes.push(ms);
1972 shapes.shapes.push(mp);
1973 shapes.shapes.push(v.clone());
1974
1975 used.push(v);
1976 }
1977 }
1978 }
1979
1980shapes.to_grid()
1982 };
1983
1984 if let Some(rule) = run_experiment(task, 1601, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
1985
1986 *cap_todo.entry(gc).or_insert(0) += 1;
1987 }
1988 let gc = InToSquaredOut;
1989 if all || cat.contains(&gc) {
1990 *cap_cats.entry(gc).or_insert(0) += 1;
1991
1992 if let Some(rule) = run_experiment(task, 1599, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.grid.in_to_squared_out(), output) { return Some(rule); };
1993
1994 *cap_todo.entry(gc).or_insert(0) += 1;
1995 }
1996 let gc = BGGridInBlack;
1997 if all || cat.contains(&gc) && !cat.contains(&BGGridOutBlack) {
1998 *cap_cats.entry(gc).or_insert(0) += 1;
1999
2000 if let Some(rule) = run_experiment(task, 1607, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_min().to_grid(), output) { return Some(rule); };
2001
2002 if let Some(rule) = run_experiment(task, 1609, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_max_colour_count().to_grid(), output) { return Some(rule); };
2003
2004 if let Some(rule) = run_experiment(task, 1611, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.has_mirror_r().to_grid(), output) { return Some(rule); };
2005
2006 if let Some(rule) = run_experiment(task, 1613, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.has_mirror_c().to_grid(), output) { return Some(rule); };
2007 let func = |ex: &Example| {
2012 if ex.input.coloured_shapes.shapes.len() != 1 || ex.input.coloured_shapes.shapes[0].dimensions() != (3, 3) {
2013 return Grid::trivial();
2014 }
2015
2016 let mut grid = ex.input.grid.clone();
2017 let ss = &ex.input.coloured_shapes.shapes[0];
2018
2019 for c in ss.cells.values() {
2020 match (c.row - ss.orow, c.col - ss.ocol) {
2021 (0, 0) => grid.draw_mut(UpLeft, c.row, c.col, c.colour),
2022 (0, 1) => grid.draw_mut(Up, c.row, c.col, c.colour),
2023 (0, 2) => grid.draw_mut(UpRight, c.row, c.col, c.colour),
2024 (1, 0) => grid.draw_mut(Left, c.row, c.col, c.colour),
2025 (1, 1) => (),
2026 (1, 2) => grid.draw_mut(Right, c.row, c.col, c.colour),
2027 (2, 0) => grid.draw_mut(DownLeft, c.row, c.col, c.colour),
2028 (2, 1) => grid.draw_mut(Down, c.row, c.col, c.colour),
2029 (2, 2) => grid.draw_mut(DownRight, c.row, c.col, c.colour),
2030 _ => todo!()
2031 }
2032 }
2033grid
2036 };
2037
2038 if let Some(rule) = run_experiment(task, 1645, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2039
2040 let func = |ex: &Example| {
2041 if ex.input.shapes.shapes.len() < 3 || !ex.input.shapes.shapes[0].is_pixel() || !ex.input.shapes.shapes[1].is_pixel() {
2042 return Grid::trivial();
2043 }
2044
2045 let cpm = ex.input.grid.cell_colour_posn_map();
2046 let mut grid = ex.input.grid.clone();
2047
2048 for (c, vp) in cpm.iter() {
2049 if vp.len() == 2 {
2050 let (_, c1) = vp[0];
2051 let (r2, _) = vp[1];
2052
2053 grid.cells[(r2,c1)].colour = *c;
2054 }
2055 }
2056
2057 grid.connect_dots();
2058
2059 grid
2060 };
2061
2062 if let Some(rule) = run_experiment(task, 1669, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2063
2064 let func = |ex: &Example| {
2065 if colour_diffs.len() != 1 {
2066 return Grid::trivial();
2067 }
2068
2069 let colour = colour_diffs[0];
2070 let grid = &ex.input.grid;
2071 let mut shapes = ex.input.shapes.clone_base();
2072
2073 for s in ex.input.shapes.shapes.iter() {
2075 if s.orow == 0 {
2076 return Grid::trivial();
2077 }
2078 if s.cells.columns > 1 && s.cells[(0,1)].colour == Black {
2079 shapes.shapes.push(s.flood_fill(0, 1, NoColour, colour));
2080 shapes.shapes.push(Shape::new_sized_coloured_position(s.orow - 1, s.ocol + 1, 1, grid.cells.columns - s.ocol, colour));
2081 } else if s.cells.columns > 2 && s.cells[(0,2)].colour == Black {
2082 shapes.shapes.push(s.flood_fill(0, 2, NoColour, colour));
2083 shapes.shapes.push(Shape::new_sized_coloured_position(s.orow- 1, 0, 1, s.ocol + 3, colour));
2084 } else {
2085 return Grid::trivial();
2086 }
2087 }
2088
2089shapes.to_grid()
2091 };
2092
2093 if let Some(rule) = run_experiment(task, 1667, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2094
2095 *cap_todo.entry(gc).or_insert(0) += 1;
2096 }
2097
2098 let gc = SingleColourOut2xIn;
2099 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
2101
2102 if let Some(rule) = run_experiment_tries(task, 1678, experiment, trans, is_test, examples, &targets, done, tries, &|ex, _, n| mirror_only(ex, n), output) { return Some(rule); };
2103
2104 *cap_todo.entry(gc).or_insert(0) += 1;
2105 }
2106
2107 let gc = SymmetricOut;
2108 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
2110
2111 let func = |ex: &Example| {
2112 let xc = ex.input.shapes.shapes.iter().filter(|s| s.orow == 0).count();
2113
2114 if xc == 0 {
2115 return Grid::trivial();
2116 }
2117
2118 Grid::new(ex.input.shapes.len() / xc, xc, ex.input.shapes.shapes[0].colour)
2119 };
2120
2121 if let Some(rule) = run_experiment(task, 1697, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2122
2123 *cap_todo.entry(gc).or_insert(0) += 1;
2124 }
2125 let gc = InOutSameShapes;
2126 if all || cat.contains(&gc) {
2127 *cap_cats.entry(gc).or_insert(0) += 1;
2128
2129 let func = &|ex: &Example| {
2130 let mut border = Shape::trivial();
2131 let mut colours: BTreeSet<Colour> = BTreeSet::new();
2132 let border_colour = ex.input.shapes.biggest_shape().colour;
2133
2134 for s in ex.input.shapes.shapes.iter() {
2135 if s.colour == border_colour {
2136 border = s.clone();
2137 } else {
2138 colours.insert(s.colour);
2139 }
2140 }
2141
2142 if colours.len() != 2 || border == Shape::trivial() {
2143 return Grid::trivial();
2144 }
2145 let sg = ex.input.grid.subgrid(border.orow, border.cells.rows, border.ocol, border.cells.columns);
2146 let colours: Vec<&Colour> = colours.iter().collect();
2147if *colours[0] == NoColour || *colours[1] == NoColour {
2149 return Grid::trivial();
2150 }
2151
2152 let s = sg.toddle_colour(*colours[0], *colours[1]);
2153
2154 let mut shapes = Shapes::new_sized(ex.input.grid.cells.rows, ex.input.grid.cells.columns);
2155
2156 shapes.shapes.push(ex.input.grid.as_shape());
2157 shapes.shapes.push(s.as_shape());
2158shapes.to_grid()
2161 };
2162
2163 if let Some(rule) = run_experiment(task, 1739, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2164
2165 let common_colour = examples.io_common_row_colour();
2166
2167 let func = |ex: &Example| {
2168 if ex.input.shapes.is_empty() || !ex.cat.contains(&InSameCountOut) {
2169 return Grid::trivial();
2170 }
2171
2172 let mut shapes = ex.input.shapes.clone();
2173 let mut row = 0;
2174
2175 for s in shapes.shapes.iter() {
2176 if s.colour == common_colour {
2177 row = s.orow;
2178
2179 break;
2180 }
2181 }
2182
2183 for s in shapes.shapes.iter_mut() {
2184 s.to_position_mut(row, s.ocol);
2185 }
2186shapes.to_grid()
2189 };
2190
2191 if let Some(rule) = run_experiment(task, 1767, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2192
2193 let func = |ex: &Example| {
2194 if ex.input.shapes.shapes.is_empty() {
2195 return Grid::trivial();
2196 }
2197
2198 let mut grid = ex.input.grid.clone();
2199
2200 for s in ex.input.shapes.shapes.iter() {
2201 if s.is_pixel() {
2202 if s.orow > 0 && grid.cells[(s.orow-1,s.ocol)].colour == Black {
2203 grid.flood_fill_mut(s.orow-1, s.ocol, NoColour, s.colour);
2204 }
2205 if s.ocol > 0 && grid.cells[(s.orow,s.ocol-1)].colour == Black {
2206 grid.flood_fill_mut(s.orow, s.ocol-1, NoColour, s.colour);
2207 }
2208 if s.orow < grid.cells.rows - 1 && grid.cells[(s.orow+1,s.ocol)].colour == Black {
2209 grid.flood_fill_mut(s.orow+1, s.ocol, NoColour, s.colour);
2210 }
2211 if s.ocol < grid.cells.columns - 1 && grid.cells[(s.orow,s.ocol+1)].colour == Black {
2212 grid.flood_fill_mut(s.orow, s.ocol+1, NoColour, s.colour);
2213 }
2214 }
2215 }
2216
2217grid
2219 };
2220
2221 if let Some(rule) = run_experiment(task, 1797, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2222
2223 if colour_diffs.len() == 2 {
2224 let first = &examples.examples[0].input.grid.to_shapes_sq().shapes[0];
2225 let first_colour = examples.examples[0].output.shapes.shapes[0].colour;
2226 let second_colour = if colour_diffs[0] == first_colour {
2227 colour_diffs[1]
2228 } else {
2229 colour_diffs[0]
2230 };
2231 let (rs, cs) = examples.examples[0].output.grid.dimensions();
2232
2233 let func = |ex: &Example| {
2234 if ex.input.shapes.shapes.is_empty() || rs.max(cs) != rs.min(cs) * 2 {
2235 return Grid::trivial();
2236 }
2237
2238 let (mut s1,mut s2) = if rs < cs {
2239 (Shape::new_sized_coloured(rs, rs, Black),
2240 Shape::new_sized_coloured_position(0, rs, rs, rs, Black))
2241 } else {
2242 (Shape::new_sized_coloured(cs, cs, Black),
2243 Shape::new_sized_coloured_position(cs, 0, cs, cs, Black))
2244 };
2245
2246 let mut size0 = 0;
2247 let mut size1 = 0;
2248
2249 for s in ex.input.grid.to_shapes_sq().shapes.iter() {
2250 if first.same_pixel_positions(s, false) {
2251 size0 += 1;
2252 } else {
2253 size1 += 1;
2254 }
2255 }
2256
2257 s1.fill_corners_mut(size0, first_colour);
2258 s2.fill_corners_mut(size1, second_colour);
2259
2260Shapes::new_shapes(&[s1.clone(), s2.clone()]).to_grid()
2262 };
2263
2264 if let Some(rule) = run_experiment(task, 1840, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2265 }
2266
2267 let func = |ex: &Example| {
2268 if !colour_diffs.is_empty() {
2269 return Grid::trivial();
2270 }
2271 let mut shapes = ex.input.shapes.clone_base();
2272
2273 let mut shape1 = Shape::trivial();
2274 let mut shape2 = Shape::trivial();
2275
2276 for s in ex.input.shapes.shapes.iter() {
2277 if shape1 == Shape::trivial() {
2278 shape1 = s.clone();
2279 } else if s.equals(&shape1) != Same {
2280 shape2 = s.clone();
2281 }
2282 }
2283 for s in ex.input.shapes.shapes.iter() {
2284 let ms = if s.equals(&shape1) == Same {
2285 shape2.to_position(s.orow, s.ocol)
2286 } else {
2287 shape1.to_position(s.orow, s.ocol)
2288 };
2289
2290 shapes.shapes.push(ms);
2291 }
2292
2293 shapes.to_grid()
2294 };
2295
2296 if let Some(rule) = run_experiment(task, 1872, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2297
2298 let func = |ex: &Example| {
2299 if ex.input.shapes.shapes.len() < 10 || ex.input.shapes.shapes.len() == ex.input.coloured_shapes.shapes.len(){
2300 return Grid::trivial();
2301 }
2302 let mut shapes = ex.input.shapes.clone_base();
2303
2304 let mut idx = Shape::trivial();
2305
2306 for s in ex.input.coloured_shapes.shapes.iter() {
2307 if s.colour == Mixed {
2308 idx = s.clone();
2309 } else {
2310 shapes.shapes.push(s.clone());
2311 }
2312 }
2313
2314 for (cell, s) in idx.cells.values().zip(shapes.shapes.iter_mut()) {
2315 s.recolour_mut(s.colour, cell.colour);
2316 }
2317
2318 shapes.shapes.push(idx.clone());
2319
2320 shapes.to_grid()
2321 };
2322
2323 if let Some(rule) = run_experiment(task, 1899, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2324
2325 let func = |ex: &Example| {
2326 if !all_colour_diffs.is_empty() {
2327 return Grid::trivial();
2328 }
2329
2330 let mut shapes = ex.input.shapes.clone();
2331 let smallest = ex.input.shapes.smallest();
2332 let largest = ex.input.shapes.largest();
2333 let edge = if smallest.cells.rows != smallest.cells.columns {
2334 smallest.cells.rows.max(smallest.cells.columns) / 2
2335 } else {
2336 smallest.cells.rows
2337 };
2338
2339 if largest.orow < edge || largest.ocol < edge {
2340 return Grid::trivial();
2341 }
2342
2343 let enclosing = Shape::new_sized_coloured_position(largest.orow - edge, largest.ocol - edge, largest.cells.rows + edge * 2, largest.cells.columns + edge * 2, smallest.colour);
2344
2345 shapes.shapes.insert(0, enclosing);
2346
2347shapes.to_grid()
2349 };
2350
2351 if let Some(rule) = run_experiment(task, 1927, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2352
2353 let func = |ex: &Example| {
2354 if !all_colour_diffs.is_empty() {
2355 return Grid::trivial();
2356 }
2357
2358 let mut shapes = ex.input.coloured_shapes.clone_base();
2359
2360 for s in ex.input.coloured_shapes.shapes.iter() {
2361 let cc = s.cell_colours();
2362 if cc.len() != 2 {
2363 return Grid::trivial();
2364 }
2365
2366 shapes.shapes.push(s.toddle_colour(cc[0], cc[1]));
2367 }
2368
2369 shapes.to_grid()
2370 };
2371
2372 if let Some(rule) = run_experiment(task, 1948, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2373
2374 let func = |ex: &Example| {
2375 if !colour_diffs.is_empty() {
2376 return Grid::trivial();
2377 }
2378
2379 let mut shapes = ex.input.shapes.clone();
2380for s in shapes.shapes.iter_mut() {
2383 for (i, r) in (0 .. s.cells.rows).rev().enumerate() {
2384 for c in 0 .. s.cells.columns {
2385 let cell = &mut s.cells[(r,c)];
2386
2387 if cell.col >= i {
2388 cell.col -= i;
2389 } else {
2390 cell.colour = Black;
2391 }
2392 }
2393 }
2394 }
2395
2396shapes.to_grid()
2398 };
2399
2400 if let Some(rule) = run_experiment(task, 1988, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2401
2402 let func = |ex: &Example| {
2403 if !colour_diffs.is_empty() {
2404 return Grid::trivial();
2405 }
2406
2407 let mut shapes = ex.input.grid.to_shapes();
2408 let mut even = true;
2409 let mut bg = NoColour;
2410
2411 for s in shapes.shapes.iter_mut() {
2412 if s.size() != ex.input.grid.size() {
2413 if even {
2414 if s.ocol == 0 {
2415 return Grid::trivial();
2416 }
2417 s.to_position_mut(s.orow, s.ocol - 1);
2418 } else {
2419 s.to_position_mut(s.orow, s.ocol + 1);
2420 }
2421
2422 even = !even;
2423 } else {
2424 bg = s.colour;
2425 }
2426 }
2427
2428 let mut grid = shapes.to_grid();
2429
2430 grid.recolour_mut(Black, bg);
2431
2432 grid
2433 };
2434
2435 if let Some(rule) = run_experiment(task, 2026, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2436
2437 let func = |ex: &Example| {
2438 if colour_diffs.is_empty() {
2439 return Grid::trivial();
2440 }
2441 let bg = ex.input.grid.majority_colour();
2442 let mut grid = ex.input.grid.clone();
2443 let mut cc: Vec<usize> = Vec::new();
2444
2445 for cell in grid.cells.values() {
2446 if cell.colour != bg {
2447 cc.push(cell.col);
2448 }
2449 }
2450
2451 cc.sort();
2452
2453 let cc = cc.unique();
2454
2455 for cell in grid.cells.values_mut() {
2456 if cell.colour != bg {
2457 if let Some(ncolour) = cc.iter().position(|n| *n == cell.col) {
2458 cell.colour = Colour::from_usize(ncolour + 1);
2459 }
2460 }
2461 }
2462
2463grid
2465 };
2466
2467 if let Some(rule) = run_experiment(task, 2027, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2468
2469 let func = |ex: &Example| {
2470 if colour_diffs.len() != 1 {
2471 return Grid::trivial();
2472 }
2473
2474 let mut grid = ex.input.grid.clone();
2475 let mut cc: Vec<Colour> = Vec::new();
2476
2477 for s in ex.input.shapes.shapes.iter() {
2478 if s.ocol == 0 || s.ocol == grid.cells.columns {
2479 return Grid::trivial();
2480 }
2481 let mut r = s.orow + s.cells.rows;
2483 let mut cm = s.ocol - 1;
2484 let mut cp = s.ocol + 1;
2485 let mut l = s.cells.rows;
2486 let mut outleft = false;
2487
2488 while r < grid.cells.rows {
2489 if grid.cells.rows - r <= l {
2490 l = grid.cells.rows - r;
2491 }
2492
2493 for rr in r .. r + l {
2494 if !cc.contains(&s.colour) {
2495 if !outleft {
2496 if grid.cells[(rr, cm)].colour != Black {
2497 grid.cells[(rr, cm)].colour = colour_diffs[0];
2498 } else {
2499 grid.cells[(rr, cm)].colour = s.colour;
2500 }
2501 }
2502 } else {
2503 if cp < grid.cells.columns {
2504 if grid.cells[(rr, cp)].colour != Black {
2505 grid.cells[(rr, cp)].colour = colour_diffs[0];
2506 } else {
2507 grid.cells[(rr, cp)].colour = s.colour;
2508 }
2509 }
2510 }
2511 }
2512
2513 if cm > 0 {
2514 cm -= 1;
2515 } else if cm == 0 {
2516 outleft = true;
2517 }
2518 cp += 1;
2519 r += l;
2520 }
2521
2522 let mut r = s.orow;
2524 let mut cm = s.ocol - 1;
2525 let mut cp = s.ocol + 1;
2526 let mut l = s.cells.rows;
2527 let mut outleft = false;
2528
2529 while r > 0 {
2530 if r <= l {
2531 l = r;
2532 }
2533
2534 for rr in r - l .. r {
2535 if !cc.contains(&s.colour) {
2536 if !outleft {
2537 if grid.cells[(rr, cm)].colour != Black {
2538 grid.cells[(rr, cm)].colour = colour_diffs[0];
2539 } else {
2540 grid.cells[(rr, cm)].colour = s.colour;
2541 }
2542 }
2543 } else {
2544 if cp < grid.cells.columns {
2545 if grid.cells[(rr, cp)].colour != Black {
2546 grid.cells[(rr, cp)].colour = colour_diffs[0];
2547 } else {
2548 grid.cells[(rr, cp)].colour = s.colour;
2549 }
2550 }
2551 }
2552 }
2553
2554 if cm > 0 {
2555 cm -= 1;
2556 } else if cm == 0 {
2557 outleft = true;
2558 }
2559 cp += 1;
2560 r -= if r >= l { l } else { r };
2561 }
2562
2563 cc.push(s.colour);
2564 }
2565
2566grid
2568 };
2569
2570 if let Some(rule) = run_experiment(task, 2028, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2571
2572 let func = |ex: &Example| {
2574 if !colour_diffs.is_empty() || ex.input.shapes.shapes.len() < 4 {
2575 return Grid::trivial();
2576 }
2577
2578 let grid = &ex.input.grid;
2579 let mut shapes = ex.input.grid.to_shapes_sq();
2580 let mut new_shapes = shapes.clone_base();
2581
2582 shapes.shapes.sort_by(|a, b| (a.ocol,a.orow).cmp(&(b.ocol,b.orow)));
2583
2584 let mut posns: BTreeMap<usize,usize> = (0 .. grid.cells.rows)
2585 .map(|r| (r, grid.cells.columns))
2586 .collect();
2587
2588 for s in shapes.shapes.iter().rev() {
2589 let c = if let Some(c) = posns.get(&s.orow) { *c } else { 0 };
2590
2591 let mut cs = c;
2593
2594 for r in s.orow .. s.orow + s.cells.rows {
2595 if let Some(c) = posns.get(&r) {
2596 cs = cs.min(*c);
2597 };
2598 }
2599
2600 if cs < s.cells.columns {
2601 return Grid::trivial();
2602 }
2603
2604 new_shapes.shapes.push(s.to_position(s.orow, cs - s.cells.columns));
2605
2606 for r in s.orow .. s.orow + s.cells.rows {
2608 let mut blanks = 0;
2609 let grid = new_shapes.to_grid();
2610
2611 for c2 in cs - s.cells.columns .. c {
2613 if grid.cells[(r,c2)].colour != Black {
2614 break;
2615 }
2616 blanks += 1;
2617 }
2618 *posns.entry(r).or_insert(cs) = cs + blanks - s.cells.columns;
2619 }
2620 }
2621
2622 new_shapes.to_grid()
2623 };
2624
2625 if let Some(rule) = run_experiment(task, 2029, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2626
2627 *cap_todo.entry(gc).or_insert(0) += 1;
2628 }
2629
2630 let gc = BGGridOutBlack;
2631 if all || cat.contains(&gc) {
2632 *cap_cats.entry(gc).or_insert(0) += 1;
2633
2634 if all || cat.contains(&IdenticalNoColours) {
2635 let func = &|ex: &Example| {
2636 if ex.input.shapes.shapes.len() % 2 != 0 || ex.input.shapes.shapes.len() == ex.input.coloured_shapes.shapes.len() {
2637 return Grid::trivial();
2638 }
2639 let mut shapes = ex.input.shapes.clone_base();
2640
2641 for shape in ex.input.coloured_shapes.shapes.iter() {
2642 let inner_shapes = shape.to_shapes();
2643 let mut small = inner_shapes.smallest();
2644 let mut large = inner_shapes.largest();
2645
2646 if shape.cells.rows != shape.cells.columns || inner_shapes.len() != 2 || !large.can_contain(&small) {
2647 return Grid::trivial();
2648 }
2649
2650 let small_colour = small.colour;
2651
2652 small.recolour_mut(small_colour, large.colour);
2653 large.recolour_mut(large.colour, small_colour);
2654
2655 let enclose = large.surround(small.cells.rows, small.colour, false, false);
2657
2658 shapes.shapes = [shapes.shapes, vec![large, small, enclose]].concat();
2659 }
2660shapes.to_grid()
2663 };
2664
2665 if let Some(rule) = run_experiment(task, 1988, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2666
2667 let func = |ex: &Example| {
2668 let mut read_shapes = ex.input.shapes.clone();
2669 let mut shapes = ex.input.shapes.clone_base();
2670 let mut row = 0;
2671 let mut col = 0;
2672
2673 read_shapes.shapes.sort_by(|a, b| a.ocol.cmp(&b.ocol));
2674
2675 for s in read_shapes.shapes.iter() {
2676 shapes.shapes.push(s.to_position(row, col));
2677
2678 row += s.cells.rows - 1;
2679 col += s.cells.columns - 1;
2680 }
2681
2682shapes.to_grid()
2684 };
2685
2686 if let Some(rule) = run_experiment(task, 2009, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2687 }
2688
2689 let func = &|ex: &Example| {
2690 let rows = ex.input.grid.cells.rows;
2691 let cols = ex.input.grid.cells.columns;
2692 let h = ex.input.grid.cell_colour_cnt_map();
2693let mut grid = Grid::new(rows, cols, Black);
2697
2698 for (col, size) in h.iter() {
2699 let c = Colour::to_usize(*col) - 1;
2700
2701 if *size >= rows || c >= cols {
2702 return Grid::trivial();
2703 }
2704
2705 for r in 0 .. *size {
2706 let r = rows - r - 1;
2707
2708 grid.cells[(r,c)].row = r;
2709 grid.cells[(r,c)].col = c;
2710 grid.cells[(r,c)].colour = *col;
2711 }
2712 }
2713
2714 grid
2715 };
2716
2717 if let Some(rule) = run_experiment(task, 2040, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2718
2719 let func = |gi: &Example| {
2720let mut rc: Vec<(usize, usize, Colour)> = Vec::new();
2722 let mut colour = NoColour;
2723 let mut shapes = gi.input.shapes.clone();
2724
2725 for s in gi.input.shapes.shapes.iter() {
2726 if colour == NoColour {
2727 colour = s.colour;
2728 }
2729 if colour != s.colour {
2730 rc.push((s.cells[(0,0)].row, s.cells[(0,0)].col, s.colour));
2731
2732 break;
2733 }
2734 }
2735
2736 for ss in shapes.shapes.iter_mut() {
2737 for (rr, cc, colour) in rc.iter() {
2738 if ss.cells[(0,0)].row == *rr || ss.cells[(0,0)].col == *cc {
2739 ss.colour = *colour;
2740
2741 for i in ss.cells.keys() {
2742 ss.cells[i].colour = *colour;
2743 }
2744 }
2745 }
2746 }
2747shapes.to_grid()
2750 };
2751
2752 if let Some(rule) = run_experiment(task, 2075, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2753
2754 let func = |ex: &Example| {
2755 if !ex.input.grid.is_square() || colour_diffs.len() != 1 || all_colour_diffs.len() != 1 {
2756 return Grid::trivial();
2757 }
2758
2759 let (rs, cs) = ex.input.grid.dimensions();
2760 let r = (rs as f32).sqrt().abs() as usize;
2761 let c = (cs as f32).sqrt().abs() as usize;
2762 let grid_shapes = ex.input.grid.to_shapes_from_grid();
2763 let mut base = Shape::trivial();
2764 let mut shapes = grid_shapes.clone_base();
2765
2766 for s in grid_shapes.shapes.iter() {
2767 if s.colour != all_colour_diffs[0] && s.colour != Black {
2768 if base == Shape::trivial() {
2769 base = s.clone().to_origin();
2770 } else if base.equals(s) != Same {
2771 return Grid::trivial();
2772 }
2773 }
2774 }
2775
2776 if base.size() < 4 {
2777 return Grid::trivial();
2778 }
2779
2780 let shape = base.clone();
2781
2782 for s in grid_shapes.shapes.iter() {
2783 if s.colour != all_colour_diffs[0] && s.colour != Black {
2784 let pr = s.orow / r;
2785 let pc = s.ocol / c;
2786
2787 if pr >= s.cells.rows || pc >= s.cells.columns {
2788 return Grid::trivial();
2789 }
2790
2791 let mut ns = s.clone();
2792
2793 ns.cells[(pr,pc)].colour = colour_diffs[0];
2794 base.cells[(pr,pc)].colour = Black;
2795 shapes.shapes.push(ns);
2796 }
2797 }
2798
2799 for cell in base.cells.values() {
2800 if cell.colour != Black {
2801 let pr = cell.row * r + cell.row;
2802 let pc = cell.col * c + cell.col;
2803 let mut ns = shape.clone();
2804
2805 ns.cells[(cell.row,cell.col)].colour = colour_diffs[0];
2806 shapes.shapes.push(ns.to_position(pr, pc));
2807 }
2808 }
2809
2810shapes.to_grid()
2812 };
2813
2814 if let Some(rule) = run_experiment(task, 2224, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2815
2816 *cap_todo.entry(gc).or_insert(0) += 1;
2817 }
2818 let gc = FullyPopulatedOut;
2819 if all || cat.contains(&gc) {
2820 *cap_cats.entry(gc).or_insert(0) += 1;
2821
2822 if let Some(rule) = run_experiment(task, 2083, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_sub_max().to_grid(), output) { return Some(rule); };
2823
2824 if let Some(rule) = run_experiment(task, 2085, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.largest().to_grid(), output) { return Some(rule); };
2825if let Some(rule) = run_experiment(task, 2089, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_sub_min().to_grid(), output) { return Some(rule); };
2829
2830 let common_colours = examples.find_output_colours();
2831
2832 for colour in common_colours {
2833 if let Some(rule) = run_experiment(task, 2094, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.cell_colour_cnts(colour).to_grid(), output) { return Some(rule); };
2834 }
2835
2836 if let Some(rule) = run_experiment(task, 2097, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_sub_largest_count().to_grid(), output) { return Some(rule); };
2837
2838 let func = |ex: &Example| {
2839 let mut cnt = 0;
2840 let mut shapes: Vec<Shape> = Vec::new();
2841
2842 for s in ex.input.shapes.shapes.iter() {
2843 if s.size() >= 9 && s.colour != Mixed && s.dense() {
2844 cnt += 1;
2845
2846 shapes.push(s.clone())
2847 }
2848 }
2849
2850 let height = cnt / 3;
2851
2852 if height == 0 {
2853 return Grid::trivial();
2854 }
2855
2856 let mut grid = Grid::new(height, 3, Black);
2857 let mut r = 0;
2858
2859 for (i, s) in shapes.iter_mut().enumerate() {
2861 if i > 0 && (i % 3) == 0 {
2862 r += 1;
2863 }
2864
2865 s.orow = r;
2866 }
2867
2868 shapes.sort_by(|a, b| (a.orow, a.ocol).cmp(&(b.orow, b.ocol)));
2869for (i, s) in shapes.iter().enumerate() {
2872 let r = i / 3;
2873 let c = i % 3;
2874if r >= grid.cells.rows || c >= grid.cells.columns {
2877 return Grid::trivial();
2878 }
2879
2880 grid.colour = s.colour;
2881
2882 grid.cells[(r,c)].row = i / 3;
2883 grid.cells[(r,c)].col = i / height;
2884 grid.cells[(r,c)].colour = s.colour;
2885 }
2886grid
2889 };
2890
2891 if let Some(rule) = run_experiment(task, 2152, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2892
2893 let func = |ex: &Example| {
2894 if !ex.input.grid.is_square() {
2895 return Grid::trivial();
2896 }
2897
2898 let colours = ex.input.grid.find_colour_row_order();
2899 let len = colours.len();
2900
2901 if len == 0 {
2902 return Grid::trivial();
2903 }
2904 let colours: BTreeMap<usize, Colour> = colours.iter()
2905 .map(|(k,&v)| (k % len, v))
2906 .collect();
2907
2908 let mut grid = ex.input.grid.clone();
2909
2910 for ((r, c), cell) in ex.input.grid.cells.items() {
2911 if cell.colour == Black {
2912 let idx = (r + c) % len;
2913
2914 if let Some(colour) = colours.get(&idx) {
2915 grid.cells[(r,c)].colour = *colour;
2916 }
2917 }
2918 }
2919grid
2922 };
2923
2924 if let Some(rule) = run_experiment(task, 2185, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2925
2926 let ex = &examples.examples[0];
2927 let in_colour = ex.output.grid.get_diff_colour(&ex.input.grid);
2928 let out_colour = ex.input.grid.get_diff_colour(&ex.output.grid);
2929
2930 let func = |ex: &Example| {
2931 ex.input.grid.recolour(in_colour, out_colour)
2932 };
2933
2934 if let Some(rule) = run_experiment(task, 2195, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2935
2936 let func = |ex: &Example| {
2937 let mut colours = ex.input.shapes.find_shape_colours();
2938
2939 let mut width = 0;
2940 let mut first = true;
2941
2942 for s in ex.input.shapes.shapes.iter() {
2943 if !first && s.ocol == 0 {
2944 break;
2945 }
2946
2947 first = false;
2948 width += 1;
2949 }
2950
2951 if colours.len() % 2 == 1 && (colours.len() + 1) % width == 0 {
2952 let mut ps = Shape::trivial();
2953
2954 for (n, s) in ex.input.shapes.shapes.iter().enumerate() {
2955 if s.cells.rows > ps.cells.rows {
2956 if ps.cells.rows > 0 {
2957 if n + n + 1 > colours.len() {
2958 return Grid::trivial();
2959 }
2960
2961 colours.insert(n + n + 1, s.colour);
2962
2963 break;
2964 }
2965 ps = s.clone();
2966 }
2967 }
2968 }
2969
2970 if width == 0 {
2971 return Grid::trivial();
2972 }
2973
2974 let mut grid = Grid::new(colours.len() / width, width, Black);
2975
2976 for (i, cell) in grid.cells.values_mut().enumerate() {
2977 cell.colour = colours[i];
2978 }
2979
2980 grid
2981 };
2982
2983 if let Some(rule) = run_experiment(task, 2244, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
2984
2985 let (rs, cs) = examples.examples[0].output.grid.dimensions();
2986
2987 let func = |ex: &Example| {
2988 if ex.input.shapes.shapes.is_empty() {
2989 return Grid::trivial();
2990 }
2991
2992 let (div_colour, shapes) = ex.input.grid.full_dim_split(&ex.input.shapes);
2993
2994 let mut colours: BTreeMap<Colour, Vec::<usize>> = BTreeMap::new();
2995
2996 for s in shapes.shapes.iter() {
2997 if s.colour != div_colour {
2998 colours.entry(s.colour).and_modify(|size| size.push(s.size())).or_insert(vec![s.size()]);
2999 }
3000 }
3001
3002 let mut colour = NoColour;
3003
3004 for (k,v) in colours.iter() {
3005 if v.len() != 2 {
3006 return Grid::trivial();
3007 }
3008
3009 if v[1] > v[0] + 2 {
3010 colour = *k;
3011 break;
3012 } else if v[0] + 2 == v[1] {
3013 colour = *k;
3014 }
3015 }
3016
3017 if colour == NoColour {
3018 return Grid::trivial();
3019 }
3020
3021 Grid::new(rs, cs, colour)
3022 };
3023
3024 if let Some(rule) = run_experiment(task, 2286, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3026
3027 let func = |ex: &Example| {
3066 if all_colour_diffs.is_empty() {
3067 return Grid::trivial();
3068 }
3069
3070 let mut grid = ex.input.grid.clone();
3071 for i in 0 .. 2 {
3072 let shapes = grid.find_colour_patches(all_colour_diffs[0]);
3073
3074 for shape in shapes.shapes.iter() {
3075 let g = if i == 0 {
3076 let cpos = ex.input.grid.cells.columns - (shape.ocol + shape.cells.columns);
3077 ex.input.grid.subgrid(shape.orow, shape.cells.rows, cpos, shape.cells.columns).mirrored_cols()
3078
3079 } else {
3080 let rpos = ex.input.grid.cells.rows - (shape.orow + shape.cells.rows);
3081 ex.input.grid.subgrid(rpos, shape.cells.rows, shape.ocol, shape.cells.columns).mirrored_rows()
3082 };
3083
3084 grid.copy_to_position_mut(&g, shape.orow, shape.ocol);
3085 }
3086 }
3087
3088 grid
3089 };
3090
3091 if let Some(rule) = run_experiment(task, 2352, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3092
3093 let func = |ex: &Example| {
3094 if all_colour_diffs.is_empty() || !ex.input.grid.is_square() {
3095 return Grid::trivial();
3096 }
3097
3098 let mut grid = ex.input.grid.clone();
3099 let shapes = grid.find_colour_patches(all_colour_diffs[0]);
3100 let gr = grid.cells.rows;
3101 let gc = grid.cells.columns;
3102
3103 for shape in shapes.shapes.iter() {
3104 for cell in shape.cells.values() {
3105 if grid.cells[(cell.row,cell.col)].colour == shape.colour {
3106 if grid.cells[(gr - cell.row - 1,cell.col)].colour != shape.colour {
3107 grid.cells[(cell.row,cell.col)].colour = grid.cells[(gr - cell.row - 1,cell.col)].colour;
3108 } else if grid.cells[(cell.row,gc - cell.col - 1)].colour != shape.colour {
3109 grid.cells[(cell.row,cell.col)].colour = grid.cells[(cell.row,gc - cell.col - 1)].colour;
3110 } else if grid.cells[(gr - cell.row - 1,gc - cell.col - 1)].colour != shape.colour {
3111 grid.cells[(cell.row,cell.col)].colour = grid.cells[(gr - cell.row - 1,gc - cell.col - 1)].colour;
3112 } else if grid.cells[(cell.col,cell.row)].colour != shape.colour {
3113 grid.cells[(cell.row,cell.col)].colour = grid.cells[(cell.col,cell.row)].colour;
3114}
3117 }
3118 }
3119 }
3120grid
3123 };
3124
3125 if let Some(rule) = run_experiment(task, 2386, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3126
3127 let func = |ex: &Example| {
3128 if !ex.input.grid.is_square() {
3129 return Grid::trivial();
3130 }
3131
3132 let cnt = ex.input.grid.cell_colour_cnt_map();
3133 let grid = ex.input.grid.scale_up(cnt.len());
3134
3135 grid
3136 };
3137
3138 if let Some(rule) = run_experiment(task, 2399, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3139
3140 let func = |ex: &Example| {
3141 if all_colour_diffs.is_empty() || !ex.input.grid.is_square() {
3142 return Grid::trivial();
3143 }
3144
3145 let mut grid = ex.input.grid.clone();
3146 let gr = grid.cells.rows;
3147 let gc = grid.cells.columns;
3148 let rs = ex.input.grid.row_skew();
3149 let cs = ex.input.grid.col_skew();
3150 let rr = gr + rs as usize - 1;
3151 let cr = gc + cs as usize - 1;
3152
3153 if rs != cs {
3154 return Grid::trivial();
3155 }
3156
3157 let shapes = grid.find_colour_patches(all_colour_diffs[0]);
3158
3159 for shape in shapes.shapes.iter() {
3160 let new_shape = if cs > 0 && (shape.ocol as isize) < cs {
3161 grid.populate_skew_edge_lr(&shape, all_colour_diffs[0])
3162 } else {
3163 shape.clone()
3164 };
3165 let new_shape = if rs > 0 && (shape.orow as isize) < rs {
3166 grid.populate_skew_edge_tb(&new_shape, all_colour_diffs[0])
3167 } else {
3168 new_shape
3169 };
3170
3171 for cell in shape.cells.values() {
3172 let r = cell.row;
3173 let c = cell.col;
3174
3175 if grid.cells[(cell.row,cell.col)].colour == shape.colour {
3176 if r > gr / 2 && grid.cells[(rr - r,c)].colour != shape.colour {
3177 grid.cells[(r,c)].colour = grid.cells[(rr - r,c)].colour;
3178 } else if c > gr / 2 && grid.cells[(r,cr - c)].colour != shape.colour {
3179 grid.cells[(r,c)].colour = grid.cells[(r,cr - c)].colour;
3180 } else if rr >= r && cr >= c && rr - r < gr && cr - c < gc && grid.cells[(rr - r,cr - c)].colour != shape.colour {
3181 grid.cells[(r,c)].colour = grid.cells[(rr - r,cr - c)].colour;
3182 } else if grid.cells[(c,r)].colour != shape.colour {
3183 if r + rs as usize >= grid.cells.rows || c + cs as usize >= grid.cells.columns {
3184 return Grid::trivial();
3185 }
3186
3187 grid.cells[(r,c)].colour = grid.cells[(r + rs as usize,c + cs as usize)].colour;
3188 }
3189 }
3190 }
3191 let shape = grid.subgrid(shape.orow, shape.cells.rows, shape.ocol, shape.cells.columns).as_shape();
3192 let grid = new_shape.copy_not_colour(&shape, all_colour_diffs[0]).to_grid();
3193
3194return grid;
3196 }
3197
3198 Grid::trivial()
3199 };
3200
3201 if let Some(rule) = run_experiment(task, 2471, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3202
3203 let dir = ex.output.shapes.border_gravity();
3204
3205 let func = |ex: &Example| {
3206 if !all_colour_diffs.is_empty() || colour_common.len() < 3 {
3207 return Grid::trivial();
3208 }
3209
3210 let conts = ex.input.shapes.group_containers();
3211 let mut shapes = ex.input.shapes.clone_base();
3212
3213 for (k, v) in conts.iter() {
3214 let nk = k.recolour(Black, v[0].colour);
3215 let nk = if let Some(dir) = dir.get(&k.colour) {
3216 match dir {
3217 Up => nk.gravity_up_colour(k.colour),
3218 Down => nk.gravity_down_colour(k.colour),
3219 Left => nk.gravity_left_colour(k.colour),
3220 Right => nk.gravity_right_colour(k.colour),
3221 _ => todo!(),
3222 }
3223 } else {
3224 return Grid::trivial();
3225 };
3226
3227 shapes.shapes.push(nk);
3228 }
3229
3230 shapes.to_grid()
3231 };
3232
3233 if let Some(rule) = run_experiment(task, 2503, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3234
3235 let mut out_colour: Vec<_> = examples.examples[0].output.grid.cell_colour_cnt_map()
3236 .into_iter()
3237 .map(|(k,v)| (v,k))
3238 .collect();
3239 out_colour.sort();
3240 out_colour.reverse();
3241 let out_colour: Vec<_> = out_colour.into_iter().map(|(_,v)| v).collect();
3242 let func = |ex: &Example| {
3244 if colour_diffs.len() != 3 || out_colour.len() != 5 {
3245 return Grid::trivial();
3246 }
3247
3248 let mut shapes = ex.input.shapes.clone_base();
3249
3250 for s in ex.input.shapes.shapes.iter() {
3251 if s.size() == ex.input.grid.size() {
3252 shapes.shapes.push(s.clone());
3253 continue;
3254 }
3255 if s.colour == out_colour[0] {
3256 continue;
3257 }
3258 let mut s = s.add_hugging_border(colour_diffs[0]);
3259
3260 s.flood_fill_border_mut(NoColour, out_colour[0]);
3261 s.recolour_mut(Black, out_colour[4]);
3262
3263 if s.contains_colour(out_colour[4]) {
3264 s.recolour_mut(out_colour[1], out_colour[3]);
3265 }
3266
3267 shapes.shapes.push(s);
3268 }
3269
3270shapes.to_grid_colour_transparent(out_colour[0])
3272 };
3273
3274 if let Some(rule) = run_experiment(task, 2544, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3275
3276 let func = |ex: &Example| {
3277 if all_colour_diffs.len() != 1 {
3278 return Grid::trivial();
3279 }
3280
3281 let mut h: BTreeMap<(Colour, u32), usize> = BTreeMap::new();
3282
3283 for s in ex.input.shapes.shapes.iter() {
3284 *h.entry((s.colour, Shape::sid(&s.cells, false))).or_insert(0) += 1;
3285 }
3286
3287 let mut colour = NoColour;
3288
3289 for s in ex.input.shapes.shapes.iter() {
3290 if let Some(cnt) = h.get(&(s.colour, Shape::sid(&s.cells, false))) {
3291 if *cnt > 1 && s.size() > 1 {
3292 colour = s.colour;
3293 break;
3294 }
3295 }
3296 }
3297
3298 let colours = Uniq::uniq(&colour_common, all_colour_diffs.clone());
3299 let colours = Uniq::uniq(&colours, vec![colour]);
3300
3301 if colours.len() != 1 {
3302 return Grid::trivial();
3303 }
3304
3305 for s in ex.input.shapes.shapes.iter() {
3306 if let Some(cnt) = h.get(&(s.colour, Shape::sid(&s.cells, false))) {
3307 if s.colour == colour && *cnt == 1 {
3308 return s.recolour(Black, colours[0]).add_border(colours[0]).to_grid();
3309 }
3310 }
3311 }
3312
3313 Grid::trivial()
3314 };
3315
3316 if let Some(rule) = run_experiment(task, 2586, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3317
3318 let func = |ex: &Example| {
3319 let mut bg = ex.input.grid.has_bg_grid_not_sq();
3320
3321 if bg == NoColour { bg = Black;
3323 }
3324
3325 let mut colour = NoColour;
3326 let mut min_r = usize::MAX;
3327 let mut min_c = usize::MAX;
3328 let mut max_r = 0;
3329 let mut max_c = 0;
3330
3331 for s in ex.input.shapes.shapes.iter() {
3332 if s.is_full() {
3333 colour = s.colour;
3334 }
3335 }
3336
3337 for s in ex.input.shapes.shapes.iter() {
3338 if s.colour == colour {
3339 min_r = min_r.min(s.orow);
3340 min_c = min_c.min(s.ocol);
3341 max_r = max_r.max(s.orow + s.cells.rows - 1);
3342 max_c = max_c.max(s.ocol + s.cells.columns - 1);
3343 }
3344 }
3345
3346 for s in ex.input.shapes.shapes.iter() {
3347 if s.colour != colour && s.orow >= min_r && s.orow <= max_r && s.ocol >= min_c && s.ocol <= max_c {
3348return s.recolour(Black, bg).to_grid();
3350 }
3351 }
3352
3353 Grid::trivial()
3354 };
3355
3356 if let Some(rule) = run_experiment(task, 2626, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3357
3358 let func = |ex: &Example| {
3359 let bg = ex.output.grid.has_bg_grid_not_sq();
3360
3361 if all_colour_diffs.len() != 1 || ex.input.grid.cells.rows < 4 || ex.input.grid.cells.columns < 4 {
3362 return Grid::trivial();
3363 }
3364
3365 let colour1 = ex.input.grid.cells[(1,1)].colour;
3366 let colour2 = ex.input.grid.cells[(2,2)].colour;
3367 let colour3 = ex.input.grid.cells[(3,3)].colour;
3368
3369 if colour1 == bg {
3370 return Grid::trivial();
3371 }
3372
3373 let mut grid = ex.input.grid.clone();
3374
3375 for ((r, c), cell) in ex.input.grid.cells.items() {
3376 if cell.colour == all_colour_diffs[0] {
3377 grid.cells[(r, c)].colour = bg;
3378 }
3379 let one = colour1 != bg && colour2 == bg && colour3 != bg;
3380 let two = colour1 != bg && colour2 == bg && colour3 == bg;
3381 let three = colour1 != bg && colour2 != bg && colour3 == bg;
3382
3383 if one && r % 2 == 1 && c % 2 == 1 ||
3384 two && r % 3 == 1 && c % 3 == 1 ||
3385 three && (r % 3 == 1 || r % 3 == 2) && (c % 3 == 1 || c % 3 == 2) {
3386 grid.cells[(r, c)].colour = colour1;
3387 }
3388 }
3389
3390grid
3392 };
3393
3394 if let Some(rule) = run_experiment(task, 2664, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3395
3396 let func = |ex: &Example| {
3397 if ex.input.shapes.shapes.len() < 3 {
3398 return Grid::trivial();
3399 }
3400
3401 let mut shapes = ex.input.shapes.clone();
3402
3403 for (i, s) in ex.input.shapes.shapes.iter().enumerate() {
3404 if s.size() == ex.input.grid.size() {
3405 shapes.shapes.remove(i);
3406 }
3407 }
3408
3409 shapes.shapes.sort_by(|a, b| b.size().cmp(&a.size()));
3410
3411 let mut new_shapes = Shapes::new_sized(shapes.shapes[0].cells.rows, shapes.shapes[0].cells.columns);
3412
3413 for s in shapes.shapes.iter() {
3414 let mut ns = s.to_origin();
3415
3416 ns.force_recolour_mut(s.colour);
3417
3418 new_shapes.shapes.push(ns);
3419 }
3420
3421new_shapes.to_grid()
3423 };
3424
3425 if let Some(rule) = run_experiment(task, 2695, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3426
3427 let func = |ex: &Example| {
3428 if ex.input.shapes.shapes.is_empty() || colour_diffs.len() != 1 {
3429 return Grid::trivial();
3430 }
3431
3432 let bg = ex.input.grid.majority_colour();
3433
3434 let mut grid = ex.input.grid.clone();
3435
3436 for s in ex.input.shapes.shapes.iter() {
3437 if s.dimensions() != ex.input.grid.dimensions() {
3438 let (dir, r, c) = s.has_border_break();
3439
3440 if s.orow == ex.input.grid.cells.rows - 1 || s.ocol == ex.input.grid.cells.columns - 1 {
3441 return Grid::trivial();
3442 }
3443
3444 grid.draw_bg_mut(dir, r, c, colour_diffs[0], bg);
3445 grid.flood_fill_bg_mut(s.orow + 1, s.ocol + 1, NoColour, bg, colour_diffs[0]);
3446 }
3447 }
3448
3449grid
3451 };
3452
3453 if let Some(rule) = run_experiment(task, 2723, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3454
3455 let func = |ex: &Example| {
3456 if colour_diffs.len() != 1 {
3457 return Grid::trivial();
3458 }
3459 let mut grid = ex.input.grid.clone();
3460
3461 for r in 0 .. grid.cells.rows {
3462 for c in 0 .. grid.cells.columns {
3463 if grid.cells[(r,c)].colour == grid.colour && c > 0 && grid.cells[(r,c-1)].colour == Black {
3464 grid.cells[(r,c-1)].colour = grid.colour;
3465 break;
3466 }
3467 }
3468 for c in (0 .. grid.cells.columns).rev() {
3469 if grid.cells[(r,c)].colour == grid.colour {
3470 grid.cells[(r,c)].colour = Black;
3471 break;
3472 }
3473 }
3474 }
3475
3476 grid.recolour_mut(Black, colour_diffs[0]);
3477
3478grid
3480 };
3481
3482 if let Some(rule) = run_experiment(task, 2752, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3483
3484 let func = |ex: &Example| {
3485 if !all_colour_diffs.is_empty() || ex.input.shapes.len() < 3 || ex.input.shapes.len() > 20 {
3486 return Grid::trivial();
3487 }
3488
3489 let mut shapes = ex.input.shapes.clone();
3490
3491 shapes.shapes.sort_by(|a, b| a.size().cmp(&b.size()));
3492
3493 let mut size = 0;
3494
3495 for s in shapes.shapes.iter() {
3496 if size == 0 {
3497 size += s.cells.rows.max(s.cells.columns);
3498 } else {
3499 size += 2;
3500 }
3501 }
3502
3503 let mut grid = Grid::new(size, size, Black);
3504
3505 shapes.shapes.sort_by(|a, b| b.size().cmp(&a.size()));
3506
3507 for (i, s) in shapes.shapes.iter().enumerate() {
3508 for r in i .. size {
3509 for c in i .. size {
3510 grid.cells[(r, c)].colour = s.colour;
3511 }
3512 }
3513 size -= 1;
3514 }
3515
3516grid
3518 };
3519
3520 if let Some(rule) = run_experiment(task, 2790, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3521
3522 let func = |ex: &Example| {
3523 if !all_colour_diffs.is_empty() {
3524 return Grid::trivial();
3525 }
3526
3527 let bg_colour = ex.input.shapes.largest().colour;
3528 let mut largest = ex.input.coloured_shapes.largest().to_grid();
3529
3530 for s in ex.input.coloured_shapes.shapes.iter() {
3531 if s.dimensions() != largest.dimensions() {
3532 let colour = s.minority_colour();
3533 let (r, c) = s.to_origin().find_colour_pixel_coords(colour);
3534 let (lr, lc) = largest.find_colour_pixel_coords(colour);
3535
3536 if lr > 0 || lc > 0 {
3537 if lr < r || lc < c {
3538 return Grid::trivial();
3539 }
3540
3541 largest.copy_shape_to_grid_position_mut(s, lr - r, lc - c);
3542 }
3543 }
3544 }
3545
3546 largest.recolour_mut(Black, bg_colour);
3547
3548largest
3550 };
3551
3552 if let Some(rule) = run_experiment(task, 2818, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3553
3554 let func = |ex: &Example| {
3555 let pred = |solver: &Grid, r, c, colour| !solver.used_in_row(r, colour) && !solver.used_in_col(c, colour);
3556
3557 let mut grid = ex.input.grid.clone();
3558
3559 grid.solve(&pred);
3560
3561grid
3563 };
3564
3565 if let Some(rule) = run_experiment(task, 2819, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3566
3567 *cap_todo.entry(gc).or_insert(0) += 1;
3568 }
3569 let gc = MirrorCIn;
3570 if all || cat.contains(&gc) || cat.contains(&MirrorCOut) {
3571 *cap_cats.entry(gc).or_insert(0) += 1;
3572
3573 let func = |ex: &Example| {
3574 if ex.input.shapes.shapes.is_empty() {
3575 return Grid::trivial();
3576 }
3577
3578 let mut row = ex.input.shapes.shapes[0].orow;
3579 let mut shapes = ex.input.shapes.clone();
3580
3581 for s in shapes.shapes.iter_mut().rev() {
3582 s.to_position_mut(row, s.ocol);
3583 row += s.cells.rows;
3584 }
3585
3586 shapes.to_grid()
3587 };
3588
3589 if let Some(rule) = run_experiment(task, 2842, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3590
3591 let func = |ex: &Example| {
3593 if ex.input.shapes.shapes.is_empty() {
3594 return Grid::trivial();
3595 }
3596
3597 let shapes = ex.input.grid.to_shapes_cons();
3598 let mut new_shapes = shapes.clone_base();
3599
3600 for s in shapes.shapes.iter() {
3601 let ns = s.mirrored_r();
3602
3603 new_shapes.shapes.push(ns);
3604 }
3605
3606 new_shapes.to_grid()
3607 };
3608
3609 if let Some(rule) = run_experiment(task, 2862, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3610
3611 *cap_todo.entry(gc).or_insert(0) += 1;
3612 }
3613 let gc = MirrorROut;
3614 if all || cat.contains(&gc) || cat.contains(&MirrorCOut) {
3615 *cap_cats.entry(gc).or_insert(0) += 1;
3616
3617 let func = |gi: &Example| {
3618 if gi.input.coloured_shapes.len() != 1 {
3619 return Grid::trivial();
3620 }
3621
3622 let s = gi.input.grid.as_shape();
3623
3624 let rows = s.cells.rows;
3625 let cols = s.cells.columns;
3626 let mut shapes = Shapes::new_sized(rows * 2, cols * 2);
3627
3628 shapes.shapes.push(s.mirrored_r().mirrored_c());
3629 shapes.shapes.push(s.mirrored_c().translate_absolute(rows, 0));
3630 shapes.shapes.push(s.mirrored_r().translate_absolute(0, cols));
3631 shapes.shapes.push(s.translate_absolute(rows, cols));
3632
3633shapes.to_grid()
3635 };
3636
3637 if let Some(rule) = run_experiment(task, 2890, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3638
3639 let func = |ex: &Example| {
3640 let bg = ex.input.grid.max_colour();
3641 let shapes = ex.input.grid.to_shapes_sq();
3642 let shapes = shapes.colour_groups_to_shapes(bg);
3643
3644 shapes.to_grid()
3645 };
3646
3647 if let Some(rule) = run_experiment(task, 2900, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3648
3649 *cap_todo.entry(gc).or_insert(0) += 1;
3650 }
3651 let gc = Div9In;
3652 if all || cat.contains(&gc) && !cat.contains(&Div9Out) {
3653 *cap_cats.entry(gc).or_insert(0) += 1;
3654
3655 let out_colours = examples.find_all_output_colours();
3658 let (rs, cs) = examples.examples[0].output.grid.dimensions();
3659
3660 if out_colours.len() == 2 && examples.examples[0].input.grid.is_3x3() {
3661 let func = |ex: &Example| {
3662 if ex.input.grid.cells[(0,1)].colour == Black && ex.input.grid.cells[(2,1)].colour == Black {
3663 Grid::new(rs,cs,out_colours[0])
3664 } else {
3665 Grid::new(rs,cs,out_colours[1])
3666 }
3667 };
3668
3669 if let Some(rule) = run_experiment(task, 2922, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3670 }
3671
3672 *cap_todo.entry(gc).or_insert(0) += 1;
3673 }
3674 let gc = Div9Out;
3675 if all || cat.contains(&Is3x3In) && cat.contains(&gc) && !cat.contains(&Div9In){
3676 *cap_cats.entry(gc).or_insert(0) += 1;
3677
3678 let func = |ex: &Example| {
3679 if colour_common.len() != 9 || !ex.input.grid.cells.is_square() {
3680 return Grid::trivial();
3681 }
3682 let div = ex.input.grid.cells.rows.isqrt();
3683 let mut cells: BTreeMap<(usize,usize),Colour> = BTreeMap::new();
3684
3685 for cell in ex.input.grid.cells.values() {
3686 if cell.colour != Black {
3687 cells.insert((cell.row / div, cell.col), cell.colour);
3688 }
3689 }
3690 let mut grid = Grid::new(3, 3, Black);
3691
3692 for (cell, colour) in grid.cells.values_mut().zip(cells.values()) {
3693 cell.colour = *colour;
3694 }
3695
3696grid
3698 };
3699
3700 if let Some(rule) = run_experiment(task, 2923, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3701
3702 *cap_todo.entry(gc).or_insert(0) += 1;
3703 }
3704 let gc = Div9In;
3705 if all || cat.contains(&gc) && cat.contains(&Is3x3Out) && !cat.contains(&Div9Out) {
3706 *cap_cats.entry(gc).or_insert(0) += 1;
3707
3708 if let Some(rule) = run_experiment(task, 2943, experiment, trans, is_test, examples, &targets, done, tries, &|ex| repeat_pattern(&ex, Black), output) { return Some(rule); };
3715
3716 let func = |ex: &Example| {
3717 let colour = if ex.input.grid.colour == Mixed {
3718 ex.input.grid.find_max_colour()
3719 } else {
3720 ex.input.grid.colour
3721 };
3722
3723 repeat_pattern(ex, colour)
3724 };
3725
3726 if let Some(rule) = run_experiment(task, 2955, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3727
3728 let func = |ex: &Example| {
3729 let colour = if ex.input.grid.colour == Mixed {
3730 ex.input.grid.find_min_colour()
3731 } else {
3732 ex.input.grid.colour
3733 };
3734
3735 repeat_pattern(ex, colour)
3736 };
3737
3738 if let Some(rule) = run_experiment(task, 2967, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3739
3740 if let Some(rule) = run_experiment_colours(task, 2969, experiment, is_test, examples, &targets, done, &|ex, colour| repeat_pattern(ex, colour), output) { return Some(rule); };
3741
3742 *cap_todo.entry(gc).or_insert(0) += 1;
3806 }
3807 let gc = IdenticalNoPixels;
3808 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
3810
3811 let func = |ex: &Example| {
3863 let grid = &ex.input.grid;
3864 if grid.cells.rows != grid.cells.columns { return Grid::trivial();
3866 }
3867 let shapes = grid.to_shapes();
3869
3870 if shapes.shapes.is_empty() {
3871 return Grid::trivial();
3872 }
3873
3874 let x_axis = shapes.shapes[0].height() > 1;
3875
3876 let borders: Vec<_> = shapes.shapes.iter().filter(|s| s.size() > 1).collect();
3877 if borders.len() != 2 {
3878 return Grid::trivial();
3879 }
3880
3881 let c1 = borders[0].colour;
3882 let c2 = borders[1].colour;
3883
3884 let mut new_grid = grid.clone();
3885
3886 for s in ex.input.shapes.shapes.iter() {
3887 if s.size() == 1 {
3888 if x_axis {
3889 new_grid.cells[(s.orow, s.ocol)].colour = if s.ocol < grid.cells.columns / 2 { c1 } else { c2 };
3890 } else {
3891 new_grid.cells[(s.orow, s.ocol)].colour = if s.orow < grid.cells.rows / 2 { c1 } else { c2 };
3892 }
3893 }
3894 }
3895new_grid
3898 };
3899
3900 if let Some(rule) = run_experiment(task, 3129, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3901
3902 let func = |ex: &Example| {
3904 let mut grid = ex.input.grid.clone();
3905
3906 for (r, c) in ex.input.grid.cells.keys() {
3907 if ex.input.grid.cells[(r, 0)].colour != Black && grid.cells[(r, c)].colour != Black {
3908 grid.cells[(r, c)].colour = ex.input.grid.cells[(r, 0)].colour;
3909 }
3910 }
3911
3912 grid
3913 };
3914
3915 if let Some(rule) = run_experiment(task, 3144, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3916
3917 let out_colours = examples.find_output_colours();
3918
3919 let func = |ex: &Example| {
3920 if out_colours.len() != 1 {
3921 return Grid::trivial();
3922 }
3923
3924 let mut shapes = ex.input.shapes.clone();
3925 shapes.shapes.sort_by_key(|a| a.size());
3927 let mut toddle = false;
3928
3929 for shape in shapes.shapes.iter_mut() {
3930 for cell in shape.cells.values_mut() {
3931 if cell.colour != Black {
3932 if toddle {
3933 cell.colour = out_colours[0];
3934 }
3935 toddle = !toddle;
3936 }
3937 }
3938 }
3939 shapes.shapes.sort_by_key(|b| std::cmp::Reverse(b.size()));
3941
3942shapes.to_grid()
3944 };
3945
3946 if let Some(rule) = run_experiment(task, 3175, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3947
3948 let func = |ex: &Example| {
3949 if colour_diffs.len() != 1 {
3950 return Grid::trivial();
3951 }
3952
3953 let mut shapes = ex.input.grid.to_shapes_sq();
3954
3955 for shape in shapes.shapes.iter_mut() {
3956 if shape.is_pixel() {
3957 shape.force_recolour_mut(colour_diffs[0]);
3958 }
3959 }
3960
3961shapes.to_grid()
3963 };
3964
3965 if let Some(rule) = run_experiment(task, 3194, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3966
3967 let func = |ex: &Example| {
3968 if colour_diffs.len() != 1 {
3969 return Grid::trivial();
3970 }
3971
3972 let mut shapes = ex.input.grid.to_shapes_sq();
3973
3974 shapes.shapes.sort_by(|a, b| (a.ocol, a.orow).cmp(&(b.ocol, b.orow)));
3975
3976 let mut toddle = ex.input.grid.cells.columns % 2 != 0;
3977
3978 for shape in shapes.shapes.iter_mut() {
3979 if toddle {
3980 shape.force_recolour_mut(colour_diffs[0]);
3981 }
3982 toddle = !toddle;
3983 }
3984
3985shapes.to_grid()
3987 };
3988
3989 if let Some(rule) = run_experiment(task, 3218, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
3990
3991 let ex = &examples.examples[0];
3992 let smallest = ex.input.shapes.smallest();
3993 let in_colour = smallest.colour;
3994
3995 if ex.output.grid.height() >= ex.input.grid.height() && ex.output.grid.width() >= ex.input.grid.width() {
3996 let out_colour = ex.output.grid.cells[(smallest.orow,smallest.ocol)].colour;
3997 let mut diag_colour = colour_diffs.clone();
3998
3999 diag_colour.retain(|&c| c != out_colour);
4000
4001 let func = |ex: &Example| {
4003 if diag_colour.len() != 1 {
4004 return Grid::trivial();
4005 }
4006
4007 let mut grid = ex.input.grid.clone();
4008 let bg = grid.has_bg_grid_not_sq();
4009
4010 for s in ex.input.shapes.shapes.iter() {
4011 if s.is_pixel() {
4012 grid.draw_bg_mut(Up, s.orow, s.ocol, in_colour, bg);
4013 grid.draw_bg_mut(Down, s.orow, s.ocol, in_colour, bg);
4014 grid.draw_bg_mut(Left, s.orow, s.ocol, in_colour, bg);
4015 grid.draw_bg_mut(Right, s.orow, s.ocol, in_colour, bg);
4016 }
4017 }
4018
4019 let mut shapes = Shapes::new_sized(grid.cells.rows, grid.cells.columns);
4020
4021 shapes.shapes.push(grid.as_shape());
4022
4023 for s in ex.input.shapes.shapes.iter() {
4024 if s.is_pixel() {
4025 let ns = s.recolour(in_colour, out_colour);
4026
4027 shapes.shapes.push(ns);
4028
4029 let surround = s.surround(1, diag_colour[0], false, true);
4030
4031 shapes.shapes.push(surround);
4032 }
4033 }
4034
4035shapes.to_grid()
4037 };
4038
4039 if let Some(rule) = run_experiment(task, 3268, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4040 }
4041
4042 let func = |ex: &Example| {
4043 if ex.input.shapes.shapes.is_empty() {
4044 return Grid::trivial();
4045 }
4046
4047 let mut shapes = ex.input.shapes.clone();
4048 let mut index: Shape = Shape::trivial();
4049
4050 for s in ex.input.coloured_shapes.shapes.iter() {
4051 if s.size() < 10 && (s.cells.rows == 1 || s.cells.columns == 1) {
4052 if s.cells.rows > 1 {
4053 index = s.to_grid().rot_rect_270().as_shape();
4055 } else {
4056 index = s.clone();
4057 }
4058 break;
4059 }
4060 }
4061
4062 if index == Shape::trivial() {
4063 return Grid::trivial();
4064 }
4065
4066 let idx_len = index.cells.columns;
4067
4068 for s in ex.input.coloured_shapes.shapes.iter() {
4069 if s.size() < 10 {
4070 continue;
4071 }
4072 let right = s.cells[(s.cells.rows - 1,0)].colour == Black;
4074 let size = if right { let mut i: usize = 0;
4076
4077 for _ in 0 .. s.cells.rows {
4078 if s.cells[(i,0)].colour == Black {
4079 break;
4080 }
4081 i += 1;
4082 }
4083
4084 i
4085 } else {
4086 let mut i: usize = 0;
4087
4088 for _ in (0 .. s.cells.rows).rev() {
4089 if s.cells[(i,s.cells.columns - 1)].colour == Black {
4090 break;
4091 }
4092 i += 1;
4093 }
4094
4095 i
4096 };
4097
4098 let mut idx = 0;
4099 let mut ns = s.clone();
4100
4101 for i in 0 .. s.cells.rows - size + 1 {
4103 for pos in 0 .. size {
4104 if i + pos >= s.cells.rows || i + pos >= s.cells.columns {
4105 return Grid::trivial();
4106 }
4107 let colour = index.cells[(0,idx)].colour;
4108 if right {
4109 ns.cells[(i+pos,i+pos)].colour = colour;
4110
4111 for inc in 1 .. size {
4112 if i+pos+inc < s.cells.rows {
4113 ns.cells[(i+pos+inc,i+pos)].colour = colour;
4114 }
4115 if i+pos+inc < s.cells.columns {
4116 ns.cells[(i+pos,i+pos+inc)].colour = colour;
4117 }
4118 }
4119 } else {
4120 ns.cells[(i+pos,s.cells.columns-1-pos-i)].colour = colour;
4121 for inc in 1 .. size {
4122 if i+pos+inc < s.cells.rows {
4123 ns.cells[(i+pos+inc,s.cells.columns-1-pos-i)].colour = colour;
4124 }
4125 if i+pos+inc < s.cells.columns {
4126 ns.cells[(i+pos,s.cells.columns-1-pos-i-inc)].colour = colour;
4127 }
4128 }
4129 }
4130 };
4131
4132 idx = (idx + 1) % idx_len;
4133 }
4134
4135 shapes.shapes.push(ns);
4136 }
4137
4138shapes.to_grid()
4140 };
4141
4142 if let Some(rule) = run_experiment(task, 3371, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4143
4144 let func = |ex: &Example| {
4145 if ex.input.shapes.shapes.len() < 3 || ex.input.shapes.shapes.len() % 2 == 0 {
4146 return Grid::trivial();
4147 }
4148
4149 let mut shapes = ex.input.shapes.clone();
4150 let mut rs: Vec<&Shape> = Vec::new();
4151 let mut ss: Vec<&Shape> = Vec::new();
4152
4153 for s in ex.input.shapes.shapes.iter() {
4154 if s.size() == 1 {
4155 rs.push(&s);
4156 }
4157 }
4158
4159 for s in ex.input.coloured_shapes.shapes.iter() {
4160 if s.size() > 1 && !s.has_border() {
4161 ss.push(&s);
4162 }
4163 }
4164
4165 for (s, m) in rs.iter().zip(ss.iter()) {
4169 shapes.shapes.push(m.recolour(m.colour, s.colour));
4170 }
4171
4172shapes.to_grid()
4174 };
4175
4176 if let Some(rule) = run_experiment(task, 3405, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4177
4178 let out_colours = examples.examples[0].output.grid.cell_colour_cnt_map();
4179 let func = |ex: &Example| {
4180 if all_colour_diffs.len() != 2 || out_colours.len() != 3 {
4181 return Grid::trivial();
4182 }
4183 let mut colour_order: Vec<(usize,Colour)> = out_colours.iter().map(|(k, v)| (*v, *k)).collect();
4184 colour_order.sort();
4185 let colours: Vec<Colour> = colour_order.iter().map(|(_, c)| *c).collect();
4186 let mut shapes = ex.input.shapes.clone();
4187
4188 for s in shapes.shapes.iter_mut() {
4189 for i in 1 ..= s.cells.rows.max(s.cells.columns) / 2 {
4190 let colour = colours[if i % 2 == 0 { 0 } else { 1 }];
4191 s.nest_mut(i, colour);
4192 }
4193 }
4194
4195shapes.to_grid()
4197 };
4198
4199 if let Some(rule) = run_experiment(task, 3406, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4200
4201 *cap_todo.entry(gc).or_insert(0) += 1;
4202 }
4203 let gc = Is3x3In;
4204 if all || cat.contains(&gc) && cat.contains(&Is3x3Out) {
4205 *cap_cats.entry(gc).or_insert(0) += 1;
4206
4207let func = |gi: &Example| {
4211 let mut big: Shape = Shape::trivial();
4212 let mut n = 0;
4213
4214 if gi.input.grid.cells.rows != 9 || gi.input.grid.cells.columns != 9 {
4215 return Grid::trivial();
4216 }
4217
4218 for s in &gi.input.shapes.shapes {
4219 if s.size() > 1 {
4220 if s.cells.rows > 3 || s.cells.columns > 3 {
4221 return Grid::trivial();
4222 }
4223 if s.cells.rows == 3 && s.cells.columns == 3 {
4224 if big != Shape::trivial() {
4225 return Grid::trivial();
4226 }
4227 big = s.clone();
4228 } else if s.cells.rows == 2 && s.cells.columns == 3 {
4229 let mut m = Matrix::new(3, 3, Cell::new(0, 0, 0));
4230 for c in 1 .. 3 {
4231 m[(0,c)].row = 0;
4232 m[(0,c)].col = c;
4233 }
4234 for r in 1 .. 3 {
4235 for c in 0 .. 3 {
4236 m[(r,c)].row = r;
4237 m[(r,c)].col = c;
4238 m[(r,c)].colour = s.cells[(r-1,c)].colour;
4239 }
4240 }
4241 big = Shape::new(0, 0, &m);
4242 } else if s.cells.rows == 3 && s.cells.columns == 2 {
4243 let mut m = Matrix::new(3, 3, Cell::new(0, 0, 0));
4244 for r in 1 .. 3 {
4245 m[(r,0)].row = r;
4246 m[(r,0)].col = 0;
4247 }
4248 for r in 0 .. 3 {
4249 for c in 1 .. 3 {
4250 m[(r,c)].row = r;
4251 m[(r,c)].col = c;
4252 m[(r,c)].colour = s.cells[(r,c-1)].colour;
4253 }
4254 }
4255 big = Shape::new(0, 0, &m);
4256 }
4257 } else {
4258 n += 1;
4259 }
4260 }
4261let rows = big.cells.rows;
4264 let cols = big.cells.columns;
4265let mut shapes = Shapes::new_sized(rows, cols * n);
4267 let big = big.to_origin();
4268
4269 shapes.shapes.push(big.clone());
4270for i in 1 .. n {
4273 shapes.shapes.push(big.translate_absolute(0, cols * i));
4274 }
4275shapes.to_grid()
4278 };
4279
4280 if let Some(rule) = run_experiment(task, 3486, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4281
4282 let func = |ex: &Example| {
4283 if ex.input.shapes.shapes.len() < 5 {
4284 return Grid::trivial();
4285 }
4286
4287 let mut two = Shape::trivial();
4289 let mut three = Shape::trivial();
4290 let mut other = Shape::trivial();
4291 let mut shapes = Shapes::trivial();
4292 let mut rows = 0;
4293
4294 for (i, s) in ex.input.shapes.shapes.iter().enumerate() {
4295 if s.ocol == 0 && s.cells.columns == ex.input.grid.cells.columns {
4296 if s.orow < 1 || ex.input.grid.cells.rows < s.orow - 1 {
4297 return Grid::trivial();
4298 }
4299 rows = ex.input.grid.cells.rows - s.orow - 1;
4300 shapes = Shapes::new_sized(rows, ex.input.grid.cells.columns);
4301 continue;
4302 }
4303
4304 match i {
4305 0 => (),
4307 1 => two = s.clone(),
4308 2 => three = s.clone(),
4309 _ => {
4310 other = s.clone();
4311
4312 break
4313 },
4314 }
4315 }
4316
4317 if other == Shape::trivial() || shapes == Shapes::trivial() || two == Shape::trivial() {
4318 return Grid::trivial();
4319 }
4320
4321 shapes.shapes.push(other.to_position(other.orow - (ex.input.grid.cells.rows - rows), other.ocol));
4322
4323 if two.cells[(0,0)].colour == Black {
4324 shapes.shapes.push(three.to_position(other.orow - (ex.input.grid.cells.rows - rows) - other.cells.rows, other.ocol));
4325 } else {
4326 shapes.shapes.push(three.to_position(other.orow - (ex.input.grid.cells.rows - rows) + other.cells.rows, other.ocol));
4327 }
4328
4329shapes.to_grid()
4331 };
4332
4333 if let Some(rule) = run_experiment(task, 3487, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4334
4335 *cap_todo.entry(gc).or_insert(0) += 1;
4336 }
4337 let gc = InOutSquareSameSize;
4338 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
4340
4341 if all || cat.contains(&InSameCountOut) || cat.contains(&InSameCountOutColoured) {
4342 let func = |ex: &Example| {
4345 let biggest = ex.input.coloured_shapes.biggest_shape();
4346 if biggest.size() != ex.input.grid.size() {
4347 return Grid::trivial();
4348 }
4349 let (idx, dir) = ex.input.grid.corner_idx();
4350 if dir == Other {
4351 return Grid::trivial();
4352 }
4353 let mut shapes = Shapes::new_from_shape(&biggest);
4354 let body = ex.input.grid.corner_body(dir.inverse());
4355 let four = body.split_4();
4356
4357 if four.is_empty() {
4358 return Grid::trivial();
4359 }
4360
4361 four.iter().zip(idx.cells.values())
4362 .for_each(|(s,c)| shapes.add(&s.recolour(s.colour, c.colour).as_shape()));
4363
4364 shapes.to_grid()
4365 };
4366
4367 if let Some(rule) = run_experiment(task, 3520, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4368
4369 let func = |ex: &Example| {
4370 if ex.input.shapes.shapes.len() > 20 {
4371 return Grid::trivial();
4372 }
4373
4374 let mut shapes = ex.input.shapes.clone_base();
4375
4376 for s in &ex.input.shapes.shapes {
4378 shapes.shapes.push(s.mirrored_r());
4379 }
4380shapes.to_grid()
4383 };
4384
4385 if let Some(rule) = run_experiment(task, 3539, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4387 }
4388
4389 if all || cat.contains(&InLessCountOut) {
4390 let s1 = examples.all(false);
4392 let s2 = examples.all_coloured(true);
4393
4394 let func = |ex: &Example| {
4395 if s1.len() != s2.len() {
4396 return Grid::trivial();
4397 }
4398 let sc: BTreeMap<Shape, Shape> = s1.iter().zip(s2.iter()).map(|(s1, s2)| (s1.to_origin(), s2.to_origin())).collect();
4399
4400 let mut shapes = ex.input.shapes.clone_base();
4402
4403 for s in ex.input.shapes.shapes.iter() {
4404 match sc.get(&s.to_origin()) {
4405 Some(ns) => {
4406 shapes.shapes.push(ns.to_position(s.orow, s.ocol));
4407 },
4408 None => (),
4409 }
4410 }
4411
4412 shapes.to_grid()
4413 };
4414
4415 if let Some(rule) = run_experiment(task, 3568, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4416
4417 }
4442
4443 if let Some(rule) = run_experiment_tries(task, 3572, experiment, trans, is_test, examples, &targets, done, tries, &|ex, _, n| transform_only(ex, n), output) { return Some(rule); };
4445 let func = |ex: &Example| {
4448 let mut grid = ex.input.grid.clone();
4449
4450 for s in ex.input.shapes.shapes.iter() {
4451 if s.size() == 1 {
4452 grid.cells[(ex.input.grid.cells.rows - 1,s.ocol)].colour = s.colour;
4453 grid.cells[(s.orow,s.ocol)].colour = Black;
4454 }
4455 }
4456
4457 grid
4458 };
4459
4460 if let Some(rule) = run_experiment(task, 3588, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4461
4462 let func = &|ex: &Example| {
4463 fn do_diag(grid: &mut Grid, s: &Shape) {
4464 grid.draw_mut(FromUpLeft, s.orow, s.ocol,s.cells[(s.cells.rows-1,0)].colour);
4465 grid.draw_mut(FromUpRight, s.orow, s.ocol + s.cells.columns, s.cells[(0,0)].colour);
4466 grid.draw_mut(FromDownRight, s.orow + s.cells.rows-1, s.ocol + s.cells.columns-1, s.cells[(0,s.cells.columns-1)].colour);
4467 grid.draw_mut(FromDownLeft, s.orow + s.cells.rows, s.ocol, s.cells[(s.cells.rows-1,s.cells.columns-1)].colour);
4468 }
4469
4470 let mut grid = ex.input.grid.clone();
4471for s in ex.input.coloured_shapes.shapes.iter() {
4474 if s.cells.rows != 8 || s.cells.columns != 6 {
4475 return Grid::trivial();
4476 }
4477if s.size() > 16 {
4479 let ss1 = s.subshape_remain(0, 4, 0, 6).shrink_coloured();
4481 let ss2 = s.subshape_remain(4, 4, 0, 6).shrink_coloured();
4482
4483 do_diag(&mut grid, &ss1);
4484 do_diag(&mut grid, &ss2);
4485 } else {
4486 do_diag(&mut grid, s);
4488 }
4489 }
4490grid
4493 };
4494
4495 if let Some(rule) = run_experiment(task, 3623, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4496
4497 let func = |ex: &Example| {
4498 if colour_diffs.len() != 1 {
4499 return Grid::trivial();
4500 }
4501 let colour = colour_diffs[0];
4502 let g = &ex.input.grid;
4503 let mut grid = g.clone();
4504
4505 for ((r, c), cell) in g.cells.items() {
4506 if c > grid.cells.columns / 2 {
4507 continue;
4508 }
4509
4510 if cell.colour != Black && cell.colour == g.cells[(r, g.cells.columns - 1 - c)].colour {
4511 grid.cells[(r, c)].colour = colour;
4512 grid.cells[(r, g.cells.columns - 1 - c)].colour = colour;
4513 }
4514 }
4515
4516 grid
4517 };
4518
4519 if let Some(rule) = run_experiment(task, 3647, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4520
4521 let func = |ex: &Example| {
4522 if ex.input.shapes.shapes.is_empty() {
4523 return Grid::trivial();
4524 }
4525
4526 let g = &ex.input.grid;
4527 let s = &ex.input.shapes.shapes[0];
4528
4529 if s.cells.rows < 2 || s.cells.columns < 2 {
4530 return Grid::trivial();
4531 }
4532
4533 let border = s.colour;
4534 let idx = g.subgrid(0, s.cells.rows - 1, 0, s.cells.columns - 1);
4535 let mut idx = idx.as_shape();
4536
4537 if idx.cells.rows < 2 || idx.cells.columns < 2 {
4538 return Grid::trivial();
4539 }
4540
4541 let (r, c) = g.find_patch(&idx);
4542
4543 if r == 0 && c == 0 {
4544 return Grid::trivial();
4545 }
4546
4547 idx.to_position_mut(r, c);
4548
4549 let idx = idx.add_border(border);
4550 let mut shapes = g.as_shapes();
4551
4552 shapes.shapes.push(idx);
4553shapes.to_grid()
4556 };
4557
4558 if let Some(rule) = run_experiment(task, 3686, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4559
4560 let min_colour = examples.examples[0].output.grid.minority_colour();
4561
4562 let func = |ex: &Example| {
4563 if colour_diffs.len() != 2 {
4564 return Grid::trivial();
4565 }
4566
4567 let mut other_colour = colour_diffs.clone();
4568
4569 other_colour.retain(|&x| x != min_colour);
4570
4571 let bg = ex.input.grid.colour;
4572 let (min_r, min_c, max_r, max_c) = ex.input.shapes.corners();
4573 let mut grid = ex.input.grid.clone();
4574
4575 for r in min_r .. max_r {
4577 for c in min_c .. max_c {
4578 if grid.cells[(r,c)].colour == Black {
4579 grid.cells[(r,c)].colour = other_colour[0];
4580 }
4581 }
4582 }
4583
4584 for r in min_r .. max_r {
4586 for c in min_c .. max_c {
4587 if grid.cells[(r,c)].colour == other_colour[0] {
4588 for rr in r .. grid.cells.rows {
4589 if grid.cells[(rr,c)].colour == bg {
4590 break;
4591 } else if grid.cells[(rr,c)].colour != other_colour[0] {
4592 grid.cells[(rr,c)].colour = min_colour;
4593 }
4594 }
4595 for cc in c .. grid.cells.columns {
4596 if grid.cells[(r,cc)].colour == bg {
4597 break;
4598 } else if grid.cells[(r,cc)].colour != other_colour[0] {
4599 grid.cells[(r,cc)].colour = min_colour;
4600 }
4601 }
4602 for rr in (0 ..= r).rev() {
4603 if grid.cells[(rr,c)].colour == bg {
4604 break;
4605 } else if grid.cells[(rr,c)].colour != other_colour[0] {
4606 grid.cells[(rr,c)].colour = min_colour;
4607 }
4608 }
4609 for cc in (0 ..= c).rev() {
4610 if grid.cells[(r,cc)].colour == bg {
4611 break;
4612 } else if grid.cells[(r,cc)].colour != other_colour[0] {
4613 grid.cells[(r,cc)].colour = min_colour;
4614 }
4615 }
4616 }
4617 }
4618 }
4619
4620grid
4622 };
4623
4624 if let Some(rule) = run_experiment(task, 3752, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4625
4626 let func = |ex: &Example| {
4627 if ex.input.coloured_shapes.shapes.len() != 1 {
4628 return Grid::trivial();
4629 }
4630
4631 let ccm = ex.input.coloured_shapes.shapes[0].cell_colour_cnt_map();
4632 let mut grid = ex.input.grid.clone();
4633 let div_colour = if let Some((_, colour)) = ccm.iter().map(|(c,n)| (n, c)).max() {
4634 *colour
4635 } else {
4636 NoColour
4637 };
4638 if let Some((_, colour)) = ccm.iter().filter(|&(&c, _)| c != div_colour).map(|(c,n)| (n, c)).max() {
4639 grid.cells[(ex.input.grid.cells.rows-1, ex.input.grid.cells.columns / 2)].colour = *colour;
4640 }
4641
4642grid
4644 };
4645
4646 if let Some(rule) = run_experiment(task, 3774, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4647
4648 let func = |ex: &Example| {
4649 let shapes = ex.input.grid.to_shapes_coloured_sq();
4650 let ss = &shapes.shapes;
4651
4652 if !all_colour_diffs.is_empty() || ss.len() != 9 {
4653 return Grid::trivial();
4654 }
4655
4656 let mut ns = shapes.clone_base();
4657 let ps = &mut ns.shapes;
4658
4659 for s in shapes.shapes.iter() {
4660 match s.pixel_position(ex.input.grid.minority_colour()) {
4661 UpLeft => ps.push(s.to_position(ss[0].orow, ss[0].ocol)),
4662 Up => ps.push(s.to_position(ss[1].orow, ss[1].ocol)),
4663 UpRight => ps.push(s.to_position(ss[2].orow, ss[2].ocol)),
4664 Left => ps.push(s.to_position(ss[3].orow, ss[3].ocol)),
4665 Middle => ps.push(s.to_position(ss[4].orow, ss[4].ocol)),
4666 Right => ps.push(s.to_position(ss[5].orow, ss[5].ocol)),
4667 DownLeft => ps.push(s.to_position(ss[6].orow, ss[6].ocol)),
4668 Down => ps.push(s.to_position(ss[7].orow, ss[7].ocol)),
4669 DownRight => ps.push(s.to_position(ss[8].orow, ss[8].ocol)),
4670 _ => ()
4671 }
4672 }
4673
4674ns.to_grid()
4676 };
4677
4678 if let Some(rule) = run_experiment(task, 3775, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4679
4680 let func = |ex: &Example| {
4681 if !colour_diffs.is_empty() {
4682 return Grid::trivial();
4683 }
4684
4685 let colour = ex.input.grid.minority_colour();
4686 let mut shapes = ex.input.grid.to_shapes();
4688 let mut idxes: Vec<Shape> = Vec::new();
4689
4690 for s in shapes.shapes.iter() {
4691 if s.colour == colour {
4692 idxes.push(s.clone());
4693 }
4694 }
4695
4696 shapes.shapes.insert(0, ex.input.grid.as_shape());
4697
4698 for s in shapes.shapes.iter_mut() {
4699 for idx in idxes.iter() {
4700 if s.colour != colour && s.equal_shape(&idx) {
4701 s.recolour_mut(s.colour, idx.colour);
4702 }
4703 }
4704 }
4705
4706shapes.to_grid_transparent()
4708 };
4709
4710 if let Some(rule) = run_experiment(task, 3776, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4711
4712 *cap_todo.entry(gc).or_insert(0) += 1;
4713 }
4714 let gc = InOutSquare;
4715 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
4717
4718 let func = |ex: &Example| {
4723 if !ex.input.grid.is_square() {
4724 return Grid::trivial();
4725 }
4726
4727 let height = ex.input.grid.height();
4728 let width = ex.input.grid.width();
4729
4730 let mut shapes = Shapes::new_sized(height * 2, width * 2);
4731
4732 let shape = ex.input.grid.as_shape();
4733 shapes.shapes.push(shape);
4734
4735 let shape = ex.input.grid.as_shape_position(0, width).rotated_270();
4736 shapes.shapes.push(shape);
4737
4738 let shape = ex.input.grid.as_shape_position(height, 0).rotated_180();
4739 shapes.shapes.push(shape);
4740
4741 let shape = ex.input.grid.as_shape_position(height, width).rotated_90();
4742 shapes.shapes.push(shape);
4743
4744 shapes.to_grid()
4745 };
4746 if let Some(rule) = run_experiment(task, 3810, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4747
4748 let func = |ex: &Example| {
4750 if !ex.input.grid.is_square() {
4751 return Grid::trivial();
4752 }
4753
4754 let height = ex.input.grid.height();
4755 let width = ex.input.grid.width();
4756
4757 let mut shapes = Shapes::new_sized(height * 2, width * 2);
4758
4759 let shape = ex.input.grid.as_shape_position(height, width);
4760 shapes.shapes.push(shape);
4761
4762 let shape = ex.input.grid.as_shape_position(0, width).mirrored_r();
4763 shapes.shapes.push(shape);
4764
4765 let shape = ex.input.grid.as_shape_position(height, 0).mirrored_c();
4766 shapes.shapes.push(shape);
4767
4768 let shape = ex.input.grid.as_shape().mirrored_r().mirrored_c();
4769 shapes.shapes.push(shape);
4770
4771 shapes.to_grid()
4772 };
4773 if let Some(rule) = run_experiment(task, 3837, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4774
4775 let func = &|ex: &Example| {
4776 if ex.input.coloured_shapes.shapes.len() != 1 || !ex.input.coloured_shapes.shapes[0].is_square() || ex.input.coloured_shapes.shapes[0].size() != 36 {
4777 return Grid::trivial();
4778 }
4779
4780 let shape = &ex.input.coloured_shapes.shapes[0];
4781 let ss = shape.subshape(0, 3, 0, 3);
4782
4783 ss.to_grid()
4784 };
4785
4786 if let Some(rule) = run_experiment(task, 3850, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4787
4788 *cap_todo.entry(gc).or_insert(0) += 1;
4789}
4791 let gc = InOutSameSize;
4792 if all || cat.contains(&gc) { *cap_cats.entry(gc).or_insert(0) += 1;
4794
4795 if cat.contains(&IsPanelledROut) {
4807 let func = |ex: &Example| {
4808 let grid_shape = ex.input.grid.as_shape();
4809 let colour = grid_shape.majority_colour();
4810 let bg_shapes = ex.input.grid.to_shapes_base_bg(colour);
4811 let not_empty: Vec<Shape> = bg_shapes.shapes.iter().filter(|s| !s.is_empty()).cloned().collect();
4812
4813 if not_empty.len() != 1 {
4814 return Grid::trivial();
4815 }
4816
4817 let mut shapes = ex.input.shapes.clone_base();
4818
4819 shapes.shapes.push(grid_shape);
4820
4821 for s in &bg_shapes.shapes {
4822 if s.is_empty() {
4823 shapes.shapes.push(not_empty[0].copy_into(s));
4824 } else {
4825 shapes.shapes.push(s.clone());
4826 }
4827 }
4828shapes.to_grid()
4831 };
4832
4833 if let Some(rule) = run_experiment(task, 3897, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4834 }
4835
4836 let func = |gi: &Example| {
4840 let mut h: BTreeMap<Colour, Shape> = BTreeMap::new();
4841 let mut size = 0;
4842
4843 for s in gi.input.shapes.shapes.iter() {
4844if size == 0 {
4846 size = s.size();
4847 }
4848 if size != 25 {
4849 return Grid::trivial();
4850 } else if s.size() < size {
4851 if let Some(ls) = h.get(&s.colour) {
4852 let mut ls = ls.clone();
4853
4854 if s.contained_by(&ls) {
4855if s.size() == 1 && size == 25 {
4858 ls.cells[(2, 2)].colour = s.colour;
4859h.insert(s.colour, ls.clone());
4861 continue;
4862 }
4863 }
4864 }
4865 return Grid::trivial();
4866 }
4867 if let Some(shape) = h.get(&s.colour) {
4868 if shape.pixels() <= s.pixels() {
4869 h.insert(s.colour, s.clone());
4870 }
4871 } else {
4872 h.insert(s.colour, s.clone());
4873 }
4874 }
4875
4876 let mut shapes = Shapes::new_sized(gi.input.shapes.nrows, gi.input.shapes.ncols);
4877
4878 for s in gi.input.shapes.shapes.iter() {
4879 if s.size() < size { continue; }
4880if let Some(shape) = h.get(&s.colour) {
4882 if shape.pixels() >= s.pixels() {
4883 let mut new_shape = s.clone();
4884for ((r, c), cell) in shape.cells.items() {
4886 if r >= new_shape.cells.rows || c >= new_shape.cells.columns {
4887 return Grid::trivial();
4888 }
4889 new_shape.cells[(r,c)].colour = cell.colour;
4890 }
4891 shapes.add(&new_shape);
4892 } else {
4893 shapes.add(shape);
4894 }
4895 }
4896 }
4897shapes.to_grid()
4900 };
4901
4902 if let Some(rule) = run_experiment(task, 3966, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4903
4904 if !cat.contains(&FullyPopulatedIn) {
4905 let func = |gi: &Example| {
4906 let mut si = gi.clone();
4907 let mut dr = 0;
4908 let mut dc = 0;
4909
4910 for s in &gi.input.shapes.shapes {
4911 if dr == 0 {
4912 dr = s.orow;
4913 } else if s.orow % dr != 0 {
4914 return Grid::trivial();
4915 }
4916 if dc == 0 {
4917 dc = s.ocol;
4918 } else if s.ocol % dc != 0 {
4919 return Grid::trivial();
4920 }
4921}
4923
4924 if dr != 0 && dc != 0 {
4925 return Grid::trivial();
4926 }
4927
4928 si.input.shapes.shapes.sort_by_key(|b| std::cmp::Reverse(b.pixels()));
4929
4930 for (i, s) in si.input.shapes.shapes.iter_mut().enumerate() {
4931 s.orow = i * dr;
4932 s.ocol = i * dc;
4933
4934 for (r, c) in s.cells.keys() {
4935 s.cells[(r, c)].row = s.orow + r;
4936 s.cells[(r, c)].col = s.ocol + c;
4937 }
4938 }
4939si.input.shapes.to_grid()
4942 };
4943
4944 if let Some(rule) = run_experiment(task, 4008, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4945 }
4946
4947 let func = |gi: &Example| {
4948 if gi.input.shapes.is_empty() || gi.input.shapes.len() > 21 {
4949 return Grid::trivial();
4950 }
4951
4952 let mut colours: Vec<Colour> = Vec::new();
4953 let mut si = gi.input.shapes.clone();
4954
4955 let mut full_size = false;
4956
4957 for s in si.shapes.iter() {
4958 if s.size() == gi.input.grid.size() {
4959 full_size = true;
4960 }
4961 if s.size() == 1 {
4962 colours.push(s.colour);
4963 }
4964 }
4965
4966 if colours.is_empty() || !full_size {
4967 return Grid::trivial();
4968 }
4969
4970 let mut i = 0;
4971
4972 for s in si.shapes.iter_mut() {
4973 if s.size() != 1 && s.size() != gi.input.grid.size() {
4974 if i >= colours.len() {
4975 return Grid::trivial();
4976 }
4977 s.mut_recolour(s.colour, colours[i]);
4978
4979 i += 1;
4985 }
4986 }
4987
4988 si.shapes.sort_by_key(|b| std::cmp::Reverse(b.size()));
4990
4991 si.to_grid()
4992 };
4993
4994 if let Some(rule) = run_experiment(task, 4058, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
4995
4996 let func = &|ex: &Example| {
4997 let mut grid = ex.input.grid.clone();
4998 let cnts = ex.input.shapes.shape_colour_cnt_map();
4999
5000 for a_colour in Colour::all_colours().iter() {
5001 if let Some(cs) = cnts.get(a_colour) {
5002 if cs.len() == 2 || cs.len() == 4 {
5003 let size = cs[0].size();
5004 if cs.len() == 2 || cs.iter().filter(|s| s.size() == 1).count() == size {
5005 let v = Vec::from_iter(cs);
5007
5008 grid.draw_lines(&v, cs.len() == 2, true);
5009 }
5010 }
5011 }
5012 }
5013grid
5016 };
5017
5018 if let Some(rule) = run_experiment(task, 4082, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5019
5020 let func = |ex: &Example| {
5021 if !ex.cat.contains(&NoShapesIn(5)) || !ex.cat.contains(&NoShapesOut(6)) || colour_diffs.is_empty() {
5022 return Grid::trivial();
5023 }
5024
5025 let shapes = &ex.input.shapes;
5026 let corners = shapes.corners();
5027
5028 if corners.0 == 0 || corners.1 == 0 || corners.2 == 0 || corners.3 == 0 {
5029 return Grid::trivial();
5030 }
5031
5032 let centre = (corners.0 + (corners.2 - corners.0) / 2, corners.1 + (corners.3 - corners.1) / 2);
5033
5034 let mut dist = f32::MAX;
5035
5036 for s in shapes.shapes.iter() {
5037 let d = s.distance_from(centre.0, centre.1);
5038
5039 if s.orow > corners.0 && s.orow < corners.2 && s.ocol > corners.1 && s.ocol < corners.3 && d < dist {
5040 dist = d;
5041 }
5042 }
5043
5044 let mut grid = ex.input.grid.clone();
5045for s in shapes.shapes.iter() {
5048 if s.orow == corners.0 {
5049 grid.draw_line_row_coords(corners.0, corners.1 - 1, corners.0, corners.3, s.colour, true, false, 1);
5050 } else if s.orow == corners.2 - 1 {
5051 grid.draw_line_row_coords(corners.2 - 1, corners.1 - 1, corners.2 - 1, corners.3, s.colour, true, false, 1);
5052 } else if s.ocol == corners.1 {
5053 grid.draw_line_col_coords(corners.0, corners.1, corners.2 - 1, corners.1, s.colour, true, false, 1);
5054 } else if s.ocol == corners.3 - 1 {
5055 grid.draw_line_col_coords(corners.0, corners.3 - 1, corners.2 - 1, corners.3 - 1, s.colour, true, false, 1);
5056 } else {
5057 grid.draw_line_row_coords(s.orow, corners.1, s.orow, corners.3 - 1, colour_diffs[0], false, false, 1);
5058 grid.draw_line_col_coords(corners.0, s.ocol, corners.2 - 1, s.ocol, colour_diffs[0], false, false, 1);
5059 }
5060 }
5061
5062grid
5064 };
5065
5066 if let Some(rule) = run_experiment(task, 4124, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5067
5068 let func = |ex: &Example| {
5069 if ex.input.shapes.shapes.is_empty() {
5070 return Grid::trivial();
5071 }
5072 let border = ex.input.shapes.shapes.iter()
5073 .map(|s| s.cells.rows.max(s.cells.columns))
5074 .max().unwrap() * 2;
5075 let mut grid = ex.input.grid.add_border(border);
5076
5077 for s in ex.input.shapes.shapes.iter() {
5078 let mut tlr = s.orow + border + s.cells.rows;
5079 let mut tlc = s.ocol + border - s.cells.columns;
5080
5081 while tlr < grid.cells.rows && tlc >= s.cells.columns {
5083 grid.copy_shape_to_grid_position_mut(s, tlr, tlc);
5084
5085 tlr += s.cells.rows;
5086 tlc -= s.cells.columns;
5087 }
5088
5089 let mut brr = s.orow + s.cells.rows + border;
5090 let mut brc = s.ocol + s.cells.columns + border;
5091
5092 while brr < grid.cells.rows && brc < grid.cells.columns {
5093 grid.copy_shape_to_grid_position_mut(s, brr, brc);
5094
5095 brr += s.cells.rows;
5096 brc += s.cells.columns;
5097 }
5098 }
5099
5100 grid = grid.remove_border(border);
5101grid
5104 };
5105
5106 if let Some(rule) = run_experiment(task, 4164, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5107
5108 let func = |ex: &Example| {
5109 if ex.input.shapes.shapes.is_empty() {
5110 return Grid::trivial();
5111 }
5112
5113 let mut grid = ex.input.grid.clone();
5114 let mut pixels: Vec<Shape> = Vec::new();
5115
5116 for s in ex.input.shapes.shapes.iter() {
5117 if s.is_pixel() && s.on_edge(&grid) {
5118 pixels.push(s.clone());
5119 }
5120 }
5121
5122 if pixels.len() % 2 != 0 {
5123 return Grid::trivial();
5124 }
5125
5126 for s in pixels.iter() {
5127 if s.orow == 0 || s.orow == grid.cells.rows - 1 {
5128 continue;
5129 }
5130
5131 let os = s.find_same_row(&pixels);
5132
5133 if os != Shape::trivial() {
5134grid.draw_line_row(s, &os, s.colour, true, true);
5136 }
5137 }
5138 for s in pixels.iter() {
5139 if s.ocol == 0 || s.ocol == grid.cells.columns - 1 {
5140 continue;
5141 }
5142
5143 let os = s.find_same_col(&pixels);
5144
5145 if os != Shape::trivial() {
5146 grid.draw_line_col(s, &os, s.colour, true, true);
5147 }
5148 }
5149
5150grid
5152 };
5153
5154 if let Some(rule) = run_experiment(task, 4212, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5155
5156 let func = |ex: &Example| {
5157 if !colour_diffs.is_empty() || ex.input.shapes.shapes.len() < 3 {
5158 return Grid::trivial();
5159 }
5160
5161 let rep = ex.input.shapes.shapes[0].cells.rows;
5162 let mut grid = ex.input.grid.clone();
5163 let (_, _, max_r, _) = grid.corners();
5164
5165 for i in (max_r .. grid.cells.rows - rep).step_by(rep) {
5166 for r in 0 .. rep {
5167 for c in 1 .. grid.cells.columns {
5168 grid.cells[(i + r + 1,c)].colour = grid.cells[(r,c)].colour;
5169 }
5170 }
5171 }
5172
5173grid
5176 };
5177
5178 if let Some(rule) = run_experiment(task, 4236, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5179
5180 let func = |ex: &Example| {
5181 if colour_diffs.len() != 1 {
5182 return Grid::trivial();
5183 }
5184 let mut shapes = ex.input.grid.to_shapes_sq();
5185
5186 for s in shapes.shapes.iter_mut() {
5187 if s.size() < 3 {
5188 s.force_recolour_mut(colour_diffs[0]);
5189 }
5190 }
5191
5192shapes.to_grid_transparent()
5194 };
5195
5196 if let Some(rule) = run_experiment(task, 4254, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5197
5198 let func = |ex: &Example| {
5199 let mut grid = ex.input.grid.clone();
5200
5201 for c in 0 .. grid.cells.columns {
5202 if grid.cells[(grid.cells.rows-1,c)].colour != Black {
5203 let mut colour = grid.cells[(grid.cells.rows-1,c)].colour;
5204
5205 for r in (0 .. grid.cells.rows).rev() {
5206 let col = grid.cells[(r,c)].colour;
5207
5208 if col != Black && col != colour {
5209 colour = col;
5210 } else if col == Black {
5211 grid.cells[(r,c)].colour = colour;
5212 }
5213 }
5214 }
5215 }
5216
5217 grid
5218 };
5219
5220 if let Some(rule) = run_experiment(task, 4278, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5221
5222 if examples.examples[0].input.grid.cells.columns != examples.examples[0].input.grid.cells.rows {
5223 let n = examples.examples[0].input.grid.cells.columns / examples.examples[0].input.grid.cells.rows;
5224 let s_to_s = examples.split_n_map_horizontal(n);
5225let func = |ex: &Example| {
5228 let globc = &ex.input.grid.cells;
5229
5230 if globc.columns % globc.rows != 0 || s_to_s.is_empty() {
5231 return Grid::trivial();
5232 }
5233 let mut grid = ex.input.grid.clone();
5234 let reps = grid.split_n_horizontal(n);
5235for (i, s) in reps.iter().enumerate() {
5238 let os = s.to_origin();
5239
5240 if let Some(ns) = s_to_s.get(&os) {
5241 grid.copy_to_position_mut(&ns, 0, i * s.cells.columns);
5242 }
5243 }
5244grid
5248 };
5249
5250 if let Some(rule) = run_experiment(task, 4304, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5251
5252 let n = examples.examples[0].input.grid.cells.rows / examples.examples[0].input.grid.cells.columns;
5253 let s_to_s = examples.split_n_map_vertical(n);
5254
5255 let func = |ex: &Example| {
5256 let globc = &ex.input.grid.cells;
5257
5258 if globc.rows % globc.columns != 0 || s_to_s.is_empty() {
5259 return Grid::trivial();
5260 }
5261 let mut grid = ex.input.grid.clone();
5262 let reps = grid.split_n_vertical(n);
5263
5264 for (i, s) in reps.iter().enumerate() {
5265 let os = s.to_origin();
5266
5267 if let Some(ns) = s_to_s.get(&os) {
5268 grid.copy_to_position_mut(&ns, i * s.cells.rows, 0);
5269 }
5270 }
5271
5272 grid
5273 };
5274
5275 if let Some(rule) = run_experiment(task, 4328, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5276 }
5277
5278 let func = |ex: &Example| {
5279 if ex.input.coloured_shapes.shapes.len() != 3 {
5280 return Grid::trivial();
5281 }
5282
5283 let cnt = ex.input.coloured_shapes.shapes[0].size();
5284 let r = ex.input.coloured_shapes.shapes[1].orow;
5285
5286 if cnt > r {
5287 return Grid::trivial();
5288 }
5289
5290 let cc = ex.input.coloured_shapes.shapes[2].cell_colour_cnt_map();
5291 let mut grid = ex.input.grid.clone();
5292
5293 for cell in ex.input.coloured_shapes.shapes[2].cells.values() {
5294 if let Some(n) = cc.get(&cell.colour) {
5295 if *n == cnt {
5296 for i in 1 ..= cnt {
5297 grid.cells[(r - i, cell.col)].colour = cell.colour;
5298 }
5299 }
5300 }
5301 }
5302
5303 grid
5304 };
5305
5306 if let Some(rule) = run_experiment(task, 4359, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5307
5308 let func = |ex: &Example| {
5309 if ex.input.coloured_shapes.shapes.len() < 2 {
5310 return Grid::trivial();
5311 }
5312 let mut shapes = ex.input.coloured_shapes.clone();
5313 let mut gr = 0;
5314 let mut gc = 0;
5315 let mut colour = NoColour;
5316
5317 for s in ex.input.coloured_shapes.shapes.iter() {
5318 if s.size() == 1 {
5319 gr = s.orow;
5320 gc = s.ocol;
5321 colour = s.colour;
5322 }
5323 }
5324
5325 for s in ex.input.coloured_shapes.shapes.iter() {
5326 if s.size() > 1 {
5327 for ((r, c), cell) in s.cells.items() {
5328 if gr < r || gc < c {
5329 return Grid::trivial();
5330 }
5331 if cell.colour == colour {
5332 shapes.shapes.push(s.to_position(gr - r, gc - c).recolour(colour, Black));
5333 }
5334 }
5335 }
5336 }
5337
5338shapes.to_grid()
5340 };
5341
5342 if let Some(rule) = run_experiment(task, 4395, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5343
5344 let func = |ex: &Example| {
5345 if colour_diffs.len() != 1 || ex.input.grid.height() < 8 || ex.input.grid.width() < 8 {
5346 return Grid::trivial();
5347 }
5348 let mut grid = ex.input.grid.clone();
5349
5350 grid.colour_squares(colour_diffs[0]);
5351
5352 grid
5353 };
5354
5355 if let Some(rule) = run_experiment(task, 4408, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5356
5357 let func = |ex: &Example| {
5359 if colour_diffs.len() != 1 || ex.input.shapes.shapes.len() != ex.input.coloured_shapes.shapes.len() {
5360 return Grid::trivial();
5361 }
5362 let mut grid = ex.input.grid.clone();
5363
5364 grid.connect_dots_colour_pairs(colour_diffs[0]);
5365
5366 grid
5367 };
5368
5369 if let Some(rule) = run_experiment(task, 4422, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5370
5371 let func = |ex: &Example| {
5372 let mut shapes = ex.input.shapes.clone();
5373
5374 for s in ex.input.shapes.shapes.iter() {
5375 if !s.is_pixel() {
5376 let pixels = ex.input.shapes.pixels_in_shapes(&s);
5377
5378 if pixels.is_empty() {
5379 return Grid::trivial();
5380 }
5381
5382 let colour = pixels[0].colour;
5383 let n = pixels.len();
5384
5385 if n == 0 || s.orow < n || s.ocol < n {
5386 return Grid::trivial();
5387 }
5388
5389 let ns = Shape::new_sized_coloured_position(s.orow - n, s.ocol - n, s.cells.rows + n * 2, s.cells.columns + n * 2, colour);
5390
5391 shapes.shapes.insert(0, ns);
5392 }
5393 }
5394
5395shapes.to_grid()
5397 };
5398
5399 if let Some(rule) = run_experiment(task, 4423, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5400
5401 let min_colour = examples.examples[0].input.grid.minority_colour();
5403 let func = |ex: &Example| {
5404 if !colour_diffs.is_empty() {
5405 return Grid::trivial();
5406 }
5407
5408 let bg = ex.input.grid.majority_colour();
5409 let all_colours = ex.input.grid.cell_colours();
5410 let colours = Uniq::uniq(&all_colours, vec![min_colour, bg]);
5411 let diag_colour = if colours.is_empty() {
5412 NoColour
5413 } else {
5414 colours[0]
5415 };
5416 let mut grid = ex.input.grid.clone();
5417
5418 for s1 in ex.input.shapes.shapes.iter() {
5419 for s2 in ex.input.shapes.shapes.iter() {
5420 if s1 != s2 && s1.is_diagonal(s2) {
5421 let dir = s1.which_direction(s2);
5422
5423 if s1.colour == s2.colour && s1.colour == min_colour {
5424 let r = if s1.orow == 0 { 0 } else { 1 };
5425 let c = if s1.ocol == 0 { 0 } else { 1 };
5426
5427 match dir {
5428 DownRight => grid.draw_bg_mc_term_other_mut(dir, s1.orow + 1, s1.ocol + 1, s1.colour, bg, false, true, diag_colour),
5429 DownLeft => grid.draw_bg_mc_term_other_mut(dir, s1.orow + 1, s1.ocol - c, s1.colour, bg, false, true, diag_colour),
5430 UpRight => grid.draw_bg_mc_term_other_mut(dir, s1.orow - r, s1.ocol + 1, s1.colour, bg, false, true, diag_colour),
5431 UpLeft => grid.draw_bg_mc_term_other_mut(dir, s1.orow - r, s1.ocol - c, s1.colour, bg, false, true, diag_colour),
5432 _ => (),
5433 }
5434 }
5435 }
5436 }
5437 }
5438
5439 for s1 in ex.input.shapes.shapes.iter() {
5440 for s2 in ex.input.shapes.shapes.iter() {
5441 if s1 != s2 && s1.is_diagonal(s2) {
5442 let dir = s1.which_direction(s2);
5443
5444 if s1.colour != s2.colour && s1.colour != min_colour {
5445 let r = if s1.orow == 0 { 0 } else { 1 };
5446 let c = if s1.ocol == 0 { 0 } else { 1 };
5447 let dir_rot = dir.rot();
5448
5449 match dir_rot {
5450 DownRight =>
5451 grid.draw_bg_mut(dir_rot, s1.orow + 1, s1.ocol + 1, s1.colour, bg),
5452 DownLeft =>
5453 grid.draw_bg_mut(dir_rot, s1.orow + 1, s1.ocol - c, s1.colour, bg),
5454 UpRight =>
5455 grid.draw_bg_mut(dir_rot, s1.orow - r, s1.ocol + 1, s1.colour, bg),
5456 UpLeft =>
5457 grid.draw_bg_mut(dir_rot, s1.orow - r, s1.ocol - c, s1.colour, bg),
5458 _ => (),
5459 }
5460 }
5461 }
5462 }
5463 }
5464
5465grid
5467 };
5468
5469 if let Some(rule) = run_experiment(task, 4424, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5470
5471 let sam = if colour_common.len() != 2 || examples.examples[0].input.shapes.shapes.len() % 2 != 0 {
5472 BTreeMap::new()
5473 } else {
5474 examples.shape_adjacency_map()
5476 };
5477
5478 let func = |ex: &Example| {
5479 if sam.is_empty() || colour_common.len() != 2 || ex.input.shapes.shapes.len() % 2 != 0 {
5480 return Grid::trivial();
5481 }
5482
5483 let mut shapes = ex.input.shapes.clone_base();
5484
5485 for (s, colour) in sam.iter() {
5486 let es = s.find_equal_shape(&ex.input.shapes);
5487 let touching = es.find_touching(&ex.input.shapes);
5488
5489 if touching != Shape::trivial() {
5490 shapes.shapes.push(touching.recolour(touching.colour, *colour));
5491 }
5492 }
5493
5494shapes.to_grid()
5496 };
5497
5498 if let Some(rule) = run_experiment(task, 4425, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5499
5500 *cap_todo.entry(gc).or_insert(0) += 1;
5501 }
5502 let gc = Double;
5503 if all || cat.contains(&gc) {
5504 *cap_cats.entry(gc).or_insert(0) += 1;
5505
5506 let func = |gi: &Example| {
5509 let s = &gi.input.grid.as_shape();
5516 let s = s.toddle_colour(Black, s.colour);
5517 let rows = s.cells.rows;
5518 let cols = s.cells.columns;
5519 let mut shapes = Shapes::new_sized(rows * 2, cols * 2);
5520
5521 shapes.shapes.push(s.clone());
5522 shapes.shapes.push(s.translate_absolute(rows, 0));
5523 shapes.shapes.push(s.translate_absolute(0, cols));
5524 shapes.shapes.push(s.translate_absolute(rows, cols));
5525
5526 shapes.to_grid()
5527 };
5528
5529 if let Some(rule) = run_experiment(task, 4453, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5530
5531 let colours = examples.io_colour_diff();
5571
5572 let func = |ex: &Example| {
5573 if colours.len() != 1 {
5574 return Grid::trivial();
5575 }
5576
5577 let grid = ex.input.grid.dup_right().dup_down();
5578 let shapes = grid.as_pixel_shapes();
5579
5580 let mut shapes = Shapes::new_given(grid.cells.rows, grid.cells.columns, &shapes.shapes);
5581
5582 shapes = shapes.embellish(colours[0]);
5583
5584 for s in grid.to_shapes_sq().shapes.iter() {
5585 shapes.shapes.push(s.clone());
5586 }
5587
5588 shapes.to_grid_transparent()
5589 };
5590
5591 if let Some(rule) = run_experiment(task, 4515, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5592
5593 *cap_todo.entry(gc).or_insert(0) += 1;
5594 }
5595 let gc = InLessThanOut;
5596 if all || cat.contains(&gc) {
5597 *cap_cats.entry(gc).or_insert(0) += 1;
5598
5599 let (in_rs, in_cs) = examples.examples[0].input.grid.dimensions();
5600 let (out_rs, out_cs) = examples.examples[0].output.grid.dimensions();
5601 let rs = out_rs / in_rs;
5602 let cs = out_cs / in_cs;
5603
5604 let func = |ex: &Example| {
5605 ex.input.grid.as_shape().chequer(rs, cs, &|r,_| r == ex.input.grid.cells.rows, &|s| s.mirrored_c(), false).to_grid()
5607 };
5608
5609 if let Some(rule) = run_experiment(task, 4533, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5610
5611 let func = |ex: &Example| {
5612 let shape = ex.input.grid.as_shape();
5614
5615 shape.chequer(rs, cs, &|r,c| shape.cells[(r / rs,c / cs)].colour != Black, &|s| s.invert_colour(), true).to_grid()
5616 };
5617
5618 if let Some(rule) = run_experiment(task, 4542, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5619
5620 let func = |ex: &Example| {
5621 let shape = ex.input.grid.as_shape();
5622
5623 let has_band = |r,c| {
5624 match ex.input.shapes.has_band() {
5625 (Down, pos) => r == pos * rs,
5626 (Right, pos) => c == pos * cs,
5627 _ => false,
5628 }
5629 };
5630
5631 shape.chequer(rs, cs, &has_band, &|s| s.clone(), true).to_grid()
5632 };
5633
5634 if let Some(rule) = run_experiment(task, 4558, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5635
5636 let shapes = examples.examples[0].output.grid.template_shapes(&examples.examples[0].input.grid);
5637
5638 if !shapes.shapes.is_empty() {
5639 if let Some(rule) = run_experiment(task, 4563, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.grid.fill_template(&shapes.shapes[0]), output) { return Some(rule); };
5640 }
5641
5642 let func = |ex: &Example| {
5643 if ex.input.shapes.shapes.is_empty() {
5644 return Grid::trivial();
5645 }
5646
5647 let shape = &ex.input.shapes.shapes[0].to_origin();
5648 let (rs, cs) = shape.dimensions();
5649 let mr = rs.max(cs);
5650 let dim = rs.max(cs) * 2 + rs.min(cs);
5651 let mut shapes = Shapes::new_sized(dim, dim);
5652
5653 shapes.shapes.push(shape.to_position(mr, 0));
5654 shapes.shapes.push(shape.rotate_90_pos(1, 0, mr));
5655 shapes.shapes.push(shape.rotate_90_pos(2, mr, rs + cs));
5656 shapes.shapes.push(shape.rotate_90_pos(3, rs + cs, mr));
5657
5658shapes.to_grid()
5660 };
5661
5662 if let Some(rule) = run_experiment(task, 4586, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5663
5664 let func = |ex: &Example| {
5665 if !cat.contains(&InLessThanOut) {
5666 return Grid::trivial();
5667 }
5668
5669 let shape = ex.input.grid.as_shape();
5670 let (rs, cs) = shape.dimensions();
5671 let mut grid = Grid::new(rs * rs, cs * cs, Black);
5672 let max_colour = ex.input.grid.find_max_colour();
5673
5674 for (or, r) in (0 .. rs * rs).step_by(rs).enumerate() {
5675 for (oc, c) in (0 .. cs * cs).step_by(cs).enumerate() {
5676 if or >= shape.cells.rows || oc >= shape.cells.columns {
5677 return Grid::trivial();
5678 }
5679 if shape.cells[(or,oc)].colour == max_colour {
5680 grid.copy_shape_to_grid_position_mut(&shape, r, c);
5681 }
5682 }
5683 }
5684
5685grid
5687 };
5688
5689 if let Some(rule) = run_experiment(task, 4613, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5690
5691 let func = |ex: &Example| {
5692 if ex.input.shapes.shapes.is_empty() || !cat.contains(&InLessThanOut) || colour_diffs.len() != 1 {
5693 return Grid::trivial();
5694 }
5695
5696 let (lrs, lcs) = ex.input.grid.dimensions();
5697 let mut shape = ex.input.grid.as_shape();
5698
5699 for ((r, c), cell) in shape.clone().cells.items() {
5700 if cell.colour != Black {
5701 if r > 0 && c > 0 {
5702 shape.cells[(r - 1, c - 1)].colour = colour_diffs[0];
5703 } else if r == 0 && c > 0 && lrs <= shape.cells.rows && shape.cells[(lrs - 1, c - 1)].colour == Black {
5704 shape.cells[(lrs - 1, c - 1)].colour = colour_diffs[0];
5705 } else if r > 0 && c == 0 && lcs <= shape.cells.columns && shape.cells[(r - 1, lcs - 1)].colour == Black {
5706 shape.cells[(r - 1, lcs - 1)].colour = colour_diffs[0];
5707 }
5708 }
5709 }
5710
5711 shape.chequer(rs, cs, &|_,_| true, &|s| s.clone(), false).to_grid()
5712 };
5713
5714 if let Some(rule) = run_experiment(task, 4638, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5715
5716 let func = |ex: &Example| {
5717 let g = &ex.input.grid;
5718
5719 if ex.input.shapes.shapes.is_empty() || !cat.contains(&InLessThanOut) || out_rs % g.height() != 0 || out_cs % g.width() != 0 {
5720 return Grid::trivial();
5721 }
5722
5723 let grid = if g.cells.rows > g.cells.columns {
5724 g.as_shape().chequer(1, cs, &|r,_| r % (g.cells.rows * 2) == 0, &|s| s.mirrored_c(), false).to_grid()
5725 } else {
5726 g.as_shape().chequer(1, cs, &|_,c| c % (g.cells.columns * 2) == 0, &|s| s.mirrored_c(), false).to_grid()
5727 };
5728
5729 grid
5730 };
5731
5732 if let Some(rule) = run_experiment(task, 4656, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5733
5734 let func = |ex: &Example| {
5735 if !cat.contains(&InLessThanOut) {
5736 return Grid::trivial();
5737 }
5738
5739 let shape = ex.input.grid.as_shape().recolour(ex.input.grid.colour, Black).add_border(ex.input.grid.colour);
5740 let (in_rs, in_cs) = shape.dimensions();
5741 let rs = (out_rs + 4) / in_rs;
5742 let cs = (out_cs + 4) / in_cs;
5743 let grid = Grid::new(in_rs, in_cs, ex.input.grid.colour);
5744
5745 grid.as_shape().chequer(rs, cs, &|_,_| true, &|_| shape.clone(), false).to_grid().trim(out_rs, out_cs)
5746 };
5747
5748 if let Some(rule) = run_experiment(task, 4672, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5749
5750 let func = |ex: &Example| {
5751 if colour_diffs.len() != 1 || colour_common.len() != 2 || !cat.contains(&InLessThanOut) {
5752 return Grid::trivial();
5753 }
5754
5755 let colour = colour_diffs[0];
5756 let grid = &ex.input.grid;
5757
5758 if grid.free_border(Left) {
5759 grid.mirror_right_func(&|g| g.invert_colour_new(colour))
5760 } else if grid.free_border(Right) {
5761 grid.mirror_left_func(&|g| g.invert_colour_new(colour))
5762 } else if grid.free_border(Up) {
5763 grid.mirror_down_func(&|g| g.invert_colour_new(colour))
5764 } else {
5765 grid.mirror_up_func(&|g| g.invert_colour_new(colour))
5766 }
5767 };
5768
5769 if let Some(rule) = run_experiment(task, 4693, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5770
5771 let func = |ex: &Example| {
5772 if !ex.input.grid.is_square() || !colour_diffs.is_empty() || colour_common.len() != 1 || !cat.contains(&InLessThanOut) {
5773 return Grid::trivial();
5774 }
5775
5776 let (rs, cs) = ex.input.grid.dimensions();
5777 let grid = ex.input.grid.scale_up(ex.input.grid.height());
5778 let mut grid = grid.resize_inc(ex.input.grid.height());
5779
5780 for ((r, c), cell) in ex.input.grid.cells.items() {
5781 if cell.colour != Black {
5782 if r == 0 && c == 0 {
5783 grid.copy_to_position_mut(&ex.input.grid, 0, cs);
5784 grid.copy_to_position_mut(&ex.input.grid, rs, 0);
5785 } else if r == 0 && c == cs - 1 {
5786 grid.copy_to_position_mut(&ex.input.grid, rs, grid.cells.columns - cs);
5787 } else if r == rs - 1 && c == 0 {
5788 grid.copy_to_position_mut(&ex.input.grid, r * rs * 2 - rs, 0);
5789 } else {
5790 if r == 0 {
5791 grid.copy_to_position_mut(&ex.input.grid, 0, c * cs * 2);
5792 }
5793 if c == 0 {
5794 grid.copy_to_position_mut(&ex.input.grid, r * rs * 2, 0);
5795 }
5796 }
5797
5798 if r == rs - 1 {
5799 grid.copy_to_position_mut(&ex.input.grid, grid.cells.rows - rs, c * cs + c + (cs - c));
5800 }
5801 if c == cs - 1 {
5802 grid.copy_to_position_mut(&ex.input.grid, r * rs + r + (rs - r), grid.cells.columns - cs);
5803 }
5804 }
5805 }
5806
5807grid
5809 };
5810
5811 if let Some(rule) = run_experiment(task, 4735, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5812
5813 let func = |ex: &Example| {
5814 if !cat.contains(&InLessThanOut) {
5815 return Grid::trivial();
5816 }
5817
5818 let grid = &ex.input.grid;
5819 let toddle = grid.toddle_colour(Black, grid.colour);
5820
5821 toddle.as_shape().chequer(rs, cs, &|r,c| toddle.cells[(r / rs,c / cs)].colour != Black, &|s| s.clone(), true).to_grid()
5822 };
5823
5824 if let Some(rule) = run_experiment(task, 4748, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5825
5826 let func = |ex: &Example| {
5827 if !cat.contains(&InLessThanOut) {
5828 return Grid::trivial();
5829 }
5830
5831 let grid = &ex.input.grid;
5832 let cnt = grid.cell_colour_cnt_map().len();
5833
5834 grid.as_shape().chequer(cnt, cnt, &|_,_| true, &|s| s.clone(), true).to_grid()
5835 };
5836
5837 if let Some(rule) = run_experiment(task, 4761, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5838
5839 let colour = examples.examples[0].input.grid.max_colour();
5840 let colour2 = examples.examples[1].input.grid.max_colour();
5841
5842 let func = |ex: &Example| {
5844 if !cat.contains(&InLessThanOut) || colour != colour2 {
5845 return Grid::trivial();
5846 }
5847
5848 let grid = &ex.input.grid;
5849 let (rs, cs) = grid.dimensions();
5850 let grid = grid.as_shape().chequer(rs, cs, &|r,c| grid.cells[(r/ rs,c / cs)].colour == colour, &|s| s.clone(), true).to_grid();
5851
5852grid.clone()
5854 };
5855
5856 if let Some(rule) = run_experiment(task, 4780, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5857
5858 let (out_rs, out_cs) = examples.examples[0].output.grid.dimensions();
5859 let all_colour_diffs = examples.io_all_colour_diff();
5860
5861 let func = |ex: &Example| {
5862 if !cat.contains(&InLessThanOut) || all_colour_diffs.len() != 1 {
5863 return Grid::trivial();
5864 }
5865 let shapes = ex.input.grid.to_shapes_base_bg(all_colour_diffs[0]);
5866
5867 let in_shape = shapes.shapes[0].scale_down(2);
5868 let (in_rs, in_cs) = in_shape.dimensions();
5869
5870 if in_rs == 0 || in_cs == 0 || shapes.shapes.len() != 2 || out_rs % (in_rs * 2) != 0 || out_cs % (in_cs * 2) != 0 {
5871 return Grid::trivial();
5872 }
5873
5874 let rs = out_rs / in_rs;
5875 let cs = out_cs / in_cs;
5876
5877 let grid = in_shape.chequer(rs, cs, &|r,c| shapes.shapes[1].cells[(r / (rs / 2), c / (cs / 2))].colour != Black, &|s| s.clone(), true).to_grid();
5878
5879grid.clone()
5881 };
5882
5883 if let Some(rule) = run_experiment(task, 4808, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5884
5885 let func = |ex: &Example| {
5886 if !cat.contains(&InLessThanOut) || !colour_diffs.is_empty() {
5887 return Grid::trivial();
5888 }
5889 let shape = ex.input.grid.as_shape();
5890
5891 let grid = shape.chequer(rs, cs, &|_,c| c % (in_rs * 2) != 0, &|s| s.mirrored_c(), false).to_grid();
5892
5893 grid.clone()
5894 };
5895
5896 if let Some(rule) = run_experiment(task, 4821, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5897
5898 let func = |ex: &Example| {
5899 if !cat.contains(&InLessThanOut) || colour_diffs.len() != 1 {
5900 return Grid::trivial();
5901 }
5902 let (in_rs, in_cs) = ex.input.grid.dimensions();
5903 let dim = in_rs.max(in_cs);
5904 let mut grid = Grid::new(dim, dim, Black);
5905 let mut c_pos = 0;
5906 let mut colour = ex.input.grid.colour;
5907
5908 for c in 0 .. dim {
5909 if ex.input.grid.cells[(0,c)].colour != Black {
5910 colour = ex.input.grid.cells[(0,c)].colour;
5911 c_pos = c;
5912 break;
5913 }
5914 }
5915
5916 grid.cells[(0,c_pos)].colour = colour;
5917
5918 let mut left = c_pos;
5919 let mut right = c_pos;
5920 let mut pos = 0;
5921
5922 for r in 1 .. dim {
5923 if left > 0 {
5924 left -= 1;
5925 grid.cells[(r,left)].colour = colour;
5926 }
5927 if right < grid.cells.rows - 1 {
5928 right += 1;
5929 grid.cells[(r,right)].colour = colour;
5930 }
5931
5932 if r > 0 && r % 2 == 0 && grid.cells[(r,left)].colour == colour {
5933 grid.draw_bg_mut(DownRight, r, left, colour_diffs[0], Black);
5934 if r + 1 >= left {
5935 pos = r + 1 - left;
5936 }
5937 }
5938
5939 if left == 0 {
5940 break;
5941 }
5942 }
5943
5944 for r in (pos + 3 .. dim).step_by(4) {
5946 grid.draw_bg_mut(DownRight, r, 0, colour_diffs[0], Black);
5947 }
5948
5949grid
5951 };
5952
5953 if let Some(rule) = run_experiment(task, 4878, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5954
5955 let func = |ex: &Example| {
5956 if !cat.contains(&InLessThanOut) || !colour_diffs.is_empty() {
5957 return Grid::trivial();
5958 }
5959
5960 let shape = ex.input.grid.as_shape();
5961 let action = &|s: &Shape, r: usize, c: usize| {
5962 let r_edge = r == 0 || r == s.cells.rows * rs - rs;
5963 let c_edge = c == 0 || c == s.cells.columns * cs - cs;
5964
5965 if r_edge && c_edge {
5966 s.rotated_180()
5967 } else if r_edge && !c_edge {
5968 s.mirrored_r()
5969 } else if !r_edge && c_edge {
5970 s.mirrored_c()
5971 } else {
5972 s.clone()
5973 }
5974 };
5975
5976 shape.combined_chequer(rs, cs, &action).to_grid()
5977 };
5978
5979 if let Some(rule) = run_experiment(task, 4904, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
5980
5981 if let Some(rule) = run_experiment(task, 4926, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.grid.extend_border(), output) { return Some(rule); };
6002
6003 let func = |ex: &Example| {
6004 if !cat.contains(&InLessThanOut) || colour_diffs.len() != 1 {
6005 return Grid::trivial();
6006 }
6007
6008 let mut grid = ex.input.grid.scale_up(2);
6009 let shapes = grid.to_shapes();
6010
6011 for s in shapes.shapes.iter() {
6012 let mr = s.cells.rows - 1;
6013 let mc = s.cells.columns - 1;
6014
6015 grid.draw_mut(UpLeft, s.cells[(0,0)].row, s.cells[(0,0)].col, colour_diffs[0]);
6016 grid.draw_mut(DownRight, s.cells[(mr,mc)].row, s.cells[(mr,mc)].col, colour_diffs[0]);
6017 }
6018
6019 grid
6020 };
6021
6022 if let Some(rule) = run_experiment(task, 4947, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6023
6024 let func = |ex: &Example| {
6025 if !cat.contains(&InLessThanOut) || colour_diffs.len() != 1 {
6026 return Grid::trivial();
6027 }
6028
6029 let rows = ex.input.grid.cells.rows;
6030 let cols = ex.input.grid.cells.columns;
6031 let mut grid = ex.input.grid.as_shape().chequer(rs, cs, &|r,c| r == 0 && c == 0 || r == rows && c == cols , &|s| s.clone(), true).to_grid();
6032 let shapes = grid.to_shapes();
6033
6034 for s in shapes.shapes.iter().skip(1).step_by(2) {
6035 if s.orow > 0 {
6036 grid.draw_mut(Right, s.orow - 1, 0, colour_diffs[0]);
6037 }
6038 }
6039grid
6042 };
6043
6044 if let Some(rule) = run_experiment(task, 4967, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6045
6046 if let Some(rule) = run_experiment(task, 4969, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.grid.scale_up(ex.input.grid.height()), output) { return Some(rule); };
6047
6048 *cap_todo.entry(gc).or_insert(0) += 1;
6049 }
6050 let gc = SingleShapeOut;
6051 if all || cat.contains(&gc) {
6052 *cap_cats.entry(gc).or_insert(0) += 1;
6053
6054 if all || cat.contains(&SingleShapeIn) {
6055 let func = |gi: &Grid, go: &Grid, n: &mut usize| {
6060 let grid = gi.recolour(gi.colour, go.colour);
6061
6062 move_only(&grid, n)
6063 };
6064
6065 if let Some(rule) = run_experiment_tries(task, 4988, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6066
6067 let func = |gi: &Example| {
6068 if gi.input.coloured_shapes.shapes.is_empty() {
6069 return Grid::trivial();
6070 }
6071
6072 gi.input.coloured_shapes.shapes[0].to_origin().to_grid()
6073 };
6074
6075 if let Some(rule) = run_experiment(task, 4998, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6076 }
6077
6078 if all || !cat.contains(&SingleShapeIn) {
6079 let r = examples.examples[0].output.grid.cells.rows;
6080 let c = examples.examples[0].output.grid.cells.columns;
6081
6082 if r == 1 || c == 1 {
6083 let colour = examples.examples[0].output.grid.colour;
6084
6085 let func = |ex: &Example| {
6086 let mut i = 0;
6087 let mut grid = Grid::new(r, c, Black);
6088
6089 for s in ex.input.shapes.shapes.iter() {
6090 if i >= c {
6091 return Grid::trivial();
6092 }
6093 if s.colour == colour && s.size() > 1 {
6094 if r == 1 {
6095 grid.cells[(0, i)].colour = colour;
6096 } else {
6097 grid.cells[(i, 0)].colour = colour;
6098 }
6099 i += 1;
6100 }
6101 }
6102
6103 grid
6104 };
6105
6106 if let Some(rule) = run_experiment(task, 5029, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6107 }
6108 }
6109
6110 *cap_todo.entry(gc).or_insert(0) += 1;
6111 }
6112 let gc = OutLessThanIn;
6113 if all || cat.contains(&gc) {
6115 *cap_cats.entry(gc).or_insert(0) += 1;
6116
6117 if let Some(rule) = run_experiment(task, 5040, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.hollow_cnt_unique().to_grid(), output) { return Some(rule); };
6118
6119 if let Some(rule) = run_experiment(task, 5042, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.first().to_grid(), output) { return Some(rule); };
6120
6121 let func = |ex: &Example| {
6124 for s in &ex.input.shapes.shapes {
6125 if !s.is_mirror_r() && !s.is_mirror_c() {
6126 return s.to_grid();
6127 }
6128 }
6129
6130 Grid::trivial()
6131 };
6132
6133 if let Some(rule) = run_experiment(task, 5056, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6134
6135 let func = |ex: &Example| {
6136 for s in &ex.input.shapes.shapes {
6137 if s.is_mirror_r() || s.is_mirror_c() {
6138 return s.to_grid();
6139 }
6140 }
6141
6142 Grid::trivial()
6143 };
6144
6145 if let Some(rule) = run_experiment(task, 5068, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6146
6147 let func = |ex: &Example| {
6148 let bordered = ex.input.shapes.border_only();
6149
6150 if bordered == Shape::trivial() {
6151 return Grid::trivial();
6152 }
6153
6154 ex.input.grid.subgrid(bordered.orow + 1, bordered.cells.rows - 2, bordered.ocol + 1, bordered.cells.columns - 2)
6155 };
6156
6157 if let Some(rule) = run_experiment(task, 5080, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6158
6159 let func = |ex: &Example| {
6160 if !cat.contains(&OutLessThanIn) {
6161 return Grid::trivial();
6162 }
6163
6164 let sc = ex.input.coloured_shapes.shape_counts();
6165
6166 if let Some(max) = sc.values().max() {
6167 let sid: Vec<_> = sc.iter().filter(|&(_,&v)| v == *max).map(|(k,_)| k).collect();
6168 for s in ex.input.coloured_shapes.shapes.iter() {
6169 let this_sid = Shape::sid(&s.cells, true);
6170
6171 if *sid[0] == this_sid {
6172 return s.to_grid();
6173 }
6174 }
6175 }
6176
6177 Grid::trivial()
6178 };
6179
6180 if let Some(rule) = run_experiment(task, 5103, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6181
6182 let func = |ex: &Example| {
6183 let colour = ex.input.grid.mid_div_colour();
6184 let ns = ex.input.grid.to_shapes_base_bg(colour);
6185
6186 if ns.shapes.len() != 2 {
6187 return Grid::trivial();
6188 }
6189
6190 let mut nns = Shapes::new_sized(ns.shapes[0].cells.rows, ns.shapes[0].cells.columns);
6191
6192 for s in ns.shapes.clone().iter() {
6193 nns.shapes.push(s.to_origin());
6194 }
6195
6196 if nns.to_grid_transparent().is_full() {
6197 nns.to_grid_transparent()
6198 } else {
6199 ns.shapes[0].to_grid()
6200 }
6201 };
6202
6203 if let Some(rule) = run_experiment(task, 5126, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6204
6205 let func = |ex: &Example| {
6206 if !colour_diffs.is_empty() || ex.input.shapes.shapes.len() < 3 {
6207 return Grid::trivial();
6208 }
6209 let big = ex.input.shapes.largest();
6210 let mut horizontal = true;
6211 let mut r = usize::MAX;
6212
6213 for s in ex.input.shapes.shapes.iter() {
6214 if s.is_pixel() {
6215 if r == usize::MAX {
6216 r = s.orow;
6217 } else if r != s.orow {
6218 horizontal = false;
6219 }
6220 }
6221 }
6222
6223 let cnt = ex.input.shapes.shapes.len() - 1;
6224 let mut shapes = if horizontal {
6225 Shapes::new_sized(big.cells.rows, big.cells.columns * cnt)
6226 } else {
6227 Shapes::new_sized(big.cells.rows * cnt, big.cells.columns)
6228 };
6229 let mut offset = 0;
6230
6231 for s in ex.input.shapes.shapes.iter() {
6232 if *s != big {
6233 let mut shape = big.clone();
6234
6235 shape.recolour_mut(big.colour, s.colour);
6236
6237 if horizontal {
6238 shape.to_position_mut(0, offset);
6239 offset += big.cells.rows;
6240 } else {
6241 shape.to_position_mut(offset, 0);
6242 offset += big.cells.columns;
6243 };
6244
6245 shapes.shapes.push(shape);
6246 }
6247 }
6248
6249shapes.to_grid()
6251 };
6252
6253 if let Some(rule) = run_experiment(task, 5176, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6254
6255 let func = |ex: &Example| {
6256 if !colour_diffs.is_empty() {
6257 return Grid::trivial();
6258 }
6259
6260 let colour = ex.input.grid.to_shapes().full_extent().colour;
6262
6263 Grid::new(1, 1, colour)
6264 };
6265
6266 if let Some(rule) = run_experiment(task, 5189, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6267
6268 let func = |ex: &Example| {
6270 if !colour_diffs.is_empty() {
6271 return Grid::trivial();
6272 }
6273 let s = ex.input.shapes.largest();
6274
6275 if s.cells.rows <= 3 || s.cells.columns <= 3 {
6276 return Grid::trivial();
6277 }
6278
6279 let s = s.shrink_border();
6280
6281 let grid = ex.input.grid.subgrid(s.orow + 1, s.cells.rows - 2, s.ocol + 1, s.cells.columns - 2);
6282grid
6285 };
6286
6287 if let Some(rule) = run_experiment(task, 5210, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6288
6289 let (rs, cs) = examples.examples[0].output.grid.dimensions();
6290
6291 let func = |ex: &Example| {
6292 if all_colour_diffs.len() != 1 {
6293 return Grid::trivial();
6294 }
6295 let mut shape = Shape::trivial();
6296 let mut ocol = 0;
6297 let mut left = false;
6298 let mut width = 0;
6299 let mut winc = 0;
6300 let mut wider = false;
6301
6302 let grid = ex.input.grid.recolour(all_colour_diffs[0], Black);
6303
6304 for s in grid.to_shapes_coloured().shapes.iter() {
6305 if s.colour != all_colour_diffs[0] {
6306 left = s.ocol > ocol;
6307 ocol = s.ocol;
6308 if width < s.cells.columns {
6309 winc = s.cells.columns - width;
6310 width = s.cells.columns;
6311 wider = true;
6312 } else {
6313 wider = false;
6314 }
6315
6316 shape = s.clone();
6317 }
6318 }
6319
6320 let mut new_shape = shape.clone();
6321 let mut shapes = Shapes::new_sized(rs, cs);
6322
6323 if left {
6324 ocol += 1;
6325 } else if wider {
6326 new_shape = Shape::new_sized_coloured_position(shape.ocol, shape.orow, shape.cells.rows, shape.cells.columns + winc, shape.colour);
6327 } else {
6328 let mut c1 = NoColour;
6329 let mut cc = 0;
6330
6331 'outer:
6332 for r in 0 .. shape.cells.rows {
6333 for c in 0 .. shape.cells.columns {
6334 let cell = &shape.cells[(r,c)];
6335 if c1 == NoColour && cell.colour != Black {
6336 c1 = cell.colour;
6337 } else if c1 != NoColour && cell.colour != Black {
6338 if c == 0 {
6339 return Grid::trivial();
6340 }
6341
6342 cc = c - 1;
6343 break 'outer;
6344 }
6345 }
6346 }
6347
6348 new_shape = shape.clone();
6349
6350 for r in 0 .. shape.cells.rows {
6351 let cell = &mut new_shape.cells[(r,cc)];
6352 if cell.colour != Black {
6353 cell.colour = c1;
6354 }
6355 }
6356 }
6357
6358 let orow = if shape.cells.rows == 1 { 1 } else { 0 };
6359
6360 new_shape.to_position_mut(orow, ocol);
6361
6362 shapes.shapes.push(new_shape);
6363
6364shapes.to_grid()
6366 };
6367
6368 if let Some(rule) = run_experiment(task, 5291, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6369
6370 let func = |ex: &Example| {
6371 if all_colour_diffs.len() != 1 {
6372 return Grid::trivial();
6373 }
6374
6375 let colour = ex.input.grid.majority_colour();
6376 let mut pix = ex.input.shapes.clone_base();
6377 let mut rd = 0;
6378 let mut cd = 0;
6379 let mut big_r = 0;
6380 let mut big_c = 0;
6381 let mut max_r = 0;
6382 let mut max_c = 0;
6383
6384 for s in ex.input.shapes.shapes.iter() {
6385 if s.colour != colour {
6386 if rd < s.orow || cd < s.ocol {
6387 return Grid::trivial();
6388 }
6389
6390 pix.shapes.push(s.clone());
6391
6392 rd += (rd as isize - s.orow as isize).abs() as usize;
6393 cd += (cd as isize - s.ocol as isize).abs() as usize;
6394 } else {
6395 big_r = big_r.max(s.cells.rows);
6396 big_c = big_c.max(s.cells.columns);
6397 max_r += s.cells.rows;
6398 max_c += s.cells.columns;
6399 }
6400 }
6401
6402 let horizontal = rd < cd;
6403 let mut o_shapes = ex.input.shapes.clone();
6404 let mut shapes = if horizontal {
6405 o_shapes.shapes.sort_by(|a, b| (a.ocol,a.orow).cmp(&(b.ocol,b.orow)));
6406 Shapes::new_sized(big_r, max_c)
6407 } else {
6408 o_shapes.shapes.sort_by(|a, b| (a.orow,a.ocol).cmp(&(b.orow,b.ocol)));
6409 Shapes::new_sized(max_r, big_c)
6410 };
6411 let mut r = 0;
6412 let mut c = 0;
6413
6414 for s in o_shapes.shapes.iter() {
6415 if s.colour == colour {
6416 let (cr, cc) = s.centre_of();
6417 let near = pix.nearest_shape(cr, cc);
6418 let ns = s.recolour(s.colour, near.colour).to_position(r, c);
6419 if horizontal { c += big_c } else { r += big_r };
6420
6421 shapes.shapes.push(ns);
6422 }
6423 }
6424
6425shapes.to_grid()
6427 };
6428
6429 if let Some(rule) = run_experiment(task, 5291, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6430
6431 let (gridr, gridc) = examples.examples[0].output.grid.dimensions();
6432 let func = |ex: &Example| {
6433 if colour_common.len() != 2 {
6434 return Grid::trivial();
6435 }
6436
6437 let mut grid = Grid::new(gridr, gridc, Black);
6438 let mut bg = NoColour;
6439
6440 for s in ex.input.shapes.shapes.iter() {
6441 if s.dimensions() == ex.input.grid.dimensions() {
6442 bg = s.colour;
6443 }
6444 }
6445
6446 let scc = ex.input.shapes.shape_colour_cnt_map();
6447 let mut ccs: Vec<(Colour,usize)> = scc.iter().filter(|(k,_)| **k != bg).map(|(k,v)| (*k, v.len())).collect();
6448
6449 ccs.sort();
6450 ccs.reverse();
6451
6452 let mut r = 0;
6453 let mut c = 0;
6454
6455 for (col, sz) in ccs.iter() {
6456 for _ in 0 .. *sz {
6457 if r >= grid.cells.rows || c >= grid.cells.columns {
6458 return Grid::trivial();
6459 }
6460 grid.cells[(r,c)].colour = *col;
6461
6462 if c + 1 == gridc {
6463 c = 0;
6464 r += 1;
6465 } else {
6466 c += 1;
6467 }
6468 }
6469 }
6470
6471grid
6473 };
6474
6475 if let Some(rule) = run_experiment(task, 5292, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6476
6477 *cap_todo.entry(gc).or_insert(0) += 1;
6478 }
6479 let gc = SingleColouredShapeOut;
6480 if all || cat.contains(&gc) {
6481 *cap_cats.entry(gc).or_insert(0) += 1;
6482
6483 let edge_colour = examples.largest_shape_colour();
6488
6489 let func = |ex: &Example| {
6490 let h = ex.input.grid.cell_colour_cnt_map();
6491
6492 if let Some(colour) = h.iter().min_by(|(_, cnt1), (_, cnt2)| cnt1.cmp(cnt2)).map(|(k, _)| k) {
6493 let h = ex.input.shapes.shape_colour_cnt_map();
6494
6495 if let Some(vc) = h.get(colour) {
6496 if vc.len() != 1 || vc[0].size() != 1 || vc[0].orow == 0 || vc[0].ocol == 0 || vc[0].orow >= ex.input.grid.cells.rows - 1 || vc[0].ocol >= ex.input.grid.cells.columns - 1 {
6497 return Grid::trivial();
6498 }
6499let enclose = vc[0].surround(1, edge_colour, true, true);
6502let mut ss = ex.input.shapes.clone();
6504
6505 ss.shapes = vec![enclose.clone(), vc[0].clone()];
6506
6507 return ss.to_grid();
6508 }
6509 }
6510
6511 Grid::trivial()
6512 };
6513
6514 if let Some(rule) = run_experiment(task, 5330, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6515
6516 let func = |ex: &Example| {
6517 if ex.input.coloured_shapes.is_empty() {
6518 return Grid::trivial();
6519 }
6520
6521 let shape = if ex.input.coloured_shapes.len() == 1 {
6522 ex.input.coloured_shapes.shapes[0].clone()
6523 } else {
6524 ex.input.coloured_shapes.to_shape()
6525 };
6526
6527 let mut shapes = ex.input.coloured_shapes.clone();
6528
6529 shapes.shapes[0] = shape.make_symmetric();
6530
6531 shapes.to_grid()
6532 };
6533
6534 if let Some(rule) = run_experiment(task, 5350, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6535
6536 if cat.contains(&InLessCountOut) && cat.contains(&InOutSameSize) {
6537 let colour = examples.examples[0].output.grid.min_colour();
6538
6539 let func = |ex: &Example| {
6540 let consolidated = ex.input.grid.as_shape();
6541 let mut shapes = Shapes::new_from_shape(&consolidated);
6542 let consolidated = ex.input.shapes.to_shape();
6543 let s = consolidated.fill_lines(colour);
6544
6545 shapes.shapes.push(s);
6546
6547 shapes.to_grid()
6548 };
6549
6550 if let Some(rule) = run_experiment(task, 5366, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6551 }
6552
6553 if colour_diffs.len() == 1 {
6554 let (r, c) = examples.examples[0].output.grid.find_pixel(colour_diffs[0]);
6555
6556 let func = |ex: &Example| {
6557 if ex.input.shapes.shapes.is_empty() || colour_diffs.len() != 1 || ex.input.grid.cells.columns < ex.input.shapes.shapes.len() {
6558 return Grid::trivial();
6559 }
6560
6561 let cs = ex.input.grid.cells.columns - ex.input.shapes.shapes.len();
6562 let mut shapes = Shapes::new_sized(cs + 1, cs);
6563 let mut row = r;
6564 let mut col = c;
6565
6566 for s in ex.input.shapes.shapes.iter() {
6567 if s.width() == 2 {
6568 if s.cells[(0,0)].colour != Black {
6569 let ns = s.to_position(row, col);
6570
6571 shapes.shapes.push(ns);
6572
6573 row += 1;
6574 col += 1;
6575 } else if col > 0 {
6576 let ns = s.to_position(row, col - 1);
6577
6578 shapes.shapes.push(ns);
6579
6580 row += 1;
6581 col -= 1;
6582 }
6583 } else {
6584 let ns = s.to_position(row + 1, col);
6585
6586 shapes.shapes.push(ns);
6587
6588 row += 2;
6589 }
6590 }
6591
6592 let ns = Shape::new_sized_coloured_position(r, c, 1, 1, colour_diffs[0]);
6593 shapes.shapes.push(ns);
6594
6595 shapes.to_grid_transparent()
6596 };
6597
6598 if let Some(rule) = run_experiment(task, 5414, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6599 }
6600
6601 *cap_todo.entry(gc).or_insert(0) += 1;
6602 }
6603 let gc = NoShapesIn(1);
6604 if all || cat.contains(&gc) && cat.contains(&NoColouredShapesOut(1)) && !cat.contains(&NoShapesOut(1)) {
6605 *cap_cats.entry(gc).or_insert(0) += 1;
6606
6607 if cat.contains(&NoShapesIn(1)) && cat.contains(&NoShapesOut(6)) {
6608 let in_colours = examples.examples[0].input.shapes.colours();
6610 let out_colours = examples.examples[0].output.shapes.colours();
6611 let colours = Uniq::uniq(&out_colours, in_colours);
6612
6613 let func = |ex: &Example| {
6614let mut grid = ex.input.grid.clone();
6616 let fb = ex.input.shapes.shapes[0].find_first_blacks();
6617let mut j = 0;
6619
6620 for (i, (r, c)) in fb.iter().enumerate() {
6621 if i != 0 && i != 2 && i != 6 && i != 8 {
6623 grid = grid.flood_fill(*r, *c, NoColour, colours[j]);
6624 j += 1;
6625 }
6626 }
6627grid
6630 };
6631
6632 if let Some(rule) = run_experiment(task, 5448, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6633 }
6634
6635 let min_colour = examples.examples[0].output.grid.find_min_colour();
6636 let max_colour = examples.examples[0].output.grid.find_max_colour();
6637
6638 let func = |ex: &Example| {
6639 let grid = ex.input.grid.recolour(Black, NoColour);
6640let mut shapes = grid.to_shapes();
6642 let mut min_size = usize::MAX;
6643 let mut max_size = 0;
6644
6645 for s in shapes.shapes.iter_mut() {
6646 if s.size() != grid.size() {
6647 s.recolour_mut(NoColour, Black);
6648 if s.size() > max_size {
6649 max_size = s.size();
6650 }
6651 if s.size() < min_size {
6652 min_size = s.size();
6653 }
6654 }
6655 }
6656
6657 for s in shapes.shapes.iter_mut() {
6658 if s.size() == max_size {
6659 s.recolour_mut(NoColour, max_colour);
6660 }
6661 if s.size() == min_size {
6662 s.recolour_mut(NoColour, min_colour);
6663 }
6664 }
6665shapes.to_grid()
6668 };
6669
6670 if let Some(rule) = run_experiment(task, 5486, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6671
6672 if cat.contains(&NoShapesIn(1)) && cat.contains(&NoShapesOut(2)) {
6673 let extra_colour = examples.examples[0].output.grid.find_min_colour();
6674
6675 let func = |ex: &Example| {
6676 if ex.input.shapes.shapes.is_empty() || !ex.input.grid.is_square() {
6677 return Grid::trivial();
6678 }
6679 let colour = ex.input.grid.colour;
6680 let mut shapes = ex.input.shapes.clone();
6681 let shape = &ex.input.shapes.shapes[0];
6682 let shape = shape.to_square();
6683 let mut shape = shape.diff(&shape.rotated_90()).unwrap();
6684
6685 shape.recolour_mut(ToBlack + colour, extra_colour);
6686 shape.uncolour_mut();
6687
6688 shapes.shapes.push(shape);
6689shapes.to_grid()
6692 };
6693
6694 if let Some(rule) = run_experiment(task, 5510, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6695 }
6696
6697 if cat.contains(&NoShapesIn(1)) && cat.contains(&NoColouredShapesOut(1)) {
6698 let extra_colour = examples.examples[0].output.grid.find_min_colour();
6699
6700 let func = |ex: &Example| {
6701 if ex.input.shapes.shapes.is_empty() {
6702 return Grid::trivial();
6703 }
6704 let mut shapes = ex.input.shapes.clone();
6705
6706 shapes.shapes[0].recolour_mut(Black, extra_colour);
6707shapes.to_grid()
6710 };
6711
6712 if let Some(rule) = run_experiment(task, 5528, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6713
6714 let func = |ex: &Example| {
6715 if ex.input.shapes.shapes.is_empty() && ex.input.shapes.shapes[0].cells.columns % 2 != 1 {
6716 return Grid::trivial();
6717 }
6718
6719 let mut shape = ex.input.shapes.shapes[0].clone();
6720 let mid_r = shape.cells.rows / 2;
6721 let cols: Vec<usize> = (0 .. shape.cells.columns).filter(|&c| shape.cells[(mid_r, c)].colour == Black).collect();
6722
6723 if cols.is_empty() {
6724 return Grid::trivial();
6725 }
6726
6727 let mut down = true;
6728
6729 for (i, &c) in cols.iter().enumerate() {
6730 if i % 3 == 0 {
6731 shape.flood_fill_mut(mid_r, c, NoColour, extra_colour);
6732 down = !down;
6733 }
6734 }
6735
6736 if cols.len() % 3 == 0 {
6737 let r = if down { mid_r + 1 } else { mid_r - 1 };
6738 let c = shape.cells.columns - 1;
6739
6740 shape.flood_fill_mut(r, c, NoColour, extra_colour);
6741 }
6742
6743 shape.to_grid()
6744 };
6745
6746 if let Some(rule) = run_experiment(task, 5562, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6747
6748 let colours = examples.examples[0].output.grid.colours();
6749 let in_colour = examples.examples[0].input.grid.colour;
6750
6751let fill_colour = colours.iter().filter(|&(&k,_)| k != in_colour).map(|(k,v)| (v,k)).min().map(|(_,k)| k).unwrap();
6767
6768 if colours.len() == 3 {
6769 let bg_colour = colours.iter().filter(|&(&k,_)| k != in_colour).map(|(k,v)| (v,k)).max().map(|(_,k)| k).unwrap();
6770
6771 let func = |ex: &Example| {
6772 if ex.input.shapes.shapes.is_empty() && ex.input.shapes.shapes[0].cells.columns % 2 != 1 {
6773 return Grid::trivial();
6774 }
6775
6776 let mut shape = ex.input.grid.as_shape();
6777 let rows = shape.cells.rows;
6778 let cols = shape.cells.columns;
6779for r in 0 .. rows {
6782 for c in 0 .. cols {
6783 if (r == 0 || c == 0 || r == rows - 1 || c == cols - 1) && shape.cells[(r, c)].colour == Black {
6784 shape.flood_fill_mut(r, c, NoColour, *bg_colour);
6785 }
6786 }
6787 }
6788
6789 shape.recolour_mut(Black, *fill_colour);
6790
6791shape.to_grid()
6793 };
6794
6795 if let Some(rule) = run_experiment(task, 5611, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6796 }
6797
6798 if colours.len() == 2 {
6799 let func = |ex: &Example| {
6800 if ex.input.shapes.shapes.is_empty() && ex.input.shapes.shapes[0].cells.columns % 2 != 1 || !ex.input.shapes.shapes[0].hollow() {
6801 return Grid::trivial();
6802 }
6803
6804 let mut shapes = ex.input.shapes.clone();
6805let mut rects = ex.input.grid.find_rectangles();
6808for s in rects.shapes.iter_mut() {
6811 s.recolour_mut(Black, *fill_colour);
6812 }
6813shapes.merge_mut(&rects);
6816
6817shapes.to_grid()
6822 };
6823
6824 if let Some(rule) = run_experiment(task, 5640, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6825 }
6826
6827 let func = |ex: &Example| {
6828 if ex.input.shapes.shapes.is_empty() {
6829 return Grid::trivial();
6830 }
6831
6832 let mut grid = ex.input.grid.clone();
6833
6834 let mut nr = 1;
6835 for r in 1 .. grid.cells.rows {
6836 if grid.cells[(r,0)].colour != grid.cells[(0,0)].colour {
6837 nr += 1;
6838 } else {
6839 break;
6840 }
6841 }
6842 let mut nc = 1;
6843 for c in 1 .. grid.cells.columns {
6844 if grid.cells[(0,c)].colour != grid.cells[(0,0)].colour {
6845 nc += 1;
6846 } else {
6847 break;
6848 }
6849 }
6850 let mut tile = grid.subgrid(0, nr, 0, nc);
6851
6852 tile = tile.roll_right();
6853 grid.tile_mut(&tile);
6854grid
6857 };
6858
6859 if let Some(rule) = run_experiment(task, 5675, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6860
6861 for inc in 1 ..= 1 { let func = |ex: &Example| {
6864 if ex.input.shapes.shapes.len() != 1 || ex.input.shapes.shapes[0].size() >= ex.input.grid.size() || ex.input.shapes.shapes[0].is_pixel() || ex.input.shapes.shapes[0].ocol > 0 || !ex.input.shapes.is_line() {
6865 return Grid::trivial();
6866 }
6867
6868 let top_colour = colours.iter().filter(|&(&k,_)| k != in_colour).map(|(k,v)| (v,k)).max().map(|(_,k)| k).unwrap();
6869 let bottom_colour = colours.iter().filter(|&(&k,_)| k != in_colour).map(|(k,v)| (v,k)).min().map(|(_,k)| k).unwrap();
6870
6871 let mut shapes = ex.input.shapes.clone();
6872 let shape = &ex.input.shapes.shapes[0];
6873 let rows = shape.cells.rows;
6874 let cols = shape.cells.columns;
6875 let bound = if inc == 1 { cols + shape.orow - 1
6876 } else {
6877 cols + shape.orow + inc
6878 };
6879
6880 for (i, c) in (0 ..= bound).rev().step_by(inc).enumerate() {
6881 if i != shape.orow {
6882 let colour = if i < shape.orow {
6883 top_colour
6884 } else {
6885 bottom_colour
6886 };
6887 let s = Shape::new_sized_coloured_position(i, 0, rows, c + 1, *colour);
6888shapes.shapes.push(s);
6891 }
6892 }
6893shapes.to_grid()
6899 };
6900
6901 if let Some(rule) = run_experiment(task, 5717, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6902 }
6903
6904 let func = |ex: &Example| {
6905 if ex.input.shapes.shapes.len() != 1 {
6906 return Grid::trivial();
6907 }
6908
6909 let shape = &ex.input.shapes.shapes[0];
6910 let (dir, r, c) = shape.has_border_break();
6911 let mut grid = ex.input.grid.clone();
6912
6913 grid.draw_mut(dir, r, c, *fill_colour);
6914 grid.flood_fill_mut(r, c, NoColour, *fill_colour);
6915
6916grid
6918 };
6919
6920 if let Some(rule) = run_experiment(task, 5736, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6921
6922 let func = |ex: &Example| {
6923 if ex.input.shapes.shapes.len() != 1 {
6924 return Grid::trivial();
6925 }
6926
6927 let shape = &ex.input.shapes.shapes[0];
6928 let mut grid = ex.input.grid.clone();
6929 let dist = grid.cells.columns - 1;
6930
6931 let mut rfrom = shape.orow;
6933 let mut cfrom = shape.ocol;
6934 let mut odd = true;
6935
6936 while rfrom > 0 {
6937 let dir = if odd { UpRight } else { UpLeft };
6938
6939 grid.draw_mut(dir, rfrom, cfrom, in_colour);
6940
6941 rfrom = rfrom.saturating_sub(dist);
6942 cfrom = if cfrom == 0 { dist } else { 0 };
6943 odd = !odd;
6944 }
6945
6946 grid = grid.recolour(Black, *fill_colour);
6947
6948grid
6950 };
6951
6952 if let Some(rule) = run_experiment(task, 5768, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
6953 }
6954*cap_todo.entry(gc).or_insert(0) += 1;
6969 }
6970 let gc = NoShapesIn(2);
6988 if all || cat.contains(&gc) {
6989 *cap_cats.entry(gc).or_insert(0) += 1;
6990
6991 let func = |ex: &Example| {
6992 if ex.input.shapes.shapes.len() != 2 || colour_diffs.len() != 1 {
6993 return Grid::trivial();
6994 }
6995 let mut shapes = ex.input.shapes.clone();
6996
6997 if shapes.shapes[0].orow + shapes.shapes[0].cells.rows + 1 == shapes.shapes[1].orow {
6998 if shapes.shapes[1].orow == 0 {
6999 return Grid::trivial();
7000 }
7001 let s = Shape::new_sized_coloured_position(shapes.shapes[1].orow - 1, 0, 1, ex.input.grid.cells.columns, colour_diffs[0]);
7002
7003 shapes.shapes.push(s);
7004 } else {
7005 if shapes.shapes[1].ocol == 0 {
7006 return Grid::trivial();
7007 }
7008 let s = Shape::new_sized_coloured_position(0, shapes.shapes[1].ocol - 1, ex.input.grid.cells.rows, 1, colour_diffs[0]);
7009
7010 shapes.shapes.push(s);
7011 }
7012
7013shapes.to_grid()
7015 };
7016
7017 if let Some(rule) = run_experiment(task, 5833, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7018
7019 let ss = examples.some(false, &|ss| ss.smallest());
7020 let sl = examples.some(true, &|ss| ss.largest());
7021 let sc: Vec<(Shape, Colour)> = ss.iter().zip(sl.iter()).map(|(s1, s2)| (s1.to_origin(), s2.colour)).collect();
7022
7023 let func = |ex: &Example| {
7024 let largest = ex.input.shapes.largest();
7025 let smallest = ex.input.shapes.smallest().to_origin();
7026 let mut shapes = ex.input.shapes.clone_base();
7027
7028 let pair: Vec<_> = sc.iter().filter(|(s, _)| s.equals(&smallest) == Same).collect();
7029
7030 if pair.len() == 0 {
7031 return Grid::trivial();
7032 }
7033
7034 shapes.shapes.push(largest.recolour(largest.colour, pair[0].1));
7035
7036shapes.to_grid()
7038 };
7039
7040 if let Some(rule) = run_experiment(task, 5856, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7041
7042 *cap_todo.entry(gc).or_insert(0) += 1;
7043 }
7044 let gc = NoColouredShapesIn(2);
7045 if all || cat.contains(&gc) {
7046 *cap_cats.entry(gc).or_insert(0) += 1;
7047
7048 let func = |ex: &Example| {
7049 let idx = ex.input.coloured_shapes.smallest();
7050 let shape = ex.input.coloured_shapes.largest();
7051
7052 if idx.width() == 0 {
7053 return Grid::trivial();
7054 }
7055
7056 let mut big = idx.rotated_90().scale_up(shape.width() / idx.width());
7057
7058 big.to_position_mut(shape.orow, shape.ocol);
7059
7060 let mut shapes = ex.input.coloured_shapes.clone();
7061
7062
7063 shapes.shapes.push(big);
7064shapes.to_grid()
7067 };
7068
7069 if let Some(rule) = run_experiment(task, 5885, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7070
7071 let func = |ex: &Example| {
7072 if ex.input.coloured_shapes.len() != 2 || !ex.input.coloured_shapes.shapes[0].is_square() || ex.input.coloured_shapes.shapes[0].size() != 4 {
7073 return Grid::trivial();
7074 }
7075 let mut ns = ex.input.coloured_shapes.clone();
7076 let idx = &ex.input.coloured_shapes.shapes[0].cells;
7077
7078 let sm: BTreeMap<Colour, Colour> = idx.keys()
7079 .map(|(r,c)|
7080 if r == 0 && c == 0 {
7081 (idx[(r,c)].colour, idx[(r,c+1)].colour)
7082 } else if r == 1 && c == 0 {
7083 (idx[(r,c)].colour, idx[(r,c+1)].colour)
7084 } else if r == 0 && c == 1 {
7085 (idx[(r,c)].colour, idx[(r,c-1)].colour)
7086 } else {
7087 (idx[(r,c)].colour, idx[(r,c-1)].colour)
7088 }
7089 )
7090 .collect();
7091
7092 ns.shapes[1].swap_colours(&sm);
7093
7094 ns.to_grid()
7095 };
7096
7097 if let Some(rule) = run_experiment(task, 5913, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7098
7099 *cap_todo.entry(gc).or_insert(0) += 1;
7100 }
7101
7102 let gc = NoColouredShapesIn(9);
7103 if all || cat.contains(&gc) && cat.contains(&NoColouredShapesOut(9)){
7104 *cap_cats.entry(gc).or_insert(0) += 1;
7105
7106 let colours: Vec<_> = examples.examples[0].input.grid.find_all_colours()
7107 .keys()
7108 .copied()
7109 .collect();
7110
7111 let order0 = [(0, 0), (0, 4), (0, 8), (4, 0), (4, 4), (4, 8), (8, 0), (8, 4), (8, 8)];
7112 let order1 = [(0, 8), (0, 4), (0, 0), (4, 8), (4, 4), (4, 0), (8, 8), (8, 4), (8, 0)];
7113 let order2 = [(8, 0), (8, 4), (8, 8), (4, 0), (4, 4), (4, 8), (0, 0), (0, 4), (0, 8)];
7114 let order3 = [(8, 8), (8, 4), (8, 0), (4, 8), (4, 4), (4, 0), (0, 8), (0, 4), (0, 0)];
7115
7116 for colour in colours.into_iter() {
7117 for order in [order0, order1, order2, order3] {
7118 let func = |ex: &Example| {
7120 if ex.input.shapes.shapes.is_empty() {
7121 return Grid::trivial();
7122 }
7123 let mut shapes = ex.input.grid.to_shapes_base_bg(Black);
7124
7125 shapes.shapes.sort_by_key(|b| std::cmp::Reverse(b.cell_count_colour(colour)));
7126
7127 let mut grid = Grid::new(ex.input.grid.cells.rows, ex.input.grid.cells.columns, Black);
7128
7129 for ((r, c), s) in order.iter().zip(shapes.shapes.iter()) {
7130 grid.copy_shape_to_grid_position_mut(s, *r, *c);
7131 }
7132
7133 grid
7134 };
7135
7136 if let Some(rule) = run_experiment(task, 5952, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7137 }
7138 }
7139
7140 *cap_todo.entry(gc).or_insert(0) += 1;
7141 }
7142 let gc = OutLessThanIn;
7143 if all || cat.contains(&gc) {
7144 *cap_cats.entry(gc).or_insert(0) += 1;
7145
7146 if all || cat.contains(&SinglePixelOut) {
7147 let (rs, cs) = examples.examples[0].output.grid.dimensions();
7148
7149 let func = |gi: &Example| {
7150 if gi.input.shapes.shapes.is_empty() {
7151 return Grid::trivial();
7152 }
7153
7154 let h = gi.input.shapes.shape_colour_cnt_map();
7155 let pair: Option<Vec<Shape>> = h.clone().into_values().filter(|p| p.len() == 2 && p[0].size() == p[1].size()).last();
7156 if let Some(pair) = pair {
7157 for s in gi.input.coloured_shapes.shapes.iter() {
7159 if s.is_contained(&pair[0]) && s.is_contained(&pair[1]) {
7160 let colour = h.keys().filter(|&&c| c != pair[0].colour && c != pair[1].colour).collect::<Vec<_>>();
7162
7163 return Grid::new(rs, cs, *colour[0]);
7164 }
7165 }
7166 }
7167
7168 Grid::new(rs, cs, Black)
7169 };
7170
7171 if let Some(rule) = run_experiment(task, 5987, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7172 }
7173
7174 let func = |ex: &Example| {
7175 let scm = ex.input.shapes.shape_colour_cnt_map();
7176
7177 for v in scm.values() {
7178 if v.len() == 1 {
7179 return v[0].to_grid();
7180 }
7181 }
7182
7183 Grid::trivial()
7184 };
7185
7186 if let Some(rule) = run_experiment(task, 6002, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7187
7188 if let Some(rule) = run_experiment(task, 6004, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.shapes.find_max().to_grid(), output) { return Some(rule); };
7189
7190 let colour = examples.examples[0].output.grid.colour;
7191
7192 let func = |g: &Grid, _: &Grid, n: &mut usize| {
7194 let colour = g.mid_div_colour();
7195 let shapes = g.to_shapes_base_bg(colour);
7196 if shapes.shapes.len() != 2 {
7199 return Grid::trivial();
7200 }
7201 let diff = shapes.shapes[0].diff(&shapes.shapes[1]);
7202
7203 if let Some(diff) = diff {
7204 diff_only(&diff.to_grid(), colour, n)
7205 } else {
7206 Grid::trivial()
7207 }
7208 };
7209
7210 if let Some(rule) = run_experiment_tries(task, 6026, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7211
7212 let func = |g: &Grid, _: &Grid, n: &mut usize| {
7214 let colour = g.mid_div_colour();
7215 let shapes = g.to_shapes_base_bg(colour);
7216
7217 if shapes.shapes.len() != 2 || colour == NoColour || colour_diffs.is_empty() {
7218 return Grid::trivial();
7219 }
7220 let diff = shapes.shapes[0].diff(&shapes.shapes[1]);
7221
7222 if let Some(diff) = diff {
7223 diff_only(&diff.to_grid(), colour, n).recolour(colour, colour_diffs[0]).inverse_colour()
7224 } else {
7225 Grid::trivial()
7226 }
7227 };
7228
7229 if let Some(rule) = run_experiment_tries(task, 6045, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7230
7231 let func = |ex: &Example| {
7232 let shapes = ex.input.grid.split_2();
7233
7234 if shapes.len() != 2 || colour_diffs.is_empty() {
7235 return Grid::trivial();
7236 }
7237
7238 let g1 = shapes.shapes[0].to_grid();
7239 let g2 = shapes.shapes[1].to_grid();
7240 let grid = g1.diff_only_not(colour_diffs[0]).diff(&g2.diff_only_not(colour_diffs[0]));
7241
7242 match grid {
7243 Some(grid) => grid.diff_only_same(),
7244 None => Grid::trivial(),
7245 }
7246 };
7247
7248 if let Some(rule) = run_experiment(task, 6064, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7249
7250 let func = |gi: &Grid, _: &Grid, n: &mut usize| {
7252 let centre = gi.centre_of();
7253 let shapes = gi.to_shapes_base_bg(gi.cells[centre].colour);
7254 if shapes.is_empty() || shapes.shapes.len() != 2 {
7255 return Grid::trivial();
7256 }
7257 let diff = shapes.shapes[1].diff(&shapes.shapes[0]);
7258
7259 if let Some(diff) = diff {
7260 diff_only(&diff.to_grid(), colour, n)
7261 } else {
7262 Grid::trivial()
7263 }
7264 };
7265
7266 if let Some(rule) = run_experiment_tries(task, 6082, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7267
7268 let func = |gi: &Grid, _: &Grid, n: &mut usize| {
7270 let shapes = gi.split_2();
7271if shapes.is_empty() || shapes.shapes.len() != 2 { return Grid::trivial(); }
7273 let diff = shapes.shapes[0].diff(&shapes.shapes[1]);
7274
7275 if let Some(diff) = diff {
7276 diff_only(&diff.to_grid(), colour, n)
7277 } else {
7278 Grid::trivial()
7279 }
7280 };
7281
7282 if let Some(rule) = run_experiment_tries(task, 6098, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7283
7284 let colours = examples.examples[0].input.grid.cell_colour_cnt_map();
7285 let colour = examples.examples[0].output.grid.colour;
7286
7287 if !colours.contains_key(&colour) {
7288 for (&in_colour, _) in colours.iter() {
7289 let func = |ex: &Example| {
7290 let mut m = 0;
7291 let mut size = 0;
7292
7293 for s in &ex.input.shapes.shapes {
7294 if s.colour == in_colour && s.size() > 1 {
7295 if size > 1 && size != s.size() {
7296 return Grid::trivial();
7297 }
7298 size = s.size();
7299
7300 m += 1;
7301 }
7302 }
7303 let side = ex.output.grid.cells.rows;
7304
7305 Grid::colour_every_nxn_for_m(colour, side, size, m)
7306 };
7307
7308 if let Some(rule) = run_experiment(task, 6123, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7309 }
7310 }
7311
7312 let (rs, cs) = examples.examples[0].output.grid.dimensions();
7313
7314 let func = |ex: &Example| {
7315 let mut colour = NoColour;
7316
7317 for s in &ex.input.shapes.shapes {
7318 if !s.is_full() {
7319 colour = s.colour;
7320
7321 break;
7322 }
7323 }
7324
7325 Grid::new(rs, cs, colour)
7326 };
7327
7328 if let Some(rule) = run_experiment(task, 6142, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7329
7330 for order in permutations(&[0,1,2,3]) {
7332 let func = |gi: &Example| {
7333 let shapes = gi.input.grid.split_4_inline(true);
7334 if shapes.is_empty() || shapes.shapes.len() != 4 {
7335 return Grid::trivial();
7336 }
7337
7338 let mut diff = Some(shapes.shapes[*order[0]].clone());
7339
7340 for i in &order {
7341 if let Some(new_diff) = diff {
7342 let clear = new_diff.diff_only_transparent();
7343
7344 diff = clear.diff(&shapes.shapes[**i]);
7345 } else {
7346 return Grid::trivial();
7347 }
7348 }
7349 if let Some(new_diff) = diff {
7350 new_diff.diff_only_transparent().to_grid()
7351 } else {
7352 Grid::trivial()
7353 }
7354 };
7355
7356 if let Some(rule) = run_experiment(task, 6170, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7357 }
7358
7359 *cap_todo.entry(gc).or_insert(0) += 1;
7360 }
7361 let gc = Div9Out;
7362 if all || cat.contains(&gc) {
7363 *cap_cats.entry(gc).or_insert(0) += 1;
7364
7365 let colour_map = examples.find_colour_io_map();
7368
7369 let func = |ex: &Example| {
7370 let mut shapes = ex.input.shapes.clone();
7371
7372 for s in shapes.shapes.iter_mut() {
7373 if let Some(colour) = colour_map.get(&s.colour) {
7374 s.recolour_mut(s.colour, *colour);
7375 }
7376 }
7377
7378 shapes.to_grid()
7379 };
7380
7381 if let Some(rule) = run_experiment(task, 6195, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7382
7383 *cap_todo.entry(gc).or_insert(0) += 1;
7384 }
7385 let gc = GravityDown;
7386 if all || cat.contains(&gc) || cat.contains(&GravityUp) {
7387 *cap_cats.entry(gc).or_insert(0) += 1;
7388
7389 if let Some(rule) = run_experiment_tries(task, 6203, experiment, trans, is_test, examples, &targets, done, tries, &|ex, _, n| gravity_only(ex, n), output) { return Some(rule); };
7390
7391 let func = |ex: &Example| {
7392 let sccm = ex.input.shapes.shape_colour_cnt_map();
7393 let mut fill_colour = NoColour;
7394 let mut shapes = ex.input.shapes.clone_base();
7395
7396 for (col, ss) in sccm.iter() {
7397 if ss.len() == 1 {
7398 shapes.shapes.push(ss[0].clone())
7399 } else {
7400 fill_colour = *col;
7401 }
7402 }
7403
7404 if shapes.shapes.is_empty() {
7405 return Grid::trivial();
7406 }
7407
7408 let grid = shapes.to_grid();
7409
7410 grid.flood_fill(grid.cells.rows - 1, 0, NoColour, fill_colour)
7411 };
7412
7413 if let Some(rule) = run_experiment(task, 6227, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7414
7415 *cap_todo.entry(gc).or_insert(0) += 1;
7416 }
7417 let gc = SingleColourIn;
7427 if all || cat.contains(&gc) {
7428 *cap_cats.entry(gc).or_insert(0) += 1;
7429
7430 if !cat.contains(&SingleColourOut) {
7432if !examples.examples.is_empty() && !examples.examples[0].input.shapes.shapes.is_empty() {
7448 let colour = examples.examples[0].input.shapes.shapes[0].colour;
7450 let mut new_colour = colour;
7451
7452 for s in examples.examples[0].output.shapes.shapes.iter() {
7453 if colour != s.colour {
7454 new_colour = s.colour;
7455
7456 break;
7457 }
7458 }
7459
7460 let func = |gi: &Example| {
7461 if gi.input.shapes.is_empty() {
7462 return Grid::trivial();
7463 }
7464
7465 let mut si = gi.input.shapes.clone();
7466
7467 si.shapes.sort_by(|a, b| (a.ocol, a.orow).cmp(&(b.ocol, b.orow)));
7468 let mut other = si.shapes.len() % 2 != 0;
7469
7470 for s in si.shapes.iter_mut() {
7471 if other {
7472 s.mut_force_recolour(new_colour);
7473 }
7474
7475 other = !other;
7476 }
7477
7478 si.to_grid()
7479 };
7480
7481 if let Some(rule) = run_experiment(task, 6295, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7482
7483 let func = |gi: &Example| {
7484 if gi.input.shapes.is_empty() {
7485 return Grid::trivial();
7486 }
7487
7488 let mut si = gi.input.shapes.clone();
7489
7490 for s in si.shapes.iter_mut() {
7491 if s.pixels() >= 4 {
7492 s.mut_recolour(colour, new_colour);
7493 }
7494 }
7495
7496 si.to_grid()
7497 };
7498
7499 if let Some(rule) = run_experiment(task, 6313, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7500 }
7501
7502 let ccm = examples.find_hollow_cnt_colour_map();
7503
7504 let func = |ex: &Example| {
7505 if ex.input.shapes.is_empty() {
7506 return Grid::trivial();
7507 }
7508
7509 let mut shapes = ex.input.shapes.clone();
7510
7511 for s in shapes.shapes.iter_mut() {
7512 let (_, n) = s.hollow_colour_count();
7513
7514 if let Some(colour) = ccm.get(&n) {
7515 s.recolour_mut(s.colour, *colour);
7516 }
7517 }
7518
7519shapes.to_grid()
7521 };
7522
7523 if let Some(rule) = run_experiment(task, 6337, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7524
7525 }
7567
7568 let func = |ex: &Example| {
7569 if colour_diffs.len() != 1 || ex.input.shapes.shapes.is_empty() {
7570 return Grid::trivial();
7571 }
7572
7573 let (rs, cs) = ex.majority_dimensions();
7575 let mut grid = ex.input.grid.clone();
7576
7577 grid.recolour_mut(Black, colour_diffs[0]);
7578 grid.recolour_mut(all_colour_diffs[0], Black);
7579
7580 grid.background_border_mut();
7581
7582 grid.row_dividers_mut(rs);
7583 grid.col_dividers_mut(cs);
7584
7585 grid
7586 };
7587
7588 if let Some(rule) = run_experiment(task, 6402, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7589
7590 let out_colours = examples.examples[0].output.grid.cell_colour_cnt_map();
7591 let func = |ex: &Example| {
7592 if all_colour_diffs.len() != 2 || out_colours.len() != 3 {
7593 return Grid::trivial();
7594 }
7595 let mut colour_order: Vec<(usize,Colour)> = out_colours.iter().map(|(k, v)| (*v, *k)).collect();
7596 colour_order.sort();
7597 let colours: Vec<Colour> = colour_order.iter().map(|(_, c)| *c).collect();
7598 let mut grid = ex.input.grid.clone();
7599
7600 for s in ex.input.shapes.shapes.iter() {
7601 let mut r = s.cells.rows + 1;
7602
7603 for c in (0 .. s.ocol).rev() {
7604 grid.draw_mut(Up, r, c, colours[2]);
7605
7606 r += if grid.cells.rows - r <= 2 {
7607 grid.cells.rows - r - 1
7608 } else {
7609 2
7610 };
7611 }
7612
7613 if s.cells.rows < 2 + 1 {
7614 return Grid::trivial();
7615 }
7616
7617 let mut r = s.cells.rows - 2 - 1;
7618
7619 for c in s.ocol + 1 .. grid.cells.columns {
7620 grid.draw_mut(Up, r, c, colours[0]);
7621
7622 if r < 2 {
7623 break;
7624 }
7625
7626 r -= 2;
7627 }
7628 }
7629
7630grid
7632 };
7633
7634 if let Some(rule) = run_experiment(task, 6403, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7635
7636 *cap_todo.entry(gc).or_insert(0) += 1;
7637 }
7638 let gc = SingleColourOut;
7639 if all || cat.contains(&gc) && !cat.contains(&SingleColourIn) {
7640 *cap_cats.entry(gc).or_insert(0) += 1;
7641
7642 if let Some(rule) = run_experiment(task, 6410, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_pixels_min().to_grid(), output) { return Some(rule); };
7643
7644 if let Some(rule) = run_experiment(task, 6412, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.find_pixels_max().to_grid(), output) { return Some(rule); };
7645
7646 if let Some(rule) = run_experiment(task, 6414, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.hollow_cnt_max().to_grid(), output) { return Some(rule); };
7647
7648 if let Some(rule) = run_experiment(task, 6416, experiment, trans, is_test, examples, &targets, done, tries, &|ex| ex.input.coloured_shapes.hollow_cnt_min().to_grid(), output) { return Some(rule); };
7649
7650 let out_colours = examples.find_output_colours();
7651
7652 if out_colours.len() == 1 {
7653 let in_colours = examples.find_input_colours().uniq(out_colours);
7654 if in_colours.len() == 2 {
7655 let func = |ex: &Example| {
7656 let c1s = ex.input.grid.find_colour(in_colours[0]);
7657 let c2s = ex.input.grid.find_colour(in_colours[1]);
7658 let len = c1s.len();
7659 if len == c2s.len() {
7660 let c_dim = c1s[0].col == c2s[0].col;
7661 let mut grid: Grid;
7662
7663 if c_dim {
7664 let width = c1s[0].row.min(c2s[0].row) - c1s[0].row.min(c2s[0].row) - 1; grid = Grid::new(width, len, Black);
7667
7668 for (c, (a, b)) in c1s.iter().zip(c2s.iter()).enumerate() {
7669 for r in a.row + 1 .. b.row {
7670 grid.cells[(r - a.row - 1, c)].row = ex.input.grid.cells[(r,a.col)].row;
7671 grid.cells[(r - a.row - 1, c)].col = ex.input.grid.cells[(r,a.col)].col;
7672 grid.cells[(r - a.row - 1, c)].colour = ex.input.grid.cells[(r,a.col)].colour;
7673 }
7674 }
7675 } else {
7676 let height = c1s[0].col.max(c2s[0].col) - c1s[0].col.min(c2s[0].col) - 1; grid = Grid::new(len, height, Black);
7679
7680 for (r, (a, b)) in c1s.iter().zip(c2s.iter()).enumerate() {
7681 for c in a.col + 1 .. b.col {
7682 grid.cells[(r, c - a.col - 1)].row = ex.input.grid.cells[(a.row,c)].row;
7683 grid.cells[(r, c - a.col - 1)].col = ex.input.grid.cells[(a.row,c)].col;
7684 grid.cells[(r, c - a.col - 1)].colour = ex.input.grid.cells[(a.row,c)].colour;
7685 }
7686 }
7687 };
7688 return grid;
7689 }
7690
7691 Grid::trivial()
7692 };
7693
7694 if let Some(rule) = run_experiment(task, 6462, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7695 }
7696 }
7697
7698 let (rs, cs) = examples.examples[0].output.grid.dimensions();
7699
7700 let func = |ex: &Example| {
7701 if ex.input.shapes.shapes.is_empty() {
7702 return Grid::trivial();
7703 }
7704
7705 let largest = ex.input.shapes.largest();
7706
7707 Grid::new(rs, cs, largest.colour)
7708 };
7709
7710 if let Some(rule) = run_experiment(task, 6478, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7711
7712 *cap_todo.entry(gc).or_insert(0) += 1;
7713 }
7714
7715 *cap_cats.entry(CatchAll).or_insert(0) += 1;
7718
7719 let func = |ex: &Example| {
7720 let largest = ex.input.coloured_shapes.largest();
7721
7722 if largest.cells.rows < 3 || largest.cells.columns < 3 {
7723 return Grid::trivial();
7724 }
7725
7726 let shape = largest.subshape(0, 3, 0, 3);
7727 let mut grid = ex.input.grid.clone();
7728
7729 for s in ex.input.coloured_shapes.shapes.iter() {
7730 if s.size() == 1 {
7731 if s.orow == 0 || s.ocol == 0 {
7732 return Grid::trivial();
7733 }
7734 let new_shape = shape.translate_absolute(s.orow-1,s.ocol-1);
7735
7736 grid.copy_shape_to_grid_mut(&new_shape);
7737 }
7738 }
7739
7740 grid
7741 };
7742
7743 if let Some(rule) = run_experiment(task, 6511, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7744
7745 let out_shapes = examples.all_shapes_out();
7746 let out_shapes = out_shapes.shape_permutations();
7747
7748 let func = |ex: &Example| {
7749 let mut shapes = ex.input.shapes.clone();
7750
7751 for s1 in out_shapes.shapes.iter() {
7752 for s2 in shapes.shapes.iter_mut() {
7753 if s1.equal_shape(s2) {
7754 s2.recolour_mut(s2.colour, s1.colour);
7755 break;
7756 }
7757 }
7758 }
7759
7760 shapes.to_grid()
7761 };
7762
7763 if let Some(rule) = run_experiment(task, 6531, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7764
7765 let spc = examples.shape_pixels_to_colour();
7766
7767 let func = |ex: &Example| {
7768 let mut shapes = ex.input.shapes.clone();
7769
7770 for s in shapes.shapes.iter_mut() {
7771 if let Some(colour) = spc.get(&s.pixels()) {
7772 s.recolour_mut(s.colour, *colour);
7773 } else {
7774 return Grid::trivial();
7775 }
7776 }
7777
7778 shapes.to_grid()
7779 };
7780
7781 if let Some(rule) = run_experiment(task, 6549, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7782
7783 let func = |ex: &Example| {
7784 if ex.input.shapes.is_empty() {
7785 return Grid::trivial();
7786 }
7787 let mut shapes = ex.input.shapes.clone();
7788
7789 for s in shapes.shapes.iter_mut() {
7790 if !Colour::in_range(s.pixels()) {
7791 return Grid::trivial();
7792 }
7793
7794 s.recolour_mut(s.colour, Colour::from_usize(s.pixels()));
7795 }
7796shapes.to_grid()
7799 };
7800
7801 if let Some(rule) = run_experiment(task, 6569, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7802
7803 let func = |ex: &Example| {
7804 let mut shapes = ex.input.shapes.clone();
7805
7806 for s1 in ex.input.shapes.shapes.iter() {
7807 for s2 in shapes.shapes.iter_mut() {
7808 if s1.equal_shape(s2) && s1.colour > s2.colour {
7809 s2.recolour_mut(s2.colour, s1.colour);
7810
7811 break;
7812 }
7813 }
7814 }
7815
7816 shapes.to_grid()
7817 };
7818
7819 if let Some(rule) = run_experiment(task, 6587, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7820
7821 let h = examples.bleached_io_map();
7823
7824 let func = |ex: &Example| {
7825 if let Some(grid) = h.get(&ex.input.grid.bleach().to_json()) {
7826 grid.clone()
7827 } else {
7828 Grid::trivial()
7829 }
7830 };
7831
7832 if let Some(rule) = run_experiment(task, 6600, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7833
7834 if (all || cat.contains(&InOutSameShapesColoured)) && !examples.examples[0].output.shapes.shapes.is_empty() {
7835 let mut pairs: BTreeMap<Shape, Shape> = BTreeMap::new();
7836
7837 for exs in examples.examples.iter() {
7838 let m = exs.output.shapes.contained_pairs();
7839 pairs.extend(m);
7840 }
7841
7842 let mut ssm: BTreeMap<usize, Colour> = BTreeMap::new();
7843
7844 for (ks, vs) in pairs.iter() {
7845 ssm.insert(ks.size(), vs.colour);
7846 }
7847
7848 let func = &|ex: &Example| {
7849 let mut shapes = ex.input.shapes.clone();
7850
7851 for s in shapes.shapes.iter_mut() {
7852 if let Some(colour) = ssm.get(&s.size()) {
7853 let (r, c) = s.centre_of();
7854
7855 s.flood_fill_mut(r - s.orow, c - s.ocol, NoColour, *colour);
7856 }
7857 }
7858
7859 shapes.to_grid()
7860 };
7861
7862 if let Some(rule) = run_experiment(task, 6630, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7863 }
7864
7865 let func = |ex: &Example| {
7866 let shape = ex.input.grid.as_shape().scale_up(2);
7867
7868 Shapes::new_shapes(&[shape]).to_grid()
7869 };
7870
7871 if let Some(rule) = run_experiment(task, 100000, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7872
7873 let func = &|ex: &Example| {
7874 let len = ex.input.shapes.shapes.len();
7875
7876if len != 4 && len != 9 && len != 25 || !ex.input.shapes.shapes.is_empty() && (!ex.input.shapes.shapes[0].is_square() || ex.input.shapes.shapes[0].size() == 1) {
7878 return Grid::trivial();
7879 }
7880
7881 let mut n = usize::MAX;
7882 let mut posn = 0;
7883
7884 for (i, s) in ex.input.shapes.shapes.iter().enumerate() {
7885 let h = s.cell_colour_cnt_map();
7886 if n > h.len() {
7887 n = h.len();
7888 posn = i;
7889 }
7890 }
7891 let ans = ex.input.shapes.shapes[posn].clone();
7892 let mut shapes = ex.input.shapes.clone_base();
7893
7894 for (i, s) in ex.input.shapes.shapes.iter().enumerate() {
7895 if ans.size() != s.size() || ans.colour == NoColour || i / ans.cells.rows >= ans.cells.rows {
7896 return Grid::trivial();
7897 }
7898
7899 let colour = ans.cells[(i / ans.cells.rows, i % ans.cells.columns)].colour;
7900 let ns = s.force_recolour(colour);
7901
7902 shapes.shapes.push(ns);
7903 }
7904
7905 if ans.cells.rows >= ex.input.grid.cells.rows || ans.cells.columns >= ex.input.grid.cells.columns {
7906 return Grid::trivial();
7907 }
7908
7909 let bg = ex.input.grid.cells[(ans.cells.rows,ans.cells.columns)].colour;
7910shapes.to_grid_colour(bg)
7913 };
7914
7915 if let Some(rule) = run_experiment(task, 100010, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7916
7917 let in_colour = examples.examples[0].output.grid.get_diff_colour(&examples.examples[0].input.grid);
7918 let colour = examples.examples[0].io_colour_diff();
7919
7920 let func = |ex: &Example| {
7921 let mut shapes = ex.input.grid.to_shapes_sq();
7922
7923 for s in shapes.clone().shapes.iter_mut() {
7924 if !s.is_pixel() {
7925 shapes.shapes.push(s.recolour(in_colour, colour));
7926 }
7927 }
7928
7929 shapes.to_grid()
7930 };
7931
7932 if let Some(rule) = run_experiment(task, 100020, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7933
7934 let in_grid = &examples.examples[0].input.grid;
7935 let out_grid = &examples.examples[0].output.grid;
7936
7937 let func = |ex: &Example| {
7938 if ex.input.shapes.shapes.is_empty() || NxNIn(0).gte_value(&NxNOut(0), &cat) {
7939 return Grid::trivial();
7940 }
7941
7942 let colour_map: BTreeMap<Colour,Colour> = in_grid.cells.values()
7943 .zip(ex.input.grid.cells.values())
7944 .map(|(k,v)| (k.colour,v.colour))
7945 .collect();
7946
7947 let mut grid = out_grid.clone();
7948
7949 for ((r, c), cell) in out_grid.cells.items() {
7950 match colour_map.get(&cell.colour) {
7951 Some(colour) => grid.cells[(r,c)].colour = *colour,
7952 None => return Grid::trivial()
7953 }
7954 }
7955
7956 grid
7957 };
7958
7959 if let Some(rule) = run_experiment(task, 100030, experiment, trans, is_test, examples, &targets, done, tries, &func, output) { return Some(rule); };
7960
7961 *cap_todo.entry(CatchAll).or_insert(0) += 1;
7962
7963 None
7964}
7965
7966#[allow(clippy::too_many_arguments)]
7967fn run_experiment(task: &str, experiment: usize, experiment_todo: &str, trans: Transformation, is_test: bool, examples: &Examples, targets: &[Grid], done: &mut BTreeSet<String>, tries: &mut usize, func: &(dyn Fn(&Example) -> Grid + std::panic::RefUnwindSafe), output: &mut BTreeMap<String, Vec<OutputData>>) -> Option<usize> {
7968 if !experiment_todo.is_empty() {
7969 if let Ok(ex) = experiment_todo.parse::<usize>() {
7970 if ex != experiment {
7971 return None;
7972 }
7973 }
7974 }
7975 if done.contains(task) { return Some(usize::MAX);
7977 }
7978
7979 let ans = panic::catch_unwind(|| experiment_example(examples, task, experiment, trans, func));
7980
7981 let ans = match ans {
7982 Ok(ans) => ans,
7983 Err(e) => {
7984 eprintln!("{task} / {experiment} Exception: {e:?}");
7985 vec![Grid::trivial()]
7986 },
7987 };
7988
7989 *tries += 1;
7990
7991 save(task, experiment, trans, is_test, &ans, targets, done, output)
7992}
7993
7994#[allow(clippy::too_many_arguments)]
7995fn run_experiment_tries(task: &str, experiment: usize, experiment_todo: &str, trans: Transformation, is_test: bool, examples: &Examples, targets: &[Grid], done: &mut BTreeSet<String>, tries: &mut usize, func: &(dyn Fn(&Grid, &Grid, &mut usize) -> Grid + RefUnwindSafe), output: &mut BTreeMap<String, Vec<OutputData>>) -> Option<usize> {
7996 if !experiment_todo.is_empty() {
7997 if let Ok(ex) = experiment_todo.parse::<usize>() {
7998 if ex != experiment {
7999 return None;
8000 }
8001 }
8002 }
8003 if done.contains(task) { return Some(usize::MAX);
8005 }
8006
8007 let ans = panic::catch_unwind(|| experiment_grid(examples, task, experiment, trans, func));
8008
8009 let ans = match ans {
8010 Ok(ans) => ans,
8011 Err(e) => {
8012 eprintln!("{task} / {experiment} Exception: {e:?}");
8013 vec![Grid::trivial()]
8014 },
8015 };
8016
8017 *tries += 1;
8018
8019 save(task, experiment, trans, is_test, &ans, targets, done, output)
8020}
8021
8022fn run_experiment_colours(task: &str, experiment: usize, experiment_todo: &str, is_test: bool, examples: &Examples, targets: &[Grid], done: &mut BTreeSet<String>, func: &(dyn Fn(&Example, Colour) -> Grid + RefUnwindSafe), output: &mut BTreeMap<String, Vec<OutputData>>) -> Option<usize> {
8023 if !experiment_todo.is_empty() {
8024 if let Ok(ex) = experiment_todo.parse::<usize>() {
8025 if ex != experiment {
8026 return None;
8027 }
8028 }
8029 }
8030 if done.contains(task) { return Some(usize::MAX);
8032 }
8033
8034 let ans = panic::catch_unwind(|| experiment_colours(examples, func));
8035
8036 let ans = match ans {
8037 Ok(ans) => ans,
8038 Err(e) => {
8039 eprintln!("{task} / {experiment} Exception: {e:?}");
8040 vec![Grid::trivial()]
8041 },
8042 };
8043
8044 save(task, experiment, NoTrans, is_test, &ans, targets, done, output)
8045}
8046
8047#[allow(clippy::too_many_arguments)]
8048fn save(task: &str, experiment: usize, trans: Transformation, is_test: bool, ans: &[Grid], targets: &[Grid], done: &mut BTreeSet<String>, results: &mut BTreeMap<String, Vec<OutputData>>) -> Option<usize> {
8049 let target_size: usize = targets.iter().map(|target| target.size()).sum();
8050 let ans_size: usize = ans.iter().map(|ans| ans.size()).sum();
8051 let same = if target_size > 0 && ans_size > 0 {
8052 targets.iter()
8053 .zip(ans.iter())
8054 .map(|(target, ans)| {
8055 if ans.equals(target) == Same {
8056 1
8057 } else {
8058 0
8059 }})
8060 .sum::<usize>() > 0
8061 } else {
8062 false
8063 };
8064
8065 if !is_test {
8066 if same {
8067 add_real_output(task, ans, results);
8068
8069 done.insert(task.to_string());
8070 println!("Success: {experiment:>05} {trans:?} / {task}");
8071
8072 Some(experiment)
8073 } else if ans_size > 0 {
8074 add_dummy_output(task, ans.len(), results);
8075
8076 let dist: Vec<_> = ans.iter().zip(targets.iter())
8077 .map(|(a,t)| format!("{:.4}", a.distance(t)))
8078 .collect();
8079
8080 println!("Final Test Failed : {experiment:>05} {trans:?} / {task} by {}", dist.join(", "));
8081
8082 None
8083 } else {
8084 add_dummy_output(task, ans.len(), results);
8085
8086 None
8087 }
8088 } else if ans_size > 0 {
8089 add_real_output(task, ans, results);
8090
8091 done.insert(task.to_string());
8092 println!("Test Success: {experiment:>05} {trans:?} / {task}");
8093
8094 Some(experiment)
8095 } else {
8096 add_dummy_output(task, ans.len(), results);
8097
8098 None
8099 }
8100}
8101
8102fn format(rule_tasks: &BTreeMap<usize, Vec<String>>) {
8103 println!();
8104 println!("Rule solving tasks:");
8105 println!("-------------------");
8106 for (k, v) in rule_tasks.iter() {
8107 println!("{k:<5}: {}", v.join(", "));
8108 }
8109 println!();
8110}