v grass

終わりました。53Bの解説…は面倒くさいので、擬似コードと分かる人にしか分からない解説を。

f(g, c){
  cp = c + 1
  b = 'w' == cp
  c_or_cp = b(c, cp)
  c_or_g = b(c, g) # ここで上で使った残骸を再利用
  c_or_g(c_or_g, c_or_cp) # 真なら1引数を取りc(つまりv)を返し、偽なら再帰呼び出し
}

r = f(f, 'w')
v = r(r)
out(v)

ポイントは、分岐の書き方。
真偽値は二引数をとり、真なら第一、偽なら第二引数を返す関数で表されるのですが、分岐を二つ作る際に、真の方は同じものを使うことで、関数適用の回数を一回抑えています。
で、このパターンはどう考えても自分も何度も書いてたのに、なんで負けたんだーと思ってたんですが、確かまだこのパターン書いてたときは、関数適用順によって長さ変わるのに気づいてなくって、多分しっかり縮め損ねてたんだと思います…もったいない。
ちなみに自分の55Bのも擬似コード書いときます。

f(g, c){
  g` = g(g)
  cp = c + 1
  b = 'w' == cp
  r = b(c) # 真なら1引数をとりcを返す関数 偽なら引数をそのまま返す関数だが使われない
  b(r, g)(cp) # 真ならさっきの関数に cp 適用、偽なら再帰呼び出し
}

v = f(f, 'w')
out(v)

こっちのほうがかっこいいかなーとか言ってみる。
53B版より関数適用の回数が少ないので、これ思いついた時はもう縮まないかなーと思ったんですよねえ。甘かったです。抜かれた後も55Bのを元に縮めようと頑張ってしまっていたので、まあ無理でしたね。負けました…

追記:上のは irie さんのです。 youz さんのがまた別の形だったのでものすごく簡単に解説。
関数の最後で v を出力するようにしています。まあなんというか、普通に考えるとそのままだと当然ガンガン v 以外も出力されるのですが、分岐を使って「vか関数」を出力関数に渡してやることで、エラーで無理やり止めてます。
エラーで止めるパターンも考えてたのですが、こっちはあんまり真面目に考えてなかったのでまずったなーという感じ。これの方が余裕で関数適用少なくなりますね。負けました…
うわー悔しいなあ。どっちももうちょっとちゃんと考えてれば、片方にはたどり着けた気がする。55Bの形を一度捨てればよかった。
さすがに普段ゴルフしてない人に負けるのはどうよ、なのでせめて並びたかったです。