在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