{
  "id": 615145,
  "title": "6th Place Solution for Google Code Golf Championship",
  "content": "<h1>Summary</h1>\n<p>Our repository is <a href=\"https://github.com/Yosshi999/ARCGolfVisualizer\" target=\"_blank\">here</a>.</p>\n<p>Score contribution is:</p>\n<ul>\n<li>Golf by hand (955,251)</li>\n<li>ZLIB compression (+2276)<ul>\n<li>code optimization (~400)</li></ul></li>\n</ul>\n<p>Although we didn't share our individual scores on the spreadsheet (<a href=\"https://www.kaggle.com/competitions/google-code-golf-2025/discussion/596679)\" target=\"_blank\">https://www.kaggle.com/competitions/google-code-golf-2025/discussion/596679)</a>, we have 5 diamonds and 58 golds.</p>\n<p>Diamond tasks:</p>\n<ul>\n<li>task288 85B (-1)</li>\n<li>task245 94B (-4)</li>\n<li>task225 122B (-1)</li>\n<li>task382 123B (-1)</li>\n<li>task349 163B (-9)</li>\n</ul>\n<h1>Visualizer</h1>\n<p>We created a visualizer using Flask + Jinja2, and managed submissions on github.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F822ea4eb59e5827dcffb29e96098fd7c%2Foutput.gif?generation=1762674380764565&amp;alt=media\" alt=\"screen\"></p>\n<h1>Important Golf Techniques</h1>\n<h2>BFS</h2>\n<p>BFS takes much computational cost, but short.</p>\n<h3>Task286</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2Fc29484e5e090b59fda5d4ea0cf7d2957%2F2025-11-09%20164836.png?generation=1762674549201209&amp;alt=media\" alt=\"\"></p>\n<h2>Unroll 'rotate left'</h2>\n<p>Sometimes you can unroll the rotating operation, <code>...for*v,in zip(*g)][::-1]</code>.</p>\n<h3>Task095</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F50ad9177acd5cbd4eab9bac5fe3a86e0%2F2025-11-09%20165056.png?generation=1762674668578820&amp;alt=media\" alt=\"\"></p>\n<h2>Embed non-ascii code</h2>\n<p>You can use b-string to shorten the constant array.</p>\n<h3>Task266🥉</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F1b94080078534c6135a46c98312e1ae6%2F2025-11-09%20165305.png?generation=1762674798687768&amp;alt=media\" alt=\"\"></p>\n<h2>Loop unrolling and exec</h2>\n<h3>Task288💎</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F57554d75559b4359d57f36c7be40e971%2F2025-11-09%20165358.png?generation=1762674848973994&amp;alt=media\" alt=\"\"></p>\n<h1>ZLIB compression</h1>\n<p>Codes longer than 240B can be shortened by ZLIB.\nWe used google/zopfli because it is better than the builtin zlib.\nIn addition we cutout the head and tail to save 3 bytes.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F5b2b2501aeaadbbdc5118af9d44c8a4b%2Fimage%20(1).png?generation=1762674958795116&amp;alt=media\" alt=\"\"></p>\n<pre><code>compressed_str = zopfli.zlib.compress(raw_str)[:-]\n</code></pre>\n<pre><code>\n zlib\n(zlib.decompress((,),-))\n</code></pre>\n<h1>ZLIB optimizer</h1>\n<p>Renaming variables gains ~400 pts.\nIt is important to use same variable names and make it more huffman-coding-friendly.</p>\n<p>We have two approaches: Static Analysis and Simulated Annealing.</p>\n<h2>Static Analysis</h2>\n<p>It takes much computational cost for validating all testcases. So we generate candidates by using Optuna (or QUBO solver in early days of the competition) with the constraint provided by the variable liveness analysis.\nThe constraint is represented as interference graph.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F71526d800cf49ee09ac5e95b8f64c7f9%2F2025-11-09%20165818.png?generation=1762675133567763&amp;alt=media\" alt=\"\"></p>\n<h2>Simulated Annealing</h2>\n<p>As well as Static Analysis, zopfli is optimized as a black box, with byte count as the metric.</p>\n<p>SA randomly changes the names of some variables to create neighboring states.\nEach candidate is validated using 10 testcases.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F31d193d9909f86d12438b594f8fc031a%2F2025-11-09%20170058.png?generation=1762675268017295&amp;alt=media\" alt=\"\"></p>\n<h2>Pros and Cons</h2>\n<p>Static Analysis takes ~3h for all handwritten submissions.\nIt does not need any testcase so it is fast.</p>\n<p>On the other hand, Simulated Annealing takes ~12h, but it has wide search space and realizes better score.</p>\n<p>So we used Static Analysis as initial guesses and optimized them by Simulated Annealing.</p>",
  "comments": [],
  "comment_count": 0,
  "messages": [
    {
      "id": 3313405,
      "postDate": "2025-11-09T08:05:23.143Z",
      "content": "<h1>Summary</h1>\n<p>Our repository is <a href=\"https://github.com/Yosshi999/ARCGolfVisualizer\" target=\"_blank\">here</a>.</p>\n<p>Score contribution is:</p>\n<ul>\n<li>Golf by hand (955,251)</li>\n<li>ZLIB compression (+2276)<ul>\n<li>code optimization (~400)</li></ul></li>\n</ul>\n<p>Although we didn't share our individual scores on the spreadsheet (<a href=\"https://www.kaggle.com/competitions/google-code-golf-2025/discussion/596679)\" target=\"_blank\">https://www.kaggle.com/competitions/google-code-golf-2025/discussion/596679)</a>, we have 5 diamonds and 58 golds.</p>\n<p>Diamond tasks:</p>\n<ul>\n<li>task288 85B (-1)</li>\n<li>task245 94B (-4)</li>\n<li>task225 122B (-1)</li>\n<li>task382 123B (-1)</li>\n<li>task349 163B (-9)</li>\n</ul>\n<h1>Visualizer</h1>\n<p>We created a visualizer using Flask + Jinja2, and managed submissions on github.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F822ea4eb59e5827dcffb29e96098fd7c%2Foutput.gif?generation=1762674380764565&amp;alt=media\" alt=\"screen\"></p>\n<h1>Important Golf Techniques</h1>\n<h2>BFS</h2>\n<p>BFS takes much computational cost, but short.</p>\n<h3>Task286</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2Fc29484e5e090b59fda5d4ea0cf7d2957%2F2025-11-09%20164836.png?generation=1762674549201209&amp;alt=media\" alt=\"\"></p>\n<h2>Unroll 'rotate left'</h2>\n<p>Sometimes you can unroll the rotating operation, <code>...for*v,in zip(*g)][::-1]</code>.</p>\n<h3>Task095</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F50ad9177acd5cbd4eab9bac5fe3a86e0%2F2025-11-09%20165056.png?generation=1762674668578820&amp;alt=media\" alt=\"\"></p>\n<h2>Embed non-ascii code</h2>\n<p>You can use b-string to shorten the constant array.</p>\n<h3>Task266🥉</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F1b94080078534c6135a46c98312e1ae6%2F2025-11-09%20165305.png?generation=1762674798687768&amp;alt=media\" alt=\"\"></p>\n<h2>Loop unrolling and exec</h2>\n<h3>Task288💎</h3>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F57554d75559b4359d57f36c7be40e971%2F2025-11-09%20165358.png?generation=1762674848973994&amp;alt=media\" alt=\"\"></p>\n<h1>ZLIB compression</h1>\n<p>Codes longer than 240B can be shortened by ZLIB.\nWe used google/zopfli because it is better than the builtin zlib.\nIn addition we cutout the head and tail to save 3 bytes.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F5b2b2501aeaadbbdc5118af9d44c8a4b%2Fimage%20(1).png?generation=1762674958795116&amp;alt=media\" alt=\"\"></p>\n<pre><code>compressed_str = zopfli.zlib.compress(raw_str)[:-]\n</code></pre>\n<pre><code>\n zlib\n(zlib.decompress((,),-))\n</code></pre>\n<h1>ZLIB optimizer</h1>\n<p>Renaming variables gains ~400 pts.\nIt is important to use same variable names and make it more huffman-coding-friendly.</p>\n<p>We have two approaches: Static Analysis and Simulated Annealing.</p>\n<h2>Static Analysis</h2>\n<p>It takes much computational cost for validating all testcases. So we generate candidates by using Optuna (or QUBO solver in early days of the competition) with the constraint provided by the variable liveness analysis.\nThe constraint is represented as interference graph.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F71526d800cf49ee09ac5e95b8f64c7f9%2F2025-11-09%20165818.png?generation=1762675133567763&amp;alt=media\" alt=\"\"></p>\n<h2>Simulated Annealing</h2>\n<p>As well as Static Analysis, zopfli is optimized as a black box, with byte count as the metric.</p>\n<p>SA randomly changes the names of some variables to create neighboring states.\nEach candidate is validated using 10 testcases.</p>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F31d193d9909f86d12438b594f8fc031a%2F2025-11-09%20170058.png?generation=1762675268017295&amp;alt=media\" alt=\"\"></p>\n<h2>Pros and Cons</h2>\n<p>Static Analysis takes ~3h for all handwritten submissions.\nIt does not need any testcase so it is fast.</p>\n<p>On the other hand, Simulated Annealing takes ~12h, but it has wide search space and realizes better score.</p>\n<p>So we used Static Analysis as initial guesses and optimized them by Simulated Annealing.</p>",
      "rawMarkdown": "# Summary\nOur repository is [here](https://github.com/Yosshi999/ARCGolfVisualizer).\n\nScore contribution is:\n* Golf by hand (955,251)\n* ZLIB compression (+2276)\n  * code optimization (~400)\n\nAlthough we didn't share our individual scores on the spreadsheet (https://www.kaggle.com/competitions/google-code-golf-2025/discussion/596679), we have 5 diamonds and 58 golds.\n\nDiamond tasks:\n- task288 85B (-1)\n- task245 94B (-4)\n- task225 122B (-1)\n- task382 123B (-1)\n- task349 163B (-9)\n\n# Visualizer\nWe created a visualizer using Flask + Jinja2, and managed submissions on github.\n\n![screen](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F822ea4eb59e5827dcffb29e96098fd7c%2Foutput.gif?generation=1762674380764565&alt=media)\n\n# Important Golf Techniques\n## BFS\nBFS takes much computational cost, but short.\n\n### Task286\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2Fc29484e5e090b59fda5d4ea0cf7d2957%2F2025-11-09%20164836.png?generation=1762674549201209&alt=media)\n\n## Unroll 'rotate left'\nSometimes you can unroll the rotating operation, `...for*v,in zip(*g)][::-1]`.\n\n### Task095\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F50ad9177acd5cbd4eab9bac5fe3a86e0%2F2025-11-09%20165056.png?generation=1762674668578820&alt=media)\n\n## Embed non-ascii code\nYou can use b-string to shorten the constant array.\n\n### Task266🥉\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F1b94080078534c6135a46c98312e1ae6%2F2025-11-09%20165305.png?generation=1762674798687768&alt=media)\n\n## Loop unrolling and exec\n### Task288💎\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F57554d75559b4359d57f36c7be40e971%2F2025-11-09%20165358.png?generation=1762674848973994&alt=media)\n\n# ZLIB compression\nCodes longer than 240B can be shortened by ZLIB.\nWe used google/zopfli because it is better than the builtin zlib.\nIn addition we cutout the head and tail to save 3 bytes.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F5b2b2501aeaadbbdc5118af9d44c8a4b%2Fimage%20(1).png?generation=1762674958795116&alt=media)\n\n```py\ncompressed_str = zopfli.zlib.compress(raw_str)[2:-4]\n```\n\n```py\n#coding:L1\nimport zlib\nexec(zlib.decompress(bytes(\" ... \",\"L1\"),-8))\n```\n\n# ZLIB optimizer\nRenaming variables gains ~400 pts.\nIt is important to use same variable names and make it more huffman-coding-friendly.\n\nWe have two approaches: Static Analysis and Simulated Annealing.\n\n## Static Analysis\nIt takes much computational cost for validating all testcases. So we generate candidates by using Optuna (or QUBO solver in early days of the competition) with the constraint provided by the variable liveness analysis.\nThe constraint is represented as interference graph.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F71526d800cf49ee09ac5e95b8f64c7f9%2F2025-11-09%20165818.png?generation=1762675133567763&alt=media)\n\n## Simulated Annealing\nAs well as Static Analysis, zopfli is optimized as a black box, with byte count as the metric.\n\nSA randomly changes the names of some variables to create neighboring states.\nEach candidate is validated using 10 testcases.\n\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-user-content/o/inbox%2F2026558%2F31d193d9909f86d12438b594f8fc031a%2F2025-11-09%20170058.png?generation=1762675268017295&alt=media)\n\n## Pros and Cons\nStatic Analysis takes ~3h for all handwritten submissions.\nIt does not need any testcase so it is fast.\n\nOn the other hand, Simulated Annealing takes ~12h, but it has wide search space and realizes better score.\n\nSo we used Static Analysis as initial guesses and optimized them by Simulated Annealing.",
      "votes": 10
    }
  ],
  "complete": true,
  "source": "live",
  "fetched_at": "2026-10-19T12:51:17Z",
  "competition_id": 95282,
  "competition_slug": "google-code-golf-2025",
  "team_id": 14198817,
  "solution_url": "/competitions/google-code-golf-2025/writeups/6th-place-solution-for-google-code-golf-championsh"
}