lj h
lj h

Reputation: 107

Haskell comparing characters in a word

I'm trying to make a function that will check how many characters are matching in a word

  1. The characters are non-repeating A-Z. The position of the letters doesn't matter

INPUT target = "ABCDE" , attempt = "CDXYZ",

OUTPUT match = 2 letters (C & D)

I've managed to write a function that compares one character in a word, but I've no clue how to make it compare every character.

import Data.List
--check if a char appears in a [char]
checkForCharInAWord :: [Char] -> Char -> Bool
checkForCharInAWord wrd lt = elem lt wrd

compareChars :: [Char] -> [Char] -> Int
compareChars = ?????
  1. I would also like to know how to count the matching characters in case of words with repeating characters, the position of the letter doesn't matter. I.e:

INPUT target = "AAAB", attempt = "ABBB" OUTPUT match = 2 letters (A & B)

INPUT target = "AAAB", attempt = "AABB" OUTPUT match = 3 letters (A, A & B)

  1. and finally how to count the matching characters in a word, but where position is also taken into consideration

INPUT target = "NICE", attempt = "NEAR" OUTPUT match = 1 letters (N) -- correct letter and a correct position

INPUT target = "BBBB", attempt = "BABA" OUTPUT match = 2 letters (B, B) -- correct letter and a correct position


In each case I need just a simple int output with a similarity rating between 0 and (max number of letters in a target word. The method should be flexible enough to allow words of different length (however target and attempt word will always be of equal length).

Thanks!

Upvotes: 1

Views: 307

Answers (1)

huch
huch

Reputation: 51

Below function seems to work for point 3. It takes two formal parameters (w1 and w2) representing the two words you want to compare, creates a list of 2-tuples of the corresponding letters using the built-in zip function (where xs = zip w1 w2 ). Then it goes through this list of 2-tuples and for each tuple compares the two elements using a list comprehension with guard. If they match, it adds a 1 to the list, otherwise it does nothing. Finaly, it sums all elements of this list (sum [1 | x<-xs, fst x == snd x]).

    match :: [Char] -> [Char] -> Int
    match w1 w2 = sum [1 | x<-xs, fst x == snd x]
        where xs = zip w1 w2

Test output

Upvotes: 2

Related Questions