Haskell Plagiarism Check
import Data.Char (isAlphaNum, isDigit)
import qualified Data.Map.Strict as Map

data Token = Word String | Sep String

tokenize :: String -> [Token]
tokenize [] = []
tokenize s@(c : _)
  | isWordChar c = let (w, rest) = span isWordChar s in Word w : tokenize rest
  | otherwise    = let (sp, rest) = break isWordChar s in Sep sp : tokenize rest
  where
    isWordChar ch = isAlphaNum ch || ch == '_'

plagiarismCheck :: [String] -> [String] -> Bool
plagiarismCheck code1 code2
  | c1 == c2                       = False
  | length words1 /= length words2 = False
  | otherwise                      = reconstructed == c2
  where
    c1 = unwords code1
    c2 = unwords code2

    toks1  = tokenize c1
    words1 = [w | Word w <- toks1]
    words2 = [w | Word w <- tokenize c2]

    isNumeric w = not (null w) && all isDigit w

    -- later mismatches overwrite earlier ones for the same original token,
    -- mirroring the source's plain array assignment
    rCand =
      Map.fromList
        [(w1, w2) | (w1, w2) <- zip words1 words2, w1 /= w2, not (isNumeric w1)]

    substitute (Word w) = Map.findWithDefault w w rCand
    substitute (Sep s)  = s

    reconstructed = concatMap substitute toks1

This flattens both snippets, tries consistent identifier replacements, and checks whether the rewritten code matches.