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
    Commented Jul 8, 2019 at 10:12

68 Answers 68

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

Bash, 26 bytes

Exit code is nonzero iff the list is of Noah.

sort|uniq -c|grep -v ' 2 '

Try it online!

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

Factor, 53 bytes

: f ( s -- ? ) dup counts [ last ] map [ 2 = ] all? ;

Unfortunately dosn't work in TIO. Here's a screenshot of the Factor Listener (REPL):

Lists-of-Noah Factor Listener

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

Python 3, 37 bytes

lambda l:all(l.count(i)==2for i in l)

Try it online!

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

Powershell (5.1), 20 48* Bytes:

I setup my variables like this (which may not be correct):

 $a = (7,13,9,2,10,2,4,10,7,13,4,9)

I then add that variable to:

$a |group|%{$m=@{}}{$m[$_.Name]=($_.Count)-eq2}{$m}

This outputs the "Name" and "True" or "False" (could also use the animals names & it would work)

  • group - Groups the items
  • % - Abbreviation for For-Each
  • $m=@{} - Assigns the new variable
  • $_.Count-eq2 - Item count that equals 2
  • $y - List each item with True or False (if it equals 2)

Results are similar to this:

Output

*Note: This answer has been edited as I bungled things the first multiple times...

\$\endgroup\$
5
  • \$\begingroup\$ I think that screenshot is from a different challenge? :S Could you perhaps post a screenshot with some of the test cases for this challenge as verification? \$\endgroup\$ Commented Jul 9, 2019 at 6:17
  • \$\begingroup\$ Standard rules requires that the code should be "programs or functions". For Powershell, this means that the code can be saved as a file with the .ps1 extension and executed as a script. Your code is a snippet, not "programs or functions". \$\endgroup\$
    – mazzy
    Commented Jul 9, 2019 at 8:13
  • \$\begingroup\$ Sorry, I bungled this one. I reused my variables so it appeared my code was working great. I may have misunderstood the variables as well. I am updating my answer again now. \$\endgroup\$
    – DBADon
    Commented Jul 10, 2019 at 16:58
  • \$\begingroup\$ I edited my post and it should work now. I think I can make it a bit smaller if I set it up differently and use the original $a variable & remove the need for the $m. I just don't have time to work it out right now... \$\endgroup\$
    – DBADon
    Commented Jul 10, 2019 at 17:19
  • 1
    \$\begingroup\$ A few things: Your current code is 51 bytes, here's some examples on how to make your code take proper arguments, and lastly: your code stops one step short of finishing the problem. You have all the bools you need, still need to reduce it into one true/false return. Good first attempt though! \$\endgroup\$
    – Veskah
    Commented Jul 12, 2019 at 12:38
2
\$\begingroup\$

Jelly, 5 bytes

ċⱮ=2P

Try it online!

Not shorter than, but different than the existing jelly answer.

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

///, 358 299 bytes

/|/\/\///`/'\\|&/%`\%`\%T;`\%R;N`\%T;`\%|:/\\\\|;/`\`\|_/%%|%/`/|%<-::>:::|QT/%R'N%Q'T_<-;>%<-;;>;;_<`->%_L`S%L'S_-` *%-`{*[_-`{*%{-_!`{%{!_^`{*%^{-_[`*%*[_-`*%*-_!`*%*!_-`[%[-_!`[%[!_{`[%!_^`!%^-!_-`$%$_-`!!`$%$_-`!$&0_!`!!$&0_^`$&1_Q`T%Q'T%R'N|RN/QT|<-:>/<-::>::|<\->/|!*/!-|-*/--|LS/^!DATA GOES HERE$|Q\T/QT/RN

Try it online!

Try it online! (legible-ish version)

I don't know if this is the first Code Golf answer which uses an actual computational loop in slashes, but I'm very proud of it regardless. The loop construction I use is due to Ørjan Johansen, and is elaborated on on the wiki (although not in very high detail, and he uses | instead of '). There is a whole lot of escaping involved.

Input is in the form of a string which replaces DATA GOES HERE in the source code. The string should be a -delimited list of unary numbers with * representing one. Output is 1 if the list is a list of Noah, 0 if it is not.

Explanation

  • The program revolves around the manipulation of the input string, which is prefixed by ^! and suffixed by $. First, the following two substitutions are made: /!*/!-/ and /-*/--/, which turn the first number of the input into dashes. It will be the number line for recording the whole list.
  • The rest of the program is inside a loop (not presented in the same order as in the program). First, it organizes the data
/- */-\{*[/ /[*/*[/    turn the next number into a "rocket"
                       eg `^!--- **` => `^!---{**[`
/-{*/{-/               the front of the rocket moves forward by "using up fuel"
/!{/{!/                moving forward through a `!` does not cost any fuel
/-*/*-/ /!*/*!/ /-[/[-/ /![/[!/
                       the rest of the rocket follows the head
/^{*/^{-/              the rocket extends the number line if it runs out of room
/{[/!/                 once the rocket runs out of fuel, it becomes a `!`
  • Since a rocket travels a number of -s equal to the number it came from, the result is a backwards number line where every member of the original list is marked with !s, eg ^!*** ** *** *****$ => ^!--!!-!--$
  • When the last number turns into a rocket, the $ begins inspecting the number line:
/^!/^-!/                 needed for some of the following to work
/-$/$/ /-!!$/$/          the inspector finds things satisfactory so far
/-!$/N\O/ /!!!$/N\O/     the inspector has rejected this input
/^$/Y\S/                 the inspector has accepted this input
  • The loop works by replacing a "variable" RN with a copy of the relevant code. The simplest way to stop the loop and output the result is to conditionally replace RN with the result so that the loop can't continue. We do this by replacing YS and NO with a replacement that replaces RN with the relevant value: /YS/\/\/T\\\/R\\N\/T\\\/1/ /NO/\/\/T\\\/R\\N\/T\\\/0/. (It is //f/r instead of /f/r/ because the YS and NO values already exist inside a replacement, so it becomes works like, eg, /LS/YS/ => /LS///RN/1/

Notes

Variables are two letters because you have to be able to escape them by putting a \ in the middle (/V\R/val/ is equivalent to /VR/val/), otherwise they'll replace themselves in the copy that's used for looping.

At the beginning of the program are several "golfing substitutions" which serve no purpose other than to make the program shorter and even less legible.

59 bytes saved by using direct replacement instead of YS and NO, and doing 2 more golfing substitutions (& for the replacement-replacement which is nearly the same for accepting and rejecting, and ` for '\)

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

Factor, 32 bytes

[ histogram [ 2 = ] assoc-all? ]

Try it online!

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

Vyxal, 5 bytes

vO2J≈

Try it Online!

Makes a list of how many times the integer exists in the list, adds 2 to the list and checks if everything is equal. A sneaky way to check if all the items are equal, and that they are all 2.

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

K (ngn/k), 14 bytes

{*(2=#'.=x)^1}

Try it online!

This one is a little bit lengthier than it needs to be though. Return 0N (i.e. null) for true and 0 for false.

Explanations:

{*(2=#'.=x)^1}  Main function. Takes x as input
  (      x)     x
        =       Group. Returns a dictionary with the keys being the values
                that appear in the array, and the values being the position
                of the corresponding key.
       .        Get just the value
     #'         Get the length for each of them
   2=           See if it's equal to 2
            ^1  Eliminate 1s in the result (i.e. remove truthy values)
 *              Get the first element
\$\endgroup\$
2
\$\begingroup\$

Thunno 2, 4 bytes

c⁻pḅ

Attempt This Online!

Port of Emigna's 05AB1E answer.

Explanation

c⁻pḅ  # Implicit input
c     # Counts of each element
 ⁻    # Decrement each
  p   # Product of this list
   ḅ  # Equals one?
      # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 7 bytes

⬤θ⁼²№θι

Try it online! Link is to verbose version of code. Outputs - for a List of Noah. Explanation:

 θ      Input array
⬤       Do all elements satisfy the condition
    №   Count of
      ι Current element
     θ  In input array
  ⁼     Equals
   ²    Literal 2
        Implicitly output
\$\endgroup\$
1
  • \$\begingroup\$ Whoa, that's one very charcoal circle. \$\endgroup\$
    – Adám
    Commented Jul 8, 2019 at 10:08
1
\$\begingroup\$

Retina 0.8.2, 32 bytes

O`\d+
(\d+)(,\1)*\b
$#2
^1(,1)*$

Try it online! Link includes test cases. Explantion:

O`\d+

Sort the integers. (This is a string sort but it doesn't matter assuming no leading zeros.)

(\d+)(,\1)*\b
$#2

Count the number of duplicates of each integer.

^1(,1)*$

Each integer should have one other duplicate.

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

Wolfram Language (Mathematica), 38 bytes

Gather@#~Cases~{_,_}~Total~2==Total@#&

Try it online!

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

Stax, 5 bytes

é♪Ccv

Run and debug it

Algorithm:

  1. Sort array.
  2. Get run-lengths.
  3. Remove all 2s from run-lengths.
  4. Result is empty?
\$\endgroup\$
1
\$\begingroup\$

Red, 52 bytes

func[b][(extract sort b 2)= unique extract next b 2]

Try it online!

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

Python 3, 41 bytes

lambda x:set([x.count(i)for i in x])=={2}

Try it online!

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

C, 84 83 bytes

c['   '],r,*p,*s,*e;f(){for(p=s;p<e;)c[*p++]++;while(s<e)r=c[*s++]-2?1:r;return r;}

Try it online!

f() returns 1 if the list is not a list of Noah, and 0 otherwise.

The variable s should point to the beginning of the array, and e should point to the end. Note that after f() is called, c must be reset to 0s before it can be called again. Also, this might not work on all computers, because I'm pretty sure multi-byte characters are implementation-defined, and it won't work if INT_MAX < 100000.

If I/O is very flexible, and outputting to a variable is enough, the return r; is unnecessary, and it can be reduced to 74 bytes.

De-golfed:

int counts[100001], return_value;

int f(int *start, int *end) {
        int *ptr;
        for (ptr = start; ptr < end; ptr++)
                counts[*ptr]++;
        for (ptr = start; ptr < end; ptr++) {
                if (counts[*ptr] != 2) {
                        return_value = 1;
                }
        }
        return return_value;
}

Thanks to @ceilingcat for -1 byte!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Functions should preferrably be reusable without massaging external values. \$\endgroup\$
    – gastropner
    Commented Jul 9, 2019 at 9:51
1
\$\begingroup\$

Dart, 66 bytes

f(n)=>n.map((m)=>n.where((o)=>o==m).length==2).reduce((p,e)=>p&e);

Try it online!

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

APL(NARS), 9 chars, 18 bytes

{⍵≡⍦,⍨∪⍵}

test:

  f←{⍵≡⍦,⍨∪⍵}
  f 7,13,9,2,10,2,4,10,7,13,4,9
1
  f 77,31,5,31,80,77,5,8,8
0
  f 2,4,6,4,4,4
0
\$\endgroup\$
1
\$\begingroup\$

Japt, 6 bytes

Outputs false for true and true for false.

ü mÊdÍ

Try it or run all test cases

ü mÊdÍ     :Implicit input of integer array
ü          :Group by value
  m        :Map
   Ê       :  Length
    d      :Any truthy (not 0)?
     Í     :  When subtracted from 2
\$\endgroup\$
1
\$\begingroup\$

Vim, 45 bytes

:sor|%norm J
:g/^\v(.*) \1$/d
:g/./norm ggcG0

Try it online!

This will output nothing for a valid Noah list, and a 0 for an invalid Noah list.

\$\endgroup\$
3
  • \$\begingroup\$ This unfortunately does not work for testcases like 7 7 7 7, but anyways, here's a solution at 33 bytes :sor<cr>qq*djkj@[email protected]<esc>qu@a \$\endgroup\$
    – user41805
    Commented Aug 6, 2019 at 10:43
  • \$\begingroup\$ tio.run/… \$\endgroup\$
    – user41805
    Commented Aug 6, 2019 at 10:43
  • \$\begingroup\$ 31 tio.run/… \$\endgroup\$
    – user41805
    Commented Aug 6, 2019 at 16:37
1
\$\begingroup\$

Brainfuck: 69

->+[>+<-[[-]+>->>[-]]+>[->++[-<<<+]->>]<,]>>>[>>[--[[-]>>-<[-]<]]>]>.

The bf interpreter/compiler needs to support 0 as EOF. It also need at least 300003 cells for be be used with number upto 100000. beef seems to match this.

The numbers are expected to come in as unary (whatever) terminated by ascii 1. It will output chr 0 on a valid set and chr 99 on an invalid set. If your terminal has UTF-8 you'll get some complaints or a replacement chars (the ?) as an indication.

The code uses bf memory as the first cell as an -1 flag that it seeks to after every number. Each number triggers it to jump 3 cells, since I have a 3 cell item and the whole BF memory is considered an array:

flag (-1) [ visited | flag | count ]* 

Thus if you supply 3 it will set count on the third index to 1 and every visited flags to 1 upto that.

I've tested like this:

#!/usr/bin/fish
set -l tests '[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]
[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]
'

for in in (echo $tests)
  echo -n $in :
  echo $in | perl -pe 's/(\d+)/"1" x $1/ge;s/[^\]\d,]//g;s/(?:]|,)/\x01/g;' | beef  moses.bf
  echo ''
end

And got the following output:

[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] :
[6,4,4,6,4,7,4,7] :[Invalid UTF-8] \xff
[2,2,2,2,2,2] :[Invalid UTF-8] \xff
[5,1,4,5,1,1,4] :[Invalid UTF-8] \xff
[77,31,5,31,80,77,5,8,8] :[Invalid UTF-8] \xff
[1,2,3,2,1] :[Invalid UTF-8] \xff
[44,4,4] :[Invalid UTF-8] \xff
\$\endgroup\$
1
\$\begingroup\$

Swift 5.1, 63 bytes

let x={(a:[Int])in a.allSatisfy{v in a.filter{v==$0}.count==2}}

When the count(where:) function will be available, it'll become:

let x={(a:[Int])in a.allSatisfy{v in a.count{v==$0}==2}}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$
    – Laikoni
    Commented Jul 31, 2019 at 11:56
  • 1
    \$\begingroup\$ Four years and seven minor releases later, and count(where:) is still in purgatory because the type-checker couldn't handle it. Regardless, I think you can drop the let x= and the explicit type, so just {a in a.allSatisfy{v in a.filter{v==$0}.count==2}} would be a valid spelling of this answer. \$\endgroup\$
    – Bbrk24
    Commented Jun 21, 2023 at 19:01
1
\$\begingroup\$

Kotlin, 46 45 bytes

fun f(l:IntArray)=l.all{l.count{i->it==i}==2}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$
    – Laikoni
    Commented Jul 31, 2019 at 11:54
1
\$\begingroup\$

jq, 30 characters

group_by(.)|map(length==2)|all

Sample run:

bash-5.0$ jq 'group_by(.)|map(length==2)|all' <<< '[7,13,9,2,10,2,4,10,7,13,4,9]'
true

Try it online!

Try all test cases online!

\$\endgroup\$

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.