{
  "id": 615039,
  "title": "8th place write-up: import itertools",
  "content": "<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F49c8620b75967d6937284391f06d652f%2Fintro.webp?generation=1762596152173797&amp;alt=media\" alt=\"\"></p>\n<h1>Introduction</h1>\n<p>We’d like to begin by thanking the organizers <a href=\"https://www.kaggle.com/mmoffitt\" target=\"_blank\">@mmoffitt</a> and all our fellow competitors we’ve shared the last three months with. It’s been a lot of work—especially for a mostly manual, mostly non-expert benchmark team like us—but we’re very happy with where we ended up on the leaderboard. We genuinely worked our behinds off to get there.</p>\n<p>You can find our solutions, compression scripts and other interesting things at this link: <a href=\"https://github.com/Natanaelel/GoogleCodeGolf2025\" target=\"_blank\">https://github.com/Natanaelel/GoogleCodeGolf2025</a></p>\n<h1>Approach</h1>\n<p>Like many other teams, we manually worked on each task, so we didn’t have a secret trick that suddenly cut dozens of bytes. Our final result was the sum of many small insights we picked up along the way. Since most of us came into this with little to no code-golf experience, our first instinct was to lean heavily on LLMs. It didn’t take long to realize it was not going to get us anywhere near the top in what was already a very saturated field just a few weeks in.</p>\n<h1>Solutions / techniques overwiew</h1>\n<h3>Recursion, cell automata, pysearch - task002</h3>\n<p>In this task we have to fill all regions closed by green borders with yellow color. There are many ways to solve this task. The simplest way is straightforward DFS/Flood-fill algorithm. Another approach is to look only at 2 cells at a time and set value of current cell based on neighbor's value, almost like <a href=\"https://en.wikipedia.org/wiki/Cellular_automaton\" target=\"_blank\">Cellular automata</a>. You just need to do enough iterations (using recursion to save bytes) while rotating array after each step to take care of neighbor pairs in each orientation.</p>\n<pre><code>p= g,i=:-i*g  p([[-%(**i|b ~a%) a,b  ([]+r,r)]*r, (*g[::-])],i-)\n</code></pre>\n<p>There are 3 important parts here:</p>\n<ul>\n<li>recursion template <code>p=lambda g,i=67:-i*g or p(...,i-1)</code></li>\n<li>how do you access the neighbor pair, we used pretty simple <code>for a,b in zip([4]+r,r)</code></li>\n<li>how do you calculate new value based on condition, we flood from the side for all iterations except last one and then swap colors in the last step using <code>4-4%(0**i|b or~a%9</code> that was figured out with help of tool called <a href=\"https://github.com/lynn/pysearch\" target=\"_blank\">pysearch</a> by lynn.</li>\n</ul>\n<p>Those parts can be done in many different ways. And there are many more tricks to be used here that you can find by looking at top teams solutions.</p>\n<p>Task002 animation, keep in mind that rotations are not shown so it's easier to follow what is happening (steps go from 67 to -1).</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F3f69ef7107ea346cc045219307d0a345%2Ftask002.gif?generation=1762594915845044&amp;alt=media\" alt=\"\"></p>\n<h3>Loop trick instead of recursion template - task095</h3>\n<p>We used recursion template shown above in many tasks, but turns out that if number of iterations is smaller than grid size and we don't need to make calculations based on the counter we can use shorter template used below.\nWhat is also interesting here is that parameter <code>b</code> could be just lambda parameter even though technically it should be set to zero before processing each row.</p>\n<pre><code>p= g,b=:[g:=[[b%|(b:=a) a  r] r  (*g[::-])] _  g][]\n</code></pre>\n<h3>Iterating while mutating using pop() - task214</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fb22cf963e20068477aab8c59eab4fe78%2Fupload_a256e11de938e616f2c337573f5512da.png?generation=1762595057379835&amp;alt=media\" alt=\"\"></p>\n<p>In this task we have to finish pattern located in the left square.</p>\n<pre><code>p= g:[r+g.pop()[::-] r,*r[:] (g*,*g[::-])]\n</code></pre>\n<p>There are a couple of interesting tricks used here:</p>\n<ul>\n<li><code>g.pop()</code> that returns last row from <code>g</code></li>\n<li><code>g*1</code> to make a shallow copy so we can still iterate over full <code>g</code> even though <code>g.pop()</code> is mutating <code>g</code> (<code>zip(g*1,*g[::-1])</code> if resolved before any <code>pop()</code>)</li>\n</ul>\n<h3>Recursion with a*0==0 trick - task021</h3>\n<p>There were tasks that could be solved in a way that we perform the same operation both for whole row and for single number in a row. So we needed a way to test if current value is a row or a number.\nWe can take advantage of the fact that:</p>\n<p><code>list * 0 = []</code></p>\n<p><code>number * 0 = 0</code></p>\n<pre><code>p= g:(g[g.count(a:=g[])-:])*[a*(a*==) p(a)]\n</code></pre>\n<p>If <code>a*0==0</code> is true then we return <code>a</code> (number)\nOtherwise we recurse with <code>or p(a)</code> branch.</p>\n<h3>Loop flattening and bitwise operations - task365.</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F44cd40e20c943a053e05718145505088%2FScreenshot%20from%202025-11-08%2012-36-32.png?generation=1762601919168586&amp;alt=media\" alt=\"\"></p>\n<p>The goal of this task is to find the rectangle with the most red pixels. We can achieve it by simply brute forcing all possible candidates using 4 loops over coordinates <code>i,j</code> and sizes <code>w,h</code>. For this task it's enough if each loop is from 0 to 7, that means we can alias <code>R=range(8)</code> and use 4 loops.</p>\n<pre><code>R=()\np= g:(((s:=(m:=[r[j:][:w] r  g[i:][:h]],[])).count()*(s),(s),m) i  R  j  R  w  R  h  R)[]\n</code></pre>\n<p>But we can also flatten all 4 loops into single one and take advantage of the fact that 8 is power of 2 so we can calculate <code>i,j,w,h</code> using bitwise operations (instead of <code>//</code> and <code>%</code> arithmetic).</p>\n<pre><code>p= g:(((s:=(m:=[x[t&amp;:][:t&gt;&gt;&amp;] x  g[t&gt;&gt;&amp;:][:t&gt;&gt;]],g))*s.count(),(s),m) t  ())[]\n</code></pre>\n<h3>Using hash to deal with edge cases - task070</h3>\n<p>There were tasks that could be solved simple way but failed 1 or 2 edge cases. So there were 2 options:</p>\n<ul>\n<li>use longer more reliable solution</li>\n<li>hash / hardcode that 1-2 edge cases and use the simpler solution</li>\n</ul>\n<p>Here we use <code>hash((*c,))%709==8</code> that calculates hash of column (as tuple) to detect that edge case so we can apply additional logic so solution pass all test cases.</p>\n<pre><code>p= g:[[x+*(x&lt; r)*(((*c,))%==  c)*c,x  (*g,r)] r  g]\n</code></pre>\n<h3>Flattening array - task286</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fcf0a1631f57ad8da512e479d693c4ef3%2Ftask286.gif?generation=1762595439433161&amp;alt=media\" alt=\"\"></p>\n<p>This is another task that uses recursion+rotation template.\nIf the current cell is empty and neighbor has one of 2 maze colors, then current cell will have the other color.\nTo find the other color we can flatten the 2D array into 1D array using <code>sum(g,[])</code>, then we can convert to set to figure out the color that we need (the only colors possible are black, cyan (wall color), neighbor color (that we know) and other color (that we are looking for)). Also interesting trick to save 1b is to set initial value of sum to e.g. <code>r</code> instead of <code>[]</code> to save a byte.</p>\n<pre><code>p= g,k=:-k*g  p([[b  a% ({*(g,r)})-a- a,b  ([]+r,r)]*r, (*g[::-])],k-)\n</code></pre>\n<h3>Iterating over raw bytes - task317</h3>\n<p>The most obvious solution for task317 is quite simple, we just use list comprehension and for each position we check the closest center of 3x3 square. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F8d0bd0e9639dc400689d87dec370bf80%2FScreenshot%20from%202025-11-08%2012-39-28.png?generation=1762602000742974&amp;alt=media\" alt=\"\"></p>\n<pre><code>R=[,,,,,,,,]\np= g:[[&lt;g[y][x] x  R] y  R]\n</code></pre>\n<p>That R array is quite long but we can use raw bytes intead.</p>\n<pre><code>R=\np= g:[[&lt;g[y][x] x  R] y  R]\n</code></pre>\n<h3>Counting bits - task369</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F7f0ab9372bbccde4f0d93a5e2591a216%2FScreenshot%20from%202025-11-08%2012-40-59.png?generation=1762602112385832&amp;alt=media\" alt=\"\"></p>\n<p>In this task we have to set color of black shapes based on the size of the shape.\nInitially we solved this task using DFS/Flood fill algorithm, but it was definitely too long.\nNext we tried regex but we still weren't happy with the result.</p>\n<p>The last solution used the following idea:</p>\n<ul>\n<li>initialize each black pixel with bits set on unique position</li>\n<li>then do enough iterations/rotations where we make bitwise OR operation for each neighbor pair</li>\n<li>in the last recursion step set the value based on number of bits set</li>\n</ul>\n<p>What is also interesting here:</p>\n<ul>\n<li>instead of using extra counter parameter, we reused recursion parameter <code>k</code> to save bytes, it made the program much slower but it worked</li>\n<li>instead of initializing with <code>1&lt;&lt;</code> we initialized with <code>3&lt;&lt;</code> (which set 2 unique bits instead of 1) because this way pysearch expression was 1 byte shorter</li>\n</ul>\n<pre><code>p= g,k=:-k*g  p([[**k*~//~a.bit_count() a|b*(a&gt;) &lt;&lt;(k:=k+) a,b  (r,[]+r)]*r, (*g[::-])],k-)\n</code></pre>\n<h3>Bruteforcing solution to avoid bad test cases - task346</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Ff8deefd24f0ca2fdbf2814c5264c8a2b%2FScreenshot%20from%202025-11-08%2012-42-44.png?generation=1762602195690805&amp;alt=media\" alt=\"\"></p>\n<p>I\nIn this task we have to return 1x1 array with color that is inside a different color square in input array.\nThe simplest solution would be to try to return the least common color using this solution:</p>\n<pre><code>p= g:[[(S:=(g,[]),key=S.count)]]\n</code></pre>\n<p>But there is good news and bad news.\nThe bad news is that it fails 3 test cases.\nThe good news is that it fails 3 test cases, so maybe we can make a slight code modifications to make all tests pass.\nThe general idea is to look at failing cases and try to figure out how we can modify parameters of sum function so it will produce expected result. We did it by trial and error with a help a tiny bruteforce script.</p>\n<pre><code>p= g:[[(S:=(g[:]+g[:],[]),key=S.count)]]\n</code></pre>\n<p>The simple script we used, we tried different templates.</p>\n<pre><code> i  ():\n     j  (i+,):\n        (i,j)\n         k  ():\n            solution=\n             verify_program(task_num, solution, task_data):\n                (solution)\n</code></pre>\n<p>Unfortunately we still missed the shortest possible solution that was really close.</p>\n<h3>Regex is quite powerful - task017</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc3b9fa1f80cdd67e48ad92ca525e2f6a%2Ftask017.gif?generation=1762595807517392&amp;alt=media\" alt=\"\"></p>\n<p>The idea was to rotate the grid, then use a regex to look for a sequence of five non-zero values followed by a zero. If that exact 5-value pattern appears again later in the grid, we replace the zero with whatever value follows the second occurrence. We repeat this until all the gaps are filled.</p>\n<p>This solution was a kind of catalyst for the team to realize regex makes reasoning about some types of tasks a lot easier. It gave some of us the motivation to read the regex manual more carefully.</p>\n<pre><code> re\np= g,k=:-k*g  p((re.sub(,,([*(*g[::-])]))),k-)\n</code></pre>\n<h3>Compression optimizations - task238</h3>\n<p>Many of our solutions ended up being long enough that compressing them was a viable way to shorten them. For this, we based our initial compression script on the ones that were shared publicly and improved them by adding more variants of <code>zlib</code> and <code>zopfli</code> compression levels, with or without blocksplitting, and setting the number of iterations to a specific value in the range 1-100. We also made heavy use of the variable optimization notebook <a href=\"https://www.kaggle.com/code/garrymoss/compressed-variable-name-optimization\" target=\"_blank\">https://www.kaggle.com/code/garrymoss/compressed-variable-name-optimization</a> by <a href=\"https://www.kaggle.com/garrymoss\" target=\"_blank\">@garrymoss</a>, thanks a lot for sharing it.</p>\n<p>While far from optimal (-28b) from diamond in the end. The solution for task238 is a very silly example of why compression golfing has a completely different approach than normal golfing.</p>\n<p>We had this code that compressed from the original 281b to 251b</p>\n<pre><code> ():\n f= f:[[*e] e  (*(f,(*t))) f(e)];r=f( e:({*e}-{}))\n  f,e  (f( e: e)):\n   p,n  (e):d=(e);r[f+][p+]=n (f&lt;p&lt;d+~f)*r[][]+(d+~f&lt;p&lt;f)*r[-][]+(p&lt;f&lt;d+~p)*r[][]+(d+~p&lt;f&lt;p)*r[][-] n\n  r\n</code></pre>\n<p>But if you unpacked all the clever lambdas you would favor in the traditional golfing into this:</p>\n<pre><code> ():\n e=n\n e=[e *e, (*e) (n% n  e)]\n e=[e *e, (*e) (n% n  e)]\n n=[e *e, (*n)  e]\n n=[e *e, (*n)  e]\n  f,n  (n):\n   a,t  (n):r=(n);e[f+][a+]=t (f&lt;a&lt;r+~f)*e[][]+(r+~f&lt;a&lt;f)*e[-][]+(a&lt;f&lt;r+~a)*e[][]+(r+~a&lt;f&lt;a)*e[][-] t\n  e\n</code></pre>\n<p>We have made the original far bigger 338b, but it now compressed to 223b. The same algorithm, just written in a DRY (Do repeat yourself) fashion yielded 28b.</p>\n<h1>Conclusion</h1>\n<p>We dedicated a lot of time and effort to manually improve our solutions for each task. We tried using LLMs but in most cases they were unhelpful, it was much easier for us to tackle the problems manually instead. We are very happy with our result, especially considering how little code-golfing experience some of us had prior to this competition.\nWe would also like to thank all the people that shared helpful insights in kaggle discussions, especially <a href=\"https://www.kaggle.com/kayjoking\" target=\"_blank\">@kayjoking</a>, <a href=\"https://www.kaggle.com/hellopir2\" target=\"_blank\">@hellopir2</a>, <a href=\"https://www.kaggle.com/lukeg10081\" target=\"_blank\">@lukeg10081</a>, <a href=\"https://www.kaggle.com/kenkrige\" target=\"_blank\">@kenkrige</a> and <a href=\"https://www.kaggle.com/garrymoss\" target=\"_blank\">@garrymoss</a>.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc97916c7bc78f2e87d3e3441ff00ab84%2Foutro.jpg?generation=1762597022697898&amp;alt=media\" alt=\"\"></p>",
  "comments": [
    {
      "id": 3313123,
      "author_name": "Tony Li",
      "author_url": "",
      "post_date": "2025-11-08T17:46:48.183000",
      "content": "<p>Super clear, delightful write-up—loved how you broke down the recursion template and the cellular-automata angle on task002. All your recursion animation are fantastic; it makes the 67→−1 sweep instantly intuitive even without showing the rotations. </p>\n<p>Really wonder how you generated it ? e.g., did you snapshot a frame per iteration (after each <code>zip(*g[::-1])</code>) and stitch with ffmpeg, or render in Python (Pillow/matplotlib) / web canvas? </p>\n<p>Also huge kudos for the compression move—great reminder that compression golf ≠ normal golf. </p>\n<p>You’re incredibly talented!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 3313540,
          "author_name": "jacekwl",
          "author_url": "",
          "post_date": "2025-11-09T12:50:35.187000",
          "content": "<p>Thank you!</p>\n<p>To generate animations I added this function in code_golf_utils.py:</p>\n<pre><code> ():\n\n  output_width, output_height = (output[]), (output)\n  width =  + output_width + \n  height = output_height + \n  offset = \n\n  image = [[bgcolor  _  (width)]  _  (height)]\n\n   r, row  (output):\n     c, cell  (row):\n      image[r + ][offset + c + ] = colors[cell]\n\n  fig = plt.figure(figsize=(, ))\n  ax = fig.add_axes([, , , ])\n  ax.imshow(np.array(image))\n\n  ax.hlines([r +   r  (output_height+)],\n            xmin=offset+, xmax=offset+output_width+, color=)\n\n  ax.vlines([offset + c +   c  (output_width+)],\n            ymin=, ymax=output_height+, color=)\n\n  ax.set_xticks([])\n  ax.set_yticks([])\n  plt.suptitle()\n  plt.savefig()\n</code></pre>\n<p>Then I used this code to capture each recursion step (task017 here):</p>\n<pre><code> ():\n    i=\n    save_image(g, task_num, i)\n     i&gt;=:\n        g=(re.sub(,,([*(*g[::-])])))\n        G=((g)) \n         _  (i%): G=[*(*G[::-])] \n        i-=   \n        save_image(G, task_num, i)\n     g\n</code></pre>\n<p>And this one to make gif from all generated .png:</p>\n<pre><code> glob\n imageio.v3  iio\n\npngs = (glob.glob(),\n              key= p: -(p.rsplit(,)[].split()[]))  \nframes = [iio.imread(p)  p  pngs]\niio.imwrite(, frames, duration=, loop=)\n</code></pre>\n<p>It would be probably better to generate everything in memory but this was simpler way and I wanted to get things done fast.</p>",
          "votes": 3,
          "replies": [
            {
              "id": 3314358,
              "author_name": "Tony Li",
              "author_url": "",
              "post_date": "2025-11-10T06:54:10.760000",
              "content": "<p>Thanks a lot for sharing the code—now I understand you generate per-step animations by saving a PNG at each recursion step with <code>save_image</code>, then sort the PNGs by step and stitch them into a GIF with <code>imageio</code> (1s per frame) using a simple file-per-frame pipeline. Super clear—appreciate it!</p>",
              "votes": 0,
              "replies": []
            },
            {
              "id": 3322893,
              "author_name": "VoltAir Global Hub",
              "author_url": "",
              "post_date": "2025-11-13T19:55:26.873000",
              "content": "<p>Hi <a href=\"https://www.kaggle.com/jacekwl\" target=\"_blank\">@jacekwl</a>,</p>\n<p>Really appreciate your write-up! 🙌 I had a few small suggestions to make recursion visualizations even smoother:</p>\n<p>In-memory GIF generation: Instead of saving PNGs for each step, keep frames in memory and write the GIF directly. This speeds up processing for larger grids.</p>\n<p>Modular transformations: Using a transform_func allows easy swapping of recursion logic without rewriting the whole pipeline.</p>\n<p>Customizable colors &amp; layout: You can define your own color mapping and figure size to match your visualization needs.</p>\n<p>Here’s a tiny snippet for the in-memory approach:</p>\n<p>frames = capture_steps_memory(grid, transform_func=my_transform, steps=10)\nmake_gif_memory(frames, gif_name=\"my_animation.gif\")</p>\n<p>Thanks again — your post really clarified step-by-step recursion visualization!</p>",
              "votes": 0,
              "replies": []
            }
          ]
        }
      ]
    },
    {
      "id": 3313051,
      "author_name": "4eta",
      "author_url": "",
      "post_date": "2025-11-08T14:59:47.433000",
      "content": "<p>Such an awesome illustration — nice work!!</p>",
      "votes": 2,
      "replies": []
    }
  ],
  "comment_count": 5,
  "messages": [
    {
      "id": 3312996,
      "postDate": "2025-11-08T12:30:07.147Z",
      "content": "<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F49c8620b75967d6937284391f06d652f%2Fintro.webp?generation=1762596152173797&amp;alt=media\" alt=\"\"></p>\n<h1>Introduction</h1>\n<p>We’d like to begin by thanking the organizers <a href=\"https://www.kaggle.com/mmoffitt\" target=\"_blank\">@mmoffitt</a> and all our fellow competitors we’ve shared the last three months with. It’s been a lot of work—especially for a mostly manual, mostly non-expert benchmark team like us—but we’re very happy with where we ended up on the leaderboard. We genuinely worked our behinds off to get there.</p>\n<p>You can find our solutions, compression scripts and other interesting things at this link: <a href=\"https://github.com/Natanaelel/GoogleCodeGolf2025\" target=\"_blank\">https://github.com/Natanaelel/GoogleCodeGolf2025</a></p>\n<h1>Approach</h1>\n<p>Like many other teams, we manually worked on each task, so we didn’t have a secret trick that suddenly cut dozens of bytes. Our final result was the sum of many small insights we picked up along the way. Since most of us came into this with little to no code-golf experience, our first instinct was to lean heavily on LLMs. It didn’t take long to realize it was not going to get us anywhere near the top in what was already a very saturated field just a few weeks in.</p>\n<h1>Solutions / techniques overwiew</h1>\n<h3>Recursion, cell automata, pysearch - task002</h3>\n<p>In this task we have to fill all regions closed by green borders with yellow color. There are many ways to solve this task. The simplest way is straightforward DFS/Flood-fill algorithm. Another approach is to look only at 2 cells at a time and set value of current cell based on neighbor's value, almost like <a href=\"https://en.wikipedia.org/wiki/Cellular_automaton\" target=\"_blank\">Cellular automata</a>. You just need to do enough iterations (using recursion to save bytes) while rotating array after each step to take care of neighbor pairs in each orientation.</p>\n<pre><code>p= g,i=:-i*g  p([[-%(**i|b ~a%) a,b  ([]+r,r)]*r, (*g[::-])],i-)\n</code></pre>\n<p>There are 3 important parts here:</p>\n<ul>\n<li>recursion template <code>p=lambda g,i=67:-i*g or p(...,i-1)</code></li>\n<li>how do you access the neighbor pair, we used pretty simple <code>for a,b in zip([4]+r,r)</code></li>\n<li>how do you calculate new value based on condition, we flood from the side for all iterations except last one and then swap colors in the last step using <code>4-4%(0**i|b or~a%9</code> that was figured out with help of tool called <a href=\"https://github.com/lynn/pysearch\" target=\"_blank\">pysearch</a> by lynn.</li>\n</ul>\n<p>Those parts can be done in many different ways. And there are many more tricks to be used here that you can find by looking at top teams solutions.</p>\n<p>Task002 animation, keep in mind that rotations are not shown so it's easier to follow what is happening (steps go from 67 to -1).</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F3f69ef7107ea346cc045219307d0a345%2Ftask002.gif?generation=1762594915845044&amp;alt=media\" alt=\"\"></p>\n<h3>Loop trick instead of recursion template - task095</h3>\n<p>We used recursion template shown above in many tasks, but turns out that if number of iterations is smaller than grid size and we don't need to make calculations based on the counter we can use shorter template used below.\nWhat is also interesting here is that parameter <code>b</code> could be just lambda parameter even though technically it should be set to zero before processing each row.</p>\n<pre><code>p= g,b=:[g:=[[b%|(b:=a) a  r] r  (*g[::-])] _  g][]\n</code></pre>\n<h3>Iterating while mutating using pop() - task214</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fb22cf963e20068477aab8c59eab4fe78%2Fupload_a256e11de938e616f2c337573f5512da.png?generation=1762595057379835&amp;alt=media\" alt=\"\"></p>\n<p>In this task we have to finish pattern located in the left square.</p>\n<pre><code>p= g:[r+g.pop()[::-] r,*r[:] (g*,*g[::-])]\n</code></pre>\n<p>There are a couple of interesting tricks used here:</p>\n<ul>\n<li><code>g.pop()</code> that returns last row from <code>g</code></li>\n<li><code>g*1</code> to make a shallow copy so we can still iterate over full <code>g</code> even though <code>g.pop()</code> is mutating <code>g</code> (<code>zip(g*1,*g[::-1])</code> if resolved before any <code>pop()</code>)</li>\n</ul>\n<h3>Recursion with a*0==0 trick - task021</h3>\n<p>There were tasks that could be solved in a way that we perform the same operation both for whole row and for single number in a row. So we needed a way to test if current value is a row or a number.\nWe can take advantage of the fact that:</p>\n<p><code>list * 0 = []</code></p>\n<p><code>number * 0 = 0</code></p>\n<pre><code>p= g:(g[g.count(a:=g[])-:])*[a*(a*==) p(a)]\n</code></pre>\n<p>If <code>a*0==0</code> is true then we return <code>a</code> (number)\nOtherwise we recurse with <code>or p(a)</code> branch.</p>\n<h3>Loop flattening and bitwise operations - task365.</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F44cd40e20c943a053e05718145505088%2FScreenshot%20from%202025-11-08%2012-36-32.png?generation=1762601919168586&amp;alt=media\" alt=\"\"></p>\n<p>The goal of this task is to find the rectangle with the most red pixels. We can achieve it by simply brute forcing all possible candidates using 4 loops over coordinates <code>i,j</code> and sizes <code>w,h</code>. For this task it's enough if each loop is from 0 to 7, that means we can alias <code>R=range(8)</code> and use 4 loops.</p>\n<pre><code>R=()\np= g:(((s:=(m:=[r[j:][:w] r  g[i:][:h]],[])).count()*(s),(s),m) i  R  j  R  w  R  h  R)[]\n</code></pre>\n<p>But we can also flatten all 4 loops into single one and take advantage of the fact that 8 is power of 2 so we can calculate <code>i,j,w,h</code> using bitwise operations (instead of <code>//</code> and <code>%</code> arithmetic).</p>\n<pre><code>p= g:(((s:=(m:=[x[t&amp;:][:t&gt;&gt;&amp;] x  g[t&gt;&gt;&amp;:][:t&gt;&gt;]],g))*s.count(),(s),m) t  ())[]\n</code></pre>\n<h3>Using hash to deal with edge cases - task070</h3>\n<p>There were tasks that could be solved simple way but failed 1 or 2 edge cases. So there were 2 options:</p>\n<ul>\n<li>use longer more reliable solution</li>\n<li>hash / hardcode that 1-2 edge cases and use the simpler solution</li>\n</ul>\n<p>Here we use <code>hash((*c,))%709==8</code> that calculates hash of column (as tuple) to detect that edge case so we can apply additional logic so solution pass all test cases.</p>\n<pre><code>p= g:[[x+*(x&lt; r)*(((*c,))%==  c)*c,x  (*g,r)] r  g]\n</code></pre>\n<h3>Flattening array - task286</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fcf0a1631f57ad8da512e479d693c4ef3%2Ftask286.gif?generation=1762595439433161&amp;alt=media\" alt=\"\"></p>\n<p>This is another task that uses recursion+rotation template.\nIf the current cell is empty and neighbor has one of 2 maze colors, then current cell will have the other color.\nTo find the other color we can flatten the 2D array into 1D array using <code>sum(g,[])</code>, then we can convert to set to figure out the color that we need (the only colors possible are black, cyan (wall color), neighbor color (that we know) and other color (that we are looking for)). Also interesting trick to save 1b is to set initial value of sum to e.g. <code>r</code> instead of <code>[]</code> to save a byte.</p>\n<pre><code>p= g,k=:-k*g  p([[b  a% ({*(g,r)})-a- a,b  ([]+r,r)]*r, (*g[::-])],k-)\n</code></pre>\n<h3>Iterating over raw bytes - task317</h3>\n<p>The most obvious solution for task317 is quite simple, we just use list comprehension and for each position we check the closest center of 3x3 square. </p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F8d0bd0e9639dc400689d87dec370bf80%2FScreenshot%20from%202025-11-08%2012-39-28.png?generation=1762602000742974&amp;alt=media\" alt=\"\"></p>\n<pre><code>R=[,,,,,,,,]\np= g:[[&lt;g[y][x] x  R] y  R]\n</code></pre>\n<p>That R array is quite long but we can use raw bytes intead.</p>\n<pre><code>R=\np= g:[[&lt;g[y][x] x  R] y  R]\n</code></pre>\n<h3>Counting bits - task369</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F7f0ab9372bbccde4f0d93a5e2591a216%2FScreenshot%20from%202025-11-08%2012-40-59.png?generation=1762602112385832&amp;alt=media\" alt=\"\"></p>\n<p>In this task we have to set color of black shapes based on the size of the shape.\nInitially we solved this task using DFS/Flood fill algorithm, but it was definitely too long.\nNext we tried regex but we still weren't happy with the result.</p>\n<p>The last solution used the following idea:</p>\n<ul>\n<li>initialize each black pixel with bits set on unique position</li>\n<li>then do enough iterations/rotations where we make bitwise OR operation for each neighbor pair</li>\n<li>in the last recursion step set the value based on number of bits set</li>\n</ul>\n<p>What is also interesting here:</p>\n<ul>\n<li>instead of using extra counter parameter, we reused recursion parameter <code>k</code> to save bytes, it made the program much slower but it worked</li>\n<li>instead of initializing with <code>1&lt;&lt;</code> we initialized with <code>3&lt;&lt;</code> (which set 2 unique bits instead of 1) because this way pysearch expression was 1 byte shorter</li>\n</ul>\n<pre><code>p= g,k=:-k*g  p([[**k*~//~a.bit_count() a|b*(a&gt;) &lt;&lt;(k:=k+) a,b  (r,[]+r)]*r, (*g[::-])],k-)\n</code></pre>\n<h3>Bruteforcing solution to avoid bad test cases - task346</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Ff8deefd24f0ca2fdbf2814c5264c8a2b%2FScreenshot%20from%202025-11-08%2012-42-44.png?generation=1762602195690805&amp;alt=media\" alt=\"\"></p>\n<p>I\nIn this task we have to return 1x1 array with color that is inside a different color square in input array.\nThe simplest solution would be to try to return the least common color using this solution:</p>\n<pre><code>p= g:[[(S:=(g,[]),key=S.count)]]\n</code></pre>\n<p>But there is good news and bad news.\nThe bad news is that it fails 3 test cases.\nThe good news is that it fails 3 test cases, so maybe we can make a slight code modifications to make all tests pass.\nThe general idea is to look at failing cases and try to figure out how we can modify parameters of sum function so it will produce expected result. We did it by trial and error with a help a tiny bruteforce script.</p>\n<pre><code>p= g:[[(S:=(g[:]+g[:],[]),key=S.count)]]\n</code></pre>\n<p>The simple script we used, we tried different templates.</p>\n<pre><code> i  ():\n     j  (i+,):\n        (i,j)\n         k  ():\n            solution=\n             verify_program(task_num, solution, task_data):\n                (solution)\n</code></pre>\n<p>Unfortunately we still missed the shortest possible solution that was really close.</p>\n<h3>Regex is quite powerful - task017</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc3b9fa1f80cdd67e48ad92ca525e2f6a%2Ftask017.gif?generation=1762595807517392&amp;alt=media\" alt=\"\"></p>\n<p>The idea was to rotate the grid, then use a regex to look for a sequence of five non-zero values followed by a zero. If that exact 5-value pattern appears again later in the grid, we replace the zero with whatever value follows the second occurrence. We repeat this until all the gaps are filled.</p>\n<p>This solution was a kind of catalyst for the team to realize regex makes reasoning about some types of tasks a lot easier. It gave some of us the motivation to read the regex manual more carefully.</p>\n<pre><code> re\np= g,k=:-k*g  p((re.sub(,,([*(*g[::-])]))),k-)\n</code></pre>\n<h3>Compression optimizations - task238</h3>\n<p>Many of our solutions ended up being long enough that compressing them was a viable way to shorten them. For this, we based our initial compression script on the ones that were shared publicly and improved them by adding more variants of <code>zlib</code> and <code>zopfli</code> compression levels, with or without blocksplitting, and setting the number of iterations to a specific value in the range 1-100. We also made heavy use of the variable optimization notebook <a href=\"https://www.kaggle.com/code/garrymoss/compressed-variable-name-optimization\" target=\"_blank\">https://www.kaggle.com/code/garrymoss/compressed-variable-name-optimization</a> by <a href=\"https://www.kaggle.com/garrymoss\" target=\"_blank\">@garrymoss</a>, thanks a lot for sharing it.</p>\n<p>While far from optimal (-28b) from diamond in the end. The solution for task238 is a very silly example of why compression golfing has a completely different approach than normal golfing.</p>\n<p>We had this code that compressed from the original 281b to 251b</p>\n<pre><code> ():\n f= f:[[*e] e  (*(f,(*t))) f(e)];r=f( e:({*e}-{}))\n  f,e  (f( e: e)):\n   p,n  (e):d=(e);r[f+][p+]=n (f&lt;p&lt;d+~f)*r[][]+(d+~f&lt;p&lt;f)*r[-][]+(p&lt;f&lt;d+~p)*r[][]+(d+~p&lt;f&lt;p)*r[][-] n\n  r\n</code></pre>\n<p>But if you unpacked all the clever lambdas you would favor in the traditional golfing into this:</p>\n<pre><code> ():\n e=n\n e=[e *e, (*e) (n% n  e)]\n e=[e *e, (*e) (n% n  e)]\n n=[e *e, (*n)  e]\n n=[e *e, (*n)  e]\n  f,n  (n):\n   a,t  (n):r=(n);e[f+][a+]=t (f&lt;a&lt;r+~f)*e[][]+(r+~f&lt;a&lt;f)*e[-][]+(a&lt;f&lt;r+~a)*e[][]+(r+~a&lt;f&lt;a)*e[][-] t\n  e\n</code></pre>\n<p>We have made the original far bigger 338b, but it now compressed to 223b. The same algorithm, just written in a DRY (Do repeat yourself) fashion yielded 28b.</p>\n<h1>Conclusion</h1>\n<p>We dedicated a lot of time and effort to manually improve our solutions for each task. We tried using LLMs but in most cases they were unhelpful, it was much easier for us to tackle the problems manually instead. We are very happy with our result, especially considering how little code-golfing experience some of us had prior to this competition.\nWe would also like to thank all the people that shared helpful insights in kaggle discussions, especially <a href=\"https://www.kaggle.com/kayjoking\" target=\"_blank\">@kayjoking</a>, <a href=\"https://www.kaggle.com/hellopir2\" target=\"_blank\">@hellopir2</a>, <a href=\"https://www.kaggle.com/lukeg10081\" target=\"_blank\">@lukeg10081</a>, <a href=\"https://www.kaggle.com/kenkrige\" target=\"_blank\">@kenkrige</a> and <a href=\"https://www.kaggle.com/garrymoss\" target=\"_blank\">@garrymoss</a>.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc97916c7bc78f2e87d3e3441ff00ab84%2Foutro.jpg?generation=1762597022697898&amp;alt=media\" alt=\"\"></p>",
      "rawMarkdown": "![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F49c8620b75967d6937284391f06d652f%2Fintro.webp?generation=1762596152173797&alt=media)\n\n# Introduction\n\nWe’d like to begin by thanking the organizers @mmoffitt and all our fellow competitors we’ve shared the last three months with. It’s been a lot of work—especially for a mostly manual, mostly non-expert benchmark team like us—but we’re very happy with where we ended up on the leaderboard. We genuinely worked our behinds off to get there.\n\nYou can find our solutions, compression scripts and other interesting things at this link: https://github.com/Natanaelel/GoogleCodeGolf2025\n\n# Approach\n\nLike many other teams, we manually worked on each task, so we didn’t have a secret trick that suddenly cut dozens of bytes. Our final result was the sum of many small insights we picked up along the way. Since most of us came into this with little to no code-golf experience, our first instinct was to lean heavily on LLMs. It didn’t take long to realize it was not going to get us anywhere near the top in what was already a very saturated field just a few weeks in.\n\n# Solutions / techniques overwiew\n\n### Recursion, cell automata, pysearch - task002\n\nIn this task we have to fill all regions closed by green borders with yellow color. There are many ways to solve this task. The simplest way is straightforward DFS/Flood-fill algorithm. Another approach is to look only at 2 cells at a time and set value of current cell based on neighbor's value, almost like [Cellular automata](https://en.wikipedia.org/wiki/Cellular_automaton). You just need to do enough iterations (using recursion to save bytes) while rotating array after each step to take care of neighbor pairs in each orientation.\n\n```python\np=lambda g,i=67:-i*g or p([[4-4%(0**i|b or~a%9)for a,b in zip([4]+r,r)]for*r,in zip(*g[::-1])],i-1)\n```\n\nThere are 3 important parts here:\n- recursion template `p=lambda g,i=67:-i*g or p(...,i-1)`\n- how do you access the neighbor pair, we used pretty simple `for a,b in zip([4]+r,r)`\n- how do you calculate new value based on condition, we flood from the side for all iterations except last one and then swap colors in the last step using `4-4%(0**i|b or~a%9` that was figured out with help of tool called [pysearch](https://github.com/lynn/pysearch) by lynn.\n\nThose parts can be done in many different ways. And there are many more tricks to be used here that you can find by looking at top teams solutions.\n\nTask002 animation, keep in mind that rotations are not shown so it's easier to follow what is happening (steps go from 67 to -1).\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F3f69ef7107ea346cc045219307d0a345%2Ftask002.gif?generation=1762594915845044&alt=media)\n\n### Loop trick instead of recursion template - task095\n\nWe used recursion template shown above in many tasks, but turns out that if number of iterations is smaller than grid size and we don't need to make calculations based on the counter we can use shorter template used below.\nWhat is also interesting here is that parameter `b` could be just lambda parameter even though technically it should be set to zero before processing each row.\n\n```python\np=lambda g,b=0:[g:=[[b%4|(b:=a)for a in r]for r in zip(*g[::-1])]for _ in g][3]\n```\n\n### Iterating while mutating using pop() - task214\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fb22cf963e20068477aab8c59eab4fe78%2Fupload_a256e11de938e616f2c337573f5512da.png?generation=1762595057379835&alt=media)\n\nIn this task we have to finish pattern located in the left square.\n\n```python\np=lambda g:[r+g.pop()[3::-1]for r,*r[4:]in zip(g*1,*g[::-1])]\n```\n\nThere are a couple of interesting tricks used here:\n- `g.pop()` that returns last row from `g`\n- `g*1` to make a shallow copy so we can still iterate over full `g` even though `g.pop()` is mutating `g` (`zip(g*1,*g[::-1])` if resolved before any `pop()`)\n\n### Recursion with a*0==0 trick - task021\n\nThere were tasks that could be solved in a way that we perform the same operation both for whole row and for single number in a row. So we needed a way to test if current value is a row or a number.\nWe can take advantage of the fact that:\n\n`list * 0 = []`\n\n`number * 0 = 0`\n\n```python\np=lambda g:len(g[g.count(a:=g[0])-1:])*[a*(a*0==0)or p(a)]\n```\n\nIf `a*0==0` is true then we return `a` (number)\nOtherwise we recurse with `or p(a)` branch.\n\n### Loop flattening and bitwise operations - task365.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F44cd40e20c943a053e05718145505088%2FScreenshot%20from%202025-11-08%2012-36-32.png?generation=1762601919168586&alt=media)\n\n\nThe goal of this task is to find the rectangle with the most red pixels. We can achieve it by simply brute forcing all possible candidates using 4 loops over coordinates `i,j` and sizes `w,h`. For this task it's enough if each loop is from 0 to 7, that means we can alias `R=range(8)` and use 4 loops.\n\n```python\nR=range(8)\np=lambda g:max(((s:=sum(m:=[r[j:][:w]for r in g[i:][:h]],[])).count(2)*all(s),len(s),m)for i in R for j in R for w in R for h in R)[2]\n```\n\nBut we can also flatten all 4 loops into single one and take advantage of the fact that 8 is power of 2 so we can calculate `i,j,w,h` using bitwise operations (instead of `//` and `%` arithmetic).\n\n```python\np=lambda g:max((all(s:=sum(m:=[x[t&7:][:t>>6&7]for x in g[t>>3&7:][:t>>9]],g))*s.count(2),len(s),m)for t in range(4096))[2]\n```\n\n### Using hash to deal with edge cases - task070\n\nThere were tasks that could be solved simple way but failed 1 or 2 edge cases. So there were 2 options:\n- use longer more reliable solution\n- hash / hardcode that 1-2 edge cases and use the simpler solution\n\nHere we use `hash((*c,))%709==8` that calculates hash of column (as tuple) to detect that edge case so we can apply additional logic so solution pass all test cases.\n\n```python\np=lambda g:[[x+2*(x<8in r)*(hash((*c,))%709==8or 8in c)for*c,x in zip(*g,r)]for r in g]\n```\n\n### Flattening array - task286\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fcf0a1631f57ad8da512e479d693c4ef3%2Ftask286.gif?generation=1762595439433161&alt=media)\n\nThis is another task that uses recursion+rotation template.\nIf the current cell is empty and neighbor has one of 2 maze colors, then current cell will have the other color.\nTo find the other color we can flatten the 2D array into 1D array using `sum(g,[])`, then we can convert to set to figure out the color that we need (the only colors possible are black, cyan (wall color), neighbor color (that we know) and other color (that we are looking for)). Also interesting trick to save 1b is to set initial value of sum to e.g. `r` instead of `[]` to save a byte.\n\n```python=\np=lambda g,k=271:-k*g or p([[b or a%8and sum({*sum(g,r)})-a-8for a,b in zip([0]+r,r)]for*r,in zip(*g[::-1])],k-1)\n```\n\n### Iterating over raw bytes - task317\n\nThe most obvious solution for task317 is quite simple, we just use list comprehension and for each position we check the closest center of 3x3 square. \n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F8d0bd0e9639dc400689d87dec370bf80%2FScreenshot%20from%202025-11-08%2012-39-28.png?generation=1762602000742974&alt=media)\n\n\n```python\nR=[1,1,1,4,4,4,7,7,7]\np=lambda g:[[0<g[y][x]for x in R]for y in R]\n```\n\nThat R array is quite long but we can use raw bytes intead.\n\n```python\nR=b\"\u0001\u0001\u0001\u0004\u0004\u0004\u0007\u0007\u0007\"\np=lambda g:[[0<g[y][x]for x in R]for y in R]\n```\n\n### Counting bits - task369\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2F7f0ab9372bbccde4f0d93a5e2591a216%2FScreenshot%20from%202025-11-08%2012-40-59.png?generation=1762602112385832&alt=media)\n\nIn this task we have to set color of black shapes based on the size of the shape.\nInitially we solved this task using DFS/Flood fill algorithm, but it was definitely too long.\nNext we tried regex but we still weren't happy with the result.\n\nThe last solution used the following idea:\n- initialize each black pixel with bits set on unique position\n- then do enough iterations/rotations where we make bitwise OR operation for each neighbor pair\n- in the last recursion step set the value based on number of bits set\n\nWhat is also interesting here:\n- instead of using extra counter parameter, we reused recursion parameter `k` to save bytes, it made the program much slower but it worked\n- instead of initializing with `1<<` we initialized with `3<<` (which set 2 unique bits instead of 1) because this way pysearch expression was 1 byte shorter\n\n```python\np=lambda g,k=3:-k*g or p([[0**k*~14//~a.bit_count()or a|b*(a>5)or 3<<(k:=k+4)for a,b in zip(r,[0]+r)]for*r,in zip(*g[::-1])],k-1)\n```\n\n### Bruteforcing solution to avoid bad test cases - task346\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Ff8deefd24f0ca2fdbf2814c5264c8a2b%2FScreenshot%20from%202025-11-08%2012-42-44.png?generation=1762602195690805&alt=media)\n\nI\nIn this task we have to return 1x1 array with color that is inside a different color square in input array.\nThe simplest solution would be to try to return the least common color using this solution:\n\n```python\np=lambda g:[[min(S:=sum(g,[]),key=S.count)]]\n```\n\nBut there is good news and bad news.\nThe bad news is that it fails 3 test cases.\nThe good news is that it fails 3 test cases, so maybe we can make a slight code modifications to make all tests pass.\nThe general idea is to look at failing cases and try to figure out how we can modify parameters of sum function so it will produce expected result. We did it by trial and error with a help a tiny bruteforce script.\n\n```python\np=lambda g:[[min(S:=sum(g[1:7]+g[1:],[]),key=S.count)]]\n```\n\nThe simple script we used, we tried different templates.\n```python\nfor i in range(10):\n    for j in range(i+1,10):\n        print(i,j)\n        for k in range(10):\n            solution=f\"p=lambda g:[[min(S:=sum(g[{i}:{j}]+g[{k}:],[]),key=S.count)]]\"\n            if verify_program(task_num, solution, task_data):\n                print(solution)\n```\n\nUnfortunately we still missed the shortest possible solution that was really close.\n\n### Regex is quite powerful - task017\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc3b9fa1f80cdd67e48ad92ca525e2f6a%2Ftask017.gif?generation=1762595807517392&alt=media)\n\nThe idea was to rotate the grid, then use a regex to look for a sequence of five non-zero values followed by a zero. If that exact 5-value pattern appears again later in the grid, we replace the zero with whatever value follows the second occurrence. We repeat this until all the gaps are filled.\n\nThis solution was a kind of catalyst for the team to realize regex makes reasoning about some types of tasks a lot easier. It gave some of us the motivation to read the regex manual more carefully.\n\n```python=\nimport re\np=lambda g,k=31:-k*g or p(eval(re.sub(r\"(([^0], ){5})0(?=.*?\\1(.))\",r\"\\1\\3\",str([*zip(*g[::-1])]))),k-1)\n```\n\n### Compression optimizations - task238\n\nMany of our solutions ended up being long enough that compressing them was a viable way to shorten them. For this, we based our initial compression script on the ones that were shared publicly and improved them by adding more variants of `zlib` and `zopfli` compression levels, with or without blocksplitting, and setting the number of iterations to a specific value in the range 1-100. We also made heavy use of the variable optimization notebook https://www.kaggle.com/code/garrymoss/compressed-variable-name-optimization by @garrymoss, thanks a lot for sharing it.\n\nWhile far from optimal (-28b) from diamond in the end. The solution for task238 is a very silly example of why compression golfing has a completely different approach than normal golfing.\n\nWe had this code that compressed from the original 281b to 251b\n\n```python\ndef p(t):\n f=lambda f:[[*e]for e in zip(*filter(f,zip(*t)))if f(e)];r=f(lambda e:any({*e}-{8}))\n for f,e in enumerate(f(lambda e:8in e)):\n  for p,n in enumerate(e):d=len(e);r[f+1][p+1]=n and(f<p<d+~f)*r[0][1]+(d+~f<p<f)*r[-1][1]+(p<f<d+~p)*r[1][0]+(d+~p<f<p)*r[1][-1]or n\n return r\n```\n\nBut if you unpacked all the clever lambdas you would favor in the traditional golfing into this:\n\n```python\ndef p(n):\n e=n\n e=[e for*e,in zip(*e)if any(n%8for n in e)]\n e=[e for*e,in zip(*e)if any(n%8for n in e)]\n n=[e for*e,in zip(*n)if 8in e]\n n=[e for*e,in zip(*n)if 8in e]\n for f,n in enumerate(n):\n  for a,t in enumerate(n):r=len(n);e[f+1][a+1]=t and(f<a<r+~f)*e[0][1]+(r+~f<a<f)*e[-1][1]+(a<f<r+~a)*e[1][0]+(r+~a<f<a)*e[1][-1]or t\n return e\n```\n\nWe have made the original far bigger 338b, but it now compressed to 223b. The same algorithm, just written in a DRY (Do repeat yourself) fashion yielded 28b.\n\n# Conclusion\n\nWe dedicated a lot of time and effort to manually improve our solutions for each task. We tried using LLMs but in most cases they were unhelpful, it was much easier for us to tackle the problems manually instead. We are very happy with our result, especially considering how little code-golfing experience some of us had prior to this competition.\nWe would also like to thank all the people that shared helpful insights in kaggle discussions, especially @kayjoking, @hellopir2, @lukeg10081, @kenkrige and @garrymoss.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F977970%2Fc97916c7bc78f2e87d3e3441ff00ab84%2Foutro.jpg?generation=1762597022697898&alt=media)\n\n\n\n",
      "votes": 36
    },
    {
      "id": 3313123,
      "postDate": "2025-11-08T17:46:48.183Z",
      "content": "<p>Super clear, delightful write-up—loved how you broke down the recursion template and the cellular-automata angle on task002. All your recursion animation are fantastic; it makes the 67→−1 sweep instantly intuitive even without showing the rotations. </p>\n<p>Really wonder how you generated it ? e.g., did you snapshot a frame per iteration (after each <code>zip(*g[::-1])</code>) and stitch with ffmpeg, or render in Python (Pillow/matplotlib) / web canvas? </p>\n<p>Also huge kudos for the compression move—great reminder that compression golf ≠ normal golf. </p>\n<p>You’re incredibly talented!</p>",
      "rawMarkdown": "Super clear, delightful write-up—loved how you broke down the recursion template and the cellular-automata angle on task002. All your recursion animation are fantastic; it makes the 67→−1 sweep instantly intuitive even without showing the rotations. \n\nReally wonder how you generated it ? e.g., did you snapshot a frame per iteration (after each `zip(*g[::-1])`) and stitch with ffmpeg, or render in Python (Pillow/matplotlib) / web canvas? \n\nAlso huge kudos for the compression move—great reminder that compression golf ≠ normal golf. \n\nYou’re incredibly talented!\n",
      "votes": 1,
      "replies": [
        {
          "id": 3313540,
          "postDate": "2025-11-09T12:50:35.187Z",
          "content": "<p>Thank you!</p>\n<p>To generate animations I added this function in code_golf_utils.py:</p>\n<pre><code> ():\n\n  output_width, output_height = (output[]), (output)\n  width =  + output_width + \n  height = output_height + \n  offset = \n\n  image = [[bgcolor  _  (width)]  _  (height)]\n\n   r, row  (output):\n     c, cell  (row):\n      image[r + ][offset + c + ] = colors[cell]\n\n  fig = plt.figure(figsize=(, ))\n  ax = fig.add_axes([, , , ])\n  ax.imshow(np.array(image))\n\n  ax.hlines([r +   r  (output_height+)],\n            xmin=offset+, xmax=offset+output_width+, color=)\n\n  ax.vlines([offset + c +   c  (output_width+)],\n            ymin=, ymax=output_height+, color=)\n\n  ax.set_xticks([])\n  ax.set_yticks([])\n  plt.suptitle()\n  plt.savefig()\n</code></pre>\n<p>Then I used this code to capture each recursion step (task017 here):</p>\n<pre><code> ():\n    i=\n    save_image(g, task_num, i)\n     i&gt;=:\n        g=(re.sub(,,([*(*g[::-])])))\n        G=((g)) \n         _  (i%): G=[*(*G[::-])] \n        i-=   \n        save_image(G, task_num, i)\n     g\n</code></pre>\n<p>And this one to make gif from all generated .png:</p>\n<pre><code> glob\n imageio.v3  iio\n\npngs = (glob.glob(),\n              key= p: -(p.rsplit(,)[].split()[]))  \nframes = [iio.imread(p)  p  pngs]\niio.imwrite(, frames, duration=, loop=)\n</code></pre>\n<p>It would be probably better to generate everything in memory but this was simpler way and I wanted to get things done fast.</p>",
          "rawMarkdown": "Thank you!\n\nTo generate animations I added this function in code_golf_utils.py:\n```python\ndef save_image(output, task_num, step, bgcolor=(255, 255, 255)):\n  \n  output_width, output_height = len(output[0]), len(output)\n  width = 1 + output_width + 4\n  height = output_height + 4\n  offset = 1\n\n  image = [[bgcolor for _ in range(width)] for _ in range(height)]\n  \n  for r, row in enumerate(output):\n    for c, cell in enumerate(row):\n      image[r + 2][offset + c + 1] = colors[cell]\n\n  fig = plt.figure(figsize=(10, 5))\n  ax = fig.add_axes([0, 0, 1, 1])\n  ax.imshow(np.array(image))\n\n  ax.hlines([r + 1.5 for r in range(output_height+1)],\n            xmin=offset+0.5, xmax=offset+output_width+0.5, color=\"black\")\n\n  ax.vlines([offset + c + 0.5 for c in range(output_width+1)],\n            ymin=1.5, ymax=output_height+1.5, color=\"black\")\n\n  ax.set_xticks([])\n  ax.set_yticks([])\n  plt.suptitle(f\"task{task_num:03d}, recursion step: {step}\")\n  plt.savefig(f\"task{task_num:03d}_{step}.png\")\n```\n\nThen I used this code to capture each recursion step (task017 here):\n```python\ndef p(g):\n    i=31\n    save_image(g, task_num, i)\n    while i>=0:\n        g=eval(re.sub(r\"(([^0], ){5})0(?=.*?\\1(.))\",r\"\\1\\3\",str([*zip(*g[::-1])])))\n        G=eval(str(g)) \n        for _ in range(i%4): G=[*zip(*G[::-1])] # return to normal orientation to save image\n        i-=1   \n        save_image(G, task_num, i)\n    return g\n```\n\nAnd this one to make gif from all generated .png:\n```python\nimport glob\nimport imageio.v3 as iio\n\npngs = sorted(glob.glob(f\"task{task_num:03d}_*.png\"),\n              key=lambda p: -int(p.rsplit('_',1)[1].split('.')[0]))  # sort by step\nframes = [iio.imread(p) for p in pngs]\niio.imwrite(f\"task{task_num:03d}.gif\", frames, duration=1, loop=0)\n```\n\nIt would be probably better to generate everything in memory but this was simpler way and I wanted to get things done fast.",
          "votes": 3,
          "replies": [
            {
              "id": 3314358,
              "postDate": "2025-11-10T06:54:10.760Z",
              "content": "<p>Thanks a lot for sharing the code—now I understand you generate per-step animations by saving a PNG at each recursion step with <code>save_image</code>, then sort the PNGs by step and stitch them into a GIF with <code>imageio</code> (1s per frame) using a simple file-per-frame pipeline. Super clear—appreciate it!</p>",
              "rawMarkdown": "Thanks a lot for sharing the code—now I understand you generate per-step animations by saving a PNG at each recursion step with `save_image`, then sort the PNGs by step and stitch them into a GIF with `imageio` (1s per frame) using a simple file-per-frame pipeline. Super clear—appreciate it!\n"
            },
            {
              "id": 3322893,
              "postDate": "2025-11-13T19:55:26.873Z",
              "content": "<p>Hi <a href=\"https://www.kaggle.com/jacekwl\" target=\"_blank\">@jacekwl</a>,</p>\n<p>Really appreciate your write-up! 🙌 I had a few small suggestions to make recursion visualizations even smoother:</p>\n<p>In-memory GIF generation: Instead of saving PNGs for each step, keep frames in memory and write the GIF directly. This speeds up processing for larger grids.</p>\n<p>Modular transformations: Using a transform_func allows easy swapping of recursion logic without rewriting the whole pipeline.</p>\n<p>Customizable colors &amp; layout: You can define your own color mapping and figure size to match your visualization needs.</p>\n<p>Here’s a tiny snippet for the in-memory approach:</p>\n<p>frames = capture_steps_memory(grid, transform_func=my_transform, steps=10)\nmake_gif_memory(frames, gif_name=\"my_animation.gif\")</p>\n<p>Thanks again — your post really clarified step-by-step recursion visualization!</p>",
              "rawMarkdown": "Hi @jacekwl,\n\nReally appreciate your write-up! 🙌 I had a few small suggestions to make recursion visualizations even smoother:\n\nIn-memory GIF generation: Instead of saving PNGs for each step, keep frames in memory and write the GIF directly. This speeds up processing for larger grids.\n\nModular transformations: Using a transform_func allows easy swapping of recursion logic without rewriting the whole pipeline.\n\nCustomizable colors & layout: You can define your own color mapping and figure size to match your visualization needs.\n\n\nHere’s a tiny snippet for the in-memory approach:\n\nframes = capture_steps_memory(grid, transform_func=my_transform, steps=10)\nmake_gif_memory(frames, gif_name=\"my_animation.gif\")\n\nThanks again — your post really clarified step-by-step recursion visualization!"
            }
          ]
        }
      ]
    },
    {
      "id": 3313051,
      "postDate": "2025-11-08T14:59:47.433Z",
      "content": "<p>Such an awesome illustration — nice work!!</p>",
      "rawMarkdown": "Such an awesome illustration — nice work!!",
      "votes": 2
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T12:50:49Z",
  "competition_id": 95282,
  "competition_slug": "google-code-golf-2025",
  "team_id": 14206337,
  "solution_url": "/competitions/google-code-golf-2025/writeups/8th-place-write-up-import-itertools"
}