Chemistry 101 - Introduction to the Periodic Table

24

3

Question

Given the atomic number of an element in the range [1-118] output the group and period, of that element as given by the following Periodic Table Of Elements.

For elements in the Lanthanide and Actinide series, (ranges [57-71] and [89-103]), you should instead return L for the Lanthanides and A for the Actinides

You may write a program or a function and use any of the our standard methods of receiving input and providing output.

You may use any programming language, but note that these loopholes are forbidden by default.

enter image description here

[Source]

Test Cases

Since there are only 118 possible inputs, a full list of the expected inputs and outputs is given below.

Created by hand, let me know if there's a mistake!

1,1,1
2,18,1
3,1,2
4,2,2
5,13,2
6,14,2
7,15,2
8,16,2
9,17,2
10,18,2
11,1,3
12,2,3
13,13,3
14,14,3
15,15,3
16,16,3
17,17,3
18,18,3
19,1,4
20,2,4
21,3,4
22,4,4
23,5,4
24,6,4
25,7,4
26,8,4
27,9,4
28,10,4
29,11,4
30,12,4
31,13,4
32,14,4
33,15,4
34,16,4
35,17,4
36,18,4
37,1,5
38,2,5
39,3,5
40,4,5
41,5,5
42,6,5
43,7,5
44,8,5
45,9,5
46,10,5
47,11,5
48,12,5
49,13,5
50,14,5
51,15,5
52,16,5
53,17,5
54,18,5
55,1,6
56,2,6
57,L,
58,L,
59,L,
60,L,
61,L,
62,L,
63,L,
64,L,
65,L,
66,L,
67,L,
68,L,
69,L,
70,L,
71,L,
72,4,6
73,5,6
74,6,6
75,7,6
76,8,6
77,9,6
78,10,6
79,11,6
80,12,6
81,13,6
82,14,6
83,15,6
84,16,6
85,17,6
86,18,6
87,1,7
88,2,7
89,A,
90,A,
91,A,
92,A,
93,A,
94,A,
95,A,
96,A,
97,A,
98,A,
99,A,
100,A,
101,A,
102,A,
103,A,
104,4,7
105,5,7
106,6,7
107,7,7
108,8,7
109,9,7
110,10,7
111,11,7
112,12,7
113,13,7
114,14,7
115,15,7
116,16,7
117,17,7
118,18,7

Scoring

Simple . Shortest number of bytes wins

James Webster

Posted 2017-03-17T08:00:23.713

Reputation: 2 809

5I just know that Mathematica will have a built-in for this... – Okx – 2017-03-17T08:49:02.360

@Okx, I'm hoping that the Lanthanides and Actinides mess up any built-ins :) – James Webster – 2017-03-17T08:50:06.587

2Are you allowed to return "6,L" and "7,A" for the Lanthanides and Actinides? – Neil – 2017-03-17T09:05:42.037

@Neil, No. Just "L" and "A" please. – James Webster – 2017-03-17T09:06:25.847

I assume trailing whitespace is fine? – Okx – 2017-03-17T11:08:14.357

1can't comment (yet) but sometimes Hydrogen is placed in group 17 - but I acknowledge that you've used an image to justify why group 1 and don't know if this makes things harder or easier? – sjb-2812 – 2017-03-17T10:58:10.427

can it be L? or it has to be L, – Felipe Nardi Batista – 2017-03-17T12:05:12.420

1L is fine. That's actually what I intended. But since the CSV outputted L, I'll accept both – James Webster – 2017-03-17T12:06:26.993

Why not L,# for lanthanides (and analogous for actinides), where # is the element's position within the Ln/An group? – hBy2Py – 2017-03-17T13:18:16.930

@hBy2Py, because I came up with an arbitrary way to note those elements :P – James Webster – 2017-03-17T13:18:44.843

@James "Just because." Fair enough! :-) – hBy2Py – 2017-03-17T13:28:09.033

Is the comma as delimiter mandatory, or could we use (example) an underscore as delim? – aross – 2017-03-17T14:42:59.327

@sjb-2812 who is putting H in group 17? That's just wrong. – OrangeDog – 2017-03-17T15:39:24.430

@OrangeDog, with just one electron, is it the first electron in its shell? Or is it missing one from a complete shell? – James Webster – 2017-03-17T15:44:31.967

@JamesWebster does its chemical properties most closely resemble Na or Cl? Hint: H-Cl and Na-Cl are a lot more common than H-H and Na-H. You can (and Mendeleev did) construct the table with no knowledge of atomic structure at all. – OrangeDog – 2017-03-17T15:46:31.377

From what I remember of my high school chemistry, since it has properties of both the alkali metals and the halogens, it is both, yet neither. The books we had placed it in neither group but on its own. This might be better argued on Chemistry SE! – James Webster – 2017-03-17T15:57:28.537

Answers

10

CJam, 64 59 58 56 54 bytes

Thanks to Dennis for saving 2 bytes.

{_80-zG-z8<{80>"LA"=}{_"X8"f>[-14_AAGH].*+:+Imd)}?}

Try it online!

Leaves either period and group or a single character on the stack.

Explanation

There are two main ideas here:

  • First, we deal with the Lanthanides and Actinides. We have the condition 56 < x < 72 for Lanthanides and 88 < x < 104 for Actinides. Both of these can be expressed as a single comparison by taking an absolute difference to the centre of the range: the inequalities become |x - 64| < 8 and |x - 96| < 8, respectively. But these are still very similar, and doing the two comparisons separately is expensive. So we apply the same idea of checking a symmetric range, by taking another absolute difference with the centre between the two ranges, 80, first: ||x-80| - 16| < 8. This condition indicates that the atom is either a Lanthanide or an Actinide, but distinguishing between these two cases is then as trivial as comparing against 80 (or some other value between the ranges).
  • Since the output is really an index in a table of width 18, an obvious approach is to try base-converting the value to base 18, so that the two digits give group and period. To do that, we need to shift some values around though. All the we really need to do is to add the gaps in periods 1, 2 and 3 and close the gaps in periods 6 and 7. It's easiest to do this from the end, so that the values of the other gaps aren't affected (and keep their values).

_            e# Make a copy of the input, to figure out whether the output
             e# should be L or A.
80-z         e# Absolute difference from 80.
G-z          e# Absolute difference from 16.
8<           e# Check whether the result is less than 8.
{            e# If so...
  80>        e#   Check whether the input is greater than 80.
  "LA"=      e#   Select 'L or 'A accordingly.
}{           e# ...otherwise...
  _          e#   Duplicate input again.
  "X8"    e#   Push a string with character codes [88 56 12 4 1].
             e#   These are the values just before the gaps.
  f>         e#   Compare the input to each of these.
  [-14_AAGH] e#   Push [-14 -14 10 10 16 17]. These are the changes we need to
             e#   make to remove or insert the gaps corresponding to the above
             e#   positions. Note that the 17 doesn't get paired with an offset.
             e#   It's a constant offset to itself, which is equivalent to
             e#   decrementing the input (to make it zero based) and adding 18
             e#   to make the increment the period and make it 1-based.
  .*         e#   Multiply each gap by whether it's before the input value.
  +:+        e#   Add all of the applicable gaps to the input value.
  Imd        e#   Divmod 18, gives 1-based period and 0-based group.
  )          e#   Increment the group to make it one-based.
}?

Martin Ender

Posted 2017-03-17T08:00:23.713

Reputation: 184 808

9

05AB1E, 113 102 99 bytes

X18©XY‚Dˆ13®Ÿ¯13®Ÿ®LD¯15'L×S15L3+©¯15'A×S®)˜¹<è,XXY8×SD>4 18×SD>S66Sð14×S6 15×S77Sð15×S7 15×S)˜¹<è,

Explanation:

(start to construct the period part)
X18 ~ push 1 and 18
© ~ store 18 in register_c without p-opping
XY ~ push 1 and 2
13® ~ push 13 and the top element in register_c (18)
Ÿ ~ range - pop 2 values and push [a .. b]
XY ~ push 1 and 2
13®Ÿ ~ range - 13 to 18
XY ~ push 1, 2
13®Ÿ ~ range - 13 to 18
®LD ~ range - 1 to 18 (twice)
2L ~ range - 1 to 2
15'L×S ~ push 'L' 15 times
15L ~ range - 1 to 15
3+ ~ add 3 to each value in topmost element in stack
© ~ store in register-c without popping
2L ~ range - 1 to 2
15'A×S ~ push 'A' 15 times
® ~ push topmost value in register_c
) ~ wrap stack to array
˜ ~ deep flatten
¹<è ~ 1-indexed value of input in array
, ~ print & pop
(start to construct the group part)
XX ~ push 1 twice
Y8×SD ~ push 2 eight times (twice)
> ~ increment each value by 1
4 18×S ~ push 4 eighteen times (twice)
> ~ increment each value by one
66S ~ push 6 twice
ð15×S ~ push a space character 15 times
6 15×S ~ push 6 fifteen times
77S ~ push 7 two times
ð15×S ~ push a space character 15 times
7 15×S ~ push 7 fifteen times
)˜ ~ wrap stack to array and deep flatten
¹<è, ~ get 1-indexed value of input in array, then pop & print

Try it online!

Okx

Posted 2017-03-17T08:00:23.713

Reputation: 15 025

Using a mask like 1000000000000000000000000000000001 1100000000000000000000000000111111 1100000000000000000000000000111111 1112222222222222221111111111111111 1113333333333333331111111111111111 may reduce bytecount, otherwise nice! – Magic Octopus Urn – 2017-03-21T15:07:09.527

7

Mathematica, 77 bytes

e=ElementData;Which[56<#<72,"L",88<#<104,"A",1>0,{#~e~"Group",#~e~"Period"}]&

It would also be quite easy to use ElementData to determine whether the input is a Lanthanide or Actinide, but it would take about 20 more bytes.

Martin Ender

Posted 2017-03-17T08:00:23.713

Reputation: 184 808

3Seriously, builtins again? – Matthew Roh – 2017-03-17T10:37:07.573

1@MatthewRoh I'm sure a well-golfed arithmetic solution in a golfing language will easily beat this. – Martin Ender – 2017-03-17T10:43:37.570

@MartinEnder Well, I'm actually sure of the exact opposite. – Erik the Outgolfer – 2017-03-17T12:45:17.767

@EriktheOutgolfer Well, there you go. I'm sure Jelly could cut off another 30-50%.

– Martin Ender – 2017-03-17T13:04:50.743

@MartinEnder I'll most probably leave that up to Dennis, I can't do such a thing in exam period. – Erik the Outgolfer – 2017-03-17T13:14:23.477

6

Python 2, 205 136 bytes

-26 bytes thanks to @Dead Possum

def f(x):a=(x>71)+(x>99);print((((x-2*(x>1)-8*(x>4)-8*(x>12)+4*a-1)%18+1,(x-(x>17)-14*a)/18+(x>2)+(x>10)+1),'L'),'A')[88<x<104][56<x<72]

Try it online!

Felipe Nardi Batista

Posted 2017-03-17T08:00:23.713

Reputation: 2 345

3

PHP, 144 bytes

Note: uses IBM-850 encoding

$x=($a=$argn-1)<57|$a>70?$a>88&$a<103?A:0:L;foreach([16,19=>10,37=>10,92=>-14,110=>-14]as$l=>$m)$a>$l&&$a+=$m;echo$x?:$a%18+1 .~Ë.ceil(++$a/18);

Run like this:

echo 118 | php -nR '$x=($a=$argn-1)<57|$a>70?$a>88&$a<103?A:0:L;foreach([16,19=>10,37=>10,92=>-14,110=>-14]as$l=>$m)$a>$l&&$a+=$m;echo$x?:$a%18+1 .~Ë.ceil(++$a/18);';echo
> 18,7

Explanation

Check whether input is within the ranges for L or A; the "exception" ranges. Then modify the input to fill the missing cells in the grid (or get rid of the extra cells). Finally, print the exception (unless that is falsy 0) or convert the position to grid coordinates.

aross

Posted 2017-03-17T08:00:23.713

Reputation: 1 583

Running your example, the output I receive is 18<t7. Is this something I'm doing wrong? (running on Mac El Capitan) – James Webster – 2017-03-17T14:14:43.160

1@JamesWebster that's because of the encoding I used for the comma. If you can't switch your terminal's encoding, you can replace the thing between the 2 dots (just before ceil) with "," for 1 extra byte – aross – 2017-03-17T14:18:16.577

3

Jelly, 57 bytes

“9Ḳ*!}ḣE’ṃ“¢£Æ¥Ø‘r2/;€"“ⱮḶıð’ḃ7¤µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị

Full program that prints the desired output.

Try it online! (A slightly modified program which prints all input : output may be seen here).

How?

Builds a list of the 118 possible outputs and then picks the entry at the index of the input.

Some prep:

“9Ḳ*!}ḣE’ - base 250 number: 14334152882934570 (call this A)

“¢£Æ¥Ø‘   - a list using Jelly's code page: [1, 2, 13, 4, 18] (call this B)

“ⱮḶıð’    - base 250 number: 2354944025 (call this C)

The program (shortened by substituting A, B, and C) :

AṃBr2/;€"Cḃ7¤µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị - Main link: atomicNumber
AṃB                                    - number A with digits B: [1,1,18,18,1,2,13,18,1,2,13,18,1,18,1,18,1,2,4,18,1,2,4,18]
    2/                                 - pair-wise reduce with
   r                                   -     inclusive range: [[1],[18],[1,2],[13,14,15,16,17,18],[1,2],[13,14,15,16,17,18],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2],[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2],[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]]
            ¤                          - nilad followed by link(s) as a nilad:
         C                             -     number C
          ḃ7                           -     converted to bijective base 7: [1,1,2,2,3,3,4,5,6,6,7,7]
        "                              - zip with:
      ,€                               -     pair each: [[1,1],[18,1],[[1,2],[2,2]],[[13,2],[14,2],[15,2],[16,2],[17,2],[18,2]],[[1,3],[2,3]],[[13,3],[14,3],[15,3],[16,3],[17,3],[18,3]],[[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4]],[[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5]],[[1,6],[2,6]],[[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6]],[[1,7],[2,7]],[[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]]
             µ                         - monadic chain separation (call the result x)
              ⁵                        - 10
               ,12                     - pair with 12: [10,12]            10↓ 12↓
                  Ṭ                    - truthy indexes: [0,0,0,0,0,0,0,0,0,1,0,1]
                   œṗ                  - partition x at the truthy indexes 
                                       -     (the locations of the runs of L's and A's)
                              ¤        - nilad followed by link(s) as a nilad:

                       ⁾LA             -     ['L','A']
                          ṁ€15         -     mould each like 15: [['L','L','L','L','L','L','L','L','L','L','L','L','L','L','L'],['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A']]
                      "                - zip with:
                     ;                 -     concatenation: [[[1,1],[18,1],[[1,2],[2,2]],[[13,2],[14,2],[15,2],[16,2],[17,2],[18,2]],[[1,3],[2,3]],[[13,3],[14,3],[15,3],[16,3],[17,3],[18,3]],[[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4]],[[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5]],[[1,6],[2,6]],'L','L','L','L','L','L','L','L','L','L','L','L','L','L','L'],[[[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6]],[[1,7],[2,7]],'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A'],[[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]]

             µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị
                                  $    - last two links as a monad:
                               j“”     -     join with [''] (a workaround for no "flatten by 1")
                                   ⁺   - repeat last link (flatten once more): [[1,1],[18,1],[1,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[1,3],[2,3],[13,3],[14,3],[15,3],[16,3],[17,3],[18,3],[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4],[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5],[1,6],[2,6],'L','L','L','L','L','L','L','L','L','L','L','L','L','L','L',[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6],[1,7],[2,7],'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A',[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]
                                    ³  - program's first input
                                     ị - index into the list

Jonathan Allan

Posted 2017-03-17T08:00:23.713

Reputation: 67 804

2

Perl5, 202 bytes

$x=substr(" !2ABMNOPQRabmnopqr\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\301\302LLLLLLLLLLLLLLL\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\341\342KKKKKKKKKKKKKKK\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362",$ARGV[0],1);print$x=~/K/?"A":$x=~/L/?$x:(ord($x)&31).",".(ord($x)>>5)

Michael Vehrs

Posted 2017-03-17T08:00:23.713

Reputation: 771

I would recommend shortening the '\201\202\203...\362' part of the string. Seriously, its long as heck. – Matthew Roh – 2017-03-17T10:33:30.833

1Curious how @MatthewRoh measured heck. – hBy2Py – 2017-03-17T13:28:56.193

2

Ruby, 130 bytes

->a{(w=32767)[a-57]>0??L:w[a-89]>0??A:([[1,2],[20,8],[38,8],[107,32],[125,32]].map{|x,y|a>x&&a+=18-y};[(b=a%18)>0?b:18,~-a/18+1])}

First get the 'A' and 'L' with the bitmask trick, then try to fit into a 18*7 rectangle and use a div/mod.

G B

Posted 2017-03-17T08:00:23.713

Reputation: 11 099

2

Python 2, 137 bytes

lambda x:[(1+(x>2)+(x>10)+min((~-x/18),3)+(x>86),(x+(x>1)*15+((x>4)+(x>12))*10-((x>71)+(x>103))*14)%18+1),"AL"[89<x]][57<x<72or 89<x<104]

Try it online!

ovs

Posted 2017-03-17T08:00:23.713

Reputation: 21 408

2

Python 2, 115 bytes

def f(n):n+=([0,17]+[33]*3+[43]*8+[53]*45+[200]*14+[39]*18+[400]*14+[25]*15)[n];print[(n%18+1,n/18),'L','A'][n/200]

Try it online!

The idea is to div-mod the grid position to get the group and period. The grid position is the input n adjusted by a displacement to account for gaps and the L/A contraction. These are extracted from a list.

The Lanthanide and Actinide handling is ugly. These are assigned large displacements 200 and 400 that can be detected with /200. I'd like to put the characters L and A here, but then n+=... will add a char to a number, giving an error even if n is not used. If not for the 1-indexing, divmod could be used to refer to n only once, and then it could be replaced with its expression,

xnor

Posted 2017-03-17T08:00:23.713

Reputation: 115 687

2

JavaScript (ES7), 100 98 bytes

f=(n,p=1,x=0,y=x+2*(p+2>>1)**2)=>(n-57&95)<15?n>71?'A':'L':n>y?f(n,p+1,y):[n-x-1>p/2?n-y+18:n-x,p]
<input type=number min=1 max=118 oninput=o.textContent=f(this.value)><pre id=o>

Explanation: The 'L' and 'A' series are special-cased, using some bitwise logic that saved me 3 bytes over direct comparisons. Otherwise the function recursively finds the period p containing the desired atomic number, the number of the last element in the previous period x, and the number of the last element in the period y which is computed each time by noting that the differences are 2, 2, 8, 8, 18, 18 i.e. repeated doubled square numbers. The group is then found by offsetting from the left or right of the table depending on whether the element lies under the Beryllium-Scandium diagonal or not.

Neil

Posted 2017-03-17T08:00:23.713

Reputation: 95 035

1

Python 2, 264 227 217 bytes

lambda x:((((((((((((((1,1),(18,1))[x>1],(x-2,2))[x>2],(x+8,2))[x>4],(x-10,3))[x>10],(x,3))[x>12],(x-18,4))[x>18],(x-36,5))[x>36],(x-54,6))[x>54],'L')[x>56],(x-68,6))[x>71],(x-86,7))[x>86],'A')[x>88],(x-100,7))[x>103]

Try it online!

Way too many brackets. It looks more like Brain-Flak.

ElPedro

Posted 2017-03-17T08:00:23.713

Reputation: 5 301

can't you place that while outside the function? it would save a byte (space) – Felipe Nardi Batista – 2017-03-17T12:44:47.180

@FelipeNardiBatista - Managed to get rid of the while loop altogether :) – ElPedro – 2017-03-17T13:17:34.143

1

JavaScript (ES6), 136 bytes

n=>[...'112626ii2ff2fff'].reduce((p,i,j)=>(n-=parseInt(i,36))>0?n:+p?+(x='112233456L67A7'[j])?[p+(9258>>j&1?j>5?3:j>2?12:17:0),x]:x:p,n)

Test

let f =

n=>[...'112626ii2ff2fff'].reduce((p,i,j)=>(n-=parseInt(i,36))>0?n:+p?+(x='112233456L67A7'[j])?[p+(9258>>j&1?j>5?3:j>2?12:17:0),x]:x:p,n)
<input oninput="o.innerHTML=f(+value)" type="number" min=1 max=118/>
<pre id="o"></pre>

Arnauld

Posted 2017-03-17T08:00:23.713

Reputation: 111 334

1

Excel, 192 bytes

Far from pretty. Borrows from existing Python answers

=SUBSTITUTE(SUBSTITUTE(IF(ABS(ABS(A1-80)-16)<8,IF(A1<80,"L","A"),MOD(A1-2*(A1>1)-8*(A1>4)-8*(A1>12)+4*((A1>71)+(A1>99)),18)&" ,"&1+(A1>2)+(A1>10)+(A1>18)+(A1>36)+(A1>54)+(A1>86)),0,18),118,10)

Struggling to handle the case where MOD(x,18)=0 for Group value gracefully.

Wernisch

Posted 2017-03-17T08:00:23.713

Reputation: 2 534

I think I've found a mistake. Should the IF for determining lanthanides and actinides read IF(A1<80? – James Webster – 2017-09-11T17:41:45.787

@JamesWebster, well spotted. Have corrected. – Wernisch – 2017-09-12T11:28:22.433

0

Ruby, 116 bytes

->n{a=(17..143).map{|i|"#{[i%18+1,i/18]}"}
a[2..17]=a[21..30]=a[39..48]=[]
a[57]=[?L]*15
a[75]=[?A]*15
a.flatten[n]}

Commented in test program

f=->n{
a=(17..143).map{|i|"#{[i%18+1,i/18]}"} #Make an array with strings "[18,0]" to "[18,7]" (first value required as input is 1 indexed.)
a[2..17]=a[21..30]=a[39..48]=[]        #Delete "missing" elements from first three periods. 
a[57]=[?L]*15                          #Replace position 57 in the table with a 15-element array ["L".."L"]
a[75]=[?A]*15                          #Replace the correct position in the table with a 15-element array ["A".."A"]
a.flatten[n]}                          #Flatten the array (break the two above elements into 15) and output element n of the array.

1.upto(118){|n|print n,f[n],$/}

Level River St

Posted 2017-03-17T08:00:23.713

Reputation: 22 049

0

PHP, 120 bytes

echo(($n=--$argn)-56&95)<15?LA[$n>70]:(($n-=14*($n>88)+14*($n>56)-10*($n>11)-10*($n>3)-16*!!$n)%18+1).",".(($n/18|0)+1);

takes input from STDIN, run with -nR.

some bitwise magic for the Lanthanides and Actinides,
the $n-= part adds and subtracts offsets for the gaps and Lanthanides/Actinides,
the rest is simple mod/div.

An iterative port of Neil´s answer takes 108 bytes:

for(;(95&71+$n=$argn)>14&&$n>$y+=2*(++$p+2>>1)**2;)$x=$y;
echo$p?$n-$x>$p/2+1?$n-$y+18:$n-$x:LA[$n>70],",$p";

Titus

Posted 2017-03-17T08:00:23.713

Reputation: 13 814

0

Perl, 169 bytes

90>($n-=14)&&($g=A)if($n=$v=pop)>88;58>($n-=14)&&($g=L)if$n>56;if(!$g){$c+=vec"\1\0\xe\xc0?\0".("\xff"x9)."?",$i++,1
while$c<$n;$p=1+($i-($g=$i%18||18))/18}say"$v,$g,$p"

Using:

perl -E '90>($n-=14)&&($g=A)if($n=$v=pop)>88;58>($n-=14)&&($g=L)if$n>56;if(!$g){$c+=vec"\1\0\xe\xc0?\0".("\xff"x9)."?",$i++,1 while$c<$n;$p=1+($i-($g=$i%18||18))/18}say"$v,$g,$p"' 103

Denis Ibaev

Posted 2017-03-17T08:00:23.713

Reputation: 876

0

Jelly, 49 43 42 41 39 bytes

45“ÞØ\€a€⁶;l;i‘bx/€F’ḣ¹Sḃ18µV=“?I‘⁾LAxȯ

Try it online!

Background

With the exception of lanthanides and actinides, the output will consist of an integer expressed in bijective base 18. For example, hydrogen corresponds to 1910 = 11b18, helium to 3610 = 1Ib18, and eka-radon/ununoctium/oganesson to 11410 = 7Ib18.

We start by mapping all atomic numbers we can to the corresponding integers, while mapping lanthanides and actinides to those that correspond to lanthanum (11110 = 63b18) and actinium (12910 = 73b18).

To do this, we record the forward differences of the integers that represent the atoms. For example, the first is 1Ib18 - 11b18 = Hb18 = 1710, the second is 1 (as are all differences between consecutive elements of the unexpanded periodic table), the fourth (B to Be) is 2Db18 - 22b18 = Bb18 = 1110, and so on. To map all lanthanides and all actinides, we'll consider all differences between two lanthanides or to actinides (e.g., La to Ce) to be 0.

To get the desired integer for an atomic number n, all we have to do is prepend 19 (hydrogen) to the differences and compute the sum of the first n elements of the resulting vector. The output is then simply displayed in bijective base 18, unless this would display 6 3 (lanthanides) or 7 3 (actinides). In the latter case, we simply replace the computed result with L or A.

Wrapped for horizontal sanity, the vector we have to encode looks as follows.

19 17  1  1 11  1  1  1  1  1  1  1 11  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  1

After run-length encoding, we get the following.

19 1    17 1    1 2    11 1    1 7    11 1    1 44    0 14    1 18    0 14    1 15

To reduce the space required to encode the vector even more, we strip rightmost 1's (lengths) and add 1 to the runs.

20      18      2 2    12      2 7    12      2 44    1 14    2 18    1 14    2 15

Now we can reversibly convert these digit arrays from base 45 to integers.

20      18      92     12      97     12      134     59      108     59      105

All of these are smaller than 250, so we can represent them with characters from Jelly's code page. Surrounded with (literal start) and (interpret as integer array), we get the Jelly literal

“ÞØ\€a€⁶;l;i‘

which appears verbatim in the code.

How it works

45“…‘bx/€F’ḣ¹Sḃ18µV=“?I‘⁾LAxȯ  Main link. Argument: n (atomic number)

45                             Set the return value to 45.
  “…‘                          Yield [20,18,92,12,97,12,134,59,108,59,105].
     b                         Convert the integers in the array to base 45.
      x/€                      Reduce each resulting digit array (length 1 or 2)
                               by repetition, mapping [z] -> [z] and
                               [y,z] -> [y,…,y] (z times).
         F                     Flatten the result.
          ’                    Decrement, yielding the vector of length 118 from
                               the previous section.
           ḣ¹                  Head; take the first n elements of the vector.
             S                 Compute their sum.
              ḃ18              Convert to bijective base 18, yielding [p, g].
                 µ             Begin a new chain with argument [p,g].
                  V            Eval. The atom casts to string first, so [6,3]
                               , e.g., is mapped to 63, [7,18] to 718, etc.
                   =“?I‘       Compare the result with [63,73], yielding
                               [1,0] for lanthanides, [0,1] for actinides, and
                               [0,0] otherwise.
                        ⁾LAx   Repeat 'L' and 'A' that many times, yielding "L" for
                               lanthanides, "A" for actinides, and "" otherwise.
                            ȯ  Flat logical OR; replace "" with [p,g].

Dennis

Posted 2017-03-17T08:00:23.713

Reputation: 196 637

While this is an interesting answer, I'm afraid I think it falls down on the output. Instead of outputting the group and the period for the input, it appears to output the atomic number, group and period for the full table. Consider if I'd asked you for a dictionary definition of a word and you just outputted a dictionary. – James Webster – 2017-03-27T08:29:45.850

The footer provides a test suite for easy verification. If you remove it and provide the input as an argument, it will just print yhe information the spec asks for. https://tio.run/nexus/jelly#@29i@qhhzuF5h2fEPGpakwjEjxq3WedYZz5qmJFUoQ/kuz1qmPlwx@JDO4Mf7mg2tDi0NcwWqMPeE6jgUeM@H8eKE@v///9vbgkA

– Dennis – 2017-03-27T14:38:34.200