48
\$\begingroup\$

IUPAC in their insufferable wisdom have created a systematic element name for any newly created element. This is the temporary name of an element until they finally make up their minds about an actual name. It works like so: each digit of an element number is assigned a prefix based on its value. The prefixes are concatenated with ‘ium’ at the end. When this is done and if you get double i’s (ii) or triple n’s (nnn), replace them with single i’s and double n’s. The symbol for the element is the first letter of each prefix used concatenated and result capitalized. The prefixes used are below.

0 nil       5 pent
1 un        6 hex
2 bi        7 sept
3 tri       8 oct
4 quad      9 enn

So for this golf, your code needs to generate both the element name and its symbol for a given positive integer. So if your code was given 137, it should print to stdout or return both untriseptium and Uts. It should be valid from at least 118 to 558. Any higher is valid if it doesn't increase your code's length.

Python example showing the method:

def elename(n):
    '''Return name and symbol of new element for given element number.'''
    prefixes=['nil','un','bi','tri','quad','pent','hex','sept','oct','enn']
    nmeFixes, symFixes = [], []

    while n:  # each digit of element number is assigned a prefix
        n, i = divmod(n, 10)
        pf = prefixes[i]

        symFixes.append(pf[0])  # symbol uses only first letter of prefix
        nmeFixes.append(pf)

    # loop assembled prefixes in reverse order
    nmeFixes.reverse()
    symFixes.reverse()

    nmeFixes.append('ium')  # suffix
    name = ''.join(nmeFixes)
    symb = ''.join(symFixes).capitalize()

    # apply rule about too many n's or i's
    name = name.replace('nnn','nn')  # can happen with -90-
    name = name.replace('ii','i')  # -2ium or -3ium

    return name, symb

Eric Towers wins with cadmium bytes!

\$\endgroup\$
4
  • 34
    \$\begingroup\$ I'm going to start calling Boron by its IUPAC systematic element name: "Pentium" \$\endgroup\$
    – Michael
    Oct 9, 2015 at 19:51
  • 24
    \$\begingroup\$ @Michael Intel Boron Processor \$\endgroup\$
    – Beta Decay
    Oct 9, 2015 at 20:10
  • 1
    \$\begingroup\$ Must we have the correct case? \$\endgroup\$
    – lirtosiast
    Oct 9, 2015 at 23:37
  • 6
    \$\begingroup\$ @BetaDecay But does this "fifth element" support MultiPass? \$\endgroup\$ Oct 11, 2015 at 21:42

29 Answers 29

26
\$\begingroup\$

Python 3, Unhexseptium (167) bytes

h=x='';r=str.replace
for i in input():s=r('nubtqphsoeinirueeecnl  ianxptn    dt t'[int(i)::10],' ','');h+=s;x+=s[0]
print(r(r(h+'ium\n','ii','i'),'nnn','nn')+x.title())

These are the results when the program is run on every number from 1 to 999 (inclusive)

\$\endgroup\$
10
  • 30
    \$\begingroup\$ Your header now makes me want everyone list the number of bytes that way. \$\endgroup\$
    – Status
    Oct 9, 2015 at 17:15
  • 4
    \$\begingroup\$ @Status Hear, hear. This is going to make those Pyth guys very sad... :) \$\endgroup\$
    – beaker
    Oct 9, 2015 at 17:20
  • 1
    \$\begingroup\$ @beaker I'm disappointed that your profile picture isn't Beaker ;) \$\endgroup\$
    – Beta Decay
    Oct 9, 2015 at 17:35
  • 4
    \$\begingroup\$ @BetaDecay Done. \$\endgroup\$
    – beaker
    Oct 9, 2015 at 18:10
  • 6
    \$\begingroup\$ @Status : if someone manages to do it in less than 112 bytes, they can have a classical element name in the title :) Like rutherfordium. Or gold. \$\endgroup\$
    – vsz
    Oct 9, 2015 at 20:15
23
\$\begingroup\$

Mathematica 10.1, indium (49) cadmium (48)

This solution uses a built-in library of element properties, including IUPAC names and abbreviations. (I haven't seen this as a technique to be avoided in Golf. It seems to be encouraged. But this might be on (perhaps over) the edge of acceptable -- Mathematica implements this library (and many others) by downloading data from Wolfram's servers the first time you use it (and I presume checks for updates occasionally).)

f=ElementData@@@{{#,"Abbreviation"},{#,"Name"}}&
(* 
Improved by @user5254 from 
f[n_]:=ElementData[n,#]&/@{"Abbreviation","Name"} 
*)

f[48]
(* {"Cd", "cadmium"} *)

f[118]
(* {"Uuo", "ununoctium"} *)

f[122]
(* {"Ubb", "unbibium"} *)

f[190]
(* {"Uen", "unennilium"} *)

f[558]
(* {"Ppo", "pentpentoctium"} *)

f[10^100-1]
(* {"Eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "ennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennennium"} *)

How would this compare to using elements.py or periodictable.py in Python?

Edit: Months later: Noticed I had typo'ed the abbreviation output for 122. I've re-run the code and verified that I made this error, not Mathematica.

\$\endgroup\$
5
  • 9
    \$\begingroup\$ When I was writing up the challenge, I thought "Should I prevent built in functions? Nah, its unlikely this is built-in to any language. Wait, Mathematica might have it." But I didn't know how to check that and then promptly forgot about it. \$\endgroup\$
    – Status
    Oct 9, 2015 at 23:18
  • 7
    \$\begingroup\$ Holy parentheticals, Batman! That paragraph looks like something I could've written (I, too, am guilty of using parentheticals as asides in an attempt to mitigate my verbosity -- they usually become like this, though). \$\endgroup\$
    – cole
    Oct 9, 2015 at 23:19
  • 1
    \$\begingroup\$ You can save one more byte by using inner apply and making f itself a pure function: f=ElementData@@@{{#,"Abbreviation"},{#,"Name"}}&. \$\endgroup\$
    – user46060
    Oct 10, 2015 at 8:47
  • \$\begingroup\$ Won't this code become invalid for 118 if the element in question gains an official name? \$\endgroup\$
    – user62131
    Nov 28, 2016 at 17:01
  • 1
    \$\begingroup\$ @ais523 : According to the specification "So for this golf, your code needs to generate both the element name and its symbol for a given positive integer." If the element has a name or symbol, that name or symbol should be reported. By your metric, then, every other submission on this page will fail to meet the specification if any element with atomic number >=118 gets a systematic symbol or name. \$\endgroup\$ Nov 28, 2016 at 17:06
15
\$\begingroup\$

Pip, Thorium Actinium Radon (86)

(Don't inhale this entry, it'll give you lung cancer.)

P(aR,tY"nil un bi tri quad pent hex sept oct enn"^s)."ium"R`ii|nnn`_@>1Yy@_@0MaUC:y@0y

Takes the element number as a command-line argument and outputs the name & abbreviation on separate lines.

Explanation (somewhat ungolfed):

Y"nil un bi tri quad pent hex sept oct enn"^s  Build list of prefixes & store in y

    ,t                                         Range(10)
 (aR  y)                                       Replace each digit in input with
                                                 corresponding element in prefix list
        ."ium"                                 Append "ium"
              R`ii|nnn`_@>1                    Reduce too-long runs of letters
P                                              Print

 {y@a@0}Ma                                     For each digit in input, get first character
                                                 of corresponding prefix
Y                                              Store that list in y
          UC:y@0                               Uppercase the first item of y in place
                y                              Print y (items concatenated)

The ii and nnn handling uses a regex replacement with a callback function (added in the most recent version of Pip): for every match of ii|nnn, take all but the first character and use as a replacement.

\$\endgroup\$
1
  • \$\begingroup\$ Protip: While inhaling other entries may not give you lung cancer, they still probably aren't the best for your health. \$\endgroup\$
    – Cyoce
    Mar 31, 2016 at 5:40
14
\$\begingroup\$

GNU sed, 171 (unseptunium)

s/0/Nil/g
s/1/Un/g
s/2/Bi/g
s/3/Tri/g
s/4/Quad/g
s/5/Pent/g
s/6/Hex/g
s/7/Sept/g
s/8/Oct/g
s/9/Enn/g
s/$/ium/
h
s/[a-z]//g
G
s/./\L&/g
s/./\U&/
s/\n/ /
s/ii/i/g
s/nnn/nn/g

I assume it doesn't matter what order the name and symbol are returned in. Here, symbol comes first:

$ seq 180 190 | sed -f iupac.sed 
Uon unoctnilium
Uou unoctunium
Uob unoctbium
Uot unocttrium
Uoq unoctquadium
Uop unoctpentium
Uoh unocthexium
Uos unoctseptium
Uoo unoctoctium
Uoe unoctennium
Uen unennilium
$ 
\$\endgroup\$
1
  • 4
    \$\begingroup\$ I don't think the last two replaces need g; the only cases would be biium/triium and ennnil, all of which can only happen once in numbers under 1000. \$\endgroup\$ Oct 10, 2015 at 17:12
8
\$\begingroup\$

Mathematica, unhexunium 163 161 bytes

now capitalises symbol

This is Mathematica without the built-in ElementData.

f=StringReplace[##<>"ium, "<>{ToUpperCase@#1,##2}~StringTake~1&@@ToString/@nil[un,bi,tri,quad,pent,hex,sept,oct,enn][[IntegerDigits@#]],{"ii"->"i","nnn"->"nn"}]&

Test on 10 random numbers:

# -> f[#]& /@ RandomInteger[{118, 558}, 10] // ColumnForm

155->unpentpentium, Upp
338->tritrioctium, Tto
477->quadseptseptium, Qss
261->bihexunium, Bhu
158->unpentoctium, Upo
164->unhexquadium, Uhq
266->bihexhexium, Bhh
331->tritriunium, Ttu
404->quadnilquadium, Qnq
389->trioctennium, Toe
\$\endgroup\$
0
8
\$\begingroup\$

JavaScript (ES6) 164 (unhexquadium) 171

The capitalization is the tricky part. (Test in FireFox)

Edit 3 bytes saved thx user2786485

f=n=>[([...n+(l='')].map(c=>(c='nil,un,bi,tri,quad,pent,hex,sept,oct,enn'.split`,`[c],n=l?n+c[0]:c[0].toUpperCase(),l+=c)),l+'ium').replace(/i(i)|n(nn)/g,'$1$2'),n]

function test() { O.innerHTML=f(+I.value) }

test()

for(o='',i=99;i++<999;)o+=i+' '+f(i)+'\n';P.innerHTML=o
<input id=I onchange="test()" value="164"><span id=O></span><pre id=P></pre>

\$\endgroup\$
5
  • \$\begingroup\$ Returns *enium instead of *ennium for anything that's *9 \$\endgroup\$
    – DankMemes
    Oct 9, 2015 at 21:01
  • \$\begingroup\$ Unhexhexium version: n=>[([...n].map(c=>(c='nil,un,bi,tri,quad,pent,hex,sept,oct,enn'.split`,`[c],i=c[0],s=s?s+i:i.toUpperCase(),c),s='').join``+'ium').replace(/ii|nnn/g,r=>r.slice(1)),s] \$\endgroup\$ Oct 10, 2015 at 4:02
  • \$\begingroup\$ @molarmanful [...n] will fail for an int parameter. The challenge is about a given positive integer \$\endgroup\$
    – edc65
    Oct 10, 2015 at 8:55
  • \$\begingroup\$ You can get unhexoctium if you replace your 'replace` call to replace(/i(i)|n(nn)/g,'$1$2') \$\endgroup\$ Oct 11, 2015 at 7:06
  • \$\begingroup\$ @user2786485 thx I thought about using captures but did not find the right way \$\endgroup\$
    – edc65
    Oct 11, 2015 at 7:55
7
\$\begingroup\$

Ruby - 163 156 147 143 134 (Untriquadium) bytes

o=u='';gets.bytes{|c|k=%w[Nil un bI trI quad pent hex sept oct enN Ium][c%48];o+=k;u+=k[0]};puts o.tr_s('IN','in'),u[0..-2].capitalize

I'm hoping to golf this way down

Edit: Thanks for @steveverrill for shaving off 9 bytes!

Edit2: Thanks for @steveverrill again for another 4 bytes! (Really clever solution!)

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 1. Instead of each_char you can use chars. According to official Ruby documentation this is "deprecated" (but not in codegolf!) You'd probably do better with each_byte or bytes then c.to_i becomes for example i%48 . 2. Also by chance \n has ascii code 10, so maybe you can get rid of the chop and include ium in your array (works great for the element name, but adds a spurious i to the element symbol .) \$\endgroup\$ Oct 9, 2015 at 23:09
  • 1
    \$\begingroup\$ You can save another 5 bytes with tr_s like this: o=u='';gets.bytes{|c|k=%w[Nil un bI trI quad pent hex sept oct enN Ium][c%48];o+=k;u+=k[0]};puts o.tr_s('IN','in'),u[0..-2].downcase.capitalize \$\endgroup\$ Oct 10, 2015 at 21:57
  • \$\begingroup\$ u.chop is shorter than u[0..-2]. Maybe I should have posted my own answer, but my initial idea was to do it exactly like you did it. Its been fun helping you golf this though. I completely missed that you don't need downcase before capitalize. \$\endgroup\$ Oct 11, 2015 at 22:23
7
\$\begingroup\$

Pyth, 67 bytes (Hol­mium)

rshMJ@Lcs@LGjC"]ß!âÿeóÑiSÑA¼R¬HE"24\fjQT3-"ium"epj"nn"csJ*\n3

Try it online in the Pyth Compiler/Executor.

How it works

            jC"…"24       Convert the string from base 256 to base 24.
        s@LG              Select the letter that corresponds to each digit.
       c           \f     Split at 'f'.
     @L              jQT  Select the chunk that corresponds to each input digit.
    J                     Save in J.
 shM                      Form a string of the first letters of the chunks.
r                       3 Capitalize the first character.
                          Print. (implicit)

             csJ*\n3      Split the flattened J at "nnn".
        j"nn"             Join, separating by "nn".
       p                  Print.
-"ium"e                   Remove the last character ('i'?) from "ium".
                          Print. (implicit)
\$\endgroup\$
0
7
\$\begingroup\$

CJam, 74 72 71 70 69 bytes (Thulium)

r:i"ؾaÈÁaÎE<Ä+&:¬úD±"380b24b'af+)/f=_:c(euoS@s'n3*/"nn"*)"ium"|

Note that the code contains unprintable characters.

Thanks to @Sp3000 for pointing out an error in my initial revision and suggesting the )/ approach.

Try it online in the CJam interpreter:.

How it works

r:i     e# Read a token and push the array of its character codes.
"…"     e# Push a string of unprintable characters.
380b24b e# Convert it from base 380 to base 24.
'af+    e# Add the character 'a' to each base-24 digit.
        e# This pushes "bijtrijquadjpentjhexjseptjoctjennjniljunj".
)/      e# Pop the last character and split the string at the remaining occurrences.
f=      e# For each character code in the input, select the correspoding chunk.
_:c     e# Push a copy and cast each string to character.
(euo    e# Shift out the first character, convert to uppercase, and print.
S@      e# Push a space and rotate the array of string on top of it.
s       e# Flatten the array of string.
'n3*/   e# Split at occurrences of "nnn". 
"nn"*   e# Join, using "nn" as separator.
)"ium"| e# Pop the last character and perform setwise union with "ium".
        e# If the last character is, e.g., 't', this pushes "tium".
        e# If the last character is 'i', this pushes "ium".
\$\endgroup\$
4
  • 3
    \$\begingroup\$ Fun fact: Tungsten is often used in counterfeit gold bars and coins, due to its extreme density comparable to gold's and its relative cheapness. \$\endgroup\$
    – lirtosiast
    Oct 10, 2015 at 4:35
  • 1
    \$\begingroup\$ Lutetium is an absurdly cool name for an element. \$\endgroup\$
    – T. Sar
    Oct 10, 2015 at 13:26
  • \$\begingroup\$ @ThalesPereira Even cooler than Ytterbium though? \$\endgroup\$
    – Beta Decay
    Oct 10, 2015 at 18:43
  • \$\begingroup\$ Fun fact: Erbium, terbium, yttrium, and ytterbium are all named after the same place. \$\endgroup\$
    – lirtosiast
    Oct 10, 2015 at 23:11
6
\$\begingroup\$

JavaScript (ES6), 210 202 Bytes (Biunnilium Binilbium)

Minus octium (8) bytes, thanks to @edc65!

130 159 147 Bytes (Untrinilium Unpentennium Unquadseptium)

f=z=>(c=(b=(z+"").split``.map(x=>"nil.un.bi.tri.quad.pent.hex.sept.oct.enn".split`.`[+x])).join``.replace(/nnn/g,"n"))+(c[c.length-1]!="i"?"i":"")+"um,"+(a=b.map(x=>x[0])).shift().toUpperCase()+a.join``

Input like f(324). Ugh, I felt so golf-y.

\$\endgroup\$
2
  • \$\begingroup\$ @edc65 Fixed all three problems. \$\endgroup\$ Oct 10, 2015 at 3:34
  • 1
    \$\begingroup\$ Fine. Now, using template strings you can avoid some brackets and save maybe 8 bytes codegolf.stackexchange.com/a/52204/21348 \$\endgroup\$
    – edc65
    Oct 10, 2015 at 8:51
5
\$\begingroup\$

TI-BASIC, 223 218 bytes

Input N
"nil un  bi  tri quadpenthex septoct enn→Str4
"int(10fPart(N/10^(X→Y₁
"sub(Str4,1+4Y₁,int(3fPart(e^(Y₁)1.5154)+2^not(X=2 and .9=fPart(N%) or X=1 and 1=int(5fPart(.1N→Y₂
"ium,"+sub("UBTQP",int(N%),1
For(X,1,3
Y₂+Ans+sub(Y₂(3-X),1,1
End
sub(Ans,1,length(Ans)-1

Element number N can only have a triple "n" if it ends in 90, and can only have a double-"i" if the last digit is 2 or 3. We use math to check those cases.

The magic number 1.5154, which stores the length of each prefix, was found using a Python script to search all decimals of length ≤7 using the functions cosh(, cos(, and e^(.

Not done golfing yet, but TI-BASIC's two-byte lowercase letters and lack of string manipulation commands, as always, will hurt this program's score.

\$\endgroup\$
5
  • \$\begingroup\$ I'll work on golfing it down. ^_^ I'll let you know what I come up with. \$\endgroup\$ Oct 10, 2015 at 3:37
  • \$\begingroup\$ I don't think it's possible for anyone to get this down to 118 or less, but if someone manages, I'll give 500 rep. \$\endgroup\$
    – lirtosiast
    Oct 10, 2015 at 18:14
  • \$\begingroup\$ Two questions: What is N% and what are "" and ""? \$\endgroup\$ Oct 10, 2015 at 19:30
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Sorry, % is a two-byte token that you can't type into your calculator. Use Cemetech's SourceCoder or TI's tools to edit it into the source, or use the file I provided. \$\endgroup\$
    – lirtosiast
    Oct 10, 2015 at 20:37
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ  is the subscript 10; I've replaced it with a regular 10. \$\endgroup\$
    – lirtosiast
    Oct 10, 2015 at 20:43
4
\$\begingroup\$

Matlab, 170 (Unseptnilium)

Works on all inputs you can throw at it, from nilium up to, well as far as you care to go. I got to ennennennennennennennennennennennennennennennennennennennennennennium before I gave up with pressing the 9 key.

l=['nubtqphsoe';'inirueeecn';'l  ianxptn';'    dt t  '];i=input('','s')-47;s=l(1,i);s(1)=s(1)-32;a=l(:,i);disp([strrep(strrep([a(a>32)' 'ium '],'nnn','nn'),'ii','i') s]);

And an explanation:

%Create a 2D array of the prefixes transposed
l=['nubtqphsoe';'inirueeecn';'l  ianxptn';'    dt t  '];
%Grab the input number
i=input('','s')     %Request the input and convert to string
               -47; %Convert from ASCII into an array of indecies (1 indexed)
%Generate the short form
s=l(1,i);
%Capitalise first letter in short form
s(1)=s(1)-32;
%Extract required prefixes for long form
a=l(:,i);
%Now the fun bit:
                     a(a>32)'                                    %Combine the prefixes removing spaces and transpose into a string
                    [         'ium ']                            %Append 'ium ' to the string (the space is to separate the short form)
             strrep(                 ,'nnn','nn')                %Replace 'nnn' with 'nn'
      strrep(                                    ,'ii','i')      %Replace 'ii' with 'i'
disp([                                                     s]); %And display both full and short form strings together
\$\endgroup\$
3
\$\begingroup\$

Retina, 206 196 186 179 (Unseptennium) bytes (Try it online)

Thanks to @MartinBüttner (https://codegolf.stackexchange.com/users/8478/martin-b%C3%BCttner) for teaching me this language.

Thanks to @FryAmTheEggman for chopping off 7 bytes.

T`d`nubtq\p\hs\oe
.+
$&, $&
(?<=,.*n)
il
(?<=,.*e)n?
nn
(?<=,.*u)
n
(?<=,.*b)
i
(?<=,.*t)
ri
(?<=,.*q)
uad
(?<=,.*p)
ent
(?<=,.*h)
ex
(?<=,.*s)
ept
(?<=,.*o)
ct
r`i?$
ium
T`l`L`^.

Ueh-byte version: here

Bnh-byte version: here

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

CJam, 95 bytes

liAbA,"nil un bi tri quad pent hex sept oct enn"S/er_:c(eu\+_1>"en"={\W"il"t\}&S@:+)_'i=!*"ium"

Try it online

This competes in the category "languages without regex, and only using printable characters." ;) Didn't really expect it to be as short as some of the already posted solutions, but I was curious how long it would end up anyway. And since I got it now, I might as well post it.

Explanation:

li      Get input and convert to int.
Ab      Encode in decimal.
A,      Build list [0 .. 9].
"..."   String with prefixes.
S/      Split at spaces.
er      Transliterate. We now have a list of the prefix for each digit.
_:c     Copy and take first character of each, for short form.
(       Pop off first character.
eu      Convert it to upper case.
\+      Put it back in place. Done with short form.
_1>     Remove first character.
"en"=   Compare with "en", corresponding to the 90 special case.
{       Handle 90 case, replace 
  \       Swap full prefix list to top.
  W"il"t  Replace "nil" by "il" to avoid "nnn".
  \       Swap short form back to top.
}&      End of 90 case.
S       Push space between short form and full name.
@       Swap prefix list to top.
:+      Concatenate all the prefixes.
)       Pop off the last letter.
_'i=    Compare it with 'i.
!*      Multiply letter with comparison result. This gets rid of letter if it's 'i.
"ium"   Add the final part of the output.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Just for reference, Dennis only saves 6 bytes with all that base encoding :P \$\endgroup\$
    – Sp3000
    Oct 10, 2015 at 19:02
2
\$\begingroup\$

Python 3, unpentquadium (156 155 154) bytes

n=e=""
for c in input():s="nil un bi tri quad pent hex sept oct enn".split()[int(c)];n+=s[c<"1"<"nn"==n[-2:]:];e+=s[0]
print(n.strip("i")+"ium",e.title())

Instead of replacing ii with i we rstrip any is before we tack on the ium, since that's the only possible source of double is. Similarly, we strip ns by checking for an enn/nil case.

\$\endgroup\$
2
\$\begingroup\$

PHP, 152 153 163 bytes, unpentbium

Well, at least PHP is somewhere around average this time.

while(null!=$x=$argv[1][$i++]){$a.=$y=[nil,un,bi,tri,quad,pent,hex,sept,oct,enn][$x];$b.=$y[0];}echo str_replace([ii,nnn],[i,nn],$a.'ium ').ucfirst($b);

Runs form command line like:

pentium.php 163

Output:

unhextrium Uht

Ungolfed

$y = array('nil','un','bi','tri','quad','pent','hex','sept','oct','enn');

while (null != ($x = $argv[1][$i++])) {
    $a .= $y[$x];
    $b .= $y[$x][0];
}

echo str_replace(
        array('ii','nnn'),
        array('i','nn'),
        $a . 'ium ')
     .ucfirst($b);

Edit

  • saved 10 bytes by replacing all (not only one, duh) array()-initializer with []
  • saved 1 byte by adding the whitespace along with 'ium ' instead using an extra concatenation .' '.
\$\endgroup\$
1
\$\begingroup\$

Go, 322 Bytes (tribibium)

package main
import("os"
"strings"
"fmt")
func main(){p,n,s:="nil un  bi  tri quadpenthex septoct enn ","",make([]byte,0)
b:=make([]byte,3)
os.Stdin.Read(b)
var d byte=32
for _,r:=range b{i:=r-48
n+=p[4*i:4*i+4]
s,d=append(s,p[4*i]-d),0}
fmt.Printf("%sium %s",strings.NewReplacer(" ","","ii","i","nnn","nn").Replace(n),s)}

Reads three characters from STDIN, more are ignored, less result in a crash. So it works for every number between unnilnilium and ennennennium.

\$\endgroup\$
2
  • \$\begingroup\$ Also, shouldn't the element for 322 bytes be tribibinium? 321 is tribiunium. \$\endgroup\$
    – Mateon1
    Oct 10, 2015 at 18:23
  • \$\begingroup\$ Damn, I missed that one when adding the "i". Now everything should be in order \$\endgroup\$ Oct 10, 2015 at 18:38
1
\$\begingroup\$

PowerShell, 170 168 165 (Unhexpentium)

-join($a="$input"[0..9]|%{(($x=(-split'Nil Un Bi Tri Quad Pent Hex Sept Oct Enn')["$_"]).ToLower(),$x)[!($y++)]})+'ium'-replace'(nn)n|(i)i','$1$2'
-join($a|%{$_[0]})

Fairly straightforward and no surprises here. Except maybe that I solved the capitalization issue by lower-casing everything but the first part and having the individual parts already in title-case. Agrressively inlined by now to avoid losing characters for bare variable assignments.

Bonus after the last change: Now works for longer element numbers as well:

> echo 1337| powershell -noprofile -file "element.ps1"
Untritriseptium
Utts
\$\endgroup\$
1
\$\begingroup\$

C on x86, 192 (Unennbium)

int c,s,a[8],x,main(){while((c=getchar()-48)>=0)x="nil\0un\0\0bi\0\0tri\0quadpenthex\0septoct\0enn"+4*c,strncat(a,x+(c<s-8),4),strncat(a+5,x,1),s=c;printf("%s%s %s",a,"ium"+((s&14)==2),a+5);}

Reads digits from stdin and prints the results to stdout. Relies on sizeof(char*) == sizeof(int).

Ungolfed version:

int c, s, // Current and last digit, initially zero (0-9, not '0'-'9')
    a[8], // Buffer to write to (type doesn't matter when passed by pointer)
    x; // Int-pointer into lookup table

main() {
    while ((c = getchar() - 48) >= 0) { // 48 == '0'
        x = "nil\0un\0\0bi\0\0tri\0quadpenthex\0septoct\0enn" + 4*c;
        strncat(a, x+(c<s-8), 4); // Write digit, skip first char if c==0 && s==9
        strncat(a+5, x, 1); // Write first digit character somewhere else
        s = c;
    }
    printf("%s%s %s", a, "ium"+((s&14)==2), a+5); // Append "ium" (or "um" if s==2||s==3)
}
\$\endgroup\$
1
\$\begingroup\$

Haskell, bipentbium (305 271 269 265 261 259 253 252 bytes)

import Data.Char
main=getLine>>=putStr.a
m=map toLower
a n=(r.m$p)++(k.filter isUpper$p)where p=(n>>=(words"Nil Un Bi Tri Quad Pent Hex Sept Oct Enn"!!).digitToInt)++"ium "
r('n':'n':'n':x)="nn"++r x
r('i':'i':x)='i':r x
r(x:z)=x:r z
r x=x 
k(h:t)=h:m t

Shaved 34 bytes off thanks to nimi.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can hardcode the nnn and ii cases into r, i.e. r('i':'i':a)='i':r a;r('n':'n':'n':a)="nn"++r a;r(x:a)=x:r a;r x=x and call it without arguments: t=r.m.p. \$\endgroup\$
    – nimi
    Oct 11, 2015 at 11:10
  • \$\begingroup\$ @nimi Cheers for that! \$\endgroup\$
    – wlad
    Oct 11, 2015 at 12:12
  • 1
    \$\begingroup\$ Some more bytes to save: concatMap is >>=, i.e. p n=(n>>=(words"..."!!))++"ium " \$\endgroup\$
    – nimi
    Oct 11, 2015 at 12:57
  • \$\begingroup\$ @nimi Cheers again. \$\endgroup\$
    – wlad
    Oct 11, 2015 at 15:49
1
\$\begingroup\$

GNU sed, unhexunium (161 bytes)

h
y/0123456789/nubtqphsoe/
s/./\u&/
x
s/$/ium/
:
s/0/nil/
s/1/un/
s/2/bi/
s/3/tri/
s/4/quad/
s/5/pent/
s/6/hex/
s/7/sept/
s/8/oct/
s/9/enn/
s/nnn/nn/
s/ii/i/
t
G

I generate the symbol first, then stash that into hold space and create the name. A loop is golfier than using /g for four or more replacements (we can have only one ii and/or one nnn, so they don't need to be inside the loop, but it doesn't hurt). Finally, retrieve and append the held symbol.

(N.B. I hadn't seen the existing sed answer when I wrote this)

Test cases

These exercise the ii and nnn special rules:

$ seq 100 89 1000 | ./60208.sed
unnilnilium
Unn
unoctennium
Uoe
biseptoctium
Bso
trihexseptium
Ths
quadpenthexium
Qph
pentquadpentium
Pqp
hextriquadium
Htq
septbitrium
Sbt
octunbium
Oub
ennilunium
Enu
ennennilium
Een

And a ridiculous one, showing how much more this code gives, compared to the physical world:

$ ./60208.sed <<<281039817
bioctunniltriennoctunseptium
Bounteous
\$\endgroup\$
1
\$\begingroup\$

T-SQL 329 bytes

creat proc x(@a char(3))as select replace(replace((select a.b as[text()]from(select left(@a,1)a union select substring(@a,2,1)union select right(@a,1))z join(values(0,'nil'),(1,'un'),(2,'bi'),(3,'tri'),(4,'quad'),(5,'pent'),(6,'hex'),(7,'sept'),(8,'oct'),(9,'enn'))a(a,b)on z.a=a.a for xml path(''))+'ium','ii','i'),'nnn','nn')

Formatted:

create proc x(@a char(3))as 
select replace(replace(
(select a.b as[text()]from
    (
    select left(@a,1)a 
    union select substring(@a,2,1)
    union select right(@a,1))z 
join(values(0,'nil'),(1,'un'),(2,'bi'),(3,'tri'),(4,'quad'),(5,'pent'),(6,'hex'),(7,'sept'),(8,'oct'),(9,'enn')
    )a(a,b)on z.a=a.a 
for xml path('')
)+'ium','ii','i'),'nnn','nn')
\$\endgroup\$
1
\$\begingroup\$

R, 278 bytes

g<-function(x){k<-data.frame(c("nil","un","bi","tri","quad","pent","hex","sept","oct","enn"));row.names(k)<-0:9;n<-unlist(strsplit(as.character(x),""));return(sub("nnn","nn",sub("ii","i",paste(c(as.vector(k[n,]),"ium"," ",sapply(k[n,],function(x)substr(x,1,1))),collapse=""))))}

Not the best... but I'm still learning R so I thought I'd post my attempt. Any suggestions to make it better? Now that I think about it it's probably possible to subset on the nth-1 row rather than wasting space creating row names.

Example usage

> g(118)
[1] "ununoctium uuo"
> g(999)
[1] "ennennennium eee"
> g(558)
[1] "pentpentoctium ppo"
> g(118)
[1] "ununoctium uuo"
> g(90)
[1] "ennilium en"
> g(2)
[1] "bium b"

Ungolfed

g <- function(x) {
    k <- data.frame(c("nil","un","bi","tri","quad","pent","hex","sept","oct","enn"))
    row.names(k) <- 0:9
    n <- unlist(strsplit(as.character(x),""))
    return(
        sub("nnn", "nn", sub("ii", "i", paste(c(as.vector(k[n,]),"ium"," ", sapply(k[n, ],function(x)substr(x,1,1))), collapse = ""))))
}
  1. Create a key, convert to data frame, and set as the variable k
  2. Set the row names as 0-9 for easy identification
  3. Take the input x, convert to character, split it up (e.g. 137 to "1" "3" "7")
  4. Subset k based on the split number input and return the entries
  5. Concatenate them together and add -ium
  6. Also subset k using substring to pull the first letter of the matches. This is concatenated to the output of step 5 with a blank space between them
  7. Use sub() to replace the nnn and ii patterns
\$\endgroup\$
1
  • \$\begingroup\$ You forgot to capitalize the first letter of symbol. For example, it should be "Uuo", not "uuo", for 118. \$\endgroup\$ May 4, 2016 at 11:01
1
\$\begingroup\$

Javascript - 169 bytes

n=>eval(`q='nil0un0bi0tri0quad0pent0hex0sept0oct0enn'.split(0);for(b of (_=$='')+n){c=q[b];$+=q[b];_+=(_?c:c.toUpperCase())[0]}$.replace(/i$()|n(nn)/g,'$1$2')+'ium '+_`)

Bizarrely, my attempts to use map were longer than the for loop.

EDIT: Oops, forgot to check the date.

\$\endgroup\$
1
\$\begingroup\$

PHP, 131+1 bytes (untriunium)

still awfully long:

for(;~$c=$argn[$i];print$i++?$n[0]:$n&_)$r.=$n=[nil,un,bi,tri,quad,pent,hex,sept,oct,enn][$c];echo strtr(_.$r.ium,[ii=>i,nnn=>nn]);

Run as pipe with -nR or try it online.

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

Perl, 109 (Unnilennium) bytes

108 code + 1 switch

perl -pe 's!.!qw{Nil Un Bi Tri Quad Pent Hex Sept Oct Enn}[$&]!ge;s!nnN!nN!g;s!i?$!ium!;$_=lc$_.y!a-z!!dr;s!\b.!\U$&!g'

Takes input from STDIN as one number per line.

\$\endgroup\$
2
  • \$\begingroup\$ You mean unnilseptium :) \$\endgroup\$
    – CompuChip
    Oct 12, 2015 at 7:37
  • \$\begingroup\$ Ah, thanks for pointing that out :) Fixed it now \$\endgroup\$
    – svsd
    Oct 12, 2015 at 7:55
0
\$\begingroup\$

Java 8 216Bytes

String f(int i){
String[] s = {"nil","un","bi","tri","quad","pent","hex","sept","oct","enn"};
return ((""+i).chars().mapToObj(y->s[y-48]).collect(Collectors.joining())+"ium").replace("ii","i").replace("nnn","n");
}
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! 1. Your code, in form of a full program or a function, should accept an integer as input and generate the proper name. 2. This does not account for ii and nnn, as explained in the question. 3. The objective of code golf is to make the code as short as possible. The answer should contain its score in the title. You can reduce your score by eliminating whitespace and shortening the variable name. \$\endgroup\$
    – Dennis
    Oct 14, 2015 at 6:24
  • \$\begingroup\$ @Dennis Thanks! but why count the whitespace? it just makes the code even more unreadable. \$\endgroup\$
    – Rnet
    Oct 14, 2015 at 11:03
  • 3
    \$\begingroup\$ @Rnet The goal is not to make the code readable. ;) Also some whitespace might be significant, so it's not obvious which whitespace to count and which not. Therefore, the answer should remove as much whitespace as possible and simply count the bytes of that version. If you want to provide a readable version with proper indentation, you can always do so separately below the counted code. See relevant consensus on meta. \$\endgroup\$ Oct 15, 2015 at 10:50
0
\$\begingroup\$

C# 229 (Bibiennium) 198 unennoctium bytes

The "n-'0'" trick is a way to convert from ascii to int. Char 9 = ASCII 57. Char 0 = ASCII 48, so 57-48 = 9.

static private string ToText(int v) { return (string.Join("",v.ToString().Select((char n)=>"nil un bi tri quad pent hex sept oct enn".Split()[n-'0']))+"ium").Replace("nnn","nn").Replace("ii","i")+" "+string.Join("",v.ToString().Select((char n)=>"nubtqphsoe"[n-'0'])); }

    static private string ToText(int  v)
    {
        string u,r="",t="";
        return v.ToString().Select((char n)=>{u="nil un bi tri quad pent hex sept oct enn".Split()[n-48];r+=u;t+=u[0];return r;}).Last()+"ium".Replace("nnn","nn").Replace("ii","i")+" "+t;
    }

This approach takes the int, converts to a string, then performs a LINQ select of characters that fires off a lambda.

The lambda generates an array on the fly (less characters than defining it) by splitting the string of prefixes. It then pulls the index of the prefix to use by looking at the current character's int value (the n-'0' trick mentioned above).

All that is wrapped in a string.Join which concatenates all of the LINQ results together. Tack on the "ium", then a couple of .Replace statements at the end to clean up the nnn' and ii's.

Added the missing symbol output. I think there's a more efficient way by merging the two LINQs, but it's way to late to keep poking at it.

\$\endgroup\$
2
  • \$\begingroup\$ Instead of n-'0', why not n-30? \$\endgroup\$ Oct 17, 2015 at 23:39
  • \$\begingroup\$ Good call, but it depends on the character set. 48 works for me though ;) \$\endgroup\$
    – Rick Way
    Oct 19, 2015 at 2:54
0
\$\begingroup\$

C, 210 204 unennennium (199) bytes

This requires ASCII as the runtime character set.

f(char*n,char*s){char*c="NilUnBiTriQuadPentHexSeptOctEnn",*p,*o=n,i,j;for(;*n;){for(j=i=*n-48,p=c;*p&32||i--;++p);for(*s++=*n=*p+32;*++p&32;)*s++=*p;s-=*n++-j==39||j/2-*n==1;}*o-=32;strcpy(s,"ium");}

I did try a recursive solution (which avoids the need for p and o) but that turned out longer.

I'm particularly proud/ashamed of the matcher for the regexp 90|[23]$, which relies on 9 and 0 being the furthest separated digits (and therefore the only pair that differ by 9 - the 39 in the code is a consequence of j being an integer value and *n still an ASCII character) and that 2 and 3 differ only in the last bit, so dividing by 2 conflates them.

Expanded code:

void f(char *n,                 /* input number / output symbol */
       char *s)                 /* output name */
{
    char *c = "NilUnBiTriQuadPentHexSeptOctEnn", /* digit names */
        *p,
        *o = n,                 /* first char of input */
        i, j;                   /* current digit value */
    for (;*n;) {
        j = i = *n-48;
        for (p=c;  *p&32 || i--;  ++p) /* Find the i'th capital letter in c */
                ;
        for (*s++ = *n++ = *p++ + 32;  *p&32;  ) /* Downcase and copy following lowercase */
            *s++ = *p++;
        s -= *n-j==39 || j/2-*n==1;   /* backup one if 9 is followed by 0, or if 2 or 3 is at end of input */
    }
    *o -= 32;                   /* Capitalise symbol */
    strcpy(s,"ium");            /* Finish name */
}

Test harness:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    char buf[1024];
    while (*++argv) {
        f(*argv, buf);
        printf("%s %s\n", *argv, buf);
    }
    return EXIT_SUCCESS;
}
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.