Find the Block on the Extended Periodic Table Using the Diagonal Rule

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.)

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)