Hi all, I’m trying the atbash exercise in Bash and one of the tests fails even if the result seems to be correct:
Code Run
run bash atbash_cipher.sh encode "The quick brown fox jumps over the lazy dog."
assert_success
assert_output "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"
Test Failure
(from function `assert_output' in file bats-extra.bash, line 394,
in test file atbash_cipher.bats, line 61)
`assert_output "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt"' failed
-- output differs --
expected : gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt
actual : gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt
--
Is it a bug or something else?
1 Like
BATS_RUN_SKIPPED=true bats atbash_cipher.bats
atbash_cipher.bats
✓ encode yes
✓ encode no
✓ encode OMG
✓ encode spaces
✓ encode mindblowingly
✓ encode numbers
✓ encode deep thought
✓ encode all the letters
✓ decode exercism
✓ decode a sentence
✓ decode numbers
✓ decode all the letters
✓ decode with too many spaces
✓ decode with no spaces
14 tests, 0 failures
I’ve checked my solution
Could you try running this? It’s my solution, I have to improve it, but I can’t understand why it’s returning this “error” (as the output seems to be correct)
#!/usr/bin/env bash
# --------------------------------- VARIABLES -------------------------------- #
# Declare a read-only associative array with the cipher, maybe overkill
# but allows for later replacements
declare -rA cipher_array=(["a"]=z ["b"]=y ["c"]=x ["d"]=w ["e"]=v ["f"]=u
["g"]=t ["h"]=s ["i"]=r ["j"]=q ["k"]=p ["l"]=o ["m"]=n ["n"]=m ["o"]=l
["p"]=k ["q"]=j ["r"]=i ["s"]=h ["t"]=g ["u"]=f ["v"]=e ["w"]=d ["x"]=c
["y"]=b ["z"]=a)
# --------------------------------- FUNCTIONS -------------------------------- #
check_arguments () {
# Requires one argument
if (( $# != 2 )); then
echo "Usage: atbash.sh (operation) \"<string>\""
echo "Where (operation) is encode or decode"
exit 1
fi
}
# No input checks as it's assumed input is a valid atbash ciphered text
decode () {
# Remove spaces and punctuation from input
input=${2//[[:space:]]}
decrypted=""
# Iterate over input
for ((pos = 0 , len=${#input}; pos < len; ++pos)); do
# If current character is a letter, replace it
if [[ ${input:pos:1} =~ [a-z] ]]; then
decrypted+=${cipher_array["${input:pos:1}"]}
# Otherwise it's a number, just append it
else
decrypted+=${input:pos:1}
fi
done
echo "$decrypted"
}
encode () {
# Remove spaces and punctuation from input
input=${2//[[:space:][:punct:]]}
# And convert it to lowercase
input=${input,,}
# empty encrypted string
encrypted=""
# Iterate over input
for ((pos = 0 , len=${#input}; pos < len; ++pos)); do
# If current character is a letter, replace it
if [[ ${input:pos:1} =~ [a-z] ]]; then
encrypted+=${cipher_array["${input:pos:1}"]}
# Otherwise it's a number, just append it
else
encrypted+=${input:pos:1}
fi
# Every 5 characters add a space
# +1 as it starts from 0
if (( pos != 0 && (pos +1) % 5 == 0 )); then
encrypted+=" "
fi
done
echo "$encrypted"
}
# ----------------------------------- MAIN ----------------------------------- #
main () {
check_arguments "$@"
# Call function according to operation
case $1 in
encode )
encode "$@"
;;
decode )
decode "$@"
;;
* )
echo "Unsupported operation"
;;
esac
}
main "$@"
Thank you, I was using the web editor and the output truncates trailing spaces 
1 Like