LoginSignup
0
0

More than 5 years have passed since last update.

第8回オフラインリアルタイムどう書くの問題をF#で

Last updated at Posted at 2013-04-23
bomb.fs
let WIDTH = 6
let HEIGHT = 5

type Matrix =
  struct
    val D : uint32
    new (d) = {D = d}
    new (s:string) = {D = System.Convert.ToUInt32(s,16)}
    new (x,y) =
      {D = 1u <<< (31 - x - (y * WIDTH))}
    member this.At(x,y) =
      (this.D >>> (31 - x - (y * WIDTH))) % 2u > 0u
    override this.ToString() =
      this.D.ToString("x8")
    static member (+) (m1: Matrix, m2: Matrix) =
      new Matrix(m1.D ||| m2.D)
    static member Zero = new Matrix()
  end

let toRow y (m:Matrix) =
  Array.map (fun x -> m.At(x,y)) [|0..WIDTH-1|]
let fromRow y (r:bool array) =
  [0..WIDTH-1]
  |> List.filter (fun x -> r.[x])
  |> List.sumBy (fun x -> new Matrix(x,y))
let toColumn x (m:Matrix) =
  Array.map (fun y -> m.At(x,y)) [|0..HEIGHT-1|]
let fromColumn x (c:bool array) =
  [0..HEIGHT-1]
  |> List.filter (fun y -> c.[y])
  |> List.sumBy (fun y -> new Matrix(x,y))
let blast1D x (w:bool array) =
  let outofRange i = (i < 0) || (Array.length w <= i)
  let rec indexOfWall d i =
    if outofRange i || w.[i] then i else indexOfWall d (i+d)
  let w1 = indexOfWall -1 (x-1)
  let w2 = indexOfWall 1 (x+1)
  Array.map (fun i -> w1 < i && i < w2) [|0..Array.length w - 1|]
let blast2D (w:Matrix) x y =
  let h = w |> toRow y |> blast1D x |> fromRow y
  let v = w |> toColumn x |> blast1D y |> fromColumn x
  h + v
let blast (w:Matrix) (b:Matrix) =
  seq {for x in 0..WIDTH-1 do
       for y in 0..HEIGHT-1 do
       yield (x,y)}
  |> Seq.filter b.At
  |> Seq.sumBy (fun (x,y) -> blast2D w x y)
let solve (s:string) =
  let a = s.Split([|'/'|])
  let b = blast (new Matrix(a.[0])) (new Matrix(a.[1]))
  b.ToString()

(* for test *)

type TestResult = Success | Failure

let test target expected =
  let actual = solve target
  printfn "%A" (if expected = actual then Success else Failure)

[<EntryPoint>]
let main args =
  test "802b1200/01400c20" "53c40cfc"
  test "28301068/84080504" "d64fef94"
  test "100a4010/80010004" "e241850c"
  test "81020400/000000fc" "0e3cfbfc"
  test "80225020/7e082080" "7fdd24d0"
  test "01201200/40102008" "fe1861fc"
  test "00201000/01000200" "43c48f08"
  test "00891220/81020408" "ff060c1c"
  test "410033c0/0c300000" "3cf0c000"
  test "00000000/01400a00" "7bf7bf78"
  test "00000000/20000a00" "fca2bf28"
  test "00000000/00000000" "00000000"
  test "00cafe00/00000000" "00000000"
  test "aaabaaaa/50000000" "51441040"
  test "a95a95a8/56a56a54" "56a56a54"
  test "104fc820/80201010" "ea30345c"
  test "4a940214/05000008" "05000008"
  test "00908000/05000200" "ff043f48"
  test "00c48c00/fe1861fc" "ff3873fc"
  test "00000004/81020400" "fffffff0"
  test "111028b0/40021100" "e08fd744"
  test "6808490c/01959000" "17f7b650"
  test "30821004/81014040" "c75de5f8"
  test "0004c810/10003100" "fe4937c4"
  test "12022020/88200000" "edf08208"
  test "2aa92098/01160000" "45165964"
  test "00242940/10010004" "fc43c43c"
  test "483c2120/11004c00" "33c3de10"
  test "10140140/44004a04" "eda3fe3c"
  test "0c901d38/72602200" "f36da280"
  0
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0