aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/nuldoc/content/posts/2025-11-27
diff options
context:
space:
mode:
Diffstat (limited to 'services/nuldoc/content/posts/2025-11-27')
-rw-r--r--services/nuldoc/content/posts/2025-11-27/anybatross-writeup.md (renamed from services/nuldoc/content/posts/2025-11-27/anybatross-writeup.dj)39
1 files changed, 13 insertions, 26 deletions
diff --git a/services/nuldoc/content/posts/2025-11-27/anybatross-writeup.dj b/services/nuldoc/content/posts/2025-11-27/anybatross-writeup.md
index 04ba13f..739bcd0 100644
--- a/services/nuldoc/content/posts/2025-11-27/anybatross-writeup.dj
+++ b/services/nuldoc/content/posts/2025-11-27/anybatross-writeup.md
@@ -14,8 +14,7 @@ tags = [
date = "2025-11-27"
remark = "公開"
---
-{#intro}
-# はじめに
+# はじめに {#intro}
[YAPC::Fukuoka 2025](https://yapcjapan.org/2025fukuoka/) に際してカヤックさんが開催されていたコードゴルフコンテスト、[Anybatross](https://perlbatross.kayac.com/contest/2025fukuoka) に参加し、優勝した。
この記事では自分の回答について解説する。
@@ -24,11 +23,9 @@ remark = "公開"
このコンテストは何度か開催されており、[前々回](https://perlbatross.kayac.com/contest/2024hiroshima) に参加したときは総合 2 位だった (前回開催は不参加)。
-{#hole-1}
-# Hole 1
+# Hole 1 {#hole-1}
-{#answer}
-## 回答 (45 byte)
+## 回答 (45 byte) {#answer}
```perl
print$a+=$\=y/8B/0/+y/0469ADO-R//.$/,","for<>
@@ -37,13 +34,11 @@ print$a+=$\=y/8B/0/+y/0469ADO-R//.$/,","for<>
Hole 1 については同一言語・同一スコアの回答が複数あるので詳細は省略する。
-{#hole-2}
-# Hole 2
+# Hole 2 {#hole-2}
こちらは縮めていった過程も記載する。
-{#answer-a}
-## 回答 A (107 byte)
+## 回答 A (107 byte) {#answer-a}
最終スコアを見ると 4 位タイ (107 byte) が多く、3 位以上の回答と明確にアルゴリズムの差があるのでここから解説をスタートしようと思う。
@@ -72,8 +67,7 @@ x = [["la"], 3]
その他、`?A` や `String#*`、`it`、numbered parameters などの細かいテクニックについては、「Ruby コードゴルフ」で調べるか、最近の Ruby のリリースノートを読むと見つかるはず。
-{#answer-b}
-## 回答 B (107 byte)
+## 回答 B (107 byte) {#answer-b}
回答 A をぐっと睨むと、`m>1&&(...)` の括弧を削りたくなる。しかしそれには `m>1&&` がどうしても邪魔になる。というわけで終了条件を工夫することでなんとか `m` を排除できないかを考えた。それがこちら。
@@ -88,8 +82,7 @@ puts$**?,,s
しかし、これだけでは回答 A とスコアは変わらない。これを短縮したものがこちら。
-{#answer-c}
-## 回答 C (106 byte)
+## 回答 C (106 byte) {#answer-c}
`Kernel#gets` は、入力を特殊変数 `$_` へ代入する。これは Perl 由来の挙動で、Ruby にはいくつか `$_` を参照するものがある。これを使って変数 `s` を置き換えると次のようになる。
@@ -102,8 +95,7 @@ puts$**?,,$_
これで 1 byte 縮む。
-{#answer-d}
-## 回答 D (104 byte)
+## 回答 D (104 byte) {#answer-d}
回答 C を眺めると、`b` への代入に文字を費やしすぎている。これを `String#gsub!` の第一引数に直接書いてはどうか。更に、直前のマッチしたパターンを指す特殊変数 `$&` を使えば、変数 `b` を排除できる。それがこちら。
@@ -115,8 +107,7 @@ puts$**?,,$_
コードゴルフとして `[0][0]` は気になるところだが、それでも 2 byte 一気に縮まった。
-{#answer-e}
-## 回答 E (103 byte)
+## 回答 E (103 byte) {#answer-e}
回答 D を提出したことで tompng 氏のスコアを越え、氏のコードを閲覧できるようになった。そこから少し変更したものが、mame 氏と (変数名などの些事を除いて) 同じ以下のコードである。
@@ -138,8 +129,7 @@ puts$**?,,s
```
-{#answer-f}
-## 回答 F (103 byte)
+## 回答 F (103 byte) {#answer-f}
さて、ヒントを求めて [前回開催の公式解説ブログ](https://techblog.kayac.com/yapc2024hakodate-perlbatross-result) を読んでいたところ、次のような興味深い記述を発見した。
@@ -180,8 +170,7 @@ puts$**?,
外側の括弧を移動させてくれば `gsub` と `b` の間のスペースを消せるが、`;` を `&&` にせねばならず失敗する。この問題を解決したのが最終回答の 102 byte コードである。
-{#answer-g}
-## 最終回答 (102 byte)
+## 最終回答 (102 byte) {#answer-g}
```ruby
#!ruby -p
@@ -194,8 +183,7 @@ puts$**?,
これによって Hole 2 の単独 1 位スコアとなった。
-{#llm}
-# LLM のコードゴルフ性能
+# LLM のコードゴルフ性能 {#llm}
ところで、今回スコア短縮に行き詰まったあたりから LLM を使ってみた (コンテストのレギュレーションとして明示的に利用が許可されている)。
@@ -205,7 +193,6 @@ puts$**?,
なお、LLM は文字数カウントを大の苦手としているので、縮めた (と言い張っている) コードを `wc` コマンドに渡し、その結果を LLM に見てもらった方がよい。
-{#outro}
-# おわりに
+# おわりに {#outro}
楽しかったです。運営のみなさま、ありがとうございました!