Challenges

# Is it a near-anagram?

+5
−0

Two words are anagrams of each other if the letters of one can be reordered to spell the other; e.g. ADOBE and ABODE are anagrams. An alternate way of describing it is that both words contain the same count of each letter. If you were to make a table:

ADOBE  ABODE
-----  -----
A: 1   A: 1
B: 1   B: 1
D: 1   D: 1
E: 1   E: 1
O: 1   O: 1


We can define a "near-anagram" as a pair of words that are almost anagrams, in the sense that they differ by only one letter. For example, TULIP and TUPLE are near-anagrams. TUPLE can be rearranged to spell TULEP, which differs from TULIP by only one letter. As a table:

TUPLE  TULIP
-----  -----
E: 1   I: 1
L: 1   L: 1
P: 1   P: 1
T: 1   T: 1
U: 1   U: 1


# Challenge

The challenge is to take two strings as input and determine if they are near-anagrams.

• The strings can be taken in any convenient format for your language (strings, sequences of characters, etc.)
• The output can be any two distinct values, as long as they are always consistent; e.g. 0 and 1 for false and true.
• The strings will only contain alphabet characters in a single case. You can assume either upper or lower, whichever is convenient; examples are in upper. Input will contain no whitespace. (It is acceptable to take the input as a single string containing the words separated by whitespace, if it is convenient.)
• You can assume the strings will not be the same. A decision problem to handle equal strings is not very interesting. They may be proper anagrams, however.
• You can assume the input is not empty.
• The two words might not be the same length; they may differ by one letter at most (see test cases.)

Winning criteria is code-golf. Shortest answer in each language wins.

# Test Cases

ADOBE ABODE   -> false (proper anagram)
TUPLE TULIP   -> true  (near-anagram)
ABCDE DADBC   -> true  (two Ds)
BAR   BARN    -> true  (one extra letter)
BARN  BARREN  -> false (too different)
Why does this post require moderator attention?
Why should this post be closed?

Oops, I missed the output criteria. Is it fine to output truthy/falsey values instead of them necessarily being exactly two values? (If not, I'll go edit my answer, it's trivial to just tack on a boolean conversion) Moshi‭ 3 months ago

@Moshi don't want to change the rules now, you should change your answer snail_‭ 3 months ago

+6
−0

# APL (Dyalog Extended), 18 bytes

Anonymous tacit prefix function taking a list of two strings as argument.

2=1⊥(≠⌿∊≢⍤⊢⌸⍤,⍤1↑)


Try it online!

() apply the following tacit function to the argument:

↑ mix the list of strings into a 2-row character matrix (padding any short string with spaces as necessary)

∊⍤1 with the enlisted (flattened into a single string) argument as left argument, apply the following function to each row of the matrix:

⍤, concatenate the enlisted string to the row string, then:

≢⍤⊢⌸ count the number of occurrences of each unique element, in their order of appearance

≠⌿ Boolean mask indicating where the rows differ

1⊥ sum (lit. evaluate as unary; i.e. count differences)

2= is 2 equal to that?

Why does this post require moderator attention?

+4
−0

# JavaScript (Node.js), 131 bytes

Returns true and false

g=(s,t,c=[...t])=>([...s].forEach(v=>(y=c.indexOf(v),c.splice(y,y>=0))),c)
f=(s,t)=>(x=g(s,t).length)<2&&(y=g(t,s).length)<2&&x+y


Try it online!

## Explanation

g computes a sort of set (Array?) difference between t and s, running through the characters of s and removing any matches in t, then returning the remaining characters in t.

f calls g to compute both s-t and t-s and checks that both are less than 2 (i.e. have only one letter difference either way). Then it checks the sum of the difference is non-zero to check that there is a difference, which I needed to add in to make perfect anagrams false.[1]

1. Without the restriction on perfect anagrams being falsey, I could have removed all of the x and y logic to get a 116 char solution ↩︎

Why does this post require moderator attention?

+4
−0

# Stax, 12 bytes

ä╫◙=♥:≡ƒélΣæ


Run and debug it

+3 after correcting it(thanks, HakerH)

## Explanation

b%s%>{s}M|-%1=
b              copy the two inputs
%s%>          is the first's length < second?
{s}M      if so, swap the two
|-    multiset difference
%   is the length of the difference
1= equal to 1?
Why does this post require moderator attention?

It fails for "AC" "ABC" Hakerh400‭ 3 months ago

@Hakerh400 should work correctly now Razetime‭ 3 months ago

+3
−0

# JavaScript (Node.js), 150 71 bytes

f=(a,b)=>a[b.length]?f(b,a):b.filter(x=>a[y=a.indexOf(x)]=!~y).length-1


Try it online!

Why does this post require moderator attention?

+3
−0

# Brachylog, 8 bytes

pᵐ≠{b|}ᵛ


Try it online!

Since it takes $5!*5! = 14400$ tries to determine that the first test case gives false, I've added some shorter ones...

pᵐ          Permute each element of the input.
≠         The permuted elements are not equal,
{  }ᵛ    but yield the same result if
|      maybe
b       their first elements are removed.
Why does this post require moderator attention?