# Give me odd, even, square, cube, prime and composite 3-digit numbers

Given a string which is guaranteed to be either odd, even, square, cube, prime or composite, your program or function must return an integer $$\100\le N\le 999\$$ which meets this description.

## Rules

• Your code must be deterministic.
• The choice of the integers is up to you. However, the six answers must be distinct. (For instance, if you return $$\113\$$ for odd, you cannot return $$\113\$$ for prime.)
• You may take the input string in full lower case (odd), full upper case (ODD) or title case (Odd) but it must be consistent.
• This is .

## Example

Below is an example of valid I/O:

• odd → $$\501\$$
• even → $$\140\$$
• square → $$\961\$$ ($$\=31^2\$$)
• cube → $$\343\$$ ($$\=7^3\$$)
• prime → $$\113\$$
• composite → $$\999\$$ ($$\=37\times 3\times 3\times 3\$$)

## Brownie points

For what it's worth, my own solution in JS is currently 24 bytes. So, brownie points for beating that.

JavaScript (ES6), 24 bytes

MD5: 562703afc8428c7b0a2c271ee7c22aff


Edit: I can now unveil it since it was found by tsh (just with a different parameter name):

s=>parseInt(s,30)%65+204

• I presume the string is not going to have the quotes around it? Jun 23, 2021 at 15:42
• At first, I thought this was simply 6 different-ish challenges wrapped into one, but the fact that it isn't a sequence and it can be any number in the range makes it a lot more interesting.
– user
Jun 23, 2021 at 15:44
• I don't often downvote things by Arnauld, but I don't like questions that are "let someone smart find a very short formula and then FGITW it in every language under the sun", and I really don't like them when said formula is found in 10 minutes Jun 23, 2021 at 15:54
• @pxeger tbf, he was hoping it would take a little more time before someone came up with it.
Jun 23, 2021 at 15:57
• @pxeger agreed, not going to downvote but not going to upvote either. Jun 23, 2021 at 15:57

# Python 2, 25 22 bytes

lambda s:hash(s)%591^1


Try it online!

Takes input in upper case and returns the following numbers:

ODD        -> 263
EVEN       -> 554
SQUARE     -> 121
CUBE       -> 512
PRIME      -> 349
COMPOSITE  -> 371


Generated with this script which searches for formulas following hash(s)%x?y, where ? is any binary operator:

from sympy import primerange

# from tqdm.notebook import tqdm

hashes = [
3275334880723988284, -8482906173967949472, -4710393751006474557,
1654718638908055491, -6487253012923789248, 8925015453505786600
]

int.__sub__, int.__rshift__, int.__lshift__,
int.__xor__, int.__or__, int.__and__,
int.__pow__, int.__floordiv__
}

primes = set(primerange(100, 1000))
squares = {x**2 for x in range(10, 32)}
cubes = {x**3 for x in range(5, 10)}

# for x in tqdm(range(6, 1000)):
for x in range(6, 1000):
for y in range(1, 100):
a, b, c, d, e, f = r = [z(h%x, y) for h in hashes]
if (
len(set(r)) == 6
and min(r) > 99
and max(r) < 1000
and a%2 == 1
and b%2 == 0
and c in squares
and d in cubes
and e in primes
and f not in primes
):
print(x, y, z)


Try it online!

# JavaScript (Node.js), 29 bytes

n=>121+'qvdou r'.search(n)


Try it online!

## How?

I found six numbers which were close to 121, then simply placed them strategically.

And also thanks to Arnauld for reminding me of the search method.

• TBH, I was hoping it would take a little more time before someone came up with that one. :-p Well done! Jun 23, 2021 at 15:52
• @Arnauld Thanks, when I saw the challenge, that somehow sprung into my mind. Took some time to find the right area to place the numbers, though.
– user100690
Jun 23, 2021 at 15:52
• BTW, you can use search instead of indexOf. Jun 23, 2021 at 15:54
• You can save 1 byte by removing 'q' and using 122. Jun 24, 2021 at 7:58
• @Kruga Thanks, but someone already posted an answer that does that, so I'll pass on that.
– user100690
Jun 24, 2021 at 8:00

# Brachylog, 10 bytes

Takes in the input in full upper case. Sum of the character code points times 415 mod 998. A sum-less version would multiply the second element with 493, modulo 583.

ạ+×₄₁₅%₉₉₈


Try it online!

┌───┬────┬──────┬────┬─────┬─────────┐
│ODD│EVEN│SQUARE│CUBE│PRIME│COMPOSITE│
├───┼────┼──────┼────┼─────┼─────────┤
│403│580 │361   │343 │431  │339      │
└───┴────┴──────┴────┴─────┴─────────┘


Found with this crude J script, typing in the operations manually:

NB. returns 1 iff correct solution
test_f =: =@i.@# ([ -: *) [: (1 = 2&|)(0 = 2&|)((= <.)@%:)(3 (= <.)@%: ])(1&p:)(1 < #@q:):0 [:(**/@~:)  (* <&1000 * >&99)"0
NB. try some variants
vars =: ,/ (a=:i.1000)|/ (b=:i.1000)*/ (1#.3&u:)&> ODDEVENSQUARECUBEPRIMECOMPOSITE
NB. show valid solutions
(((,/a,"0/b),.&<"1 [) #~ (test_f :: 0)"1) vars

• Is taking it in uppercase allowed? Jun 23, 2021 at 17:34
• @rak1507 You may take the input string in full lower case (odd), full upper case (ODD) or title case (Odd) but it must be consistent.
– xash
Jun 23, 2021 at 17:38
• Uh, but it sure looks like you're taking it as code points.
Jun 23, 2021 at 17:56
• @Adám I was pretty sure, there was a meta-consensus for it, but I cannot find it. Well, I put in a bytecount equal Brachylog answer in. Not that it makes this answer/challenge more interesting, but alas …
– xash
Jun 23, 2021 at 18:25
• I think separate languages should go into separate posts.
Jun 23, 2021 at 18:26

# Python 3, 22 21 bytes

lambda x:628*x%831


Try it online!

Takes input in uppercase as a byte string. Takes the penultimate character's code, and applies some hashing to get:

ODD => 323
EVEN => 120
SQUARE => 196
CUBE => 729
PRIME => 139
COMPOSITE => 158


Found using this brute-force program: Try it online!

PS: I retract my downvote. Writing and optimising various brute-force programs was actually quite fun. (I don't think it's great to have too many challenges like this, though)

• +1 but are we allowed to accept a bytearray when the specification is a "string in full lower case (odd), full upper case (ODD) or title case (Odd)"? (If so I have 21.) Jun 23, 2021 at 19:31
• @JonathanAllan what's your 21? Does it use a different hash? If not, I'm struggling to see how this can be shorter. And I'm not completely sure what you mean by "but are we allowed to accept a bytearray" - do you mean that you think mine is invalid (it accepts bytes not bytearray, and bytes is allowed by consensus), or do you mean that accepting bytearray instead of bytes allows a -1 golf (what?)? Jun 23, 2021 at 19:37
• Sorry bytes (bytearray is a function to go from str to bytes). Yeah, a different hash - it's in my Python 2 post. Where is the consensus, since people are asking about character codes too? Jun 23, 2021 at 19:43
• @JonathanAllan This (at +11/-4 I think it meets our definition of consensus), but regardless they're definitely generally accepted as an alternative for string input Jun 23, 2021 at 19:51
• @JonathanAllan By the way, bytearray is a distinct type of its own, basically a mutable version of bytes Jun 23, 2021 at 19:54

# Rattle, 21, 20 18 bytes

|Ig1n+8s%7[3g+5s]g


Try it Online!

This is my first ever answer with my own interpreter running on my own website!!!

# Outputs

odd: 113
even: 126
square: 121
cube: 125
prime: 127
composite: 119


# Explanation

|                 takes the user's input as a string
I                splits this string into characters and stores them in consecutive memory
slots
g1              gets the character at index 1 (2nd character, Rattle is 0-indexed)
n             converts this character to its ASCII code (int value)
+8           adds 8 to this value
s          saves this value to memory at the current pointer

%7             takes mod(7) of the value on top of the stack. This gives three for
inputs of "prime" and "odd" (which are special cases)
[3 .... ]    if the value on top of the stack is three, the code in this if statement
executes
g         gets the value from memory at the pointer
+5       adds five to this value to fix the special cases
s      saves the result to memory
g   gets the value saved in memory, prints implicitly


• that color scheme is... interesting. glad you got it working though, and +1 :P Jun 23, 2021 at 17:45

# Jelly,  8  7 bytes

-1 thanks to the default. (looked for shorter salt/domain combinations with domains other than the one byte 1000 I'd considered and the different case formats allowed in the OP.)

91,651ḥ


A monadic Link accepting a list of characters that yields an integer:

input      output   (notes)
odd        897
even       516
square     625      (25²)
cube       125      (5³)
prime      347
composite  752      (2⁴×47)


Try it online!

### How?

91,651ḥ - Link: list of characters, S
,   ḥ - hash (S) using...
91      - ... salt: literal = 91
651  - ... domain: literal 651 (i.e. a domain of [1..651])


The salt for the 8 byte version, using a domain of [1..1000] and only the lower-case version of the inputs, was found using this Python code (Try it online!); it can easily be modified to search other domains and to go through the three allowed case formats:

import hashlib

from sympy import isprime

def main():
odds = set(range(101, 1000, 2))
evens = set(range(100, 1000, 2))
primes = set()
composites = set()
for n in range(100, 1000):
if isprime(n):
else:
squares = {n ** 2 for n in range(10, 32)}
cubes = {n ** 3 for n in range(5, 11)}
values = ["odd", "even", "square", "cube", "prime", "composite"]
domain_length = 1000
parts = [
[
int.from_bytes(
hashlib.shake_256(repr(list(v)).encode("utf-8")).digest(512)[i : i + 8],
"little",
)
for i in range(0, 512, 8)
]
for v in values
]
salt = 1
while 1:
if (
hfn(parts, salt, domain_length, 3) in cubes
and hfn(parts, salt, domain_length, 2) in squares
and hfn(parts, salt, domain_length, 4) in primes
and hfn(parts, salt, domain_length, 5) in composites
and hfn(parts, salt, domain_length, 1) in evens
and hfn(parts, salt, domain_length, 0) in odds
):
print(salt - 1)
break
salt += 1

def hfn(parts, salt, domain_length, value_index):
return (
sum(
((salt >> i) - (salt >> i + 1)) * parts[value_index][i] for i in range(64)
)
% 18446744073709551616
* domain_length
>> 64
)

if __name__ == "__main__":
main()

• How do you find these hash-based solutions? I've got a brute forcer running atm that's been going for close to 3 hours now with nothing Jun 23, 2021 at 18:11
• Added the code I wrote for this one. Jun 23, 2021 at 18:11
• 7 bytes: 91,651ḥ, if you use title case (Odd, Even, ...) Jun 24, 2021 at 10:36
• Thanks @thedefault. I had not actually noticed the case optionality, and had not got around to searching domains other than the one-byte ones 1000 and 256. I was also thinking using the input string itself as the salt might work (since if the first element is a string it's treated as a base-250 literal) with either a fixed object to hash (i.e. something like ,Ø°ḥ6) but not tried a search. Jun 25, 2021 at 18:34

# JavaScript (Node.js), 28 bytes

n=>122+'vdou r'.search(n)


Try it online!

All credits go to Recursive Co., I would have commented but since It's my first time on posting on stackexchange I don't have the reputation for that. When search doesn't find anything it return -1, making it possible to remove q and saving one byte.

• Welcome to Code Golf! Jun 23, 2021 at 18:43

# JavaScript (ES6), 24 bytes

x=>parseInt(x,30)%17^212


Try it online!

Some other 24 bytes

x=>parseInt(x,30)%65+204
x=>parseInt(x,33)%37+497
x=>parseInt(x+87,35)%349


# JavaScript (Node.js), 22 bytes

x=>Buffer(x)%29^115


Try it online!

Some other 22 bytes

x=>Buffer(x)%87^115
x=>Buffer(x)%89^113
x=>Buffer(x)%55^115 // UpperCase
x=>Buffer(x)%57^113 // UpperCase

• I have no idea how this would work, but is there anything you can do with s.searche? Jun 24, 2021 at 7:08
• @Ausername hadn't find some useful formula using it. Tried both title case and lower case. Not sure why...
– tsh
Jun 24, 2021 at 10:35
• really interesting answers. Can you explain how you found them/the program you used for bruteforcing
– user100752
Jun 24, 2021 at 15:26

# Java (JDK), 22 bytes

s->150-s.hashCode()%30


Try it online!

## Outputs

       odd: 139
even: 140
square: 169
cube: 125
prime: 149
composite: 155


## Alternate

s->160-s.hashCode()%50


Try it online!

## How

Brute-forced with this code:

import java.util.*;

class Main {

private static long[] cubes = computeCubes(100, 1000);
private static long[] squares = computeSquares(100, 1000);
private static long[] primes = computePrimes(100, 1000);

public static void main(String[] args) {
for (int o = 0; o <= 1000; o++) {
for (int m = 2; m < 10000; m++) {
if (test(o, m)) {
System.out.printf("o = %d, m = %d%n", o, m);

System.out.printf("odd: %d%n",       f("odd",       o, m));
System.out.printf("even: %d%n",      f("even",      o, m));
System.out.printf("square: %d%n",    f("square",    o, m));
System.out.printf("cube: %d%n",      f("cube",      o, m));
System.out.printf("prime: %d%n",     f("prime",     o, m));
System.out.printf("composite: %d%n", f("composite", o, m));
System.out.printf("%n");
}
}
}
}

//  static long f(String s, int o, int m) {
//    return o + s.hashCode() % m;
//  }

static long f(String s, int o, int m) {
return o - s.hashCode() % m;
}

static boolean test(int o, int m) {
var odd =       f("odd",       o, m);
var even =      f("even",      o, m);
var square =    f("square",    o, m);
var cube =      f("cube",      o, m);
var prime =     f("prime",     o, m);
var composite = f("composite", o, m);

var values = new long[]{ odd, even, square, cube, prime, composite };

var result = Arrays.stream(values)
.filter(v -> 100 <= v && v < 1000)
.distinct()
.count()
== 6;

result &= odd % 2 == 1;
result &= even % 2 == 0;
result &= Arrays.binarySearch(squares, square) >= 0;
result &= Arrays.binarySearch(cubes, cube) >= 0;
result &= Arrays.binarySearch(primes, prime) >= 0;
result &= Arrays.binarySearch(primes, composite) < 0;

return result;
}

private static long[] computeSquares(int min, int max) {
var minSqrt = (int)Math.sqrt(min); if (minSqrt * minSqrt < min) minSqrt++;
var maxSqrt = (int)Math.sqrt(max);
var squares = new long[maxSqrt - minSqrt + 1];
for (int i = 0; i < squares.length; i++) {
var sqrt = minSqrt + i;
squares[i] = sqrt * sqrt;
}
return squares;
}
private static long[] computeCubes(int min, int max) {
int minCbrt = (int)Math.pow(min, 1/3d); if (minCbrt * minCbrt * minCbrt < min) minCbrt++;
int maxCbrt = (int)Math.pow(max, 1/3d);
var cubes = new long[maxCbrt - minCbrt + 1];
for (int i = 0; i < cubes.length; i++) {
int cbrt = minCbrt + i;
cubes[i] = cbrt * cbrt * cbrt;
}
return cubes;
}
private static long[] computePrimes(int min, int max) {
var composites = new boolean[max];
composites = false;
var primes = new long[max];
var primeCount = 0;
for (int i = 2; i < max; i++) {
if (!composites[i]) {
for (int c = i * i; c < max; c += i) {
composites[c] = true;
}
primes[primeCount++] = i;
}
}
var minPos = Arrays.binarySearch(primes, 0, primeCount, min);
var maxPos = Arrays.binarySearch(primes, 0, primeCount, max);
return Arrays.copyOfRange(primes, minPos < 0 ? ~minPos : minPos, primeCount);
}
}


Try it online!

• Which Java version is that using? The exact formula used by String.hashCode() changed between versions, if I remember correctly. Jun 24, 2021 at 22:44
• @PaüloEbermann looking as far as Java 1.0, String.hashCode() hasn't changed, ever. You must be mistaken with another method or class. Jun 25, 2021 at 5:09

# Python 3, 42 bytes

lambda s:sum(s[:-1])-2+6*(81in s)+(77in s)


Try it online!

Takes input as bytes in uppercase.

Not as short as an uninteresting clone of the current shortest formula, and can very likely be golfed further, but I wanted to show a different approach.

My first instinct on seeing this challenge was to use sum, because you can sum a byte string in Python 3 and it's a useful quick method to do string lookups like this.

Cube numbers were definitely the hardest to get to behave with a sum, because there are only 3 practicable cube numbers in the region of the sums of the strings ($$\ 6^3, 7^3, 8^3 \$$).

I played around with different slices of the string and different input casings, and I found that sum(s[:-1]) was promising:

ODD => 147
EVEN => 224
SQUARE => 396
CUBE => 218
PRIME => 312
COMPOSITE => 622


Subtracting 2 makes 216, a cube, while keeping the rest. 396 is also very close to 400, and the rest were pretty easy too.

81in s tests for a Q, and then +6*() adds 6 if there is one (abusing Python's weak interpretation of booleans). Similarly, +(77in s) fixes PRIME by making 311 instead of 310. (I'm sure these bits can be golfed somehow.)

# Python 2, 24 bytes

lambda s:hash(s)%853^702


An unnamed function accepting a string that returns an integer:

      odd: 783
even: 832
square: 196
cube: 512
prime: 661
composite: 679


Try it online!

...or perhaps 21 in Python 3?

lambda b:b**95%547


where b is bytes if that is allowed in place of a string.

# Python 3, 26 25 bytes

lambda x:497+int(x,33)%37


Try it online!

-1 thanks to ovs

Converts the string to an integer in base 33, then does a bit of hashing.

Outputs:

odd => 509
even => 508
square => 529
cube => 512
prime => 499
composite => 522


Found using this brute-force script and a tiny bit of manual filtration:

PRIMES = {101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997}
SQUARES = {256, 900, 144, 400, 529, 784, 289, 676, 169, 441, 576, 961, 196, 324, 841, 729, 225, 100, 484, 361, 625}
CUBES = {125, 216, 343, 512, 729}

CUBE, SQUARE, PRIME, EVEN, ODD, COMPOSITE = "cube", "square", "prime", "even", "odd", "composite"

for s in range(800):
for b in range(32, 37):
for m in range(1, 10000):
if \
s + int(CUBE, b) % m in CUBES \
and \
s + int(SQUARE, b) % m in SQUARES \
and \
s + int(PRIME, b) % m in PRIMES \
and \
s + int(COMPOSITE, b) % m not in PRIMES \
and \
(s + int(ODD, b) % m) % 2 \
and \
(s + int(EVEN, b) % m) % 2 == 0:
print(f"{s} + int(x, {b}) % {m}")



Try it online!

# 05AB1E, 6 bytes

HƵ₅%₁+


Try it online!

This computes from_hex(input)%193+256, found by the same script I used for my Python answer.

# Charcoal, 12 bytes

Ｉ﹪⁺⁴⁷⁰⍘Ｓγ⁸⁶⁶


Try it online! Link is to verbose version of code. Takes input in lower case. Explanation:

       Ｓ        Input string
⍘ γ       Converted from base 95
⁺⁴⁷⁰          Plus 470
﹪       ⁸⁶⁶    Modulo 866
Ｉ               Cast to string
Implicitly print


These constants were the only ones I could find that worked with lowercase inputs. There are other constants that work for title or upper case:

           lower    Title       UPPER
+ 470 162 710 100 254 588 708
% 866 586 778 840 851 948 972
odd 327 155 401 723 683 671 659
even 206 400 750 278 286 386 470
square 729 169 529 529 361 841 841
cube 343 343 729 729 343 729 729
prime 269 397 457 659 467 919 571
composite 299 511 119 539 495 451 763


I also tried base 26 but I didn't find any solutions. I also tried "base 1000" which had one solution for each case: +499, %837: 819 176 121 512 389 371 (lowercase) +674, %703: 173 194 225 216 577 512 (title case) +334, %667: 353 186 625 512 383 372 (upper case).

## Batch, 74 bytes

@cmd/cset/aeven=120,square=121,odd=123,cube=125,prime=127,composite=128,%1


Case insensitive. Explanation: Sets six variables and evaluates the input.

# Wolfram Language (Mathematica), 2419 18 bytes

Hash@#~Mod~619-90&


Try it online!

Hash@#~Mod~775+35&


Try it online!

This code was developed on Mathematica 12.3.0 for Mac OS X x86 (64-bit) (May 10, 2021) and verified on 12.0.1 for Linux x86 (64-bit) (October 16, 2019). According to the documentation,

The "Expression" hash code is computed from the internal representation of an expression and may vary between computer systems and from one version of the Wolfram Language to another.

# C (gcc), 23 bytes

#define f(n)n%29^115
`

Try it online!

• just a port of tsh answer the difference is : while js had to use buffer() C can access every single character directly.