美文网首页
一行Java代码八皇后

一行Java代码八皇后

作者: 风干鸡 | 来源:发表于2017-01-21 15:35 被阅读0次

一行代码八皇后

其实是标题党,准确的说是在一定条件只需要一行。

先上代码:

count(accumulate((r, i) -> flatmap((List<Integer> ps0) -> map(y -> cons(y, ps0), filter(y0 -> y((TriFunction<List<Integer>, Integer, Integer, Boolean> fn) -> (List<Integer> ps, Integer y, Integer gap) -> ps == null || !(car(ps) == y || car(ps) == y + gap || car(ps) == y - gap) && fn.apply(cdr(ps), y, gap + 1)).apply(ps0, y0, 1), range(1, 8))), r), list((List<Integer>) null), range(1, 8)));

当然他是不能独立运行的,完整代码:https://gist.github.com/ezksd/07a91873fcacdf66e44ed7aca7171b17

首先要定义一些辅助的数据结构

类似scheme里的pair和list。

class Pair<A, B> {
    A a;
    B b;
    Pair(A a, B b) {
        this.a = a;
        this.b = b;
    }
}

class List<E> extends Pair<E, List<E>> {
    List(E e, List<E> eList) {
        super(e, eList);
    }
}

@FunctionalInterface:用来表示lambda表达式的类型,

interface TriFunction<A,B,C,R>{
    R apply(A a, B b, C c);
}

interface RecurFunc<T> extends Function<RecurFunc<T>, T> {}

function包里面只有单参数的Function,两个参数的BiFunction,现在我们需要一个三参数的。三个参数也可以科里化成单参数的,考虑到代码长度(已经很长了)的原因就直接加了这个东西。

RecurFunc是y combinator里面用来表达一个高阶函数,apply自己,返回目标函数。

因为java的定义不能递归(不支持letrec),比如你不能写int i = i + 1,而且lambda表达式不借助其他手段不能递归调用自己,y combinator就是这个其他手段。

关于y combinator,可以看看Y combinator 推导过程 ,抄袭自The Y Combinator

然后是一些工具函数

package core;


import java.util.function.BiFunction;
import java.util.function.Function;

public class EightQueens {

    static <A, B> A car(Pair<A, B> pair) {
        return pair.a;
    }

    static <A, B> B cdr(Pair<A, B> pair) {
        return pair.b;
    }

    static <E> List<E> cons(E item, List<E> list) {
        return new List<>(item, list);
    }

    static <E> List<E> list(E... items) {
        List<E> r = null;
        for (int i = items.length - 1; i >= 0; i--) {
            r = new List<>(items[i], r);
        }
        return r;
    }

    static <E> List<E> append(List<E> l1, List<E> l2) {
        return l1 == null ? l2 : cons(car(l1), append(cdr(l1), l2));
    }

    static <T, R> R apply(Function<T, R> f, T t) {
        return f.apply(t);
    }

    static <T, U, R> R apply(BiFunction<T, U, R> op, T first, U second) {
        return op.apply(first,second);
    }


    static <T, R> List<R> map(Function<T, R> f, List<T> list) {
        return list == null ? null : cons(apply(f, car(list)), map(f, cdr(list)));
    }

    static <E> List<E> filter(Function<E, Boolean> pred, List<E> list) {
        return isNull(list)?null:apply(pred, car(list)) ? cons(car(list), filter(pred, cdr(list))) : filter(pred, cdr(list));
    }


    static <T,R> R accumulate(BiFunction<R, T, R> op, R initial, List<T> list) {
        return list == null ? initial : accumulate(op, apply(op, initial, car(list)), cdr(list));
    }

    static <T, R> List<R> flatmap(Function<T, List<R>> op, List<T> list) {
        return accumulate(EightQueens::append, null, map(op, list));
    }

    static List<Integer> range(int start,int end){
        return start>end?null:cons(start, range(start + 1, end));
    }


    static <A, B, C, D> TriFunction<A, B, C, D> y(Function<TriFunction<A, B, C, D>, TriFunction<A, B, C, D>> x) {
        RecurFunc<TriFunction<A,B,C,D>> prod = f -> x.apply((a,b,c) -> f.apply(f).apply(a,b,c));
        return prod.apply(prod);
    }

    static int count(List<?> list){
        return isNull(list)? 0:1 + count(cdr(list));
    }


    static boolean isNull(Object o) {
        return o == null;
    }

}



是的,你没有看错,虽然标题是一行Java代码,辅助函数却有这么长。但是如果你仔细看看,这些辅助函数并不是为写八皇后特化的,或者说把复杂的东西包起来。

具体这行代码是什么意思,可以看看[用Stream API写八皇后](用Stream API写八皇后) ,其实是一个东西。

相关文章

  • 一行Java代码八皇后

    一行代码八皇后 其实是标题党,准确的说是在一定条件只需要一行。 先上代码: 当然他是不能独立运行的,完整代码:ht...

  • 八皇后问题之java实现

    1.八皇后指在八行八列的的矩阵上放八个皇后,任意两个皇后不在同一行或同一列,或同一斜线上。 2.代码实现

  • Gym - 100947B 八皇后变形题

    题意:就是八皇后问题的变形,给你八个皇后的位置,问是否满足八皇后的摆放.注: 任意皇后可以攻击同一行,同一列,同一...

  • 《Lua程序设计》-2.八皇后问题

    1.解决八皇后问题,必须认识到每一行只能有一个皇后

  • 八皇后问题(N皇后问题)

    八皇后问题是一个经典的递归回溯问题。 描述 八皇后问题是在一个 8*8 的棋盘上放置皇后,要求其放置后满足同一行,...

  • 【洛谷 P1219】八皇后

    八皇后(题目链接) 思路 典型的深搜回溯问题 代码

  • 第二节:Java入门第一行代码

    前言 大家好,我是 Vic,今天给大家带来Java入门第一行代码的概述,希望你们喜欢 第一行代码 学习Java基础...

  • JS回溯算法--八皇后问题

    八皇后问题 在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一...

  • 八皇后问题

    八皇后问题:在8*8的棋盘上放置8个皇后,保证任意两个皇后之间不能相互攻击。(即没有两个皇后是在同一行、同一类、或...

  • 八皇后(代码有bug)

网友评论

      本文标题:一行Java代码八皇后

      本文链接:https://www.haomeiwen.com/subject/npxnbttx.html