# Rarity of a String

Input: A string
Output: The rarity of the string, as described below.
To find the rarity of a string, follow the steps below.

• Subtract 3 for each E, A, T, or O in the string.
• Subtract 2 for each I, N, S, or H in the string.
• Subtract 1 for each R, D, L, or C in the string.
• Add 1 for each W, F, G, or Y in the string.
• Add 2 for each K, V, B, or P in the string.
• Add 3 for each J, Q, X, or Z in the string.

Test cases:
Input: "rarity"
Output: -9

Input: "aardvark"
Output: -8

Input: "quine"
Output: -4

Input: "wow"
Output: -1

Input: "why"
Output: 0

Input: "puppy"
Output: 7

Scoring:
This is . The shortest answer in bytes wins!

Clarifications:

• The input only consists of lowercase letters.
• The input is guaranteed to be non-empty.
• For U and M, do nothing.
• The text can be in any format.
• the "puppy" and "quine" test cases both have a u in them, despite the challenge not mentioning how to handle u. How is u (and also m, which isn't in the 24 letters provided) handled? Nov 23, 2022 at 13:47
• This seems like a decent challenge, but please consider in the future to post in the sandbox first. This way you can get some feedback while a post can still be changed. Nov 23, 2022 at 13:58
• Is it allowed to take the input all in uppercase letters? Nov 23, 2022 at 14:36
• Just FYI: It's not recommended to accept an answer on the same day the challenge was posted. It's fine now, but in future, just wait a few days before accepting. Nov 23, 2022 at 20:08
• Can we assume the text is ascii? Or could it be utf8 or whatever? Nov 23, 2022 at 23:14

# 05AB1E, 27 26 bytes

A2úœ•ι9η†₁Ù^Pι²Qš•èIk4÷3-O


Input as a list of characters.

Try it online or verify all test cases. (With œ•...•è replaced with S•...•.I, so it won't time out.)

Explanation:

A        # Push the lowercase alphabet
œ     # Get a list of all permutations of this string
•ι9η†₁Ù^Pι²Qš•
# Push compressed integer 24022710646877664751280873208
è   # Index it into the list of permutations to get string
#  "aeothinscdlr  mufgwybkpvjqxz"
Ik       # Get the (0-based) index of each character of the input-list in this string
4÷     # Integer-divide each index by 4
3-   # Subtract each by 3
O  # Take the sum
# (which is output implicitly as result)


See this 05AB1E tip of mine (section How to compress large integers?) to understand why •ι9η†₁Ù^Pι²Qš• is 24022710646877664751280873208.

24022710646877664751280873208 is generated by the Jelly builtin Œ¿ (minus 1, to convert Jelly's 1-based indexing to 05AB1E's 0-based).

# Python, 63 bytes

lambda x:sum('inshrdlcmumuwfgykvbpjqxz'.find(c)//4-2for c in x)


Attempt This Online!

Port of @Neil's not yet written charcoal answer. ;-p

• Three Python answers already and no one does the bleedin obvious ... Nov 23, 2022 at 15:59
• I had been planning to use this approach (including omitting eato) once I got around to writing my second answer, but I'm generously crediting you anyway, if only because I could copy and paste your string literal.
– Neil
Nov 24, 2022 at 0:55
• You can save two bytes by replacing x with input() and getting rid of the lambda Nov 24, 2022 at 1:02
• @AAM111 then you would need print Nov 24, 2022 at 6:59
• @Neil acknowledged. Nov 24, 2022 at 13:02

# Java 8, 63 62 bytes

s->s.map(c->"␁ ␆ ␃ ␃ ␁ ␅ ␅ ␂ ␂ ␇ ␆ ␃ ␄ ␂ ␁ ␆ ␇ ␃ ␂ ␁ ␄ ␆ ␅ ␇ ␅ ␇".charAt(c-97)-4).sum()


Try it online.

Explanation:

s->                 // Method with character IntStream parameter and integer return-type
s.map(c->         //  Map over each character:
"␁ ␆ ␃ ␃ ␁ ␅ ␅ ␂ ␂ ␇ ␆ ␃ ␄ ␂ ␁ ␆ ␇ ␃ ␂ ␁ ␄ ␆ ␅ ␇ ␅ ␇"
//   In this String†
.charAt(     //   Get the character at index:
c    //    The codepoint of the current character
-97 //    Minus 97 to convert it to a 0-based index
)-4          //   Then subtract 4 from it
//   (-1 to convert the codepoint to a digit; and an additional -3)
).sum()          //  After the map: sum the stream together and return it


† This String consists only of unprintable characters. The codepoint-integers of these characters are [1,6,3,3,1,5,5,2,2,7,6,3,4,2,1,6,7,3,2,1,4,6,5,7,5,7] (represented above with space-delimited Control Picture unicode characters).

• Is this not 111 bytes? byte counter
– jdt
Nov 24, 2022 at 13:42
• @jdt Read the bottom of the answer. :) The actual bytes can be found in the TIO-link, which are unprintables and cannot be put in an answer. If I copy it to my answer or this comment: s->s.map(c->"".charAt(c-97)-4).sum(), it would be displayed and saved as just an empty string. It filters out unprintables, hence the use of the Control Picture unicode characters as visible representation of those automatically removed unprintables. Nov 24, 2022 at 13:59

# Excel (ms365), 87, 86, 80 bytes

-1 Byte thanks to @DominicvanEssen

-6 Bytes thanks to @jdt

=SUM(MID("16331552276342167321465757",CODE(MID(A1,SEQUENCE(LEN(A1)),1))-96,1)-4)


• At least in my installation of Excel (16.67 for Mac), you can use an empty second argument to ROUNDUP (so: =ROUNDUP(4.5,) gives 5) to save 1 byte. Nov 24, 2022 at 11:40

# K (ngn/k), 38 37 bytes

+/3--4!24^"jqxzkvbpwfgymumurdlcinsh"?


Try it online!

Essentially a port of Kevin's 05AB1E answer.

• 24^"jqxzkvbpwfgymumurdlcinsh"? get 0-based indices of input in this lookup string (the "missing" "eato" is filled with 24^)
• 3--4! integer divide the indices by 4, then subtract the result from 3
• +/ take the sum (and implicitly return)

+.$- 3=?;$$D7 3c2740e64a52f8f4a8d  A rather sneaky port of hakr14's Pyth answer: upvote that!  . # map across each character of input ?;$$ # get index+1 in alphabet = # get element at that index D # of data value 3c2740e64a52f8f4a8d 7 # in base-7 -3 # and subtract from 3 + # finally, get the sum  Previously: # Nibbles, 24.5 24 bytes (48 nibbles) +.$- 3/+?D-26$3 4 2a4654a17c30c595a94262e628a6  +.$- 3/+?D-26$3 4 .$                 # map across letters of the input
?     $# getting the index (or 0 if not found) of each in: D # the data value 2a4654a17c30c595a94262e628a6 - # interpreted as characters 26 # in base 26 # (this equates to the string "bkpvfgwy mucdlrhinsaeot") + 3 # add 3, / 4 # integer-divide by 4, - 3 # and subtract from 3, + # and finally output the sum.  • I am confused. how do you get half a byte ? Is a character somehow represented in less than a byte ? Nov 26, 2022 at 19:17 • @Itération122442 Basically, yes. Nibbles programs are made up of half-byte (nibble) units: these are (mostly) input as single characters for ease of coding, but represent 4-bit nibbles in the final .nbb program. Here is a byte-count and hexdump of this program (note that bash can only read whole-byte files, so the file-size is rounded-up to 18 bytes by the shell). If you're interested (I hope so!), read more about it at the Nibbles homepage. Nov 26, 2022 at 19:49 # Vyxal, 26 bytes «ƛ₇⇩⇧ɽ¬Ẏ₁5≬*⋎ǑṄǑz!«vḟ4ḭ3-∑  Try it Online! Port of Kevin's 05AB1E answer. ## Explained (old) I'll rework this tomorrow when it's not 12:59am ƛ«∧Ǒ₄ẇ*§,(ε±ẏt∩⁽→«6/$vcT›h3ɾḂNJ0pi
ƛ                                   # To each character in the input
«∧Ǒ₄ẇ*§,(ε±ẏt∩⁽→«                  #    Push the string "wfgykvbpjqxzeatoinshrdlc" - this corresponds to the groups [+1, +2, +3, -3, -2, -1]
6/                #    And split that string into 6 equal length pieces.
vcT›h # Get the 1-based index of where the character is in the +- grouped string (u and m will return 0) 3ɾḂNJ0p # The list [0, 1, 2, 3, -3, -2, -1] i # Indexed by the previous number # At the end of execution, the s flag sums the list of numbers  • I think you can save some bytes by porting my 05AB1E answer: instead of splitting in 6 equal parts, just get the indices in the whole string and integer-divide by 4 minus 3. Nov 23, 2022 at 13:57 • @KevinCruijssen I sure did save bytes - enough to outgolf you by 1 :p Nov 23, 2022 at 13:58 • Not anymore, been able to golf 1 byte in my answer. ;) (Although I think you can use the sum flag?) Nov 23, 2022 at 14:37 • Charcoal port is 24, 23 with flags Nov 25, 2022 at 7:13 # ><> (Fish), 6260 56 bytes Rare case where ><> beats python • -2 bytes because I can't be beaten by Java, and by poluting the stacks. • -4 bytes by reading from the stack instead of jumping, which eliminates the delete stack loop 0i:0(?^'a'-1g'3'-+00. 05220441165231056210354646 ;n~\  Experience it in full HD* *only if you have a full HD monitor, you have anti-aliasing enabled in your browser, you are zoomed out 50%, and the stars are aligned. ## Explanation Top row: Take input, subtract it from "a" to get the index at the bottom. If the input is negative we go up. Read the letter from the middle row, subtract the char code of 3 then add it to accumulator. Middle row: Raw data on char values. Print result and exit # Python, 80 79 bytes • -1 byte thanks to @Mukandan314 lambda x:sum(map(int,x.translate('0'*98+'5220441165231056210354646')))-len(x)*3  Attempt This Online! # Python, 70 64 bytes lambda x:sum(int(b'"v4!g2euqc1U'.hex()[ord(c)%26])-4for c in x)  Attempt This Online! -6 bytes thanks to @loopy walt and @Steffan • -3 by shifting and hexifying the table. Nov 24, 2022 at 13:37 • 66 by just using a binary string of unprintables: ATO Nov 24, 2022 at 17:25 # JavaScript (Node.js), 64 bytes s=>Buffer(s).map(c=>s="11652310562103546460522044"[c%26]-4-~s)|s  Try it online! # TI-Basic, 55 bytes sum(seq(int(~inString("KVBPWFGYMMUURDLCINSHEATO",sub(Ans,I,1))/4)+3,I,length(Ans  Takes input in Ans as a string with all uppercase letters. ~ represents the negative symbol. # Python 3, 154 150 bytes -4 thanks to Ismael o=0 for I in input(): if I in'eato':o-=3 if I in'insh':o-=2 if I in'rdlc':o-=1 if I in'wfgy':o+=1 if I in'kvbp':o+=2 if I in'jqxz':o+=3 print(o)  Attempt This Online! • Don't think this is the best approach, but it is an approach. To quickly save a few bytes, you can do for I in input(): instead of i=input() [...] for I in i:. Nov 23, 2022 at 16:43 • You shouldn't answer your own posts right away as you have an unfair advantage (you already know and have studied the challenge). In the future please wait at least a day (3 is better) before doing this. Nov 23, 2022 at 22:03 # Charcoal, 29 bytes ＩΣＥＳ⊖⊖÷⌕”&⌈∨v_≕º↖Rb)}ζ⎇K⮌9”ι⁴  Try it online! Link is to verbose version of code. Explanation: Port of @loopywalt's answer, but only because I didn't have time to write this answer 10 hours ago. Explanation:  Ｓ Input string Ｅ Map over characters ⌕ Find index of ι Current character in ”...” Compressed string inshrdlcmumuwfgykvbpjqxz ÷ Integer divide by ⁴ Literal integer 4 ⊖ Decremented ⊖ Decremented Σ Take the sum Ｉ Cast to string Implicitly print  # Ruby, 64 ... 52 bytes ->s{s.bytes.sum{0x69a560ad416ae264095[_1%49*3,3]-3}}  Attempt This Online! Thanks south for -2 bytes. So long, TIO, and thanks for all the fish. ### How? The value of each letter is encoded in 3 bit (0 to 6 instead of -3 to +3), then packed into a 26-digit octal number. The letter 'a' is discarded because "out of range" is automatically translated to zero, which becomes -3. This gives a 75-bit value (25*3) which can be encoded in 19 hexadecimal nibbles. • Nov 24, 2022 at 7:24 • Why don't you also discard E, T and O, which should also translate to zero, like A? Nov 24, 2022 at 11:46 • @DominicvanEssen: Because the values are in alphabetical order, I can rotate between them using the modulo operator, but I can only discard one (I could discard more only if they were adjacent). – G B Nov 24, 2022 at 12:55 # Retina 0.8.2, 88 87 bytes +Teiran\dts\l\o\hc321o \d*-
+Tjk\wqvfxbgz\py321o
\d
$* m|u +.\b. ^(-)?.*$1$.&  Try it online! Link includes test cases. Explanation: +Teiran\dts\l\o\hc321o  Translate common letters to digits. (Some letters have special meanings, such as o, which means copy the other pattern, so they have to be quoted.) \d$*-


Expand the digits to -s.

+Tjk\wqvfxbgz\py321o


Translate rare letters to digits.

\d
$*  Expand the digits to 1s (golfier than +s). m|u  Delete any leftover ms and us. +.\b.  Cancel out pairs of -s and 1s. This works because they create a word boundary between them. ^(-)?.*$1$.&  Convert to decimal. Edit: Saved 1 byte by copying @MartinEnder's code to subtract signed numbers from his answer to Add two numbers. # C (gcc), 68 63 bytes -4 bytes thanks to c-- f(int*s){s=*s?"22763421673214657571633155"[*s%26]-52+f(s+1):0;}  Try it online! # C (gcc), 62 bytes With the unprintable characters from Kevin Cruijssen's answer as suggested by c-- and Mukundan314. f(int*s){s=*s?""[*s-97]-4+f(s+1):0;}  Try it online! • 62 bytes Nov 25, 2022 at 6:29 # Zsh--extendedglob, 68 bytes a=(insh rdlc um wfgy kvbp jqxz) <<<$[${1//(#m)?/+$a[(I)*$MATCH*]-3}]  Try it online! Because shell raw strings don't need quotes, using an array is shorter than doing math on a single string lookup. a=(insh rdlc um wfgy kvbp jqxz) # lookup table, offset by 3, with no 'eato' <<<$[${1//(#m)?/+$a[(I)*$MATCH*]-3}] #${1//(#m)?/                  }  # Replace every character in the string with
#               +               -3   # "+", "-3" literal strings
#                $a[(I)*$MATCH*]     # The lowest index of $a matching *<char>*, 1-indexed # If no match (e.g.: *e*) substitute "0" #$[                              ] # Evaluate arithmetically

• Don't you need to count the setopt extendedglob? Nov 26, 2022 at 19:53
• I forgot to add --extendedglob to the language name, as per the meta post. Nov 27, 2022 at 4:04

# APL, 60 bytes

{s←⍵⋄+/⊃(4-⍨⍳7)+.×{s∊⍵}¨↓7 4⍴'eatoinshrdlcumumwfgykvbpjqxz'}


Try it online!

# Raku, 64 bytes

.comb>>.&{('inshrdlcmumuwfgykvbpjqxz'.index(\$_)//-2)div 4-2}.sum


Try it online!

# Pyth, 22 (or 29?) bytes.

sXQG-L3jC"ÅŽ˜–Žê"7

Test suite

Note: the program uses characters not properly displayed by StackExchange, which have been replaced in the above snippet for readability. The link provides a correct and copyable source.

If Pyth's supposed SBCS works the way C seems to imply, then this is encoded as 22 bytes. In UTF-8, it's 29 bytes. I've never found a foolproof answer to this issue.

(For the record, C just uses chr and ord over base 256, which would suggest each of the characters those functions spit out for range [0-255] should be considered a single byte. I dunno though.)

##### Explanation:
sXQG-L3jC"..."7 | Full code (with string contents omitted)
----------------+----------------------------------------------------------------------
C"..."  | Convert a magic string to an integer from base 256
j      7 | Convert this int to base 7 as a list
-L3         | Replace each digit d with 3-d
XQG            | Translate the input from the lowercase alphabet to the resulting list
s               | Sum the results

• Nice! TIO seems to agree that it's 22 bytes: try it. Nov 26, 2022 at 15:18

# Javascript (Browser) 155 Bytes

var r=s=>[...s].reduce((o,I)=>o+(({e:-3,a:-3,t:-3,o:-3,i:-2,n:-2,s:-2,h:-2,r:-1,d:-1,l:-1,c:-1,w:1,f:1,g:1,y:1,k:2,v:2,b:2,p:2,j:3,q:3,x:3,z:3})[I]||0),0);
`