Hello, with
$stack test
I have
alphametics> Test suite test passed
for my code. However, for
$ exercism submit src/Alphametics.hs package.yaml
Your solution has been submitted successfully.
I get:
An error occurred
An error occurred while running your tests. This might mean that there was an issue in our infrastructure, or it might mean that you have something in your code that’s causing our systems to break.
Please check your code, and if nothing seems to be wrong, try running the tests again.
The instructions state that it can be solved with a brute force algorithm so I suspect the fact that my code involves generating permutations should not be the cause of the failure. Can you please help me understand why I get the failure on submission via the CLI.? I tried several time via the CLI. No joy. Then I submitted via the editor and it passed first time.
What’s your code for both the src/Alphametics.hs and package.yaml files?
My code for both src/Alphametics.hs and package.yaml follows:
module Alphametics (solve) where
import Data.Char (isLetter)
import qualified Data.List as List
import qualified Data.Map as Map
import Data.Maybe (fromMaybe)
import qualified Data.Set as Set
data Expression
= WordExpr String
| AddExpr Expression Expression
| MultiplyExpr Expression Expression
| PowerExpr Expression Expression
| EqualsExpr Expression Expression
deriving Show
data Token
= Word String
| Add
| Multiply
| Power
| Equals
deriving (Eq, Ord, Show)
data OperatorPrecedence = Add' | Multiply' | Power'
deriving (Eq, Ord, Show)
digitValue :: Map.Map Char Int -> (Char, Int) -> Int
digitValue dict (c, x) = (fromMaybe 0 (Map.lookup c dict)) * 10^x
equationIsTrue :: Map.Map Char Int -> Expression -> Bool
equationIsTrue dict (EqualsExpr left right) = eval dict left == eval dict right
eval :: Map.Map Char Int -> Expression -> Int
eval dict (WordExpr s) = foldl (\acc x -> acc + digitValue dict x) 0 $ zip s [n - 1, n - 2 .. 0]
where
n = length s
eval dict (AddExpr left right) = eval dict left + eval dict right
eval dict (MultiplyExpr left right) = eval dict left * eval dict right
eval dict (PowerExpr left right) = eval dict left ^ eval dict right
tokensToExpr :: [Token] -> Expression
tokensToExpr (Word a : []) = WordExpr a
tokensToExpr xs
| Equals `elem` xs =
let (left, right) = tokensToEquation xs
leftExpr = tokensToExpr left
rightExpr = tokensToExpr right
in makeExpression Equals leftExpr rightExpr
| otherwise =
let (left, op, right) = tokensToOperandsAndOp xs
leftExpr = tokensToExpr left
rightExpr = tokensToExpr right
in makeExpression op leftExpr rightExpr
tokensToEquation :: [Token] -> ([Token], [Token])
tokensToEquation xs = (left, rs)
where
(left, (Equals:rs)) = break (== Equals) xs
makeExpression :: Token -> Expression -> Expression -> Expression
makeExpression Add left right = AddExpr left right
makeExpression Multiply left right = MultiplyExpr left right
makeExpression Power left right = PowerExpr left right
makeExpression Equals left right = EqualsExpr left right
tokensToOperandsAndOp :: [Token] -> ([Token], Token, [Token])
tokensToOperandsAndOp xs =
let splitToken = findLowestPrecedence xs
(left, (t:ts)) = span (/= splitToken) xs
in (left, t, ts)
findLowestPrecedence :: [Token] -> Token
findLowestPrecedence xs = fromPrecedence $ minimum $ map toPrecedence xs'
where
xs' = filter (\x -> x `elem` [Add, Multiply, Power]) xs
toPrecedence :: Token -> OperatorPrecedence
toPrecedence Add = Add'
toPrecedence Multiply = Multiply'
toPrecedence Power = Power'
fromPrecedence :: OperatorPrecedence -> Token
fromPrecedence Add' = Add
fromPrecedence Multiply' = Multiply
fromPrecedence Power' = Power
tokenize :: String -> Token
tokenize str
| all isLetter str = Word str
| str == "+" = Add
| str == "*" = Multiply
| str == "^" = Power
| str == "==" = Equals
parse :: String -> [Token]
parse [] = []
parse xs =
let _words = words xs
in map (\w -> tokenize w) _words
subsets ::Int -> [a] -> [[a]]
subsets 0 _ = [[]]
subsets _ [] = []
subsets n (x:xs) = map (x:) (subsets (n-1) xs) ++ subsets n xs
rPermutations :: Int -> [a] -> [[a]]
rPermutations r = concatMap List.permutations . subsets r
makeTrans :: Ord k => [k] -> [a] -> Map.Map k a
makeTrans chars permutation = Map.fromList $ zip chars permutation
solve :: String -> Maybe [(Char, Int)]
solve puzzle =
let parts = words puzzle
_words = filter (\s -> all isLetter s) parts
chars = Set.fromList(concat _words)
chars' = Set.toList chars
r = Set.size chars
firsts = Set.fromList [head w | w <- _words]
perms = filter validPerm (rPermutations r [0 .. 9])
where
validPerm p = all (\(c,d) -> c `Set.notMember` firsts || d /= 0)
(zip chars' p)
dicts = map (\p -> makeTrans chars' p) perms
expr = tokensToExpr (parse puzzle)
result = List.find (\d -> equationIsTrue d expr) dicts
in fmap Map.toList result
name: alphametics
version: 1.3.0.6
dependencies:
- base
library:
exposed-modules: Alphametics
source-dirs: src
ghc-options: -Wall
dependencies:
- containers # List here the packages you
# - bar # want to use in your solution.
tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- alphametics
- hspec
Is this dependency listed both in your local package.yaml and the online editor when your solution passes in the editor?
The test runner doesn’t have internet access at runtime so if you specify a package that it doesn’t already have pre-installed, I could see where that’d cause an error. However, that only makes sense if the passing solution’s package.yaml is different than your local one.
Yes the - containers dependency is listed both in my local package.yaml and in the package.yaml in the online editor.
IsaacG
September 25, 2026, 6:04pm
6
This ran fine for me on the website. It might’ve been a temporary backend issue.
1 Like
OK that is fine - like I posted - I also found, after several failed CLI submissions, it passed first time on the website via the online editor. I will consider my question answered.