3
\$\begingroup\$

As preparation for the nth Exodus, Noah decides to write a program that will decide If he will let animals on his ark. However, Noah wants to go back to grass roots. Thus he decides that the program should be as small and as simple as possible.

GOAL:
Recreate the Contrabulous Choosematron, in a way that follows evangelical stories.

INPUT:

The program is simple, and elegant, and takes in 2 inputs:
The species of animal [String]
and The animal's gender [boolean]

OUTPUT:

The program then puts out Either 'Y' or 'N', Which determines whether or not the given animal is allowed onto the ark.

RULES:

Only one Animal of each species and gender is allowed on the ark. No more.
Your output can be any set of boolean values (true false, yes no, y n, yin yang) so long as they're easily distinguishable.
If your program should want to accept a list of input, rather than use STDIN, that's fine. However, each output has to be in corresponding order of the input (FIFO), as well as be in the exact same format as the input.
This is a golf, so the lowest byte count wins, good luck!!!!

EXAMPLE:

"Monkey" true<
y
"Monkey" false<
y
"Monkey" false<
n
"Monkey with symbols" false<
y
"monkey" true<
n

This is valid, as your program doesn't need to distinguish that Monkey, and monkey with symbols are the same thing species, however, Monkey and monkey are very much the same thing, and so the last critter would be denied.

\$\endgroup\$
8
  • \$\begingroup\$ Could you add an example to your question for completeness? \$\endgroup\$
    – gowrath
    Sep 7, 2016 at 17:46
  • \$\begingroup\$ Will the species of animal only contain letters i.e. [a-zA-Z]? \$\endgroup\$
    – Riley
    Sep 7, 2016 at 17:49
  • \$\begingroup\$ @gowrath added! thanks for the suggestion! \$\endgroup\$
    – user56309
    Sep 7, 2016 at 17:51
  • \$\begingroup\$ @Riley some animals names may contain hyphens. Those animals are usually on the track to getting a divorce. However, I should note, all real species of animals are valid input, excluding the shortening period added to truncate their name. Some of those will include hyphens, and spaces. \$\endgroup\$
    – user56309
    Sep 7, 2016 at 17:52
  • 2
    \$\begingroup\$ @Jordan, no, he has a foam ochothorpe and ampersand that he carries around, and he won't give them up.... \$\endgroup\$
    – user56309
    Sep 11, 2016 at 20:26

11 Answers 11

3
\$\begingroup\$

Perl, 15 13 bytes

Includes +1 for -n

Input on STDIN (or 1 or more filenames as argument like cat), one animal and gender per line in any consistent notation. Prints a line with 1 for true, an empty line for false

perl -M5.010 -n ark.pl

ark.pl

say!${+lc}++
\$\endgroup\$
3
\$\begingroup\$

Python 2, 72 bytes

Takes input as a list of strings of the form "animalname T". The idea is it just uses each string as an identifier and should only print true if the string has not occurred in the list so far.

def f(l):k=map(str.lower,l);print[j not in k[:i]for i,j in enumerate(k)]

Try it here!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Very nice, and elegant entry. \$\endgroup\$
    – user56309
    Sep 7, 2016 at 18:23
1
\$\begingroup\$

Python, 54 52 50 bytes

def f(s,l={}):x=s.lower();r=x in l;l[x]=1;return r

Test case is at ideone

This borrows this neat idea from @gowrath, but extends it by using the fact that when a function is defined with a default argument that is mutable, like a dictionary, it acts as a memoisation (the object retains state between function calls).

Saved 2 bytes by returning None for truthy ("Y") and 0 for falsey ("N").
Save 2 more by (confusingly) returning False for truthy ("Y") and True for falsey ("N").

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

Perl (35 + 1 for -p) 36

Takes input from STDIN, one animal per line in the form animal T. Where T is anything you want to be used for the gender (e.g. T/F, M/F). You could even have multi-character genders, or more than 2 genders (e.g. male/female/apache helicopter).

Includes all character on the line, so if you're inputting from a file you need a newline after the last animal.

$\=($a{lc()}?N:Y);$a{lc()}=1;$_='';
\$\endgroup\$
0
\$\begingroup\$

PowerShell v3+, 33 bytes

$a=@();$args|%{$_-notin$a;$a+=$_}

Takes input as command-line arguments of strings of the form Animal Gender where Gender is (pretty much) any identifier you want. Sets an empty array $a, then loops through the input arguments. Places the Boolean result of the -notin operator on the pipeline, and adds the current element into the $a array. PowerShell by default is case-insensitive when comparing strings, so Monkey f, monkey f, mOnKeY F and other variations will all evaluate as the same.

The resulting Booleans are left on the pipeline, and output via implicit Write-Output happens at program completion.

Example

PS C:\Tools\Scripts\golfing> .\noahs-upgraded-ark.ps1 'Monkey m' 'Monkey f' 'Monkey f' 'Monkey with symbols m' 'monkey m'
True
True
False
True
False
\$\endgroup\$
0
\$\begingroup\$

Dyalog APL, 16 bytes

Case sensitive solution:

(⍳⍴)∊(∪⍳⍨)

(⍳⍴) which indices

are member of

⍳⍨ each entry's first occurrence in the list

Unfortunately, case-insensitivity is bulky:

(⍳⍴)∊(∪c⍳c←819⌶)

c←819⌶ assign the lowercase function to c

c⍳c is the same as ⍳⍨c. See explanation above.

TryAPL online! (casing is not supported on TryAPL)

\$\endgroup\$
5
  • \$\begingroup\$ Could you or each character with space (32) to get a mock lowercase mapping ? That seems OK with the restricted set of special characters that ineeds to be supported \$\endgroup\$
    – Ton Hospel
    Sep 8, 2016 at 6:22
  • \$\begingroup\$ @TonHospel or? \$\endgroup\$
    – Adám
    Sep 8, 2016 at 6:51
  • \$\begingroup\$ Bitwise or of the ASCII codes. A is 0x41, or with space (0x20) and get a (0x61). Some languages allow an or directly on the characters themselves. I have no idea if APL easily supports this \$\endgroup\$
    – Ton Hospel
    Sep 8, 2016 at 7:22
  • \$\begingroup\$ @TonHospel No, APL only adjusts number of bits used to represent numbers (1,8,16,32,64,128) or characters (8,16,32), but you have to be explicit to convert characters to numbers or vice-versa. \$\endgroup\$
    – Adám
    Sep 8, 2016 at 8:16
  • \$\begingroup\$ 14 bytes: ⍳∘⍴∊∘∪(⍳⍨819⌶) \$\endgroup\$ Feb 15, 2018 at 0:04
0
\$\begingroup\$

Groovy 43 Bytes

{s->y=[];s.collect{!y.contains(it)&&y.add(it)}}

Try it here: https://groovyconsole.appspot.com/edit/5147446497771520

It uses a list of tuples as the input:

z = [new Tuple('Monkey',true), new Tuple('Monkey',false), new Tuple('Monkey',true), new Tuple('Bee',true)]

Which results in:

[true, true, false, true]

The add function in groovy always returns true, and in groovy tuples have inherent comparison ability for primitive objects, so the contains actually works well for strings and integers without changing it.

So, basically just check if the list contains it and add it to the list.

  • If the list already contains it we get (false && N/A)
  • If it does not we get (True && True) and it is added to the running list.

This is all you really need to accomplish this, if you want to tell me to turn it into a closure or something as well it would probably cap out at approximately 45-50 bytes in Groovy.

\$\endgroup\$
1
  • \$\begingroup\$ It's a code snippet, which is not allowed. You must post a full program or a function. \$\endgroup\$ Sep 8, 2016 at 12:09
0
\$\begingroup\$

Java, 246 218 bytes

Lowered byte count thanks to Kevin!.

Takes STDIN as input, outputs weather or not the animal is allowed to board.

import java.util.*;class B{public static void main(String[]a){List l=new ArrayList();Scanner s=new Scanner(System.in);for(;;){String b=s.nextLine().toLowerCase();l.add(b);System.out.println(l.contains(b)?"n"‌​:"y");}}}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can golf it quite a bit by removing unnecessary spaces. Also, you can remove public before class, change args to a, etc. Also, you should include the imports you use. Here is your code golfed: import java.util.*;class B{public static void main(String[]a){List l=new ArrayList();Scanner s=new Scanner(System.in);for(;;){String b=s.nextLine();if(l.contains(b))b="n";else{l.add(b);b="y";}System.out.println(b);}}} (217 bytes) You might like to read through Tips for golfing in Java. :) \$\endgroup\$ Sep 8, 2016 at 7:17
  • 1
    \$\begingroup\$ Since you use contains to check if it's in the list or not, it doesn't matter if it's added a second, third, etc. time. So you can just always add it and use a ternary check to directly print it. So it becomes this: import java.util.*;class B{public static void main(String[]a){List l=new ArrayList();Scanner s=new Scanner(System.in);for(;;){String b=s.nextLine();l.add(b);System.out.println(l.contains(b)?"n":"y");}}} (202 bytes) \$\endgroup\$ Sep 8, 2016 at 7:28
  • 1
    \$\begingroup\$ Hmm btw, you neglected one of your own rules atm ("however, Monkey and monkey are very much the same thing, and so the last critter would be denied.") - you forgot to use .toLowercase() somewhere. \$\endgroup\$ Sep 8, 2016 at 13:24
  • \$\begingroup\$ @KevinCruijssen is import *; or import *.*; a valid statement in java golfing? it used to work in java 6.... \$\endgroup\$
    – user56309
    Sep 8, 2016 at 15:14
0
\$\begingroup\$

Swift 2.2 169 bytes

I did not accept input from standard in I just passed an array of dictionaries to function x.

Golfed

var a=[String]();let x={(d:[[String:Bool]]) in for r in d{for(s,t)in r{let y=s.lowercaseString+t.description;a.append(y);print(a.indexOf(y)==(a.count-1) ? true:false)}}}

UnGolfed

var a=[String]();
let x={(d:[[String:Bool]]) in
    for r in d{
        for(s,t)in r{
            let y=s.lowercaseString+t.description;
            a.append(y);
            print(a.indexOf(y)==(a.count-1) ? true:false)
        }
    }
}

Input

x([["Monkey":true],["Monkey":false],["monkey":true],["Zebra":true]])

Also just for giggles did a crappy javascript version since I did not see anyone else do a javascript one.

JS (ES6) 125 bytes

Golfed

a=[],i=0,j=0;y=(r)=>{for(;j<r.length;j+=2){var y=r[j].toLowerCase()+r[j+1];a[i]=y;console.log(a.indexOf(y)==i++?true:false)}}a=[],i=0,j=0;y=(r)=>{for(;j<r.length;j+=2){var y=r[j].toLowerCase()+r[j+1];a[i]=y;console.log(a.indexOf(y)==i++?true:false)}}

UnGolfed

a=[],i=0,j=0;
y=(r)=>{
  for(;j<r.length;j+=2){
    var y=r[j].toLowerCase()+r[j+1];
    a[i]=y;
    console.log(a.indexOf(y)==i++?true:false)
  }
}

Input

y(["Monkey", true, "Monkey", false, "monkey",true,"zebra",false])
\$\endgroup\$
0
\$\begingroup\$

Jelly, 4 bytes

ŒuŒQ

Try it online!

Each animal in the list (argument) is [species, gender], where gender can either be 1 for male or 0 for female. Output is a list of 0s and 1s, where 0 means "not allowed" and 1 means "allowed". This is a function, and therefore a footer has been added to show the actual result.

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

Ruby, 50 48 bytes

->a,*s{a.map{|x|x[0].upcase!
(s<<x).count(x)<2}}

Try it online!

A lambda accepting an array of [animal, gender] pairs and returning a boolean array.

-2 bytes: Initialize the list of seen animals as a splat arg

->a,*s{                # s is the list of animals seen so far, initially []
  a.map{ |x|           # x is the current animal
    x[0].upcase!       # Transform x's name in place to uppercase
    (d<<x).count(x)<2  # Add x to s, and return true if s has only 1 instance of x
  }
}
\$\endgroup\$

Your Answer

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