凄いバカなプログラムを作ろう
凄いバカなプログラムを作ろう@きしだのはてなに参加。
初代チャンピオン藤田さんに乗せられ、とりあえず再帰でバブルソート書いた。ただ、いろいろ考えたのだけども、単にループを再帰にしただけで全然関数っぽく書けない。しょうがないので「単にYって書きたかっただけじゃないのか」という方向に。
class BakaSort { public static void main(String[] args) { print(new int[]{14, 13, 71, 2, 24, 19}); print(new int[]{3, 2}); print(new int[]{5}); print(new int[]{}); print(null); } //=================================== 準備 //これが無いと始まらない static abstract class λ { abstract Object call(Object arg); } //再帰するのに必要だから static λ Y() { return new λ() { Object call(final Object t) { return new λ() { Object call(final Object s) { return f(t).call(new λ() { Object call(final Object x) { return f(f(s).call(s)).call(x); }}); } }.call(new λ() { Object call(final Object s) { return f(t).call(new λ() { Object call(final Object x) { return f(f(s).call(s)).call(x); }}); }}); } }; } //分岐はやっぱり必要かな static Object IF(boolean 二度寝しても大丈夫なSICP読書会,λ 入会します,λ 入会しません) { for(;二度寝しても大丈夫なSICP読書会;) { return 入会します.call(null); } return 入会しません.call(null); } //面倒なので static λ f(Object f) {return (λ)f;} static int[] os(Object o) {return (int[])o;} static λ NOP = new λ(){ Object call(Object x) {return null;}}; //再帰するのに必要だから static int[] cdr(final int[] a) { return (int[])IF(a == null || a.length == 0, NOP, new λ(){ Object call(Object x) { int[] dest = new int[a.length-1]; System.arraycopy(a,1,dest,0,dest.length); return dest; }}); } //=================================== 本体 //文字列を作って表示 static void print(final int[] arg) { System.out.println ( IF(arg == null, new λ() {Object call(Object i) { return "nullです"; }}, new λ() {Object call(Object i) { return IF(arg.length == 0, new λ() {Object call(Object i) { return "空です"; }}, new λ() {Object call(Object i) { return join(sort(arg)); }}); }}) ); } //再帰でバブルソート static int[] sort(final int[] arg) { final λ iter = new λ() {Object call(final Object t) { return new λ() {Object call(Object i) { final int[] os = os(i);//loop index 0:head, 1:search return IF(os[0] == (arg.length-1), new λ(){ Object call(Object a) { return arg; }}, new λ(){ Object call(Object a) { return IF(os[1] == arg.length, new λ(){ Object call(Object a) { return f(t).call(new int[]{os[0]+1,os[0]+2}); }}, new λ(){ Object call(Object a) { IF(arg[os[0]] > arg[os[1]], new λ(){ Object call(Object a) { int tmp = arg[os[1]]; arg[os[1]] = arg[os[0]]; arg[os[0]] = tmp; return null;//これはひどい }},NOP); return f(t).call(new int[]{os[0],os[1]+1}); }}); }}); }}; }}; //数が少ないときはソートしない return (int[])IF(arg.length == 1, new λ(){ Object call(Object a) { return arg; }}, new λ(){ Object call(Object a) { return f(Y().call(iter)).call(new int[]{0,1}); }}); } //再帰で文字列結合 static String join(int[] arg) { λ pr = new λ() {Object call(final Object t) { return new λ() {Object call(Object i) { final int[] os = os(i); return IF(os == null || os.length == 0, new λ(){ Object call(Object x) {return "";}}, new λ(){ Object call(Object a) { return ""+os[0]+" "+f(t).call(cdr(os)); }}); }}; }}; return (String)f(Y().call(pr)).call(arg); } }