在Clojure(/ Java)中代表棋盘的一些可能的方式是什么?我应该如何在clojure中代表象棋棋盘?
http://pages.cs.wisc.edu/~psilord/blog/data/chess-pages/rep.html
我需要能够访问各个位,并执行按位运算。
我想过使用java.lang.Long,但由于标牌,这导致1x10^63的问题。我也不确定我将如何访问特定索引处的位?
我也看了一下BitSet,但是我需要一个固定的长度。
在Clojure(/ Java)中代表棋盘的一些可能的方式是什么?我应该如何在clojure中代表象棋棋盘?
http://pages.cs.wisc.edu/~psilord/blog/data/chess-pages/rep.html
我需要能够访问各个位,并执行按位运算。
我想过使用java.lang.Long,但由于标牌,这导致1x10^63的问题。我也不确定我将如何访问特定索引处的位?
我也看了一下BitSet,但是我需要一个固定的长度。
没有理由不能使用直长。正如您所指出的那样,问题在于Java的(因此clojure的)long是有符号的,只允许正数的63位。
默认情况下,Java允许算术溢出而没有错误。默认情况下,Clojure不允许算术溢出而没有错误(参见*unchecked-math*标志)。它增加了对算术运算和强制转换的额外检查,因此,例如,(byte 128)
将导致异常。由于Clojure的V1.3.0有像(unchecked-byte)
这相当于Java功能的功能....
(unchecked-byte 128)
;=> -128 ; 2s-complement of 10000000
(unchecked-byte 2r10000001)
;=> -127 ; 2s-complement of 10000001
有可用unchecked-*
操作(see clojuredocs)的整个筏。
如果你使用直线长和unchecked-*
的操作,你大部分都在那里,然后你可以使用bit-*
操作来旋转/检查位。
最后储存您的棋盘中的原子是有道理的,然后你用(swap! chessboard fn args)
(更新15/02/13略有更地道掉!呼叫)更新
例如
(inc Long/MAX_VALUE) ; java.lang.ArithmeticException
(unchecked-inc Long/MAX_VALUE) ; wraps.
-9223372036854775808
(def chessboard (atom 0))
@chessboard
;=> 0
(bit-test @chessboard 1)
;=> false
(swap! chessboard bit-flip 1)
;=> 2
(bit-test @chessboard 1)
;=> true
@chessboard
;=> 2
(reset! chessboard 0)
;=> 0
(swap! chessboard bit-flip 63)
;=> -9223372036854775808
(bit-test @chessboard 63)
;=> true
=> (def chessboard (byte-array 8))
#'user/chessboard
=> (vec chessboard)
[0 0 0 0 0 0 0 0]
=> (for [row (range 8)] (aset-byte chessboard row (rand-int 8)))
(3 0 6 6 2 3 6 7)
=> (bigint chessboard)
216179404987106823N
=> (defn bigint-to-array
[bi]
(.toByteArray (biginteger bi)))
=> (vec (bigint-to-array 216179404987106823N))
[3 0 6 6 2 3 6 7]
Clojure支持您需要的大多数功能。像所有clojure数字一样,clojure.lang.BigInt支持二进制操作(比特等)。在字节数组上,您可以使用java.util.Arrays(搜索,填充,排序)中的所有方法。
注意bigint fn强制clojure.lang.BigInt,biginteger fn强制java.math.BigInteger。如果你想使用java.math.BigInteger的方法,你需要通过biginteger强制你的bigint或者字节数组。
谢谢,不知道这将如何比较性能方面与使用long?我想它会变慢。 – DanS 2012-04-27 14:26:49
Clojure bigints不支持位操作。 user =>(bit-and(bigint 5)(bigint 3)) IllegalArgumentException位操作不支持:类clojure.lang.BigInt clojure.lang.Numbers.bitOpsCast(Numbers.java:1008) – RedDeckWins 2013-08-13 17:30:28
'最好的方式' - 在http://codereview.stackexchange.com/上显示您的代码; '我应该如何' - 不具有建设性。你有什么代码?你有什么要求?你卡在哪里? – sehe 2012-04-27 08:27:27
@sehe我试过使用java.lang.Long但遇到了parseLong()和“10000 ... x63” - 1x10^63的问题)另外,我不确定是否可以访问特定位指数? 我要求合理化的建议和想法,不一定是绝对的。 – DanS 2012-04-27 09:10:58
你应该在你的问题中编辑这些细节。 – sehe 2012-04-27 09:12:18