ASCII art diagram converter: Difference between revisions

→‎{{header|Haskell}}: added solution
(→‎{{header|Haskell}}: added solution)
Line 1,783:
ARCOUNT 16 0110100110100100
</pre>
 
=={{header|Haskell}}==
<lang haskell>import Text.ParserCombinators.ReadP
import Control.Monad (guard)
 
data Field a = Field { fieldName :: String
, fieldSize :: Int
, fieldValue :: Maybe a}
 
instance Show a => Show (Field a) where
show (Field n s a) = case a of
Nothing -> n ++ "\t" ++ show s
Just x -> n ++ "\t" ++ show s ++ "\t" ++ show x
 
newtype Data a = Data { fields :: [Field a] }
 
instance Show a => Show (Data a) where
show (Data fs) = "NAME\tSIZE\tVALUE\n" ++ unlines (show <$> fs)
 
instance Read (Data a) where
readsPrec _ = readP_to_S parseData
 
parseData = do n <- parseHeader
guard (n `elem` [8,16,32,64]) -- check size of the table
Data . concat <$> many1 (parseRow n)
where
parseRow n = do
fs <- char '|' *> many parseField <* char '\n'
guard $ sum (fieldSize <$> fs) == n -- check that size of all fields match the row size
m <- parseHeader
guard $ m == n -- check that all rows have the same size
return fs
parseHeader = do
char '+'
n <- length <$> many1 (string "--+")
char '\n'
return n
parseField = do
s1 <- many (char ' ')
f <- munch1 $ not . (`elem` " |")
s2 <- many (char ' ')
char '|'
let n = (length (s1 ++ f ++ s2) + 1) `div` 3
return $ Field f n Nothing
-- emulation of reading a stream of bits
readData :: Data a -> [b] -> Data [b]
readData d = Data . go (fields d)
where
go fs [] = (\f -> f {fieldValue = Nothing}) <$> fs
go (f:fs) s =
let (x, xs) = splitAt (fieldSize f) s
in f {fieldValue = Just x} : go fs xs
 
diagram = unlines
["+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"| ID |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"|QR| Opcode |AA|TC|RD|RA| Z | RCODE |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"| QDCOUNT |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"| ANCOUNT |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"| NSCOUNT |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"
,"| ARCOUNT |"
,"+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+"]
dataSample = concat
["011110000100011101111011101111110101010010010110",
"111000010010111000011011111100010110100110100100"]
</lang>
 
<pre>λ> let d = read diagram :: Data Int
λ> d
NAME SIZE VALUE
ID 16
QR 1
Opcode 4
AA 1
TC 1
RD 1
RA 1
Z 3
RCODE 4
QDCOUNT 16
ANCOUNT 16
NSCOUNT 16
ARCOUNT 16
 
λ> dataSample
"011110000100011101111011101111110101010010010110111000010010111000011011111100010110100110100100"
 
λ> readData d dataSample
NAME SIZE VALUE
ID 16 "0111100001000111"
QR 1 "0"
Opcode 4 "1111"
AA 1 "0"
TC 1 "1"
RD 1 "1"
RA 1 "1"
Z 3 "011"
RCODE 4 "1111"
QDCOUNT 16 "0101010010010110"
ANCOUNT 16 "1110000100101110"
NSCOUNT 16 "0001101111110001"
ARCOUNT 16 "0110100110100100"
 
λ> readData d (take 70 dataSample) -- corrupted input
NAME SIZE VALUE
ID 16 "0111100001000111"
QR 1 "0"
Opcode 4 "1111"
AA 1 "0"
TC 1 "1"
RD 1 "1"
RA 1 "1"
Z 3 "011"
RCODE 4 "1111"
QDCOUNT 16 "0101010010010110"
ANCOUNT 16 "1110000100101110"
NSCOUNT 16
ARCOUNT 16
</pre>
 
 
=={{header|J}}==
Anonymous user