试图用位表解决代码的出现 2015 天 06

  • 本文关键字:2015 代码 解决 haskell
  • 更新时间 :
  • 英文 :


我正在学习Haskell,我正在使用Advent of Code 2015进行练习。我试图用位表而不是坐标和状态列表来解决 Day06,但它没有计算正确的值,我无法理解逻辑或实现中是否存在错误。

代码如下:

module Day06 where
import Data.Bits
import Data.Ix
import Data.List
parse :: String -> [Int]
parse a =
  let (c1,c2) = break (==',') a
  in range (read c1, read (tail c2))
mFlatten :: String -> String -> [Int]     
mFlatten x y =
    [ a + b * 1000 | a <- parse x, b <- parse y]
action :: (Bits b, Num b) => b -> [[Char]] -> b          
action state instruction = case instruction of
      ["toggle", a, _, b] -> foldl' complementBit state $ mFlatten a b
      ["turn","on", a, _, b] -> foldl' setBit state $ mFlatten a b
      ["turn","off", a, _, b] -> foldl' clearBit state $ mFlatten a b
main :: IO ()
main = do
  input <- readFile "input"
  print $ popCount $ (foldl ( acc x -> action acc $ words x) 0 (lines input) :: Integer)

我有几个问题:

  1. 有没有更惯用的方法来编写此代码?
  2. 如何提高性能?

最重要的是

  1. 我是否犯了任何会导致程序计算错误结果的错误?我正在考虑诸如类型转换之类的东西,但是我可能错过了一些非常明显的东西。

(为了避免必须登录查看输入,您可以在此处找到它(

  1. 确保由于溢出而不使用Int。请改用Integer,它可以任意增大。

  2. 据我了解,该问题要求您打开/关闭相对角(a,b(,(A,B(之间的矩形区域。我认为您将两个元组解释为矩形 [a..b]x[A..B],但它应该是[a.。A]x[b..B](假设 a<=A, b<=B(

早就说对了,我这边有很大的疏忽。这是工作代码:

module Day06 where
import Data.Bits
import Data.List
parse :: String -> (Int,Int)
parse a =
  let (c1,c2) = break (==',') a
  in (read c1, read (tail c2))
mFlatten :: String -> String -> [Int]     
mFlatten a b =
    let (x1,y1) = parse a
        (x2,y2) = parse b
    in [ x + y * 1000 | x <- [x1..x2], y <- [y1..y2]]
action :: (Bits b, Num b) => b -> [[Char]] -> b          
action state instruction = case instruction of
      ["toggle", a, _, b] -> foldl' complementBit state $ mFlatten a b
      ["turn","on", a, _, b] -> foldl' setBit state $ mFlatten a b
      ["turn","off", a, _, b] -> foldl' clearBit state $ mFlatten a b
main :: IO ()
main = do
  input <- readFile "input"
  print $ popCount $ (foldl ( acc x -> action acc $ words x) 0 (lines input) :: Integer)

非常感谢!

最新更新