meteor.scm 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. #| The Computer Language Benchmarks Game
  2. http://shootout.alioth.debian.org/
  3. Contributed by Jamison Hope. Based on the "Java 6 steady state #2"
  4. version by Amir K and Isaac Gouy.
  5. |#
  6. (module-static #t)
  7. (define-alias SB java.lang.StringBuilder)
  8. ;; Some helpful macros
  9. (define-syntax while
  10. (syntax-rules ()
  11. ((_ pred e ...)
  12. (let loop ()
  13. (when pred
  14. e ...
  15. (loop))))))
  16. (define-syntax ++!
  17. (syntax-rules ()
  18. ((_ var) (++! var 1))
  19. ((_ var amt)
  20. (begin
  21. (set! var (+ var amt)) var))))
  22. (define-syntax !++
  23. (syntax-rules ()
  24. ((_ var) (!++ var 1))
  25. ((_ var amt)
  26. (let ((ret var)) (set! var (+ var amt)) ret))))
  27. (define-syntax --!
  28. (syntax-rules ()
  29. ((_ var) (--! var 1))
  30. ((_ var amt)
  31. (begin
  32. (set! var (- var amt)) var))))
  33. (define-syntax !--
  34. (syntax-rules ()
  35. ((_ var) (!-- var 1))
  36. ((_ var amt)
  37. (let ((ret var)) (set! var (- var amt)) ret))))
  38. (define-syntax set-<<!
  39. (syntax-rules ()
  40. ((_ var amt)
  41. (set! var (bitwise-arithmetic-shift-left var amt)))))
  42. (define-syntax set->>!
  43. (syntax-rules ()
  44. ((_ var amt)
  45. (set! var (bitwise-arithmetic-shift-right var amt)))))
  46. (define-syntax set-ior!
  47. (syntax-rules ()
  48. ((_ var e ...)
  49. (set! var (bitwise-ior var e ...)))))
  50. (define-syntax set-xor!
  51. (syntax-rules ()
  52. ((_ var e ...)
  53. (set! var (bitwise-xor var e ...)))))
  54. (define-syntax set-and!
  55. (syntax-rules ()
  56. ((_ var e ...)
  57. (set! var (bitwise-and var e ...)))))
  58. ;; Constants
  59. (define-constant X :: int 0)
  60. (define-constant Y :: int 1)
  61. (define-constant N-DIM :: int 2)
  62. (define-constant EVEN :: int 0)
  63. (define-constant ODD :: int 1)
  64. (define-constant N-PARITY :: int 2)
  65. (define-constant GOOD :: int 0)
  66. (define-constant BAD :: int 1)
  67. (define-constant ALWAYS-BAD :: int 2)
  68. (define-constant OPEN :: int 0)
  69. (define-constant CLOSED :: int 1)
  70. (define-constant N-FIXED :: int 2)
  71. (define-constant MAX-ISLAND-OFFSET :: int 1024)
  72. (define-constant N-COL :: int 5)
  73. (define-constant N-ROW :: int 10)
  74. (define-constant N-CELL :: int (* N-COL N-ROW))
  75. (define-constant N-PIECE-TYPE :: int 10)
  76. (define-constant N-ORIENT :: int 12)
  77. ;; Board constants
  78. (define-constant TOP-ROW :: int (- (bitwise-arithmetic-shift-left 1 N-COL) 1))
  79. (define-constant L-EDGE-MASK :: int
  80. (bitwise-ior (bitwise-arithmetic-shift-left 1 0)
  81. (bitwise-arithmetic-shift-left 1 5)
  82. (bitwise-arithmetic-shift-left 1 10)
  83. (bitwise-arithmetic-shift-left 1 15)
  84. (bitwise-arithmetic-shift-left 1 20)
  85. (bitwise-arithmetic-shift-left 1 25)
  86. (bitwise-arithmetic-shift-left 1 30)))
  87. (define-constant R-EDGE-MASK :: int
  88. (bitwise-arithmetic-shift-left L-EDGE-MASK 4))
  89. (define-constant ROW-0-MASK :: int
  90. (bitwise-ior TOP-ROW
  91. (bitwise-arithmetic-shift-left TOP-ROW 10)
  92. (bitwise-arithmetic-shift-left TOP-ROW 20)
  93. (bitwise-arithmetic-shift-left TOP-ROW 30)))
  94. (define-constant ROW-1-MASK :: int
  95. (bitwise-arithmetic-shift-left ROW-0-MASK 5))
  96. (define-constant BOARD-MASK :: int
  97. (- (bitwise-arithmetic-shift-left 1 30) 1))
  98. ;; Piece constants
  99. (define-constant N-ELEM :: int 5)
  100. (define-constant ALL-PIECE-MASK :: int
  101. (- (bitwise-arithmetic-shift-left 1 N-PIECE-TYPE) 1))
  102. (define-constant SKIP-PIECE :: int 5)
  103. (define-constant BaseVecs :: int[]
  104. (int[] #x10f #x0cb #x1087 #x427 #x465 #x0c7 #x8423 #x0a7 #x187 #x08f))
  105. ;; (do-decrementing COUNTER START . BODY)
  106. ;; Do BODY with COUNTER set top START-1 down to 0.
  107. ;; Equivalent to Java's: for (int COUNTER=START; --COUNTER>=0; ) { BODY }
  108. (define-syntax do-decrementing
  109. (syntax-rules ()
  110. ((_ counter start . body)
  111. (let ((counter ::int start))
  112. (let loop ()
  113. (set! counter (- counter 1))
  114. (if (>= counter 0)
  115. (begin
  116. (begin . body)
  117. (loop))))))))
  118. (define s-base-pieces ::Piece[] (Piece[] length: (* N-PIECE-TYPE N-ORIENT)))
  119. (do-decrementing i (* N-PIECE-TYPE N-ORIENT)
  120. (set! (s-base-pieces i) (Piece)))
  121. (define-syntax s-base-piece
  122. (syntax-rules ()
  123. ((_ ipiece iorient) (s-base-pieces (+ (* N-ORIENT ipiece) iorient)))))
  124. ;; Global variables
  125. (define g-island-info :: IslandInfo[]
  126. (IslandInfo[] length: MAX-ISLAND-OFFSET))
  127. (define g-n-island-info :: int 0)
  128. (define g-ok-pieces :: OkPieces[] (OkPieces[] length: N-CELL))
  129. (define-constant g-first-region :: int[]
  130. (int[]
  131. #x00 #x01 #x02 #x03 #x04 #x01 #x06 #x07
  132. #x08 #x01 #x02 #x03 #x0c #x01 #x0e #x0f
  133. #x10 #x01 #x02 #x03 #x04 #x01 #x06 #x07
  134. #x18 #x01 #x02 #x03 #x1c #x01 #x1e #x1f))
  135. (define-constant g-flip :: int[]
  136. (int[]
  137. #x00 #x10 #x08 #x18 #x04 #x14 #x0c #x1c
  138. #x02 #x12 #x0a #x1a #x06 #x16 #x0e #x1e
  139. #x01 #x11 #x09 #x19 #x05 #x15 #x0d #x1d
  140. #x03 #x13 #x0b #x1b #x07 #x17 #x0f #x1f))
  141. (define-constant s-first-one :: int[]
  142. (int[]
  143. 0 0 1 0 2 0 1 0
  144. 3 0 1 0 2 0 1 0
  145. 4 0 1 0 2 0 1 0
  146. 3 0 1 0 2 0 1 0))
  147. (define-syntax get-mask
  148. (syntax-rules ()
  149. ((_ i-pos)
  150. (bitwise-arithmetic-shift-left 1 i-pos))))
  151. (define-syntax my-floor
  152. (syntax-rules ()
  153. ((_ top bot)
  154. (let ((to-zero :: int (quotient top bot)))
  155. (if (and (not (= top (* to-zero bot)))
  156. (not (eq? (< top 0) (<= bot 0))))
  157. (- to-zero 1)
  158. to-zero)))))
  159. (define (get-first-one (v :: int)) :: int
  160. (if (= 0 v) 0
  161. (let ((start-pos :: int 0)
  162. (i-pos :: int 0)
  163. (mask :: int #xff))
  164. (while (= 0 (bitwise-and mask v))
  165. (set-<<! mask 8)
  166. (++! i-pos 8))
  167. (let* ((result :: int
  168. (bitwise-arithmetic-shift-right
  169. (bitwise-and mask v) i-pos))
  170. (result-low :: int (bitwise-and result #x0f)))
  171. (if (= 0 result-low)
  172. (+ i-pos 4 (s-first-one (bitwise-arithmetic-shift-right
  173. result 4)))
  174. (+ i-pos (s-first-one result-low)))))))
  175. ;; (define count-ones bitwise-bit-count)
  176. (define (count-ones (v :: int)) :: int
  177. (let ((n :: int 0))
  178. (while (not (= 0 v))
  179. (++! n)
  180. (set-and! v (- v 1)))
  181. n))
  182. (define (flip-two-rows (bits :: int)) :: int
  183. (let ((flipped :: int
  184. (bitwise-arithmetic-shift-left
  185. (g-flip (bitwise-arithmetic-shift-right bits N-COL))
  186. N-COL)))
  187. (bitwise-ior flipped (g-flip (bitwise-and bits TOP-ROW)))))
  188. (define (mark-bad (info :: IslandInfo)
  189. (mask :: int)
  190. (eo :: int)
  191. (always :: boolean))
  192. :: void
  193. (set-ior! (info:has-bad (+ (* eo N-PARITY) OPEN)) mask)
  194. (set-ior! (info:has-bad (+ (* eo N-PARITY) CLOSED)) mask)
  195. (when always
  196. (set-ior! (info:always-bad eo) mask)))
  197. (define (init-globals) :: void
  198. (do ((i :: int 0 (+ i 1)))
  199. ((= i MAX-ISLAND-OFFSET))
  200. (set! (g-island-info i) (IslandInfo)))
  201. (do-decrementing yx N-CELL
  202. (set! (g-ok-pieces yx) (OkPieces))))
  203. ;; OkPieces
  204. (define-simple-class OkPieces ()
  205. (n-pieces :: byte[] init: (byte[] length: N-PIECE-TYPE))
  206. (piece-vec :: int[] init: (int[] length: (* N-PIECE-TYPE N-ORIENT))))
  207. ;; IslandInfo
  208. (define-simple-class IslandInfo ()
  209. (has-bad :: int[] init: (int[] length: (* N-FIXED N-PARITY)))
  210. (is-known :: int[] init: (int[] length: (* N-FIXED N-PARITY)))
  211. (always-bad :: int[] init: (int[] length: N-PARITY)))
  212. ;; SPiece
  213. (define-simple-class SPiece ()
  214. (vec :: int)
  215. (i-piece :: short)
  216. (row :: short)
  217. ((*init*)
  218. (set! vec 0)
  219. (set! i-piece 0)
  220. (set! row 0))
  221. ((*init* (other :: SPiece))
  222. (set! vec other:vec)
  223. (set! i-piece other:i-piece)
  224. (set! row other:row)))
  225. (define-syntax m-cell
  226. (syntax-rules ()
  227. ((_ obj r c) (obj:m-cells (get-index c r)))))
  228. (define-syntax p-cell
  229. (syntax-rules ()
  230. ((_ pts x y) (pts (+ (* N-ELEM y) x)))))
  231. ;; Soln
  232. (define-simple-class Soln ()
  233. (NO-PIECE :: int allocation: 'static init: -1)
  234. (m-pieces :: SPiece[] (SPiece[] length: N-PIECE-TYPE))
  235. (m-n-piece :: int)
  236. (m-cells :: byte[] init: (byte[] length: N-CELL))
  237. (m-synched :: boolean)
  238. ((is-empty) :: boolean (= 0 m-n-piece))
  239. ((pop-piece) :: void
  240. (--! m-n-piece)
  241. (set! m-synched #f))
  242. ((push-piece (vec :: int) (i-piece :: int) (row :: int)) :: void
  243. (let ((p :: SPiece (m-pieces (!++ m-n-piece))))
  244. (set! p:vec vec)
  245. (set! p:i-piece i-piece)
  246. (set! p:row row)))
  247. ((*init*)
  248. (set! m-synched #f)
  249. (set! m-n-piece 0)
  250. (*:init (this)))
  251. ((init)
  252. (do ((i :: int 0 (+ i 1)))
  253. ((= i N-PIECE-TYPE))
  254. (set! (m-pieces i) (SPiece))))
  255. ((*init* (fill-val :: int))
  256. (*:init (this))
  257. (set! m-n-piece 0)
  258. (*:fill (this) fill-val))
  259. ((clone2) :: Soln
  260. (let ((s :: Soln (Soln)))
  261. (do ((i :: int 0 (+ i 1)))
  262. ((= i m-pieces:length))
  263. (set! (s:m-pieces i) (SPiece (m-pieces i))))
  264. (set! s:m-n-piece m-n-piece)
  265. (do-decrementing ij N-CELL
  266. (set! (s:m-cells ij) (m-cells ij)))
  267. (set! s:m-synched m-synched)
  268. s))
  269. ((fill (val :: int)) :: void
  270. (set! m-synched #f)
  271. (do-decrementing ij N-CELL
  272. (set! (m-cells ij) val)))
  273. ((to-string) :: String
  274. (let ((result :: SB (SB)))
  275. (do ((y :: int 0 (+ y 1)))
  276. ((= y N-ROW) (result:to-string))
  277. (do ((x :: int 0 (+ x 1)))
  278. ((= x N-COL) (result:append
  279. (constant-fold
  280. list->string '(#\newline))))
  281. (let ((val :: int (m-cell (this) y x)))
  282. (result:append val))
  283. (result:append " "))
  284. (when (even? y) (result:append " ")))))
  285. ((set-cells) :: void
  286. (unless m-synched
  287. (do ((i-piece :: int 0 (+ i-piece 1)))
  288. ((= i-piece m-n-piece))
  289. (let* ((p :: SPiece (m-pieces i-piece))
  290. (vec :: int p:vec)
  291. (p-id :: byte p:i-piece)
  292. (row-offset :: int p:row)
  293. (n-new-cells :: int 0))
  294. (call-with-current-continuation
  295. (lambda (break)
  296. (do ((y :: int row-offset (+ y 1)))
  297. ((= y N-ROW))
  298. (do ((x :: int 0 (+ x 1)))
  299. ((= x N-COL))
  300. (when (not (= 0 (bitwise-and vec 1)))
  301. (set! (m-cell (this) y x) p-id)
  302. (++! n-new-cells))
  303. (set->>! vec 1))
  304. (when (= n-new-cells N-ELEM)
  305. (break)))))))
  306. (set! m-synched #t)))
  307. ((less-than (r :: Soln)) :: boolean
  308. (cond ((not (= (m-pieces 0):i-piece (r:m-pieces 0):i-piece))
  309. (< (m-pieces 0):i-piece (r:m-pieces 0):i-piece))
  310. (else
  311. (*:set-cells (this))
  312. (*:set-cells r)
  313. (call-with-current-continuation
  314. (lambda (return)
  315. (do ((y :: int 0 (+ y 1)))
  316. ((= y N-ROW) (return #f))
  317. (do ((x :: int 0 (+ x 1)))
  318. ((= x N-COL))
  319. (let ((lval :: int (m-cell (this) y x))
  320. (rval :: int (m-cell r y x)))
  321. (when (not (= lval rval))
  322. (return (< lval rval)))))))))))
  323. ((spin (spun :: Soln)) :: void
  324. (*:set-cells (this))
  325. (do-decrementing yx N-CELL
  326. (set! (spun:m-cells yx)
  327. (m-cells (- N-CELL 1 yx))))
  328. (set! (spun:m-pieces 0):i-piece (m-pieces (- N-PIECE-TYPE 1)):i-piece)
  329. (set! spun:m-synched #t)))
  330. (define-syntax get-index
  331. (syntax-rules ()
  332. ((_ x y)
  333. (+ (* y N-COL) x))))
  334. ;; Board
  335. (define-simple-class Board ()
  336. (m-cur-soln :: Soln init: (Soln Soln:NO-PIECE))
  337. (m-min-soln :: Soln init: (Soln N-PIECE-TYPE))
  338. (m-max-soln :: Soln init: (Soln Soln:NO-PIECE))
  339. (m-n-soln :: int init: 0)
  340. ((bad-region (to-fill ::int) (r-new ::int)) ::int
  341. allocation: 'static
  342. ;; grow empty region until it doesn't change anymore
  343. (let loop ((r-new :: int r-new))
  344. (let ((region :: int r-new))
  345. ;; simple grow up/down
  346. (set-ior! r-new (bitwise-arithmetic-shift-right region N-COL))
  347. (set-ior! r-new (bitwise-arithmetic-shift-left region N-COL))
  348. ;; grow right/left
  349. (set-ior! r-new (bitwise-arithmetic-shift-right
  350. (bitwise-and region (bitwise-not L-EDGE-MASK)) 1))
  351. (set-ior! r-new (bitwise-arithmetic-shift-left
  352. (bitwise-and region (bitwise-not R-EDGE-MASK)) 1))
  353. ;; tricky growth
  354. (let ((even-region
  355. :: int
  356. (bitwise-and
  357. region (bitwise-and ROW-0-MASK (bitwise-not L-EDGE-MASK)))))
  358. (set-ior! r-new
  359. (bitwise-arithmetic-shift-right even-region (+ N-COL 1)))
  360. (set-ior! r-new
  361. (bitwise-arithmetic-shift-left even-region (- N-COL 1))))
  362. (let ((odd-region
  363. :: int
  364. (bitwise-and
  365. region (bitwise-and ROW-1-MASK (bitwise-not R-EDGE-MASK)))))
  366. (set-ior! r-new
  367. (bitwise-arithmetic-shift-right odd-region (- N-COL 1)))
  368. (set-ior! r-new
  369. (bitwise-arithmetic-shift-left odd-region (+ N-COL 1))))
  370. ;; clamp against existing pieces
  371. (set-and! r-new to-fill)
  372. (cond ((and (not (= r-new to-fill))
  373. (not (= r-new region)))
  374. (loop r-new))
  375. (else
  376. (bitwise-xor to-fill r-new))))))
  377. ((has-bad-islands (board-vec :: int) (row :: int)) :: int
  378. allocation: 'static
  379. (while (= TOP-ROW (bitwise-and board-vec TOP-ROW))
  380. (set->>! board-vec N-COL)
  381. (!++ row))
  382. (let* ((i-info
  383. :: int
  384. (bitwise-and
  385. board-vec
  386. (- (bitwise-arithmetic-shift-left 1 (* 2 N-COL)) 1)))
  387. (info :: IslandInfo (g-island-info i-info))
  388. (last-row
  389. :: int
  390. (bitwise-and
  391. (bitwise-arithmetic-shift-right board-vec (* 2 N-COL))
  392. TOP-ROW))
  393. (mask :: int (get-mask last-row))
  394. (is-odd :: int (bitwise-and row 1))
  395. (is-closed :: int (if (> row 6) 1 0))
  396. (odd-closed-index (+ (* is-odd N-PARITY) is-closed)))
  397. (cond ((not (= 0 (bitwise-and mask (info:always-bad is-odd))))
  398. BAD)
  399. ((not (= 0 (bitwise-and board-vec
  400. (bitwise-arithmetic-shift-left
  401. TOP-ROW (* N-COL 3)))))
  402. (Board:calc-bad-islands board-vec row))
  403. ((not (= 0 (bitwise-and mask
  404. (info:is-known odd-closed-index))))
  405. (bitwise-and mask (info:has-bad odd-closed-index)))
  406. ((= 0 board-vec) GOOD)
  407. (else
  408. (let ((has-bad :: int (Board:calc-bad-islands board-vec row)))
  409. (set-ior! (info:is-known odd-closed-index) mask)
  410. (when (not (= 0 has-bad))
  411. (set-ior! (info:has-bad odd-closed-index) mask))
  412. has-bad)))))
  413. ((calc-bad-islands (board-vec :: int) (row :: int)) :: int
  414. allocation: 'static
  415. (let ((to-fill :: int (bitwise-not board-vec))
  416. (board-mask :: int BOARD-MASK)
  417. (bottom :: int (bitwise-arithmetic-shift-left TOP-ROW (* 5 N-COL)))
  418. (start-region :: int 0))
  419. (when (not (= 0 (bitwise-and row 1)))
  420. (!-- row)
  421. (set-<<! to-fill N-COL))
  422. (when (> row 4)
  423. (let ((board-mask-shift :: int (* (- row 4) N-COL)))
  424. (set->>! board-mask board-mask-shift)))
  425. (set-and! to-fill board-mask)
  426. (let ((filled :: boolean (= bottom (bitwise-and bottom to-fill))))
  427. (while (= bottom (bitwise-and bottom to-fill))
  428. (set-xor! to-fill bottom)
  429. (set->>! bottom N-COL))
  430. (if (or filled (< row 4))
  431. (set! start-region (bitwise-and bottom to-fill))
  432. (begin
  433. (set! start-region
  434. (g-first-region (bitwise-and to-fill TOP-ROW)))
  435. (when (= 0 start-region)
  436. (set! start-region
  437. (bitwise-and (bitwise-arithmetic-shift-right
  438. to-fill N-COL) TOP-ROW))
  439. (set! start-region
  440. (g-first-region start-region))
  441. (set-<<! start-region N-COL))
  442. (set-ior! start-region
  443. (bitwise-and
  444. (bitwise-arithmetic-shift-left start-region N-COL)
  445. to-fill))))
  446. (call-with-current-continuation
  447. (lambda (return)
  448. (while (not (= 0 to-fill))
  449. (set! to-fill (bad-region to-fill start-region))
  450. (when (> (remainder (count-ones to-fill) N-ELEM) 0)
  451. (return (if (not (= 0 to-fill)) ALWAYS-BAD BAD)))
  452. (set! start-region (get-mask (get-first-one to-fill))))
  453. (return GOOD))))))
  454. ((calc-always-bad) :: void allocation: 'static
  455. (do ((i-word :: int 1 (+ i-word 1)))
  456. ((= i-word MAX-ISLAND-OFFSET))
  457. (let ((isle-info :: IslandInfo (g-island-info i-word))
  458. (flipped :: IslandInfo (g-island-info (flip-two-rows i-word))))
  459. (let loop ((i :: int 0) (mask :: int 1))
  460. (cond ((= i 32))
  461. ((not (= 0 (bitwise-and mask (isle-info:is-known OPEN))))
  462. (loop (+ i 1) (bitwise-arithmetic-shift-left mask 1)))
  463. (else
  464. (let* ((board-vec
  465. :: int
  466. (bitwise-ior
  467. (bitwise-arithmetic-shift-left i (* 2 N-COL))
  468. i-word))
  469. (has-bad :: int
  470. (Board:calc-bad-islands board-vec 0)))
  471. (when (not (= has-bad GOOD))
  472. (let ((always :: boolean (= has-bad
  473. ALWAYS-BAD)))
  474. (mark-bad isle-info mask EVEN always)
  475. (let ((flip-mask :: int (get-mask (g-flip i))))
  476. (mark-bad flipped flip-mask ODD always))))
  477. (loop (+ i 1) (bitwise-arithmetic-shift-left mask 1))))))
  478. (set! (flipped:is-known (+ N-PARITY OPEN)) -1)
  479. (set! (isle-info:is-known OPEN) -1))))
  480. ((has-bad-islands-single (board-vec :: int) (row :: int)) :: boolean
  481. allocation: 'static
  482. (let ((to-fill :: int (bitwise-not board-vec))
  483. (is-odd :: boolean (not (= 0 (bitwise-and row 1))))
  484. (start-region :: int TOP-ROW)
  485. (last-row :: int (bitwise-arithmetic-shift-left
  486. TOP-ROW (* 5 N-COL)))
  487. (board-mask :: int BOARD-MASK))
  488. (when is-odd
  489. (!-- row)
  490. (set-<<! to-fill N-COL)
  491. (set-ior! to-fill TOP-ROW))
  492. (cond ((>= row 4)
  493. (set->>! board-mask (* (- row 4) N-COL)))
  494. ((or is-odd (= row 0))
  495. (set! start-region last-row)))
  496. (set-and! to-fill board-mask)
  497. (set-and! start-region to-fill)
  498. (call-with-current-continuation
  499. (lambda (return)
  500. (while (not (= 0 to-fill))
  501. (set! to-fill (bad-region to-fill start-region))
  502. (when (> (remainder (count-ones to-fill) N-ELEM) 0)
  503. (return #t))
  504. (set! start-region
  505. (get-mask (get-first-one to-fill))))
  506. (return #f)))))
  507. ((gen-all-solutions (board-vec :: int)
  508. (placed-pieces :: int)
  509. (row :: int))
  510. :: void
  511. (while (= TOP-ROW (bitwise-and board-vec TOP-ROW))
  512. (set->>! board-vec N-COL)
  513. (!++ row))
  514. (let* ((i-next-fill :: int (s-first-one
  515. (bitwise-and TOP-ROW (bitwise-not board-vec))))
  516. (allowed :: OkPieces (g-ok-pieces (+ (* row N-COL) i-next-fill)))
  517. (i-piece :: int (get-first-one (bitwise-not placed-pieces)))
  518. (piece-mask :: int (get-mask i-piece)))
  519. (do ((i-piece :: int i-piece (+ i-piece 1))
  520. (piece-mask :: int piece-mask (bitwise-arithmetic-shift-left
  521. piece-mask 1)))
  522. ((= i-piece N-PIECE-TYPE))
  523. (call-with-current-continuation
  524. (lambda (continue-outer)
  525. (when (not (= 0 (bitwise-and piece-mask placed-pieces)))
  526. (continue-outer))
  527. (set-ior! placed-pieces piece-mask)
  528. (do ((i-orient :: int 0 (+ i-orient 1)))
  529. ((= i-orient (allowed:n-pieces i-piece)))
  530. (call-with-current-continuation
  531. (lambda (continue-inner)
  532. (let ((piece-vec :: int (allowed:piece-vec (+ (* i-piece N-ORIENT) i-orient))))
  533. (when (not (= 0 (bitwise-and piece-vec board-vec)))
  534. (continue-inner))
  535. (set-ior! board-vec piece-vec)
  536. (when (not (= 0 (Board:has-bad-islands board-vec row)))
  537. (set-xor! board-vec piece-vec)
  538. (continue-inner))
  539. (m-cur-soln:push-piece piece-vec i-piece row)
  540. ;; recur or record solution
  541. (if (< placed-pieces ALL-PIECE-MASK)
  542. (*:gen-all-solutions (this) board-vec
  543. placed-pieces row)
  544. (*:record-solution (this) m-cur-soln))
  545. (set-xor! board-vec piece-vec)
  546. (m-cur-soln:pop-piece)))))
  547. (set-xor! placed-pieces piece-mask))))))
  548. ((record-solution (s :: Soln)) :: void
  549. (!++ m-n-soln 2)
  550. (if (m-min-soln:is-empty)
  551. (begin (set! m-min-soln (s:clone2))
  552. (set! m-max-soln m-min-soln))
  553. (begin
  554. (cond ((s:less-than m-min-soln)
  555. (set! m-min-soln (s:clone2)))
  556. ((m-max-soln:less-than s)
  557. (set! m-max-soln (s:clone2))))
  558. (let ((spun :: Soln (Soln)))
  559. (s:spin spun)
  560. (cond ((spun:less-than m-min-soln)
  561. (set! m-min-soln spun))
  562. ((m-max-soln:less-than spun)
  563. (set! m-max-soln spun))))))))
  564. ;; Instance
  565. (define-simple-class Instance ()
  566. (m-allowed :: long)
  567. (m-vec :: int)
  568. (m-offset :: int))
  569. ;; Piece
  570. (define-simple-class Piece ()
  571. (m-instance :: Instance[] init: (Instance[] length: N-PARITY))
  572. (init: (do ((i :: int 0 (+ i 1)))
  573. ((= i N-PARITY))
  574. (set! (m-instance i) (Instance))))
  575. ((set-coord-list (vec :: int) (pts :: int[])) :: void
  576. allocation: 'static
  577. (let ((i-pt :: int 0)
  578. (mask :: int 1))
  579. (do ((y :: int 0 (+ y 1)))
  580. ((= y N-ROW))
  581. (do ((x :: int 0 (+ x 1)))
  582. ((= x N-COL))
  583. (when (not (= 0 (bitwise-and mask vec)))
  584. (set! (p-cell pts i-pt X) x)
  585. (set! (p-cell pts i-pt Y) y)
  586. (!++ i-pt))
  587. (set-<<! mask 1)))))
  588. ((to-bit-vector (pts :: int[])) :: int allocation: 'static
  589. (let ((result :: int 0))
  590. (do ((i-pt :: int 0 (+ i-pt 1)))
  591. ((= i-pt N-ELEM) result)
  592. (set-ior! result
  593. (bitwise-arithmetic-shift-left
  594. 1 (get-index (p-cell pts i-pt X) (p-cell pts i-pt Y)))))))
  595. ((shift-up-lines (pts :: int[]) (shift :: int)) :: void
  596. allocation: 'static
  597. (do ((i-pt :: int 0 (+ i-pt 1)))
  598. ((= i-pt N-ELEM))
  599. (when (not (= 0 (bitwise-and (p-cell pts i-pt Y) shift #x1)))
  600. (++! (p-cell pts i-pt X)))
  601. (--! (p-cell pts i-pt Y) shift)))
  602. ((shift-to-x0 (pts :: int[])
  603. (instance :: Instance)
  604. (offset-row :: int))
  605. :: int allocation: 'static
  606. (let* ((x-min :: int (p-cell pts 0 X))
  607. (x-max :: int x-min))
  608. (do ((i-pt :: int 1 (+ i-pt 1)))
  609. ((= i-pt N-ELEM))
  610. (let ((x :: int (p-cell pts i-pt X)))
  611. (cond ((< x x-min) (set! x-min x))
  612. ((> x x-max) (set! x-max x)))))
  613. (let ((offset :: int N-ELEM))
  614. (do ((i-pt :: int 0 (+ i-pt 1)))
  615. ((= i-pt N-ELEM))
  616. (--! (p-cell pts i-pt X) x-min)
  617. (when (and (= (p-cell pts i-pt Y) offset-row)
  618. (< (p-cell pts i-pt X) offset))
  619. (set! offset (p-cell pts i-pt X))))
  620. (set! instance:m-offset offset)
  621. (set! instance:m-vec (Piece:to-bit-vector pts))
  622. (- x-max x-min))))
  623. ((set-ok-pos (is-odd :: int) (w :: int) (h :: int)) :: void
  624. (let ((p :: Instance (m-instance is-odd))
  625. (pos-mask :: long (bitwise-arithmetic-shift-left
  626. 1 (* is-odd N-COL))))
  627. (set! p:m-allowed (as long 0))
  628. (do ((y :: int is-odd (+ y 2))
  629. (pos-mask :: long pos-mask (bitwise-arithmetic-shift-left
  630. pos-mask N-COL)))
  631. ((>= y (- N-ROW h)))
  632. (when (not (= 0 p:m-offset))
  633. (set-<<! pos-mask p:m-offset))
  634. (do ((x-pos :: int 0 (+ x-pos 1)))
  635. ((= x-pos (- N-COL p:m-offset)))
  636. (when (< x-pos (- N-COL w))
  637. (let ((piece-vec :: int (bitwise-arithmetic-shift-left
  638. p:m-vec x-pos)))
  639. (unless (Board:has-bad-islands-single piece-vec y)
  640. (set-ior! p:m-allowed pos-mask))))
  641. (set-<<! pos-mask 1)))))
  642. ((gen-orientation (vec :: int) (i-orient :: int) (target :: Piece))
  643. :: void allocation: 'static
  644. (let ((pts :: int[] (int[] length: (* N-ELEM N-DIM))))
  645. (Piece:set-coord-list vec pts)
  646. (let* ((rot :: int (remainder i-orient 6))
  647. (flip :: boolean (>= i-orient 6)))
  648. (when flip
  649. (do-decrementing i-pt N-ELEM
  650. (set! (p-cell pts i-pt Y) (- (p-cell pts i-pt Y)))))
  651. (while (not (= 0 (!-- rot)))
  652. (do ((i-pt :: int 0 (+ i-pt 1)))
  653. ((= i-pt N-ELEM))
  654. (let ((x :: int (p-cell pts i-pt X))
  655. (y :: int (p-cell pts i-pt Y)))
  656. (let ((x-new
  657. :: int
  658. (my-floor (+ (* 2 x) (* -3 y) 1) 4))
  659. (y-new
  660. :: int
  661. (my-floor (+ (* 2 x) y 1) 2)))
  662. (set! (p-cell pts i-pt X) x-new)
  663. (set! (p-cell pts i-pt Y) y-new)))))
  664. (let* ((y-min :: int (p-cell pts 0 Y))
  665. (y-max :: int y-min))
  666. (do ((i-pt :: int 1 (+ i-pt 1)))
  667. ((= i-pt N-ELEM))
  668. (let ((y :: int (p-cell pts i-pt Y)))
  669. (cond ((< y y-min) (set! y-min y))
  670. ((> y y-max) (set! y-max y)))))
  671. (let ((h :: int (- y-max y-min))
  672. (even :: Instance (target:m-instance EVEN))
  673. (odd :: Instance (target:m-instance ODD)))
  674. (Piece:shift-up-lines pts y-min)
  675. (let ((w :: int (Piece:shift-to-x0 pts even 0)))
  676. (target:set-ok-pos EVEN w h)
  677. (set->>! even:m-vec even:m-offset)
  678. (Piece:shift-up-lines pts -1)
  679. (set! w (Piece:shift-to-x0 pts odd 1))
  680. (set->>! odd:m-vec N-COL)
  681. (target:set-ok-pos ODD w h)
  682. (set->>! odd:m-vec odd:m-offset)))))))
  683. ((gen-all-orientations) :: void allocation: 'static
  684. (do ((i-piece :: int 0 (+ i-piece 1)))
  685. ((= i-piece N-PIECE-TYPE))
  686. (let ((ref-piece :: int (BaseVecs i-piece)))
  687. (do ((i-orient :: int 0 (+ i-orient 1)))
  688. ((= i-orient N-ORIENT))
  689. (let ((p :: Piece (s-base-piece i-piece i-orient)))
  690. (Piece:gen-orientation ref-piece i-orient p)
  691. (when (and (= i-piece SKIP-PIECE) ;; 5
  692. (not (= 0 (bitwise-and 1 (quotient i-orient 3)))))
  693. (set! (p:m-instance 0):m-allowed 0)
  694. (set! (p:m-instance 1):m-allowed 0))))))
  695. (do ((i-piece :: int 0 (+ i-piece 1)))
  696. ((= i-piece N-PIECE-TYPE))
  697. (do ((i-orient :: int 0 (+ i-orient 1)))
  698. ((= i-orient N-ORIENT))
  699. (let ((mask :: long 1))
  700. (do ((i-row :: int 0 (+ i-row 1)))
  701. ((= i-row N-ROW))
  702. (let ((p :: Instance (Piece:get-piece i-piece i-orient
  703. (bitwise-and i-row 1))))
  704. (do ((i-col :: int 0 (+ i-col 1)))
  705. ((= i-col N-COL))
  706. (when (not (= 0 (bitwise-and p:m-allowed mask)))
  707. (let* ((allowed :: OkPieces
  708. (g-ok-pieces (+ (* i-row N-COL) i-col)))
  709. (val :: int (bitwise-arithmetic-shift-left
  710. p:m-vec i-col))
  711. (i2 :: int (allowed:n-pieces i-piece)))
  712. (set! (allowed:piece-vec (+ (* i-piece N-ORIENT) i2)) val)
  713. (++! (allowed:n-pieces i-piece))))
  714. (set-<<! mask 1))))))))
  715. ((get-piece (i-piece :: int) (i-orient :: int) (i-parity :: int))
  716. :: Instance allocation: 'static
  717. ((s-base-piece i-piece i-orient):m-instance i-parity)))
  718. ;;;; main
  719. (define (program-main (args :: list) (is-warm :: boolean))
  720. (when (> (length args) 2) (exit -1))
  721. (init-globals)
  722. (let ((b :: Board (Board)))
  723. (Piece:gen-all-orientations)
  724. (Board:calc-always-bad)
  725. (b:gen-all-solutions 0 0 0)
  726. (when is-warm
  727. (format #t "~A solutions found~2%" b:m-n-soln)
  728. (format #t "~A~%~A~%" b:m-min-soln b:m-max-soln))))
  729. #|
  730. (do ((i :: int 0 (+ i 1)))
  731. ((= i 65))
  732. (program-main (cdr (command-line)) #f))
  733. |#
  734. (program-main (cdr (command-line)) #t)