Haskell:使用“ putStr”时出现神秘的“数组索引错误”

问题描述 投票:1回答:1

我正在尝试为Haskell中的this hackerrank problem实现解决方案。由于hackerrank从stdout读取解决方案,因此我使用putStr输出答案。

不幸的是,这产生了一个相当不翔实的信息,并且很难跟踪错误:Error in array index

这里是解决方案的main功能:

main :: IO()
main = do
    mnrTemp <- getLine
    let mnr = L.words $ rstrip mnrTemp

    let m = read (mnr !! 0) :: Int

    let n = read (mnr !! 1) :: Int

    let r = read (mnr !! 2) :: Int

    matrixTemp <- readMultipleLinesAsStringArray m

    let raw_matrix = L.map (\x -> L.map (read :: String -> Int) . L.words $ rstrip x) matrixTemp

    let matrix = array ((0::Int, 0::Int), (n-1, m-1)) $ L.concat [ [ ((i,j), a)| (j, a) <- L.zip [0..] row] | (i, row) <- L.zip [0..] raw_matrix] :: Array (Int, Int) Int

    let rotated_matrix = matrixRotation matrix r
    putStr $ showMatrix rotated_matrix

从调用readMultipleLinesAsStringArray起的所有内容都作为解决方案框架的一部分提供。自然,我认为该错误在此之后的某个时间出现。可能在Data.Array中以某种数组(matrixRotation)的方式访问,或者在showMatrix中的可能性较小。

但是,某些打印调试似乎表明并非如此。如果我将putStr $ showMatrixprint交换,我会看到正确的答案(尽管格式不正确)。这似乎可以排除matrixRotation中的任何错误。此外,如果将putStrprint交换,我还将看到正确的答案(作为字符串,带有引号和换行符的明确显示)。这似乎可以排除showMatrix中的任何错误。

以某种方式,使用putStr会导致Error in array index,但我不确定如何确定发生这种情况。

这里是我的解决方案的其余部分,以防万一那里有任何明显的问题:

  • 该问题的默认导入和语言扩展:
{-# LANGUAGE DuplicateRecordFields, FlexibleInstances, UndecidableInstances #-}

module Main where

import Control.Monad
import Data.Array
import Data.Bits
import Data.List as L
import Data.List.Split
import Data.Set
import Data.Text
import Debug.Trace
import System.Environment
import System.IO
import System.IO.Unsafe
import Control.DeepSeq
  • 我的showMatrix实现:
showMatrix :: Array (Int, Int) Int -> String
showMatrix matrix =
    let ((min_row, min_col), (max_row, max_col)) = bounds matrix
        row_major_order m = [ [show $ m!(i,j) | j <- [min_col..max_col]] | i <- [min_row..max_row]]
    in L.intercalate "\n" . L.map (L.intercalate " ") . row_major_order $ matrix
  • 我的matrixRotation解决方案
-- Complete the matrixRotation function below.
matrixRotation :: Array (Int, Int) Int -> Int -> Array (Int, Int) Int
matrixRotation matrix r =
    let (max_row_ix, max_col_ix) = snd $ bounds matrix :: (Int, Int)
        (n, m) = (max_row_ix + 1, max_col_ix + 1)
        num_squares = n `div` 2

        rotated_square k =
            let (max_row_k, max_col_k) = (max_row_ix-k, max_col_ix-k)
                top = L.zip (repeat k) [k+1..max_row_k-1]
                bot = L.zip (repeat max_row_k) [k+1..max_row_k-1]
                left = L.zip [k+1..max_row_k-1] (repeat k)
                right = L.zip [k+1..max_row_k-1] (repeat max_col_k)
                corners = [(k,k), (k, max_col_k), (max_row_k, k), (max_row_k, max_col_k)]
                square_domain = top ++ bot ++ left ++ right ++ corners
            in [((i,j), rotated_elem (i,j) k) | (i,j) <- square_domain]


        rotated_elem :: (Int, Int) -> Int -> Int
        rotated_elem (i,j) k =
            let (max_row_k, max_col_k) = (max_row_ix-k, max_col_ix-k) in

            -- handle corners first
            -- top left => read from right
            if i == k && j == k then matrix!(i,j+1)
            -- top right => read from bottom 
            else if i == k && j == max_col_k then matrix!(i+1,j)
            -- bottom left => read from top
            else if i == max_row_k && j == k then matrix!(i-1,j)
            -- bottom right => read from left
            else if i == max_row_k && j == max_col_k then matrix!(i,j-1)
            else
                -- top row => read from right
                if i == k then matrix!(i, j+1)
                -- bottom row => read from left
                else if i == max_row_k then matrix!(i, j-1)
                -- left col => read from top
                else if j == k then matrix!(i-1,j)
                -- right col => read from bot
                else if j == max_col_k then matrix!(i+1,j)
                else error "ERROR"
                --else error "index " ++ show (i,j) ++ " not in " ++ show k ++ "th square " 
        rotated_matrix :: Array (Int, Int) Int
        rotated_matrix = matrix // L.concat [rotated_square k | k <- [0..num_squares-1]]
        in if r <= 0 then matrix
        else if r == 1 then rotated_matrix
        else matrixRotation rotated_matrix (r-1)

我正在尝试在Haskell中实现针对此hackerrank问题的解决方案。由于hackerrank从stdout读取解决方案,因此我使用putStr输出答案。不幸的是,这产生了一个...

haskell
1个回答
1
投票

let matrix = ...行中,您已经翻转了nm的角色,因此它在非对称矩阵上崩溃。您想要:

© www.soinside.com 2019 - 2024. All rights reserved.