40
\$\begingroup\$

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

50 Answers 50

22
\$\begingroup\$

Python 3, 30 28 bytes

lambda m:len({*m})+1==len(m)

Try it online!

{*m} casts the list to a set object, an unordered list of items without duplicates. Doing this will always decrease the length of the list by the number of duplicates in it. By computing how much the length has changed, we can easily tell if the list had a single duplicate and return the result of the test.

-2 bytes thanks to ovs.

\$\endgroup\$
  • \$\begingroup\$ Exactly the solution I had, but forgot about the {*m} shortcut instead of set, well golfed! \$\endgroup\$ – FlipTack Oct 11 '17 at 20:29
  • \$\begingroup\$ 27 bytes for the negation. (Falsey when it should be Truthy, etc) \$\endgroup\$ – mbomb007 Oct 11 '17 at 21:02
  • 3
    \$\begingroup\$ Here's another weird way to do it (also negation): lambda m:~-len(m[len({*m}):]) \$\endgroup\$ – mbomb007 Oct 11 '17 at 21:06
9
\$\begingroup\$

Husk, 4 bytes

εṠ-u

Try it online!

Explanation

εṠ-u  Implicit input.
   u  Unique elements.
 Ṡ-   Delete them from input, counting multiplicities.
ε     Is the result a singleton list?
\$\endgroup\$
7
\$\begingroup\$

MATL, 7, 6 bytes

&=sp4=

Try it online!

One byte saved thanks to @Guiseppe!

Explanation:

&=  % Table of pair-wise equality comparisons
    %
    % [1 0 0 0 0 0 0
    %  0 1 0 0 0 0 0
    %  0 0 1 0 0 0 0
    %  0 0 0 1 1 0 0
    %  0 0 0 1 1 0 0
    %  0 0 0 0 0 1 0
    %  0 0 0 0 0 0 1]
    %
s   % Sum each Column. Stack:
    %
    % [1 1 1 2 2 1 1]
    %
p   % Product of the array. Stack:
    %
    % [4]
    %
4=  % Compare the stack to '4'
\$\endgroup\$
  • 1
    \$\begingroup\$ Since s is sum and sum sums along the first non-singleton dimension (columns), and the matrix is symmetric, couldn't this just be s instead of Xs? \$\endgroup\$ – Giuseppe Oct 11 '17 at 21:11
  • 1
    \$\begingroup\$ @Giuseppe Ah, TIL. Thankyou! \$\endgroup\$ – DJMcMayhem Oct 11 '17 at 21:13
7
\$\begingroup\$

Haskell, 34 bytes

f x=[1|a<-x,b<-x,a==b]==1:1:(1<$x)

Try it online! Based on H.PWiz' answer.

\$\endgroup\$
6
\$\begingroup\$

Jelly, 8 5 bytes

QL‘=L

Try it online!

Explanation

QL‘=L  - Main link, argument L (a list)   e.g [1,6,3,4,4,7,9]
Q      - Deduplicated elements                [1,6,3,4,7,9]
 L     - Length                               6
  ‘    - Increment                            7
    L  - Length of the input                  7 ([1,6,3,4,4,7,9])
   =   - Are they equal?                      1

If the output values can be any consistent values, then QL_L works, which outputs -1 for truthy and any other non-positive number for falsey (thanks @JonathanAllan)

\$\endgroup\$
  • \$\begingroup\$ QL_L would output -1 for truthy and some number less than -1 or 0 for falsey (e.g. [1,6,3,4,4,7,9,9,9] would return -3, while [1,6,3,4,7,9] would return 0). \$\endgroup\$ – Jonathan Allan Oct 11 '17 at 21:01
  • \$\begingroup\$ @JonathanAllan Oh yeah. I guess the examples I tested it on all happened to return -2. \$\endgroup\$ – caird coinheringaahing Oct 11 '17 at 21:06
5
\$\begingroup\$

JavaScript (ES6), 30 bytes

a=>new Set(a).size==a.length-1

Try it online

\$\endgroup\$
4
\$\begingroup\$

Pushy, 8 bytes

Simple implementation of checking whether len(set(list)) == len(list)-1:

LtvuL^=#

Explanation:

       \ Implicit: Put all input on stack
Ltv    \ Get the stack length - 1, save in auxiliary stack
u      \ Remove non-unique elements
L      \ Get the new length
^=     \ Compare with the previously saved length
#      \ Print result

This works as the length will only decrease by 1 if there was only exactly 1 non-distinct integer in the initial list.

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Wow, haven't seen a Pushy answer in ages! +1 \$\endgroup\$ – caird coinheringaahing Oct 11 '17 at 21:09
  • 1
    \$\begingroup\$ @cairdcoinheringaahing Pushy will never die. It will only come back stronger. \$\endgroup\$ – FlipTack Oct 11 '17 at 21:16
4
\$\begingroup\$

Octave, 25 bytes

This is not using a group or unique approach as many of the other answers, but rather the "cartesian product" of all possible comparisions.

@(x)nnz(triu(x==x',1))==1

Explanation

             x==x'        %create a matrix where the entry at (i,j) compares whether x(i) == x(ju)
        triu(x==x',1)     %only consider the strict upper triangular matrix
    nnz(triu(x==x',1))    %count the number of nonzero entries
@(x)nnz(triu(x==x',1))==1 %check whether this number is actually 1

Try it online!

And because no program would be complete without a convolution (thanks @LuisMendo for fixing a mistake):

Octave, 40 bytes

@(x)nnz(~conv(sort(x),-1:2:1,'same'))==1

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You inspired me to come up with this approach :) \$\endgroup\$ – Stewie Griffin Oct 12 '17 at 7:06
  • 2
    \$\begingroup\$ @StewieGriffin I think the MATL answer used your exact approach:) \$\endgroup\$ – flawr Oct 12 '17 at 14:27
4
\$\begingroup\$

J, 7 6 bytes

=&#0,=

= check every element for equality with every unique element, creates a matrix with m rows for m unique elements.
0, add an empty row on top.
=&# does the number of rows equal the length of input?

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I think you can replace .~ with = \$\endgroup\$ – H.PWiz Oct 11 '17 at 23:13
  • \$\begingroup\$ @H.PWiz Nice, edited. \$\endgroup\$ – FrownyFrog Oct 11 '17 at 23:46
4
\$\begingroup\$

Retina, 15 12 11 bytes

Thanks to Neil for saving 1 byte.

D`
Mm2`^$
1

Try it online!

Input is linefeed-separated. (The test suite uses comma-separation for convenience.)

Explanation

D`

Deduplicate the lines in the input, which removes any integer that has appeared before (but leaves the surrounding linefeed(s)).

Mm2`^$

Count the number of empty lines, which is equal to the number of duplicates we removed, but only consider the first two matches. So the output will only be 0 (no duplicates), 1 (one duplicate), 2 (two or more duplicates).

1

Make sure that exactly one duplicate was removed.

\$\endgroup\$
  • \$\begingroup\$ Save a byte by limiting the newline match to 2, so that the input to the third line is always 0, 1, or 2, simplifying the test. (Annoyingly you can't use A`. to count newlines, because it drops the last one.) \$\endgroup\$ – Neil Oct 12 '17 at 9:00
  • \$\begingroup\$ @Neil Thanks, the limit is a neat idea. I also tried using A`., but the problem is rather that you can't distinguish a single empty line from having no lines at all. Maybe I should consider terminating A and G output with a linefeed if there are any lines. Although that should probably be an option since I can imagine that linefeed being annoying in other scenarios. \$\endgroup\$ – Martin Ender Oct 12 '17 at 10:38
  • \$\begingroup\$ Matching a single empty line is easy - that's just ^$¶. \$\endgroup\$ – Neil Oct 12 '17 at 11:58
  • \$\begingroup\$ @Neil No, I mean that the output of A is identical regardless of whether it retains a single empty line or discards all lines. \$\endgroup\$ – Martin Ender Oct 12 '17 at 11:59
  • \$\begingroup\$ Sorry, that's what I meant by "drops the last one" - it returns one fewer empty line, but then you can't distinguish between 0 and 1. \$\endgroup\$ – Neil Oct 12 '17 at 12:02
3
\$\begingroup\$

05AB1E, 4 bytes

{¥_O

Try it online!

Outputs 1 as truthy, any other non-negative integer as falsy. In 05AB1E, 1 is the only truthy number (thanks @Emigna for the insight!).

Explanation

{       Implicit input. Sort
 ¥      Consecutive differences
  _     Boolean negate
   O    Sum. Implicit display
\$\endgroup\$
3
\$\begingroup\$

Ruby, 32 bytes

->(s){s.uniq.length==s.length-1}
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! Because this is code golf, you need to include the byte count of your program. I've taken the liberty of doing it for you this time. \$\endgroup\$ – Pavel Oct 12 '17 at 1:16
  • \$\begingroup\$ How about Array#size? \$\endgroup\$ – Travis Oct 12 '17 at 21:31
  • \$\begingroup\$ You can get down to 26 bytes by using ->s{s.uniq.size==s.size-1} \$\endgroup\$ – Conor O'Brien May 25 '18 at 2:35
3
\$\begingroup\$

C# (.NET Core), 35 + 18 bytes

+18 for using System.Linq.

n=>n.Distinct().Count()==n.Length-1

Try it online!

67 byte alternative without Linq:

n=>new System.Collections.Generic.HashSet<int>(n).Count==n.Length-1

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Excel, 42 bytes

Danish language version

=TÆLV(A:A)=SUM(--(FREKVENS(A:A,A:A)>0))+1

Assumes each integer from the list in separate cell in column A.
If we were allowed for inconsistent falsey values, we could save 3 bytes:

=TÆLV(A:A)+SUM(-(FREKVENS(A:A,A:A)>0))

English language version (44 bytes)

=COUNTA(A:A)=SUM(--(FREQUENCY(A:A,A:A)>0))+1
\$\endgroup\$
3
\$\begingroup\$

R, 32 31 bytes

-1 byte thanks to @JarkoDubbeldam

cat(sum(duplicated(scan()))==1)

Try it online!

Reads from stdin, writes to stdout.

duplicated iterates through the list, replacing the values of l with TRUE if that value occurs earlier in the list, and FALSE otherwise. If there's a unique pair of soulmates, there should be exactly one TRUE value, so the sum should be 1.

\$\endgroup\$
  • 1
    \$\begingroup\$ 31 bytes \$\endgroup\$ – JAD Oct 12 '17 at 19:46
  • 1
    \$\begingroup\$ @JarkoDubbeldam ah, of course. Good to see you again! It's been a while. \$\endgroup\$ – Giuseppe Oct 12 '17 at 19:48
  • \$\begingroup\$ Been busy with some other stuff, not sure I'm completely back yet. \$\endgroup\$ – JAD Oct 12 '17 at 20:04
  • \$\begingroup\$ @Giuseppe, I just read this question and immediately thought of your Original Approach.... Very nice! I would have never thought of the scan() approach. \$\endgroup\$ – Joseph Wood Oct 12 '17 at 23:15
3
\$\begingroup\$

PowerShell, 40 37 bytes

($args|sort -u).count-eq$args.count-1

Try it online!

The Sort-Object command (alias sort) with the -unique flag pulls out only the unique components of the input. For example, for input @(1,3,3,2), this will result in @(1,2,3).

Thus, we just need to make sure that the .count of this object (i.e., how many elements it has) is -equal to the .count of our input array -1 (i.e., we have exactly one duplicate entry).

Saved 3 bytes thanks to Sinusoid.
Fixed bug thanks to TessellatingHeckler.

\$\endgroup\$
  • \$\begingroup\$ Can you use the get-unique alias 'gu' instead of group to reach the same result? \$\endgroup\$ – Sinusoid Oct 12 '17 at 20:54
  • \$\begingroup\$ @Sinusoid Yes, we can. Thanks! \$\endgroup\$ – AdmBorkBork Oct 13 '17 at 12:19
  • \$\begingroup\$ This doesn't work on the second test case 1,2,1 - get-unique only works on pre-sorted input. How about ($args|sort -u).count-eq$args.count-1 which is also 37 but does work for all the test cases, if you call it like f 1 2 1 instead of f 1,2,1 ? \$\endgroup\$ – TessellatingHeckler Oct 15 '17 at 23:48
  • \$\begingroup\$ @TessellatingHeckler Ah, good catch. All of the testing I did was with pre-sorted input. Thanks! \$\endgroup\$ – AdmBorkBork Oct 16 '17 at 12:55
2
\$\begingroup\$

Perl 5, 36 + 1 (-a) = 37 bytes

map$k{$_}++,@F;@a=keys%k;say@a+1==@F

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ may be golfed @k{@F}++;say@F==1+keys%k \$\endgroup\$ – Nahuel Fouilleul Oct 12 '17 at 12:47
2
\$\begingroup\$

Haskell, 37 bytes

f x=sum[1|a<-x,b<-x,a==b]==2+length x

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Octave / MATLAB (with Statistics package / toolbox), 21 bytes

@(x)nnz(~pdist(x))==1

Anonymous function. Input is a column vector. Output is true (displayed as 1) or false (displayed as0).

Try it online!

Explanation

pdist(x) computes a vector of Euclidean distances between all pairs of rows from x. It considers each pair only once (order of the two rows doesn't matter), and doesn't consider pairs formed by the same row twice.

In our case x is a column vector, so Euclidean distance between two rows is just absolute difference between the two numbers.

~ is logical (Boolean) negation, nnz is number of nonzeros, and ==1 compares to 1. So the result is true if and only if there is only one pair that gives zero distance.

\$\endgroup\$
2
\$\begingroup\$

Jq 1.5, 53 25 bytes

length-(unique|length)==1

Inspired by Riley's answer and much shorter then my original solution.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Julia, 39 26 bytes

!a=sum(a.==a')==endof(a)+2

Explanation

The code generates a 2-dimensional table of booleans, which is then collected using the sum function, counting the number of same-element pairs in the cartesian square of A. Then this is compared to the length of the string plus two, and the quantities are equal only when there is exactly one repeat character.

This code redefines the NOT operator.

\$\endgroup\$
  • \$\begingroup\$ !a=sum(a.==a')==endof(a)+2 saves a few bytes. Try it online! \$\endgroup\$ – Dennis Oct 11 '17 at 23:55
2
\$\begingroup\$

Pyth, 6 bytes

qtlQl{

Verify all the test cases.

  • l{ - Gets the number of unique elements.

  • tlQ - Gets the length of the input list, decremented.

  • q - Checks equality.

7 bytes

q1l.-Q{

Verify all the test cases

\$\endgroup\$
2
\$\begingroup\$

Octave, 23 26 bytes

@(x)prod(sum(x==x'))==4

Try it online!

The x==x' part was inspired by flawr's answer. This is longer than Luis' answer, but it doesn't use any toolboxes.

Explanation:

This is an anonymous function that takes a vector x as input, and compares it to itself transposed. This will give a matrix where all diagonal elements are 1, and any off diagonal elements signals that there are duplicates elements.

The sum along any given column shows how many duplicates there are of that number. We want two of the numbers to have a duplicate, so we two values equal to two, and the rest unequal to two.

If we take the product of this matrix, we'll get 4 if there are only two equal elements (2*2*1*1*1*1*...), and something other than 4 if there are no duplicates, or more than two.

\$\endgroup\$
2
\$\begingroup\$

PHP, 46 bytes

<?=count(array_unique($argv))==count($argv)-1;

Counts the number of entries in $argv and compares it to the number of unique entries. If the former is higher than the latter by 1 then truthy, else falsey.

Try it on eval.in!

\$\endgroup\$
  • \$\begingroup\$ Do you have to use the variable name $argv can you not just use $a instead? \$\endgroup\$ – dading84 Oct 12 '17 at 10:44
  • 3
    \$\begingroup\$ @dading84 $argv is the list of command line parameters. So: no, he cannot just use $a. \$\endgroup\$ – Titus Oct 12 '17 at 11:36
2
\$\begingroup\$

05AB1E, 6 5 bytes

{¥>ΘO

Try it online!

{¥>ΘO   # example input:               [1, 6, 3, 4, 4, 7, 9]
{       # sort                      -> [1, 3, 4, 4, 6, 7, 9]
 ¥      # get deltas                -> [  2, 1, 0, 2, 1, 2 ]
  >     # increment                 -> [  3, 2, 1, 3, 2, 3 ]
   Θ    # truthify (only 1 gives 1) -> [  0, 0, 1, 0, 0, 0 ]
    O   # sum                       -> 1

1 being the only truthy value in 05AB1E, we can stop here. (Thanks @Emigna for pointing that out.)

To get only two distinct values, we can optionally add:

     Θ  # equals 1?                 -> 1
\$\endgroup\$
  • 1
    \$\begingroup\$ If it is okay to return any falsey value for the falsey cases, you can skip the Θ, as 1 is the only truthy value in 05AB1E. \$\endgroup\$ – Emigna Oct 11 '17 at 21:06
  • \$\begingroup\$ @Emigna Thanks! I was not sure whether it was approved by the OP, but I guess it is. \$\endgroup\$ – Arnauld Oct 11 '17 at 21:52
  • \$\begingroup\$ I'm afraid you need to revert to the previous solution as ¢ will not work. It would count [19,4,4,9] as false and [19,9] as true since it finds the 0 in 10. \$\endgroup\$ – Emigna Oct 12 '17 at 6:10
  • \$\begingroup\$ @Emigna Thanks for spotting that. I think that's fixed. \$\endgroup\$ – Arnauld Oct 12 '17 at 11:42
  • \$\begingroup\$ {¥_O should be okay as well. \$\endgroup\$ – Emigna Oct 12 '17 at 11:44
2
+100
\$\begingroup\$

APL (Dyalog Unicode), 7 bytesSBCS

1=≢-≢∘∪

Try it online!

Explanation:

1=≢-≢∘∪  ⍝ Monadic function train
    ≢∘∪  ⍝ Generate a list of unique items in the input,
         ⍝ and return the length of that list
  ≢-     ⍝ Take the length of the input and subtract the above
1=       ⍝ If the difference is 1, true, otherwise false
\$\endgroup\$
1
\$\begingroup\$

Jelly, 10 bytes

ċ@€`QṢ⁼1,2

Try it online!

a longer but different approach

\$\endgroup\$
1
\$\begingroup\$

Japt, 7 bytes

â ʶUÊÉ

Try it


Explanation

Remove duplicates (â), get length (Ê) and compare equality () with the length (Ê) of the input (U) minus 1 (É).

\$\endgroup\$
  • \$\begingroup\$ Isn't that 12 bytes? Aren't âÊɶ multibyte characters? \$\endgroup\$ – RedClover Oct 13 '17 at 11:54
1
\$\begingroup\$

Haskell, 37 bytes

f x=sum[1|0<-(-)<$>x<*>x]==2+length x

Try it online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 bytes

gIÙg-

Try it online!

g     # Get number of elements in input
 IÙg  # Get number of unique elements in input
    - # Subtract

In 05AB1E 1 is the only truthy value, so for a truthy result there must be exactly 1 duplicate element removed by the uniquify.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.