25
\$\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\$
  • 12
    \$\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 at 10:12

54 Answers 54

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\$
  • \$\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\$ – Kevin Cruijssen Jul 9 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 Jul 9 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 Jul 10 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 Jul 10 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 Jul 12 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\$

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\$
  • \$\begingroup\$ 2==##&@@ is brilliant! \$\endgroup\$ – Roman Aug 6 at 12:20
1
\$\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\$
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\$
  • \$\begingroup\$ Whoa, that's one very charcoal circle. \$\endgroup\$ – Adám Jul 8 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\$

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\$
  • \$\begingroup\$ Another 7-byte solution is !smtt/Q \$\endgroup\$ – RK. Jul 11 at 14:11
  • \$\begingroup\$ @RK Unfortunately.that one fails for input [1,2,2,2,3,4] :( \$\endgroup\$ – Sok Jul 11 at 15:27
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\$
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
    \$\begingroup\$ Functions should preferrably be reusable without massaging external values. \$\endgroup\$ – gastropner Jul 9 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\$
  • \$\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@qquG@qqar.ggcG0<esc>qu@a \$\endgroup\$ – Cows quack Aug 6 at 10:43
  • \$\begingroup\$ tio.run/… \$\endgroup\$ – Cows quack Aug 6 at 10:43
  • \$\begingroup\$ 31 tio.run/… \$\endgroup\$ – Cows quack Aug 6 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\$
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$ – Laikoni Jul 31 at 11:56
1
\$\begingroup\$

Kotlin, 46 45 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Welcome to the site! \$\endgroup\$ – Laikoni Jul 31 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\$
1
\$\begingroup\$

PHP, 58 bytes

for(;$n=$argv[++$i];$a[$n]++);echo min($a)==2&&max($a)==2;

Each number in the list is passed as an argument.

Outputs 1 for truthy and nothing for falsey.

Try it online!

Tests

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

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.