尝试使用位列表解决2015年第06天的代码问题

时间:2018-01-31 14:55:11

标签: 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. 如何提高表现?
  3. 最重要的

    1. 我是否犯了会导致程序计算错误结果的错误?我正在考虑类型转换这样的事情,但是我可能会错过一些非常明显的事情。
    2. (为了避免登录以查看输入,您可以找到它here

2 个答案:

答案 0 :(得分:0)

  1. 请确保由于溢出而不使用Int。使用Integer代替,可以任意增长。

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

答案 1 :(得分:0)

龙一切正确,从我身边大肆疏忽。这是工作代码:

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)

非常感谢!