33
\$\begingroup\$

Introduction:

I think we've all heard of it, but here a very brief summary: Noah gathered two of every species of animal on the planet, male and female, to save in his Ark during a great flood. The actual quote from the Bible is:

Genesis 7:2-3
You must take with you seven of every kind of clean animal, the male and its mate, two of every kind of unclean animal, the male and its mate, and also seven of every kind of bird in the sky, male and female, to preserve their offspring on the face of the earth.
source

But for the sake of this challenge we will ignore the clean/unclean part and the part where he took seven of each animal. This challenge is only about this part:

two of every kind of unclean animal, the male and its mate

Challenge:

Input:

You are given a list of positive integers (in random order).

Output:

Two distinct values indicating whether it's a 'List of Noah' or not. This doesn't necessary have to be a truthy/falsey value, so could also be 0/1 in Java/C#, or 'A'/'B' in any language, to give some examples.

When is a list a 'List of Noah'? When there are exactly two of every integer in the list.

Challenge rules:

  • I/O is flexible. Input can be a list/array/stream of integers/floats/strings, or read one by one from STDIN. Output can be any two distinct values, returned from a function or output to STDOUT / a file.
  • The integers in the input-list are in random order, and are guaranteed to be positive within the range \$1\leq n\leq100000\$.
  • The input-list is guaranteed to be non-empty.
  • Having an integer a multiple of two times present above 2 (i.e. 4, 6, 8, etc.) will be falsey. I.e. [6,4,4,6,4,7,4,7] is falsey, although you could still create equal pairs like this: [[4,4],[4,4],[6,6],[7,7]].

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Truthy:
[7,13,9,2,10,2,4,10,7,13,4,9]
[1,2,3,1,2,3]
[10,100,1000,1,100,10,1000,1]
[123,123]
[8,22,57189,492,22,57188,8,492,57188,57189,1,1]

Falsey:
[6,4,4,6,4,7,4,7]
[2,2,2,2,2,2]
[5,1,4,5,1,1,4]
[77,31,5,31,80,77,5,8,8]
[1,2,3,2,1]
[44,4,4]
[500,30,1]
[1,2,1,1]
[2,4,6,4,4,4]
[2,23,34,4]
[2,23,3,3,34,4]
\$\endgroup\$
1
  • 15
    \$\begingroup\$ And in Quran also; Surah Al-Mumenoon, Verse 27: So We inspired him (with this message): "Construct the Ark within Our sight and under Our guidance: then when comes Our Command, and the fountains of the earth gush forth, take thou on board pairs of every species, male and female, and thy family- except those of them against whom the Word has already gone forth: And address Me not in favour of the wrong-doers; for they shall be drowned (in the Flood). (Yusuf Ali) \$\endgroup\$
    – Ishaq Khan
    Jul 8, 2019 at 10:12

68 Answers 68

20
\$\begingroup\$

Python 3, 31 bytes

lambda l:{*map(l.count,l)}=={2}

Try it online!


Python 2, 33 bytes

lambda l:set(map(l.count,l))=={2}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Cool, didn't know the splat operator worked inside set literals, if I'm interpreting this correctly. \$\endgroup\$ Jul 11, 2019 at 0:18
16
\$\begingroup\$

Python 3.8 (pre-release), 62 bytes (non-competing)

lambda x:{*[y.count(C)for C	in	(y:=x)]}!={*[2.]}##!2bcdfilmrtu

Try it online!

Just for fun, a solution that is itself a "List of Noah".

\$\endgroup\$
16
  • 8
    \$\begingroup\$ While fun, this breaks the rules by not being a serious contender. \$\endgroup\$
    – Adám
    Jul 8, 2019 at 9:32
  • 4
    \$\begingroup\$ @DaniilTutubalin There is very strong consensus to warn non-serious contenders, and then delete if the author has not corrected the answer given reasonable time to do so. Note that this answer actually falls under the label deliberately invalid, and wouldn't even require waiting, but we're being unusually nice about this one because it is fun. \$\endgroup\$
    – Adám
    Jul 8, 2019 at 10:05
  • 9
    \$\begingroup\$ @Adám For code golf, e.g., this is limited to answers that do not even attempt to golf the code. Answers that are simply poorly golfed are not invalid. This answer is definitely well golfed and also introduces additional restriction of being list-of-Noah-truthy, which makes it even stronger contender than other solutions. So this rule does not apply here. \$\endgroup\$ Jul 8, 2019 at 10:10
  • 7
    \$\begingroup\$ I think the best way to satisfy everybody: put 2 solutions in one answer, one is competing and follows specs, another is with extra restriction followed. \$\endgroup\$ Jul 8, 2019 at 11:46
  • 8
    \$\begingroup\$ @Adám IMO, having a self-imposed restricted-source requirement is more akin to using a different language. There is a serious attempt to golf here, but he's not golfing Python 3.8 per se, but rather a subset of it governed by the restricted source. I see nothing wrong with this answer. \$\endgroup\$ Jul 8, 2019 at 20:46
14
\$\begingroup\$

05AB1E, 4 bytes

¢<PΘ

Try it online! or as a Test Suite

Explanation

¢      # count all occurrences of each element in the input list
 <     # decrement each
  P    # product
   Θ   # is equal to 1
\$\endgroup\$
2
  • \$\begingroup\$ Ah, I had prepared ¢2QP, but using Θ is also a nice alternative. :) \$\endgroup\$ Jul 8, 2019 at 9:42
  • \$\begingroup\$ Thought I had a 3 with {ιË, but of course that fails when integers occur 4 times. \$\endgroup\$
    – Grimmy
    Jul 8, 2019 at 10:21
11
\$\begingroup\$

Brachylog, 4 bytes

ọtᵛ2

Try it online!

Explanation

ọ           Get the list of occurences of elements in the input: [[x,2], [y,2], …]
  ᵛ         Verify that for each of those pairs…
 t          …the tail (i.e. the number of occurences)
   2        …is 2
\$\endgroup\$
8
\$\begingroup\$

R, 20 bytes

-6 bytes thanks to digEmAll by changing the input method

any(table(scan())-2)

Try it online!

Outputs FALSE if it is a list of Noah, and TRUE otherwise. Works for any input type, not only integers.

Computes the count of each value in the list, and checks whether any of the counts are different from 2.

\$\endgroup\$
2
  • \$\begingroup\$ You could take input from stdin saving 6 bytes : Try it online! \$\endgroup\$
    – digEmAll
    Jul 8, 2019 at 11:40
  • \$\begingroup\$ @digEmAll Thanks; I misread the challenge rules and thought this was not allowed. \$\endgroup\$ Jul 8, 2019 at 12:39
7
\$\begingroup\$

C# (Visual C# Interactive Compiler), 39, 32 bytes

l=>l.All(x=>l.Count(y=>y==x)==2)

Thanks to @Expired_Data

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 32 bytes \$\endgroup\$ Jul 8, 2019 at 9:41
  • \$\begingroup\$ 30 bytes 🤙 \$\endgroup\$ Jan 31 at 17:44
  • \$\begingroup\$ My previous comment passes all listed test cases, but fails on cases like 2, 2, 2, 2, 3, 3, 4; disregard 😭 \$\endgroup\$ Jan 31 at 18:06
7
\$\begingroup\$

APL (Dyalog Extended), 5 bytesSBCS

2¨≡⍧⍨

Try it online!

Is it true that…

 two for each element

 is identical to

⍧⍨ the count-in selfie (count of own elements in self)

?

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

Haskell, 33 bytes

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

Try it online!

For each element of the input we ensure it appears twice in the input list.

sum[1|b<-x,b==a] is just a golfier version of length(filter(==a)x).

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

Perl 6, 18 bytes

{so.Bag{*}.all==2}

Try it online!

  • .Bag converts the input list to a Bag--a set with multiplicity.
  • {*} extracts all of the multiplicities.
  • .all creates an and-junction of the multiplicities.
  • == 2 results in another and-junction of Booleans, each true if the multiplicity is 2.
  • so collapses the junction to a single Boolean.
\$\endgroup\$
5
\$\begingroup\$

J, 10 bytes

[:*/2=#/.~

Try it online!

\$\endgroup\$
5
  • 3
    \$\begingroup\$ also 10 bytes: [:*/2=1#.= I really want to remove that cap but can’t figure out how. \$\endgroup\$
    – cole
    Jul 8, 2019 at 22:57
  • 1
    \$\begingroup\$ @cole when I tried this, I got your solution. If you really wanted to remove the cap you could do 2*/@:=1#.=, also 10 bytes \$\endgroup\$ Jul 9, 2019 at 6:08
  • \$\begingroup\$ @cole Nice alternative! \$\endgroup\$ Jul 9, 2019 at 6:24
  • \$\begingroup\$ @ConorO'Brien Yes, @: comes handy here too. \$\endgroup\$ Jul 9, 2019 at 6:24
  • 1
    \$\begingroup\$ @GalenIvanov gotta love monadic =, so strangely useful in niche golfing scenarios \$\endgroup\$
    – cole
    Jul 9, 2019 at 6:34
5
\$\begingroup\$

JavaScript (ES6), 37 bytes

Returns false for Noah or true for non-Noah.

a=>a.some(v=>a.map(x=>t-=v==x,t=2)|t)

Try it online!

Commented

a =>               // a[] = input
  a.some(v =>      // for each value v in a[]:
    a.map(x =>     //   for each value x in a[]:
      t -= v == x, //     decrement t if v is equal to x
                   //     (i.e. if v appears exactly twice, t is decremented twice)
      t = 2        //     start with t = 2
    )              //   end of map()
    | t            //   yield t, which is supposed to be equal to 0
  )                // end of some()
\$\endgroup\$
0
4
\$\begingroup\$

APL (Dyalog Unicode), 8 bytesSBCS

Anonymous tacit prefix function. Returns 0/1.

∧/2=⊢∘≢⌸

Try it online!

 for each value as left argument and indices of occurrences of that value as right argument, call:

 tally the right argument (the occurrences)
 then
 return that, ignoring the left argument

2= Boolean list indicating which tallies are 2

∧/ AND-reduction (i.e. are they all true?)

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

MS SQL Server 2017, 152 150 146 bytes

CREATE FUNCTION f(@ NVARCHAR(MAX))RETURNS
TABLE RETURN SELECT IIF(2=ALL(SELECT
COUNT(*)FROM STRING_SPLIT(@,',')GROUP BY
PARSE(value AS INT)),1,0)r

The readable version:

CREATE FUNCTION f(@ NVARCHAR(MAX)) RETURNS TABLE RETURN
  SELECT IIF(2 = ALL(SELECT COUNT(*)
                     FROM STRING_SPLIT(@, ',')
                     GROUP BY PARSE(value AS INT)), 1, 0) AS r

Try it on SQL Fiddle!

-2 bytes thanks to Kevin Cruijssen

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Since you don't use the alias, can't the c be removed after the COUNT(*)? \$\endgroup\$ Jul 8, 2019 at 11:09
  • \$\begingroup\$ @KevinCruijssen, you are right, thank you. \$\endgroup\$ Jul 8, 2019 at 11:29
4
\$\begingroup\$

Haskell, 61 45 bytes

import Data.List
all((2==).length).group.sort

Try it online!

Thanks to @KevinCruijssen for 12 bytes, and @nimi for another 4.

First Haskell answer, but it was surprisingly easy to do. Can probably be golfed a lot. Case in point...

\$\endgroup\$
4
  • 3
    \$\begingroup\$ I don't know Haskell, but I'm pretty sure all(True==).map(2==) can be all(2==). :) \$\endgroup\$ Jul 8, 2019 at 13:45
  • 4
    \$\begingroup\$ ... and move length to all: all((2==).length).group.sort. No need to give the function a name, i.e. drop the f=. \$\endgroup\$
    – nimi
    Jul 8, 2019 at 13:47
  • \$\begingroup\$ Indeed, I overlooked the all(2==) when I was testing in GHCi. Thanks Kevin and Nimi, I'll update the answer. \$\endgroup\$
    – J. Sallé
    Jul 8, 2019 at 13:49
  • 4
    \$\begingroup\$ ... oh and for future use: all(True==) is and. \$\endgroup\$
    – nimi
    Jul 8, 2019 at 13:49
4
\$\begingroup\$

TI-Basic, 47 Bytes

Input(L1
SortA(L1
not(remainder(dim(L1,2)) and prod(not(△List(L1))=seq(remainder(I,2),I,1,-1+dim(L1

I am a big of fan of TI-Basic. It's not a great language for really any purpose, but I enjoy programming (and golfing) in it.

How does this code work?

First, it sorts the list.

Second, it uses the △List function to generate another list, which is the difference between elements of the sorted list. (For example, △List({1,3,7,8}) would yield {2,4,1}). Applies not to this list, which converts every non-zero element of the list to zero and every zero to one.

Then, the program checks that the resultant list fits the pattern {1, 0, 1, 0, ...}, which will only be true if the original list is a Noah list.

There is also an additional check that the length of the list is even, to catch some edge cases.

Here are some screenshots of test cases:

Some test cases Some more test cases

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

Julia, 30 characters 26 bytes

!a=all(x->2==sum(a.==x),a)

Thank you, H.PWiz for this trick!

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can have !a=all(x->2==sum(a.==x),a) for 26 bytes. NB. that I recommend counting in bytes on this site \$\endgroup\$
    – H.PWiz
    Aug 6, 2019 at 16:06
  • \$\begingroup\$ Thank you very much! I didn't know you could (ab)use ! for anonymous functions \$\endgroup\$ Aug 6, 2019 at 16:15
4
\$\begingroup\$

Jelly, 4 bytes

Qœ^Ƒ

Try it online!

Q       Is the list of unique elements
   Ƒ    unchanged by
 œ^     symmetric multiset difference with the whole input?

In broader terms, "if you remove each unique element once, do you have one of each left?" This is guaranteed to stay in the right order because œ^ is implemented as equivalent to œ-œ|œ-@, Qœ- is just empty, and œ- specifically removes elements last-first while Q is in the order of first appearances.

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

VDM-SL, 64 bytes

f(a)==forall y in set inds a&card{x|x in set inds a&a(x)=a(y)}=2

Explanation

VDM works predominantly like second order logic statements.

forall y in set inds a                //Bind y to each of the indices of a

{x|x in set inds a&a(x)=a(y)}         //build a set of the indices of a who have the same
                                      //value as the value at y

card {...} = 2                        //and check the cardinality of that set is 2

Since you can't TIO VDM here's output from a debug session

\$\endgroup\$
2
  • \$\begingroup\$ I know there probably isn't any online compiler for it, but could you perhaps add some screenshots of (some of) the test cases as verification? :) \$\endgroup\$ Jul 8, 2019 at 11:07
  • \$\begingroup\$ @KevinCruijssen saved some bytes fixing the bug, which probably made the code itself easier to understand. I'll add an explanation too :) \$\endgroup\$ Jul 8, 2019 at 11:41
3
\$\begingroup\$

PowerShell, 66 37 26 bytes

-11 bytes thanks to mazzy

!(($args|group|% c*t)-ne2)

Try it online!

Groups up $l and grabs all the counts of matching values. It then filters out all counts of 2 from this list. If the list is empty, it's a Noah number; otherwise, it'll be populated still with non-2 counts. Not-ing the list will yield True if it's empty and False if it's populated

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Fails if the values balance each other out.. i.e [1,2,1,1] so the count is 4, the count of unique is 2 and hence will resolve as noah despite not being noah. \$\endgroup\$ Jul 8, 2019 at 12:42
  • \$\begingroup\$ @ExpiredData Heck \$\endgroup\$
    – Veskah
    Jul 8, 2019 at 12:43
  • \$\begingroup\$ I tried this approach in another language before realising it just won't work... \$\endgroup\$ Jul 8, 2019 at 12:43
  • 1
    \$\begingroup\$ ¯\_(ツ)_/¯ 26 \$\endgroup\$
    – mazzy
    Jul 8, 2019 at 13:47
  • 1
    \$\begingroup\$ @mazzy Thanks. Forgot all about group being a thing that exists \$\endgroup\$
    – Veskah
    Jul 8, 2019 at 13:54
3
\$\begingroup\$

Elixir, 52 bytes

fn v->Enum.all?v,fn x->2==Enum.count v,&x==&1end end

Try it online!

Complete Elixir noob here :-D.

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

PHP, 60 bytes

function($a){return!array_diff(array_count_values($a),[2]);}

Try it online!

PHP has great built-ins for this, though at 20 chars, array_count_values() is not a very golfy one.

\$\endgroup\$
1
  • \$\begingroup\$ PHP always has great built-ins, with long names, sigh! \$\endgroup\$
    – Night2
    Aug 6, 2019 at 11:06
3
\$\begingroup\$

Mathematica, 25 24 bytes

MatchQ[{{_,2}..}]@*Tally

Try it online!

The Tally function returns a list of the form {{element, count}, ...}, which is then matched against a pattern that checks whether all count are 2.

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

Attache, 16 bytes

${All&x!{_~x=2}}

Try it online!

Explanation

${All&x!{_~x=2}}
${             }    lambda with input x
  All&x!{     }     over each element _ of x:
         _~x            check that the number of occurrences of _ in x
            =2          is 2

Alternatives

17 bytes: {All&_!`=&2@`~&_}

18 bytes: {All[`=&2@`~&_,_]}

23 bytes: Same@2&`'@Sum@Table[`=]

25 bytes: Same«2'Sum@Table[`=,_]»

25 bytes: Same<~2'Sum@Table[`=,_]~>

25 bytes: {Same[2'Sum@Table[`=,_]]}

35 bytes: {Commonest@_==Unique@_and _[0]~_=2}

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

Octave / MATLAB, 22 21 bytes

@(x)any(sum(x==x')-2)

Anonymous function that inputs a numeric vector, and outputs 0 if the vector satisfies the condition or 1 otherwise.

Try it online! Or verify all test cases.

Explanation

@(x)                   % define anonymous function with input x
            x          % x
               x'      % x transposed and conjugated
             ==        % equality comparison, element-wise with broadcast. Gives a
                       % square matrix
        sum(     )     % sum of each column
                  -2   % subtract 2, element-wise
    any(            )  % true if and only if any value is not zero
\$\endgroup\$
3
\$\begingroup\$

Julia 1.0, 32 bytes

l->sum(isone,l./l')/length(l)==2

Try it online!

Divides each element of the input array l by the transpose l' giving a matrix. Summing over this matrix while applying isone to each element gives twice the length of l if each element appears exactly twice.

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

K (oK), 9 bytes

Solution:

&/2=#:'.=

Try it online!

Explanation:

&/2=#:'.= / the solution
        = / group
       .  / value
    #:'   / count (length of) each
  2=      / equal to 2?
&/        / take minimum
\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 17 bytes

2==##&@@Counts@#&

Try it online!

Counts returns an association of <| (value)->(# occurences), ... |>. Then 2==##& checks if those occurence-counts are all equal to 2.

\$\endgroup\$
1
  • \$\begingroup\$ 2==##&@@ is brilliant! \$\endgroup\$
    – Roman
    Aug 6, 2019 at 12:20
3
\$\begingroup\$

Nekomata + -e, 4 bytes

oĉŤđ

Attempt This Online!

oĉŤđ
o       Sort
 ĉ      Split into runs of equal elements
  Ť     Transpose; fails if not rectangular
   đ    Check if length is 2

Nekomata + -e, 4 bytes

oĭu=

Attempt This Online!

oĭu=
o       Sort
 ĭ      Uninterleave
  u     Uniquify
   =    Check equality

Nekomata + -e, 4 bytes

Ţ≡2=

Attempt This Online!

Ţ≡2=
Ţ       Tally; produces a list of unique elements and a list of their counts
 ≡      Check if all counts are equal, and return that value
  2=    Check if equal to 2
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Nice answer! For a moment I was confused why you had a đ - Check if length is 2 builtin, but I saw it's actually an unpair builtin, which as side effect fails if the length isn't 2. :) \$\endgroup\$ Aug 21, 2023 at 12:33
2
\$\begingroup\$

Elm 0.19, 66 bytes

n a=List.all(\x->List.foldl(\y c->if x==y then c+1 else c)0 a==2)a

Verify all test cases here.

For every item, iterate over the list and count how many items it is equal to. Return True if the count is exactly 2 for each item, False otherwise.

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

Pyth, 7 bytes

!n#2/LQ

Try it online!

!n#2/LQQ   Implicit: Q=eval(input())
           Trailing Q inferred
     L Q   For each element of Q...
    / Q    ... count its occurrences in Q
  #        Filter keep those elements...
 n 2       ... which are not equal to 2
!          NOT - maps [] to True, others to False
           Implicit print
\$\endgroup\$
2
  • \$\begingroup\$ Another 7-byte solution is !smtt/Q \$\endgroup\$
    – RK.
    Jul 11, 2019 at 14:11
  • \$\begingroup\$ @RK Unfortunately.that one fails for input [1,2,2,2,3,4] :( \$\endgroup\$
    – Sok
    Jul 11, 2019 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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