Skip to content

Instantly share code, notes, and snippets.

@tkych
Last active December 29, 2015 12:59
Show Gist options
  • Select an option

  • Save tkych/7674032 to your computer and use it in GitHub Desktop.

Select an option

Save tkych/7674032 to your computer and use it in GitHub Desktop.
ビットボンバーマン ver.2, 鍋谷さんの模範解答を参考にビット演算で書き直しました。
;;;; Last modified: 2013-11-27 20:05:56 tkych
;;====================================================================
;; Bit Bomberman ver.2
;;====================================================================
;; - [第8回オフラインリアルタイムどう書くの問題](http://qiita.com/Nabetani/items/709d61dff282cff7a890)
;; - [ビットボンバーマン 〜 横へな 2013.3.1](http://nabetani.sakura.ne.jp/hena/ord8biboma/)
;; - [鍋谷さんの模範解答: 第8回オフラインリアルタイムどう書く。ruby による実装例。](http://qiita.com/Nabetani/items/0a9fbd1d33ccfd533dc6)
;;--------------------------------------------------------------------
(in-package :cl-user)
(defpackage :bit-bomberman (:use :cl))
(in-package :bit-bomberman)
;;--------------------------------------------------------------------
;; Main
;;--------------------------------------------------------------------
;; (setf *print-base* 2) ;for DEV
;; (parse-input "802b1200/01400c20")
;; => 10000000001010110001001000000000, 1010000000000110000100000
(defun parse-input (input)
(let ((split-pos (position #\/ input)))
(values (parse-integer input :end split-pos :radix 16)
(parse-integer input :start (1+ split-pos) :radix 16))))
;; MEMO: cl:ASH = ruby:<<
(defun main (input)
(multiple-value-bind (walls bombs) (parse-input input)
(let* ((field #.(mask-field (byte 31 2) #xFFFFFFFF))
(no-walls (logand field (lognot walls)))
(blast bombs))
(loop :for (shift mask) :in '((-1 #b11111011111011111011111011111000) ; Right
( 1 #b01111101111101111101111101111100) ; Left
(-6 #xFFFFFFFF) ; Down
( 6 #xFFFFFFFF)) ; Up
:for fire := bombs
:do (loop :until (zerop fire)
:do (setf blast (logior blast (logand fire field))
fire (logand (ash (logand fire mask) shift)
no-walls))))
(format nil "~(~8,'0X~)" blast))))
#|
for DEV
(defun main (input)
(multiple-value-bind (walls bombs) (parse-input input)
(let* ((field #.(mask-field (byte 31 2) #xFFFFFFFF))
(no-walls (logand field (lognot walls)))
(blast bombs))
(format t "~&Bombs: ~32,'0B" bombs)
(format t "~&No-Walls: ~32,'0B" no-walls) (terpri) (terpri)
(loop :for (shift mask) :in '((-1 #b11111011111011111011111011111000)
( 1 #b01111101111101111101111101111100)
(-6 #xFFFFFFFF)
( 6 #xFFFFFFFF))
:for fire := bombs
:do (format t "~&Mask: ~32,'0B" mask)
(terpri) (princ (make-string 42 :initial-element #\-))
(loop
:until (zerop fire)
:do (setf blast (logior blast (logand fire field))
fire (logand (ash (logand fire mask) shift)
no-walls))
(format t "~&Blast: ~32,'0B" blast)
(format t "~&Fire: ~32,'0B" fire)
(terpri) (terpri)))
(format t "~&Blast: ~32,'0B" blast)
(format nil "~(~8,'0X~)" blast))))
(main "802b1200/01400c20") => "53c40cfc"
Bombs: 00000001010000000000110000100000
No-Walls: 01111111110101001110110111111100
Mask: 11111011111011111011111011111000
------------------------------------------
Blast: 00000001010000000000110000100000
Fire: 00000000100000000000010000010000
Blast: 00000001110000000000110000110000
Fire: 00000000010000000000000000001000
Blast: 00000001110000000000110000111000
Fire: 00000000000000000000000000000100
Blast: 00000001110000000000110000111100
Fire: 00000000000000000000000000000000
Mask: 01111101111101111101111101111100
------------------------------------------
Blast: 00000001110000000000110000111100
Fire: 00000010100000000000100001000000
Blast: 00000011110000000000110001111100
Fire: 00000001000000000000000010000000
Blast: 00000011110000000000110011111100
Fire: 00000010000000000000000000000000
Blast: 00000011110000000000110011111100
Fire: 00000000000000000000000000000000
Mask: 11111111111111111111111111111111
------------------------------------------
Blast: 00000011110000000000110011111100
Fire: 00000000000001000000000000110000
Blast: 00000011110001000000110011111100
Fire: 00000000000000000000000000000000
Mask: 11111111111111111111111111111111
------------------------------------------
Blast: 00000011110001000000110011111100
Fire: 01010000000000000000100000000000
Blast: 01010011110001000000110011111100
Fire: 00000000000000000000000000000000
Blast: 01010011110001000000110011111100
|#
;;--------------------------------------------------------------------
;; Tests
;;--------------------------------------------------------------------
(defun =>? (got want)
(assert (string= got want)))
(progn
(=>? (main "802b1200/01400c20") "53c40cfc")
(=>? (main "28301068/84080504") "d64fef94")
(=>? (main "100a4010/80010004") "e241850c")
(=>? (main "81020400/000000fc") "0e3cfbfc")
(=>? (main "80225020/7e082080") "7fdd24d0")
(=>? (main "01201200/40102008") "fe1861fc")
(=>? (main "00201000/01000200") "43c48f08")
(=>? (main "00891220/81020408") "ff060c1c")
(=>? (main "410033c0/0c300000") "3cf0c000")
(=>? (main "00000000/01400a00") "7bf7bf78")
(=>? (main "00000000/20000a00") "fca2bf28")
(=>? (main "00000000/00000000") "00000000")
(=>? (main "00cafe00/00000000") "00000000")
(=>? (main "aaabaaaa/50000000") "51441040")
(=>? (main "a95a95a8/56a56a54") "56a56a54")
(=>? (main "104fc820/80201010") "ea30345c")
(=>? (main "4a940214/05000008") "05000008")
(=>? (main "00908000/05000200") "ff043f48")
(=>? (main "00c48c00/fe1861fc") "ff3873fc")
(=>? (main "00000004/81020400") "fffffff0")
(=>? (main "111028b0/40021100") "e08fd744")
(=>? (main "6808490c/01959000") "17f7b650")
(=>? (main "30821004/81014040") "c75de5f8")
(=>? (main "0004c810/10003100") "fe4937c4")
(=>? (main "12022020/88200000") "edf08208")
(=>? (main "2aa92098/01160000") "45165964")
(=>? (main "00242940/10010004") "fc43c43c")
(=>? (main "483c2120/11004c00") "33c3de10")
(=>? (main "10140140/44004a04") "eda3fe3c")
(=>? (main "0c901d38/72602200") "f36da280")
)
;;====================================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment