Get the Systematic Chemical Symbol

Background

The systematic chemical symbol is defined as such for $$\ 118 < n < 1000 \$$:

• The first letter corresponds to the first digit, capitalized.
• The second letter corresponds to the second digit.
• The third letter corresponds to the third digit.

This can be generalized for all $$\ n > 0\$$:

• For each digit, get the corresponding letter.
• Capitalize the first character.

Write a function or full program that takes an integer or a list of digits $$\n > 0\$$ and returns or prints the corresponding systematic chemical symbol.

Digit | Letter
--------------
0     | n
1     | u
2     | b
3     | t
4     | q
5     | p
6     | h
7     | s
8     | o
9     | e


This is , so shortest code wins.

Test Cases

In - Out
----------
119 - Uue
120 - Ubn
123 - Ubt
999 - Eee
6859 - Hope
1 - U
92 - Eb
987654321 - Eoshpqtbu
1010101 - Unununu

• @pppery That challenge requires getting the entire name, rather than just the abbreviation; answers from this challenge could not easily be ported over to fit that one, and so, in my view, this isn't a duplicate – caird coinheringaahing Oct 23 '20 at 21:39
• Duplicate vote retracted. – pppery Oct 23 '20 at 22:19
• Presumably the input will never have leading 0s, if we can take it as an integer? – caird coinheringaahing Oct 23 '20 at 22:28
• Shouldn't it be 987654321 -> Eoshpqtbu? – Noodle9 Oct 23 '20 at 23:01
• 121031 -> Ubuntu – qwr Oct 24 '20 at 5:57

05AB1E, 13 bytes

Input is a list of digits.

.•*Š"—Êo•sèJ™


Commented:

.•*Š"—Êo•      # compressed alphabet string "nubtqphsoe"
s     # swap to implicit input
è    # index each digit into the string
J   # join into a single string
™  # apply title case


See the step-by-step output here.

Lyxal has suggested another 13-byter with a nicer input format:

.•*Š"—Êo•ÅвJ™


Try it online!

This uses Åв, which converts the input integer into the custom base defined by the string.

• Alternate 13 byter – lyxal Oct 24 '20 at 9:37
• @Lyxal Thats the first time I've seen Åв used, very nice! – ovs Oct 24 '20 at 9:57
• @Lyxal D'oh! I can apply that to Charcoal, saving me 2 bytes! – Neil Oct 25 '20 at 10:02
• You could get another 13 bytes alternative using the transliterate builtin: žh.•*Š"—Êo•‡™. – Kevin Cruijssen Oct 26 '20 at 7:41

f(h:t)="NUBTQPHSOE"!!h:map("nubtqphsoe"!!)t


Try it online!

Input is a list of digits. Yes, the code really just writes out the string once in uppercase and a second time in lowercase. This kludge seems shorter than other things I tried. Haskell without imports doesn't have built-ins to capitalize and is really clumsy in working with characters.

43 bytes

zipWith(!!)$"NUBTQPHSOE":repeat"nubtqphsoe"  Try it online! Taking Lynn's solution and making it more boring. We can also write: 43 bytes zipWith(!!)$"NUBTQPHSOE":l
l="nubtqphsoe":l


Try it online!

47 bytes

(%0)
(h:t)%i=["NUBTQPHSOE"!!h..]!!i:t%32
_%_=""


Try it online!

Based off Lynn's solution. Handles the capitalization by passing in an offset i of 0 initially, then updating it to 32 in each recursive function call.

It doesn't seem like Haskell has a nice function to title-case a string even with imports, which are probably too lengthy anyway to be competitive. The below with Data.Text doesn't work because it operates on Text not [Char]. Data.Char only has toUpper to capitalize a single character.

44 bytes (non-working)

import Data.Text
toTitle.map("NUBTQPHSOE"!!)


Try it online!

Jelly, 15 bytes

ị“ubtqphsoen”Œt


Try it online!

Inputs as a list of digits, which the Footer does for you.

As it appears the string can't be compressed, this is likely to be the shortest approach in Jelly

How it works

ị“ubtqphsoen”Œt - Main link. Takes a list l on the left
“ubtqphsoen”   - Yield the string “ubtqphsoen”
ị               - For each digit in l, index into the string (1-indexing)
Œt - Title case (capitalise the first character)


R, 8072 56 bytes

-8 bytes thanks to Kirill L.

-16 bytes thanks to Giuseppe.

sub("(.)","\\U\\1",chartr("0-9","nubtqphsoe",scan()),,T)


Try it online!

First we translate the digits to the relevant letters thanks to chartr, then sub switches the first letter to upper case. This last part is possible thanks to the option perl = T, a nice trick found by Giuseppe.

Also, note that all the functions are vectorized the way we need them to be, so we can handle several inputs at a time, which is rather unusual in R golf with scan().

• You can use 0-9 shortcut in chartr. Also, I tried titlecasing with utf-int conversions, but apparently it only saves 1 more byte and does not vectorize as nicely: 72 bytes – Kirill L. Oct 24 '20 at 10:51
• @KirillL. Neat shortcut, thanks! – Robin Ryder Oct 24 '20 at 11:22
• The x<- seems redundant so you can save three bytes on the stringr version. The language for that one should probably also be listed as R + stringr package since it’s not just base R. – Nick Kennedy Oct 25 '20 at 13:50
• @NickKennedy Thanks! Indeed, the x<- was left over from the previous version, and the language is R+stringr. – Robin Ryder Oct 25 '20 at 15:24
• 56 bytes in base R using perl=T. I've never been able to use that flag as a golf, but reading through the docs for sub reveals this hidden gem: "For perl = TRUE only, it can also contain "\U" or "\L" to convert the rest of the replacement to upper or lower case" – Giuseppe Oct 30 '20 at 18:27

Japt, 17 16 bytes

Input as a digit array, output as a character array.

mgeo¢pqt¿nw)vu


Try it

mg...w)vu     :Implicit input of digit array
m               :Map
g              :  Index (0-based) into
...         :    Compressed string "eoshpqtbun"
w        :    Reversed
)       :End map
v      :Modify first element
u     :  Uppercase


zipWith(\i d->["NUBTQPHSOE"!!d..]!!i)$0:k k=32:k  Try it online! Husk, 20 17 bytes §:oa←tm!¨Ḃ+q²"ṗen  Try it online! input as a list of digits. There's probably a better way to do the titlecasing part. -3 bytes from Dominic van Essen. Explanation (old) §:oa←tmo!¨nḂ+q²"ṗe¨→ → increment input to accomodate 0-indexing mo map each digit to !¨nḂ+q²"ṗe¨ it's index value in the compressed string §: join the oa← first letter uppercased t with it's tail  • 17 bytes anyway, without managing to improve the titlecasing... – Dominic van Essen Oct 24 '20 at 8:19 • @DominicvanEssen ah, circular indexing. – Razetime Oct 24 '20 at 8:25 • Would base conversion help? It's already been exercised in 2 answers already and it helped save two bytes for Neil. – lyxal Oct 25 '20 at 10:27 • @Lyxal Husk doesn't have custom base conversion, from what I know. – Razetime Oct 25 '20 at 11:29 Charcoal, 20 18 bytes ⭆⍘Ｎnubtqphsoe⎇κι↥ι  Try it online! Link is to verbose version of code. Edit: Saved 2 bytes thanks to @Lyxal's comment on @ovs's answer. Explanation:  Ｎ Input number ⍘ Custom base conversion using nubtqphsoe Literal string ⭆ Map over characters κ Current index ⎇ If not first character then ι Current character ↥ι Else uppercased character Implicitly print  • It's great when I manage to inadvertently provide golfing suggestions for other answers! – lyxal Oct 25 '20 at 10:25 Python 3, 51 bytes lambda a:"".join("nubtqphsoe"[x]for x in a).title()  Try it online! Proton, 42 bytes a=>"".join("nubtqphsoe"[x]for x:a).title()  Try it online! C (gcc), 51 49 bytes Apparently I can get rid of the customary "assign to first parameter" because I only care about a false/non-false answer from this function. Interesting to know! f(n){n&&putchar("nubtqphsoe"[n%10]^32*!f(n/10));}  Try it online! Perl 5, 27 bytes y/0-9/nubtqphsoe/;$_="\u$_"  Try it online! • 24 bytes – Nahuel Fouilleul Oct 24 '20 at 13:11 • @NahuelFouilleul – Nice! I thought about bit fiddling, but that didn't came to mind. – Kjetil S. Oct 24 '20 at 13:31 JavaScript (ES6), 54 bytes Expects an array of digits. a=>a.map((c,i)=>"nNuUbBtTqQpPhHsSoOeE"[c*2+!i]).join  Try it online! Scala, 47 40 bytes _+""map(d=>"nubtqphsoe"(d-48))capitalize  Try it online! • -7 Thanks to user! • You can save 7 bytes by using _ and infix/postfix operators – user Oct 28 '20 at 21:47 x86 machine code (MS-DOS .COM format), 35 33 bytes The program will terminate at the end of input from the command line. For fun, I decided to use XLAT to index each digit's representation as the translation array easily fits into an 8-bit index and everything is 1:1. Byte representation: 0000 B4 20 BB 19 01 BE 82 00 AC 2C 0D 74 09 D7 32 C4 0010 CD 29 32 E4 EB F0 C3 6E 75 62 74 71 70 68 73 6F 0020 65  Assembly code (TASM): IDEAL MODEL TINY CODESEG ORG 100H SYMS_M EQU OFFSET SYMS-23H MAIN: MOV AH,20H MOV BX,SYMS_M MOV SI,82H VAL: LODSB SUB AL,0DH JZ QUIT XLATB XOR AL,AH INT 29H XOR AH,AH JMP VAL QUIT: RET SYMS DB "nubtqphsoe" END MAIN ENDS  Retina 0.8.2, 26 bytes Tdnubtq\p\hs\oe TlL^.  Try it online! Link includes test cases. Explanation: Tdnubtq\p\hs\oe  Translate each digit to the appropriate letter. The letters h, o and p have special meaning, so they need to be quoted. TlL^.  Translate the first letter to upper case. • christ that speed – bigyihsuan Oct 23 '20 at 20:00 • The symbols' first character needs to be capitalized, as per the spec – bigyihsuan Oct 23 '20 at 20:01 • @bigyihsuan oh sorry, there's a bug in the test suite – Neil Oct 23 '20 at 20:02 Ruby-nl, 37 bytes p$_.tr("0-9","nubtqphsoe").capitalize


Try it online!

APL+WIN, 39 bytes

Prompts for a character vector of digits with index origin = 0

⎕av[(↑n),32+1↓n←⎕av⍳'NUBTQPHSOE'[⍎¨⍕⎕]]


Explanation:

[⍎¨⍕⎕]] Convert input to individual digits

⎕av⍳'NUBTQPHSOE' Find index positions of all upper case characters in atomic vector
and use result above to select those according to input

(↑n),32+1↓n Concatenate first index to remaining indices + 32 to apply appropriate case

⎕av[...] Use the above indices to select required characters from atomic vector


GolfScript, 3129 28 bytes

~{"nubtqphsoe"1/=}%()[32-]|\


Try it online!

Input as a digit array.

~                             # Parse the input to an array         [6 8 5 9]
{               }%           # For each digit
"nubtqphsoe"1/              # Split each letter of this string    6 ["n" "u" ... "e"]
=             # Get the corresponding letter        "h"
(          # Get the first letter                ["o" "p" "e"] "h"
)         # Get the ascii value                 ["o" "p" "e"] "" 104
32-     # Subtract 32                         ["o" "p" "e"] "" 72
[   ]    # Put it in an array                  ["o" "p" "e"] "" [72]
|   # Convert to ascii                    ["o" "p" "e"] "H"
\  # Swap the two elements in the stack  "H" ["o" "p" "e"]
# Only the strings are outputted      "Hope"

• If it helps, you can take input as a list of digits, rather than as a single number – caird coinheringaahing Oct 23 '20 at 22:27

Befunge-93, 105 bytes

Terrible implementation, it works at least, input is each digit of the number then any other character to terminate. Feel free to suggest any optimisations.

~::68*vnubtqphsoe
v+4*96_@

@_68*8--0 v
v        <
v:~<,-*84g<
>:68* v
v+4*96_@

@_68*8--0 g,^


Try it online!

Vyxal, 11 10 bytes

«/
∨+Ċ≤«βǐ


Try it Online!

I finally turned my suggested 13 byte 05AB1E answer into a Vyxal answer.

Explained

«...«βǐ
«...«    # the string "nubtqphsoe"
β   # convert the input to bijective-base 10 using the above string as the alphabet
ǐ  # titlecase that result


C (gcc), 63 60 bytes

Saved 3 bytes thanks to AZTECCO!!!

f(a,l)int*a;{l--&&f(a,l)+putchar("nubtqphsoe"[a[l]]-!l*32);}


Try it online!

Inputs a pointer to an array of digits and its length (since there's no way to know how long an array passed into a function as a pointer is in C) and prints the corresponding systematic chemical symbol.

• Try it online! you can save 3 by using recursion! – AZTECCO Oct 24 '20 at 2:02
• @AZTECCO Very nice - thanks! :D – Noodle9 Oct 24 '20 at 9:41

Pyth, 41 bytes

V.T,.T]."buÞ“;UØ".T]."09I–Ò"=:zeNhN;rz3


Try it online!

Explanation

The main part of the program is .T,.T]."buÞ“;UØ".T]."09I–Ò", which returns the list [['u', '1'], ['b', '2'], ['t', '3'], ..., ['n', '0']]. ."buÞ“;UØ" is the packed string ubtqphsoen, and ."09I–Ò" is the packed string 1234567890. .T] splits them into characters, and .T, zips them together.

Pyth, 24 bytes

Vz=+k@."bu\nL‘"vN;rk3


Try it online!

This one is a port of HyperNeutrino's Python 3 answer.

CJam, 24 bytes

q~{"nubtqphsoe"1/=}%(eu\


Try it online!

Input in the form of a digit array string.

Raku, 29 bytes

*.trans(^10=>'nubtqphsoe').tc


Try it online!

JavaScript, 264157150 100 bytes

-107 bytes by replacing if statements with a JavaScript object to match each number with a corresponding string.

-7 bytes by using ES6 for loop through a string, and shorter arrow functions.

-50 bytes by replacing JavaScript Object with ES6 string indexing.

a='';o='nubtqphsoe';x=c=>a+=o[c];for(let e of prompt())x(e);alert(a[0].toUpperCase()+a.substring(1))

• I made it shorter (from 157 --> 90) (idk im new, do I comment on this or make a new answer?): a='';o="nubtqphsoe";[...prompt()].map(n=>a+=o[n]);alert(a[0].toUpperCase()+a.substring(1)) – Samathingamajig Oct 26 '20 at 2:13
• Also just got rid of another 4 characters: a='';o="nubtqphsoeNUBTQPHSOE";[...prompt()].map((n,i)=>a+=o[Number(n)+!i*10]);alert(a) – Samathingamajig Oct 26 '20 at 2:24
• So I kept finding ways to condense this, with alert([...prompt()].map((n,i)=>"nNuUbBtTqQpPhHsSoOeE"[n*2+!i]).join), and then I realized this is very similar to @Arnauld's answer, which I guess happens on CodeGolf eventually – Samathingamajig Oct 26 '20 at 2:30

$k=[string]$args;0..9|%{$k=$k.replace([string]$_,'nubtqphsoe'[$_])};get-culture|% t*o|% *se $k  Try it online! Zsh, 29 bytes <<<${(C)\$(tr 0-9 nubtqphsoe)}


Try it online!