Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two strings in Haskell

I came across a rather silly practice problem that was listed as easy, so I thought I could do it. The premise is that a doctor must hear a patient say aah in order to give a diagnosis, but the aah from the patient must match the aah requested by the doctor. If the doctor asks for aaaaah and the patient says ah, then no diagnosis can be given. The Haskell program is supposed to read in a doctor and a patient aah in that order and return a Bool value for if a diagnosis may be given. At first I thought they needed to be identical so this was my code:

seeDoctor :: String -> String -> Bool
seeDoctor a b = if a == b then True
                else False

However, I realized I wasn't following all the rules of the problem and it wasn't so simple. The patient may say aah for longer than the doctor and return True, so "aah" "aaaah" returns True, as does "" "aaah" and "h" "aah", but "aaah" "ah" returns False. But even if the doctor doesn't include an 'h' in their aah, the patient must, so "a" "a" returns False, but my code would return True. So if the patient says anything, it must be the necessary number of 'a's followed by a single 'h' and no other characters. You see, once I started trying the suggested test cases, I realized how little I understood. Can I keep a count of 'a' in each string? How do I check for extra characters? Sorry this took a while to read. Thanks for making it this far.

Here is the exact question:

"When we go to see a doctor, the doctor always asks us to say "aaah". Sometimes, the doctor needs us to say "aaaaaah", but we are only able to say "aaah". In that case, the doctor is unable to diagnose our disease, because the 'a's in our "aaah" are fewer than his or her requirements. Now, write a Haskell function called seeDoctor to judge if the doctor can diagnose us with our "aah". The input of the function consists of two strings. The first string is the "aaaah" the doctor needs and the second string is the "aah" we are able to say. Output "True" if our "aah" meets the requirements of the doctor, and output "False" otherwise. The test should pass with a "True" only when lowercase 'a's and 'h's are used, and each string contains a certain number of 'a's followed by a single 'h'."

like image 930
Matt Robbins Avatar asked Oct 12 '25 10:10

Matt Robbins


1 Answers

Since you're trying to learn Haskell, I'm not going to give you a solution, but I'll try to give you enough hints to enable you to put a function together yourself.

Strings are lists, so you can use the normal list functions from Data.List. For instance, isSubsequenceOf almost does what you need:

Prelude Data.List> isSubsequenceOf "aah" "aaah"
True
Prelude Data.List> isSubsequenceOf "aaaah" "aah"
False

If I interpret the problem description correctly, you should probably also check that only a and h are in the input strings, and that h is the last character.

In order to check that h is the last character, you could use the last function:

Prelude Data.List> last "aaaah"
'h'
Prelude Data.List> last "ah"
'h'
Prelude Data.List> last "foo"
'o'

Perhaps you'd also want to check the input for rogue characters, and return False if the two strings contain any other character than a and h...

Prelude Data.List> all (\c -> c == 'a' || c == 'h') "aaah"
True
Prelude Data.List> all (\c -> c == 'a' || c == 'h') "aaah!"
False

What would you do about a string like "aha", though? I'll leave that as an exercise :)

like image 200
Mark Seemann Avatar answered Oct 15 '25 12:10

Mark Seemann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!