# In Search of a Soulmate

Given a nonempty finite list of integers, output a truthy value if there are exactly two equal entries and all other entries are distinct, and a falsey value otherwise.

### Examples

truthy:
[1,1]
[1,2,1]
[1,6,3,4,4,7,9]

falsey:
[0]
[1,1,1]
[1,1,1,2]
[1,1,2,2]
[2,1,2,1,2]
[1,2,3,4,5]

• I suppose we can't assume that the integers will always be less than 10? – Martin Ender Oct 11 '17 at 20:17
• Yes except if your language does not support any larger integers. – flawr Oct 11 '17 at 20:22
• Can you elaborate what you mean by consistent? – flawr Oct 11 '17 at 20:40
• Saw this on the top of HNQ & thought we’d reached the final interpersonal.se question – gntskn Oct 11 '17 at 23:15
• @Walfrat Post it as your own challenge. Also such feedback is usually appreciated in the sandbox. – flawr Oct 12 '17 at 14:37

sort|uniq -dc|grep -Pqz '^ *2 .*\n$'  Output is via exit code, where 0 is success (truthy) and 1 is failure (falsy). Try it online! # C (GCC), 80 78 bytes i,j,t;f(x,l)int*x;{for(i=t=0;i<l;++i)for(j=0;j<i;)t+=x[i]==x[j++];return!~-t;}  -1 thanks to Jonathan Frech -1 thanks to Kevin Cruijssen Try it Online! f is a function that takes in an int* pointing to the list, and an int that is the length of the list, and returns 1 if there are exactly two equal entries and all other entries are distinct, and 0 value otherwise. The function checks all pairs of numbers in the list, counting the number of pairs, and returns whether the number of pairs is 1. • return 1==t; can be return!~-t; to save a byte. – Jonathan Frech Oct 12 '17 at 7:15 • j<i;++j)t+=x[i]==x[j] can be j<i;)t+=x[i]==x[j++] to save a byte. – Kevin Cruijssen Oct 12 '17 at 8:03 • 73 bytes – ceilingcat Nov 2 '19 at 9:11 # Bash, 36, 35 bytes for k;{ H[$k]=;};((${#H[@]}+1==$#))


TIO exit status 0: true, 1: false, ((..)) can be changed to echo $((..)), to see boolean value (1:true, 0:false) # Clojure, 31 bytes #(=(count(set %))(-(count %)1))  Try it online! Does the same as LyricLy's answer • Welcome to PPCG! – Laikoni Oct 12 '17 at 22:14 • Thanks! Hope this answer is ok, I felt like I was misusing TIO haha – Gabe Laughlin Oct 12 '17 at 22:17 # Java 8, 46 44 bytes l->l.stream().distinct().count()==l.size()-1  -2 bytes thanks to @Nevay. (Old answer: l->new java.util.HashSet(l).size()==l.size()-1) Explanation: Try it here. l-> // Method with List parameter and boolean return-type l.stream() // Stream over the List .distinct() // ignoring all duplicated items .count() // and get the total amount of non-duplicated items in the List == // And check if it's size is equals to l.size()-1 // the size of the input-list - 1 // End of method (implicit / single-line return-statement)  • 44 bytes: l->l.stream().distinct().count()==l.size()-1 – Nevay Oct 13 '17 at 20:16 # Japt, 7 bytes ÊÉ¶Uâ Ê Ê // Return whether the number of Uâ // unique items in the input ¶ // is equal to ÊÉ // the input's length minus one.  Try it online! # Brachylog, 7 bytes dl.&l-₁  Try it online! Truthy/falsy input is achieved through predicate success/failure, as if this predicate is run as the entire program on a single input, it will print true. if it succeeds and false. if it fails. The header on TIO is there so you can run all of the cases at once. dl The length of the input with duplicates removed . is the output variable, & and l-₁ so is the length of the input minus 1.  # Regex (ECMAScript), 69 67 bytes The input is in the form of a comma-delimited list of nonnegative integers in decimal. ^(?=.*\b(\w+\b).*,\1\b)(?!(.*\b\1\b){3}|.*\b(?!\1\b)(\w+\b).*,\3\b)  Try it online! ^ (?= .*\b(\w+\b) # \1 = an element that occurs at least twice .*,\1\b # locate the second occurrence of \1; since there's at least one # element before it, it's guaranteed to have a commma in front ) (?! (.*\b\1\b){3} # Assert that \1 does not occur 3 or more times | .*\b(?!\1\b)(\w+\b) # \3 = any element that's different from \1 .*,\3\b # Assert that \3 does not occur again; since there's at least one # element before it, it's guaranteed to have a commma in front )  # Regex (ECMAScript), 67 65 bytes ^(?=.*(\bx+\b).*,\1\b)(?!(.*\b\1\b){3}|.*\b(?!\1\b)(x+\b).*,\3\b)  Try it online! This is a straight port of the decimal version to positive unary, changing both occurrences of \w+ to x+. Input is a list of positive unary numbers separated by ,. Each one is a string of xs whose length represents the number. # Regex (ECMAScript), 92 bytes This version fully supports nonnegative unary. That is very costly; \b can no longer be used at all. The part that ballooned the most in length was where it's asserted that no element other than \2 is repeated 3 or more times, because with a simple {3} loop, it would get a false negative due to falsely finding a repeated zero consisting of 3 repeated zero-width matches with no commas consumed. ^(?=.*(^|,)(x*(?!x)).*,\2(?!x))(?!.*(^|,)(\2(?!x)(.*,\2(?!x)){2}|(?!\2(?!x))(x*(?!x)).*,\6(?!x)))  Try it online! ^ (?= .*(^|,)(x*(?!x)) # \2 = an element that occurs at least twice .*,\2(?!x) # locate the second occurrence of \2; since there's at least one # element before it, it's guaranteed to have a commma in front ) (?! .*(^|,) ( \2((?!x).*,\2){2} # Assert that \2 does not occur 3 or more times | (?!\2(?!x))(x*(?!x)) # \6 = any element that's different from \2 .*,\6 # Assert that \6 does not occur again; since there's at least one # element before it, it's guaranteed to have a commma in front ) (?!x) )  # Mathematica, 26 bytes (l=Length)@Union@#+1==l@#&  Try it online! # Convex, 7 bytes _Å,)\,=  Try it online! ## Batch, 109 bytes @set/ap=1,s=0 @for %%x in (%*)do @(for %%y in (%*)do @set/a"s+=!(%%x-%%y)")&set/ap*=s,s=0 @if %p%==4 echo 1  Port of @DJMcMayhem's answer. # Perl 5, 25+1 (-p)=26 bytes $H{$_}=1}{$\=$.-1==keys%H  TIO # Batch, 131 set b=,%*, goto j :l call set f=%%b:,%1,=,#,%% if "%b%"=="%f%" exit 1 set b=%f% goto:eof :j FOR %%A IN (%b%) DO call :l %%A  The %errorlevel% can be checked for the result. it works by tokenising the input, FOR %%A IN (%b%) DO call :l %%A every instance of that token + to commas is then replaced in a copy of the input with a ",#," call set f=%%b:,%1,=,#,%% the resulting string is then compared to the copy of the previous string. If there is no change in the string, it is because that number has already occured. c:\>batfile.bat 1,2,3 # Perl 6, 12 bytes {.Set+1==$_}


Try it online!

Convert to Set, test if the number of elements is less by one.

# R, 40 bytes

sum(outer(x<-scan(),x,"=="))==2+sum(x|1)


Try it online!

Approach is different from the other R solution - and not as golfy...

• Nit's Japt answer can (I think) be ported but using unique is certainly close-ish to duplicated – Giuseppe May 24 '18 at 20:41

# 12-basic, 31 bytes

FUNC S(L)?LEN(L|L)==LEN(L)-1END


The | (union) operator returns an array containing elements that are in both of the input arrays. As a side effect, it removes duplicates.

# Pari/GP, 16 bytes

a->#a==#Set(a)+1


Try it online!

# R, 38 bytes

Not quite as golfed as another R answer, but a different approach.

length(a<-scan())-length(unique(a))==1


Try it online!

## F#, 49 bytes

let s c=Seq.distinct c|>Seq.length=Seq.length c-1


Try it online!

Seq.distinct creates a sequence of all the unique elements in the collection. If the number of distinct elements is one less than the original collection, there are soulmates.

# Javascript,96 bytes

for(i=0;i<a.length;i++)for(j=0;j<a.length;j++)(a[i]==a[j]&& i!=j)?count++:0 console.log(count==2)


for(i=0;i<a.length;i++){
for(j=0;j<a.length;j++){
(a[i]==a[j]&& i!=j)?count++:0
}
}
console.log(count==2)


# GolfScript, 7 bytes

.,\.&,-


Try it online!

.,\.&,- # Stack will be show as [], with L being our list.
.       # Duplicate array [L L]
,      # Size of top element [L N]
\     # Swap the positions of the top two elements [N L]
.&   # Listwise OR (remove duplicates) [N L&]
,  # Size of top elements (should be 1 lesser) [N N-1?]
- # Difference

Output is 1 if TRUE. Any other result is FALSE.


# Factor, 25 bytes

[ duplicates length 1 = ]


Try it online!

## Explanation

It's a quotation (anonymous function) that takes a sequence as input and leaves a boolean as output. Assuming { 1 6 3 4 4 7 9 } is on top of the data stack when this quotation is called...

• duplicates Obtain a list of duplicate values. Stack: { 4 }
• length Get the length. Stack: 1
• 1 Push 1 to the stack. Stack: 1 1
• = Return t if the top two objects on the data stack are equal, otherwise return f. Stack: t