たらい回し関数についてはクロージャーの説明には使えそうにないので変数を使わないように書き直す意味はあまりないとは思いますが、やってみます。
たらい回し関数をできるだけ変数を使わないように書き直します。このために前回「呼び出しの深さ」について考えました。「呼び出しの深さ」別に tarai_0、tarai_1、tarai_2 のように関数を作っていきます。以下では「呼び出しの深さ」2 でかなり複雑になるので以下の関数では 2 までしかありません.が、これが無限に続くと考えると擬似的に無限の場合を表しています。
C# ではあまりうまく書くことができないのでわかりにくいですし、「呼び出しの深さ」2 までしかないので「幅」0 の場合しか計算できません(これはあまり意味がありません)。これが続いていくことを想像できるようコードを掲載します。
public static string Test() { float tarai_0(float x, float y, float z) { return (x <= y ? y : 0); } float tarai_1(float x, float y, float z) { return (x <= y ? y : ((x - 1 <= y ? y : 0) <= (y - 1 <= z ? z : 0) ? (y - 1 <= z ? z : 0) : 0)); } float tarai_2(float x, float y, float z) { return (x <= y ? y : ((x - 1 <= y ? y : ((x - 1 - 1 <= y ? y : 0) <= (y - 1 <= z ? z : 0) ? (y - 1 <= z ? z : 0) : 0)) <= (y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) ? (y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) : (((x - 1 <= y ? y : ((x - 1 - 1 <= y ? y : 0) <= (y - 1 <= z ? z : 0) ? (y - 1 <= z ? z : 0) : 0)) - 1 <= (y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) ? (y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) : 0) <= ((y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) - 1 <= (z - 1 <= x ? x : ((z - 1 - 1 <= x ? x : 0) <= (x - 1 <= y ? y : 0) ? (x - 1 <= y ? y : 0) : 0)) ? (z - 1 <= x ? x : ((z - 1 - 1 <= x ? x : 0) <= (x - 1 <= y ? y : 0) ? (x - 1 <= y ? y : 0) : 0)) : 0) ? ((y - 1 <= z ? z : ((y - 1 - 1 <= z ? z : 0) <= (z - 1 <= x ? x : 0) ? (z - 1 <= x ? x : 0) : 0)) - 1 <= (z - 1 <= x ? x : ((z - 1 - 1 <= x ? x : 0) <= (x - 1 <= y ? y : 0) ? (x - 1 <= y ? y : 0) : 0)) ? (z - 1 <= x ? x : ((z - 1 - 1 <= x ? x : 0) <= (x - 1 <= y ? y : 0) ? (x - 1 <= y ? y : 0) : 0)) : 0) : 0))); } int diff(float x, float y) { if (x <= y) { return 0; } else { return (int)Math.Ceiling(x - y); } } int dist(float x, float y, float z) { float m = Math.Min(Math.Min(x, y), z); return diff(x, m) + diff(y, m) + diff(z, m); } float tarai(float x, float y, float z) { switch (dist(x, y, z) * 3 + 1) { case 0: return tarai_0(x, y, z); case 1: return tarai_1(x, y, z); case 2: return tarai_2(x, y, z); } return -1; } return tarai(0, 0, 0).ToString(); }
このように x、y、z 以外の変数を使わないように書き直すことができました。