The periodic table gets its shape from the arrangement of elements into blocks:

blocks intro

An element is assigned its block based on what type of orbital holds its valence electron(s). For instance, the sole valence electron of neutral hydrogen occupies the 1s orbital in the 1s subshell, and so hydrogen belongs to the s-block.

The least energetic subshell is the 1s subshell, followed by 2s, 2p, 3s, etc. Electrons fill orbitals in less-energetic subshells first, in accordance with the following chart:


The diagonal arrows give the diagonal rule its name.

When finding the block of an element, there are some important facts to consider:

  • Each subsequent element has one more electron than its predecessor.

  • Every new type of subshell (s, p, d . . . ) can hold four more electrons than its predecessor as a consequence of the presence of two additional orbitals.

  • All subshells (1s, 2s . . . ) have an odd number of orbitals, each of which can hold two electrons. As such, all subshells can hold twice an odd number of electrons.

  • Subshells beyond s, p, d and f have names reserved for their eventual observation: after f comes the rest of the alphabet, starting with g and omitting j.

The Challenge

Given the atomic number of an element, output its block (a letter).

Because one can tell how many electrons are held by theorized, not-yet-observed subshells, input will be less than or equal to 17296 (found with the sum \$2\sum_{n=1}^{23}\sum_{\ell=0}^{n-1}2\left(2\ell+1\right)\$), the atomic number of the last element with valence electrons in the 46s subshell. Letters beyond z would be needed for elements past that point, and so they will not be included in the challenge. An extended version of the diagonal line chart above can be seen here.


  • This is so the shortest answer in bytes in each language wins

  • For the purpose of this challenge, when s and p are reached a second time after f, they will be capitalized. This means letters are sequenced as follows: s p d f g h i k l m n o P q r S t u v w x y z. Additionally, it means output is case-sensitive.

  • Assume only valid input is given.

  • There is a discrepancy between the periodic table above and the expected output: in reality, lanthanum and actinium (57 and 89) are in the d-block, and lutetium and lawrencium (71 and 103) are in the f-block. The diagonal rule implies that lanthanum and actinium are in the f-block, and that lutetium and lawrencium are in the d-block, and so that is what the program should state.

Test Cases

In: 1
Out: s

In: 5
Out: p

In: 21
Out: d

In: 57
Out: f

In: 2784
Out: l

In: 17296
Out: s

In: 15181
Out: z

In: 12024
Out: q
  • \$\begingroup\$ Shouldn't 2784 be l? \$\endgroup\$ Jul 13, 2020 at 10:16
  • \$\begingroup\$ @KevinCruijssen That is correct, thank you for telling me. Also, 12024 is q like you pointed out elsewhere \$\endgroup\$
    – golf69
    Jul 13, 2020 at 19:03

3 Answers 3


Charcoal, 59 bytes


Try it online! Link is to verbose version of code. Explanation:


Input the atomic number.


Start with just an s-shell.


Repeat while the number of electrons left will fill all the shells twice...


... remove those electrons, and...


... add another shell which can hold 4 more electrons than the previous.


Count how many of the remaining shells have no electrons and look that up in the compressed string of block letters. (Because of the way Sum works in Charcoal, the calculation is adjusted slightly to avoid a sum of no elements, which ends up offsetting the result by 1, which is compensated by moving the z to the beginning of the string where it can be cyclically indexed.)

  • \$\begingroup\$ @KevinCruijssen No, because that breaks for equal values. But it turns out I had to do that anyway because the previous code was buggy and I had to subtract 1 to fix that (costing a byte) but then fortunately I do now want Less inside the filter, thus balancing the bug fix. \$\endgroup\$
    – Neil
    Jul 13, 2020 at 10:52
  • \$\begingroup\$ Yeah, I deleted my comment when I noticed that. Btw, you forgot to update your TIO after your fix just yet. \$\endgroup\$ Jul 13, 2020 at 10:54
  • 1
    \$\begingroup\$ @KevinCruijssen Yes, I noticed when I went to see whether it affected 17296 or 2784. BTW that fix was for 12, which was resulting in p instead of s. \$\endgroup\$
    – Neil
    Jul 13, 2020 at 10:56
  • \$\begingroup\$ Hmm, 12024 now results in q instead of P. Again, not sure if the test cases are wrong or our implementations.. \$\endgroup\$ Jul 13, 2020 at 11:07

J, 64 bytes

-4 for 12024 being q


Try it online!

How it works


Create a 99x99 matrix where each row counts up: 0 1 2 3 …


Take each diagonal 0;1 0;2 1 0 two times: 0 0 1 0 1 0 2 1 0 2 1 0 ….


Multiply each number by 4, add 2, add each number left to it: 2 4 10 12 18 20 30 …


Use this as range boundaries to find the index for the input, e.g. 13.


Get the corresponding shell at that index, e.g. 1.


Retrieve the shell name.


05AB1E, 46 bytes


Port of @Neil's Charcoal answer, so make sure to upvote him as well!

Try it online or verify all test cases.


[                    # Start an infinite loop:
 N4*                 #  Multiply the (0-based) loop-index by 4
    Ì                #  Increase it by 2
     ˆ               #  Pop and add this value to the global array
 ¯O                  #  Get the sum of the global array
   ·                 #  Double this sum
    -                #  Subtract it from the current integer,
                     #  which will be the (implicit) input in the first iteration
     Ð               #  Triplicate this new value
      1‹             #  If it's 0 or negative:
        #            #   Stop the infinite loop
      U              #  Pop and store the triplicated value in variable `X`
                     #  (which is 1 by default, which doesn't matter for inputs ≤ 4)
}A                   # After the infinite loop: push the lowercase alphabet
  3.$                # Remove the leading "abc"
     „sp             # Push string "sp"
        ©            # Store it in variable `®` (without popping)
         D           # Duplicate "sp"
          u          # Uppercase the copy: "SP"
           ‡         # Transliterate "s" to "S" and "p" to "P"
            ®ì       # Prepend "sp" from variable `®`
              „ejм   # Remove "e" and "j"
                  Á  # Rotate it once towards the right
                     # (we now have the string "zspdfghiklmnoPqrStuvwxy")
 ¯.s                 # Get a list of suffices of the global array
    O                # Sum each inner suffix
     X<              # Push value `X`, and decrease it by 1
       ¯O%           # Modulo it by the sum of the global array
          ›          # Check for each prefix-sum if it's larger than this value
                     # (1 if truthy; 0 if falsey)
           O         # Get the amount of truthy values by summing
 è                   # And use it to (0-based) index into the string
                     # (after which the resulting character is output implicitly)

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.