Java 我应该如何在clojure中表示棋盘?
在Clojure(/Java)中表示国际象棋棋盘的可能方式有哪些 我需要能够访问单个位,并执行按位操作 我曾想过使用java.lang.Long,但这会导致1x10^63出现问题,原因是标牌。我也不确定如何访问特定索引中的位 我还研究了位集,但我需要一个理想的固定长度Java 我应该如何在clojure中表示棋盘?,java,clojure,chess,Java,Clojure,Chess,在Clojure(/Java)中表示国际象棋棋盘的可能方式有哪些 我需要能够访问单个位,并执行按位操作 我曾想过使用java.lang.Long,但这会导致1x10^63出现问题,原因是标牌。我也不确定如何访问特定索引中的位 我还研究了位集,但我需要一个理想的固定长度 => (def chessboard (byte-array 8)) #'user/chessboard => (vec chessboard) [0 0 0 0 0 0 0 0] => (for [row
=> (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支持二进制操作(位等)。在字节数组中,可以使用(搜索、填充、排序)中的所有方法
注意bigint fn强制为clojure.lang.bigint,而biginger fn强制为java.math.biginger。如果要使用的方法,需要通过biginger强制bigint或byte数组。没有理由不能使用直长字符。正如您所注意到的,问题在于java的(因此clojure的)长是有符号的,只允许63位的正数 默认情况下,Java允许无错误的算术溢出。默认情况下,Clojure不允许无错误的算术溢出(请参见标志)。它在算术运算和强制转换周围添加了额外的检查,因此,例如,
(字节128)
将导致异常。自从clojure v1.3.0以来,就有类似于java功能的(未经检查的字节)
(unchecked-byte 128)
;=> -128 ; 2s-complement of 10000000
(unchecked-byte 2r10000001)
;=> -127 ; 2s-complement of 10000001
有大量的未选中-*
操作可用()
如果您使用的是直长的unchecked-*
操作,那么您就可以使用bit-*
操作来旋转/检查位
最后,将棋盘存储在atom中是有意义的,然后使用(swap!chessboard fn args)
(2013年2月15日更新,略带惯用的swap!调用)
e、 g
“最佳方式”-在屏幕上显示代码;'我该怎么做呢。你有什么密码?你的要求是什么?你卡在哪里了?@sehe我尝试过使用java.lang.Long,但在parseLong()和“10000…x63”-1x10^63)方面遇到了问题。此外,我不确定是否可以访问特定索引处的位?我要求的是合理化的建议和想法,不一定是绝对的。你应该将这些细节编辑到你的问题中。这有助于理解位掩码:
10^63
?这不适合长时间…谢谢,不确定这将如何与使用长时间进行性能比较?我想它会慢一些。Clojure Bigint不支持位操作。user=>(bit and(bigint 5)(bigint 3))IllegalArgumentException位操作不支持:类clojure.lang.bigint clojure.lang.Numbers.bitOpsCast(Numbers.java:1008)Hmmm,这应该在核心中,但出于某种原因我得到:user=>(未检查的字节2r100101)java.lang.Exception:无法解析symbol:unchecked byte在此上下文中(无源文件:4)
我更新了答案,注意到unchecked-*出现在clojure 1.3.0+1中,这是一个很好的答案。我要补充的唯一一点是,您可能希望使用Java原语long数组(因为通常您希望同时操作多个位板)。如果比特板处理将占CPU使用量的90%,那么使用基本阵列可以获得额外的速度和空间效率,这是值得的。
(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