29
\$\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
  • 13
    \$\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

55 Answers 55

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
14
\$\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
  • 7
    \$\begingroup\$ While fun, this breaks the rules by not being a serious contender. \$\endgroup\$
    – Adám
    Jul 8, 2019 at 9:32
  • 7
    \$\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
  • 4
    \$\begingroup\$ @DaniilTutubalin No, removing comments is an obvious way to shorten code, so it isn't well-golfed. And one cannot just make up restricted-source requirements on a pure code-golf challenge and claim superiority based on that. If the author of this answer wants to do so, they may ask the challenge author to (or for permission to) post such a challenge. \$\endgroup\$
    – Adám
    Jul 8, 2019 at 10:13
  • 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
  • 7
    \$\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
13
\$\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
10
\$\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\$

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\$

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\$
1
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
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\$

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\$

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
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\$

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\$

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
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\$

Jelly, 5 bytes

ĠẈ=2Ạ

Try it online!

A monadic link that takes a list of integers and returns 1 if a Noah list and 0 if not.

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

MATL, 6 bytes

8#uqqa

Try it online!

0 for truthy, 1 for falsy. Ports Robin Ryder's answer.

MATL, 6 bytes

&=s2=A

Try it online!

1 for truthy, 0 for falsy. Ports Luis Mendo's answer.

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

Ruby, 29 bytes

->a{a.all?{|e|a.count(e)==2}}

Try it online!

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

Kotlin, 96 77 69 51 bytes

fun f(t:List<Int>)=t.count{t.count{i->it==i}!=2}==0

Try it online!

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

Excel, 45 bytes

=SUM(IF(FREQUENCY(A:A,A:A)=2,1))=COUNT(A:A)/2

Assumes data in column A, with this entered in any cell other than one in column A. Returns TRUE if there are pairs and FALSE if they are not matching pairs

        FREQUENCY(A:A,A:A)                     Counts how many of each value there is
     IF(                  =2,1)                If this is 2, add value of 1 to array otherwise 0
=SUM(                          )               Sum the count in that array that have a exactly 2
                                 COUNT(A:A)/2  Count how many total values in column
                                =              If this is equal, return TRUE else FALSE

Tried removing the /2 and adding .5 for the summing, but this did not work.
Tried counting the frequencies that are <>2 and this did not return the right amount.

\$\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.