Erlang Plagiarism Check
-module(plagiarism_check).
-export([plagiarism_check/2]).
%% Re-derived as a token-isomorphism check instead of porting PHP's
%% placeholder/regex substitution dance: tokenize both snippets, build a
%% one-way rename map from the mismatched, non-numeric tokens of Code1 onto
%% Code2, then verify applying that map to every token of Code1 reproduces
%% Code2 exactly.
plagiarism_check(Code1, Code2) ->
C1 = string:join(Code1, " "),
C2 = string:join(Code2, " "),
case C1 =:= C2 of
true ->
false;
false ->
D1 = tokenize(C1),
D2 = tokenize(C2),
Map = lists:foldl(fun({T1, T2}, Acc) ->
case T1 =/= T2 andalso not is_numeric_token(T1) of
true -> maps:put(T1, T2, Acc);
false -> Acc
end
end, #{}, lists:zip(D1, D2)),
[maps:get(T, Map, T) || T <- D1] =:= D2
end.
tokenize(S) ->
case re:run(S, "[A-Za-z0-9_]+", [global, {capture, all, list}]) of
{match, Matches} -> [Tok || [Tok] <- Matches];
nomatch -> []
end.
is_numeric_token(T) ->
case string:to_integer(T) of
{_, ""} -> true;
_ ->
case string:to_float(T) of
{_, ""} -> true;
_ -> false
end
end.
This flattens both snippets, tries consistent identifier replacements, and checks whether the rewritten code matches.