Periodic table: Difference between revisions

From Rosetta Code
Content added Content deleted
m (syntax highlighting fixup automation)
Line 66: Line 66:
Since the 6502 can't index an array larger than 256 bytes, we'll store all the "low bytes" in one table and all the "high bytes" in another. Both tables share the same index, so this lets us store up to 255 possible elements while taking the same amount of memory as a single table of 16-bit values. Right now, we can do this either way, but since we're close to 128 elements, may as well future-proof the code, right?
Since the 6502 can't index an array larger than 256 bytes, we'll store all the "low bytes" in one table and all the "high bytes" in another. Both tables share the same index, so this lets us store up to 255 possible elements while taking the same amount of memory as a single table of 16-bit values. Right now, we can do this either way, but since we're close to 128 elements, may as well future-proof the code, right?


<lang 6502asm>Lookup: ;INPUT: X = atomic number of the element of interest.
<syntaxhighlight lang="6502asm">Lookup: ;INPUT: X = atomic number of the element of interest.
LDA PeriodicTable_Column,x
LDA PeriodicTable_Column,x
STA $20 ;store column number in memory (I chose $20 arbitrarily, you can store it anywhere)
STA $20 ;store column number in memory (I chose $20 arbitrarily, you can store it anywhere)
Line 76: Line 76:
db $ff,$01,$18,$01,$02,$13,$14,$15,$16,$17,$18,... ;I don't need to write them all out, the concept is self-explanatory enough.
db $ff,$01,$18,$01,$02,$13,$14,$15,$16,$17,$18,... ;I don't need to write them all out, the concept is self-explanatory enough.
PeriodicTable_Row:
PeriodicTable_Row:
db $ff,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,...</lang>
db $ff,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,...</syntaxhighlight>


=={{header|68000 Assembly}}==
=={{header|68000 Assembly}}==
Line 84: Line 84:
The table consists of 118 16-bit values. The high byte is the row number, the low byte is the column number. Both are stored as binary-coded decimal (i.e. hex values that look like base 10 numbers.)
The table consists of 118 16-bit values. The high byte is the row number, the low byte is the column number. Both are stored as binary-coded decimal (i.e. hex values that look like base 10 numbers.)


<lang 68000devpac>Lookup:
<syntaxhighlight lang="68000devpac">Lookup:
;input: D0.W = the atomic number of interest.
;input: D0.W = the atomic number of interest.
LEA PeriodicTable,A0
LEA PeriodicTable,A0
Line 103: Line 103:
DC.W $0217 ;FLUORINE
DC.W $0217 ;FLUORINE
DC.W $0218 ;NEON
DC.W $0218 ;NEON
;etc.</lang>
;etc.</syntaxhighlight>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
<lang algol68>BEGIN # display the period and group number of an element, #
<syntaxhighlight lang="algol68">BEGIN # display the period and group number of an element, #
# given its atomic number #
# given its atomic number #
INT max atomic number = 118; # highest known element #
INT max atomic number = 118; # highest known element #
Line 166: Line 166:
FI
FI
OD
OD
END</lang>
END</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 188: Line 188:
==={{header|Applesoft BASIC}}===
==={{header|Applesoft BASIC}}===
This program borrows from the [[#Python|Python]] solution but only PRINTs the results of the tests shown in the task. Each row and column from the tests are PLOTted in a COLORful table.
This program borrows from the [[#Python|Python]] solution but only PRINTs the results of the tests shown in the task. Each row and column from the tests are PLOTted in a COLORful table.
<lang gwbasic>0 GR:HOME:COLOR=11:FORR=1TO7:FORC=1TO2:GOSUB7:NEXTC,R:COLOR=7:FORR=4TO7:FORC=3+(R>5)TO12:GOSUB7:NEXTC,R:COLOR=13:FORR=2TO7:FORC=13TO18:GOSUB7:NEXTC,R
<syntaxhighlight lang="gwbasic">0 GR:HOME:COLOR=11:FORR=1TO7:FORC=1TO2:GOSUB7:NEXTC,R:COLOR=7:FORR=4TO7:FORC=3+(R>5)TO12:GOSUB7:NEXTC,R:COLOR=13:FORR=2TO7:FORC=13TO18:GOSUB7:NEXTC,R
1 forr=2to7:forc=13to18:GOSUB7:NEXTC,R:COLOR=14:R=8:FORC=4TO18:GOSUB7:NEXTC:COLOR=12:R=9:FORC=4TO18:GOSUB7:NEXTC:R=9:FORC=4TO18:GOSUB7:NEXTC:Z=2:R=7:C=3:GOSUB7:COLOR=14:R=6:C=3:GOSUB7:COLOR=15
1 forr=2to7:forc=13to18:GOSUB7:NEXTC,R:COLOR=14:R=8:FORC=4TO18:GOSUB7:NEXTC:COLOR=12:R=9:FORC=4TO18:GOSUB7:NEXTC:R=9:FORC=4TO18:GOSUB7:NEXTC:Z=2:R=7:C=3:GOSUB7:COLOR=14:R=6:C=3:GOSUB7:COLOR=15
2 S=14:W=18:FORI=1TO7:READN(I),I(I):NEXT:DATA2,0,10,0,18,0,36,0,54,0,86,57,118,89,1,1,1,2,1,18,29,4,11,42,5,6,57,8,4,58,8,5,72,6,4,89,9,4,59,8,6,71,8,18,90,9,5,103,9,18
2 S=14:W=18:FORI=1TO7:READN(I),I(I):NEXT:DATA2,0,10,0,18,0,36,0,54,0,86,57,118,89,1,1,1,2,1,18,29,4,11,42,5,6,57,8,4,58,8,5,72,6,4,89,9,4,59,8,6,71,8,18,90,9,5,103,9,18
Line 195: Line 195:
5 E=N-P:K=A-P:IFI(R)AND(I(R)<=AANDA<=I(R)+S)THENR=R+2:C=K+1:RETURN
5 E=N-P:K=A-P:IFI(R)AND(I(R)<=AANDA<=I(R)+S)THENR=R+2:C=K+1:RETURN
6 E=W-E:L=1+(N>2):C=K+E*(K>L):RETURN
6 E=W-E:L=1+(N>2):C=K+E*(K>L):RETURN
7 K=C+(R=1ANDC=2)*16:VLINR*4+Z,R*4+2ATK*2+1:RETURN</lang>
7 K=C+(R=1ANDC=2)*16:VLINR*4+Z,R*4+2ATK*2+1:RETURN</syntaxhighlight>


=== {{header|ASIC}} ===
=== {{header|ASIC}} ===
{{trans|Nascom BASIC}}
{{trans|Nascom BASIC}}
<lang basic>
<syntaxhighlight lang="basic">
REM Periodic table
REM Periodic table
DIM A(7)
DIM A(7)
Line 240: Line 240:
PRINT C
PRINT C
RETURN
RETURN
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 257: Line 257:
==={{header|BASIC256}}===
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang BASIC256>subroutine MostarPos(N)
<syntaxhighlight lang="basic256">subroutine MostarPos(N)
dim A = { 1, 2, 5, 13, 57, 72, 89, 104}
dim A = { 1, 2, 5, 13, 57, 72, 89, 104}
dim B = {-1, 15, 25, 35, 72, 21, 58, 7}
dim B = {-1, 15, 25, 35, 72, 21, 58, 7}
Line 273: Line 273:
for I = 0 to Element[?]-1
for I = 0 to Element[?]-1
call MostarPos(Element[I])
call MostarPos(Element[I])
next I</lang>
next I</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 279: Line 279:
==={{header|FreeBASIC}}===
==={{header|FreeBASIC}}===
{{trans|XPL0}}
{{trans|XPL0}}
<lang freebasic>Sub MostarPos(N As Integer)
<syntaxhighlight lang="freebasic">Sub MostarPos(N As Integer)
Dim As Integer M, I, R, C
Dim As Integer M, I, R, C
Dim As Integer A(0 To 7) = { 1, 2, 5, 13, 57, 72, 89, 104} 'magic numbers
Dim As Integer A(0 To 7) = { 1, 2, 5, 13, 57, 72, 89, 104} 'magic numbers
Line 296: Line 296:
For I As Integer = 0 To Ubound(Element)
For I As Integer = 0 To Ubound(Element)
MostarPos(Element(I))
MostarPos(Element(I))
Next I</lang>
Next I</syntaxhighlight>
{{out}}
{{out}}
<pre>Atomic number 1 -> 1, 1
<pre>Atomic number 1 -> 1, 1
Line 314: Line 314:
==={{header|FutureBasic}}===
==={{header|FutureBasic}}===
Old fashioned way:
Old fashioned way:
<lang futurebasic>
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
include "NSLog.incl"


Line 365: Line 365:


HandleEvents
HandleEvents
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 385: Line 385:


Modern way. (Too bad you can no longer upload images to Rosetta Code.)
Modern way. (Too bad you can no longer upload images to Rosetta Code.)
<lang futurebasic>
<syntaxhighlight lang="futurebasic">
_window = 1
_window = 1


Line 455: Line 455:


HandleEvents
HandleEvents
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 462: Line 462:


==={{header|Gambas}}===
==={{header|Gambas}}===
<lang gambas>Sub MostarPos(N As Integer) 'Mostrar fila y columna para el elemento
<syntaxhighlight lang="gambas">Sub MostarPos(N As Integer) 'Mostrar fila y columna para el elemento
Dim M, I, R, C As Integer
Dim M, I, R, C As Integer
Dim A As Integer[] = [1, 2, 5, 13, 57, 72, 89, 104] 'magic numbers
Dim A As Integer[] = [1, 2, 5, 13, 57, 72, 89, 104] 'magic numbers
Line 483: Line 483:
Next
Next


End</lang>
End</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 490: Line 490:
{{trans|Nascom BASIC}}
{{trans|Nascom BASIC}}
{{works with|Commodore BASIC|3.5}}
{{works with|Commodore BASIC|3.5}}
<lang gwbasic>
<syntaxhighlight lang="gwbasic">
10 REM Periodic table
10 REM Periodic table
20 GOSUB 200
20 GOSUB 200
Line 523: Line 523:
1030 REM Example elements (atomic numbers).
1030 REM Example elements (atomic numbers).
1040 DATA 1, 2, 29, 42, 57, 58, 72, 89, 90, 103
1040 DATA 1, 2, 29, 42, 57, 58, 72, 89, 90, 103
</syntaxhighlight>
</lang>


=== {{header|Nascom BASIC}} ===
=== {{header|Nascom BASIC}} ===
{{works with|Nascom ROM BASIC|4.7}}
{{works with|Nascom ROM BASIC|4.7}}
<lang basic>
<syntaxhighlight lang="basic">
10 REM Periodic table
10 REM Periodic table
20 GOSUB 200
20 GOSUB 200
Line 551: Line 551:
1030 REM ** Example elements (atomic numbers).
1030 REM ** Example elements (atomic numbers).
1040 DATA 1,2,29,42,57,58,72,89,90,103
1040 DATA 1,2,29,42,57,58,72,89,90,103
</lang>
</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 570: Line 570:
{{works with|QuickBasic|4.5}}
{{works with|QuickBasic|4.5}}
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang qbasic>SUB MostarPos (N)
<syntaxhighlight lang="qbasic">SUB MostarPos (N)
DIM a(7)
DIM a(7)
RESTORE a:
RESTORE a:
Line 601: Line 601:
DATA 1, 2, 5, 13, 57, 72, 89, 104
DATA 1, 2, 5, 13, 57, 72, 89, 104
b:
b:
DATA -1, 15, 25, 35, 72, 21, 58, 7</lang>
DATA -1, 15, 25, 35, 72, 21, 58, 7</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 609: Line 609:
{{works with|Liberty BASIC}}
{{works with|Liberty BASIC}}
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang lb>dim Element(12)
<syntaxhighlight lang="lb">dim Element(12)
Element(0) = 1
Element(0) = 1
Element(1) = 2
Element(1) = 2
Line 655: Line 655:
C = (M mod 18) +1
C = (M mod 18) +1
print "Atomic number "; using("###", N); " -> "; R; ", "; C
print "Atomic number "; using("###", N); " -> "; R; ", "; C
end sub</lang>
end sub</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 661: Line 661:
==={{header|True BASIC}}===
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang qbasic>SUB MostarPos (n)
<syntaxhighlight lang="qbasic">SUB MostarPos (n)
DIM a(0 TO 7)
DIM a(0 TO 7)
LET a(0) = 1
LET a(0) = 1
Line 708: Line 708:
CALL MostarPos (element(e))
CALL MostarPos (element(e))
NEXT e
NEXT e
END</lang>
END</syntaxhighlight>
{{out}}
{{out}}
<pre>Similar to FreeBASIC entry.</pre>
<pre>Similar to FreeBASIC entry.</pre>
Line 715: Line 715:
{{works with|Windows XBasic}}
{{works with|Windows XBasic}}
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang xbasic>PROGRAM "Periodic table"
<syntaxhighlight lang="xbasic">PROGRAM "Periodic table"


DECLARE FUNCTION Entry ()
DECLARE FUNCTION Entry ()
Line 771: Line 771:


END FUNCTION
END FUNCTION
END PROGRAM</lang>
END PROGRAM</syntaxhighlight>
{{out}}
{{out}}
<pre>Similar to FreeBASIC entry.</pre>
<pre>Similar to FreeBASIC entry.</pre>
Line 777: Line 777:
==={{header|Yabasic}}===
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
{{trans|FreeBASIC}}
<lang freebasic>// Rosetta Code problem: http://rosettacode.org/wiki/Periodic_table
<syntaxhighlight lang="freebasic">// Rosetta Code problem: http://rosettacode.org/wiki/Periodic_table
// by Jjuanhdez, 06/2022
// by Jjuanhdez, 06/2022


Line 813: Line 813:
C = mod(M, 18) +1
C = mod(M, 18) +1
print "Atomic number ", N using("###"), " -> ", R, ", ", C
print "Atomic number ", N using("###"), " -> ", R, ", ", C
end sub</lang>
end sub</syntaxhighlight>
{{out}}
{{out}}
<pre>Same as FreeBASIC entry.</pre>
<pre>Same as FreeBASIC entry.</pre>
Line 819: Line 819:
=={{header|Go}}==
=={{header|Go}}==
{{trans|Wren}}
{{trans|Wren}}
<lang ecmascript>package main
<syntaxhighlight lang="ecmascript">package main


import (
import (
Line 865: Line 865:
fmt.Printf("Atomic number %3d -> %d, %-2d\n", n, row, col)
fmt.Printf("Atomic number %3d -> %d, %-2d\n", n, row, col)
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 888: Line 888:
Basically, here, we want a lookup table. For example:
Basically, here, we want a lookup table. For example:


<lang J>PT=: (' ',.~[;._2) {{)n
<syntaxhighlight lang="j">PT=: (' ',.~[;._2) {{)n
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 H He
1 H He
Line 911: Line 911:
}}
}}


rowcol=: ptrc''</lang>
rowcol=: ptrc''</syntaxhighlight>


In other words, start with a hand crafted representation of the periodic table. Elements here are tokens with 1 or 2 letters. Locate the position of each token in the table. Get an initial row and column number from the character positions in the table. Translate character column to periodic table column by enumerating the unique (sorted) list of column numbers and using the index in that list. Character row was already periodic table row. Most elements here were already in atomic number order, and we can fix the exceptions by temporarily prefixing each row,col value and sorting. (Here, we use 0 for the first 56 elements, 3 for the next 17 elements (after Lantanoidi, before Aktinoidi), 12 for the next 15 (after Aktinoidi), 2 for the next 15 (the Lantanoidi) and 11 for the final 15 elements (the Aktinoidi).)
In other words, start with a hand crafted representation of the periodic table. Elements here are tokens with 1 or 2 letters. Locate the position of each token in the table. Get an initial row and column number from the character positions in the table. Translate character column to periodic table column by enumerating the unique (sorted) list of column numbers and using the index in that list. Character row was already periodic table row. Most elements here were already in atomic number order, and we can fix the exceptions by temporarily prefixing each row,col value and sorting. (Here, we use 0 for the first 56 elements, 3 for the next 17 elements (after Lantanoidi, before Aktinoidi), 12 for the next 15 (after Aktinoidi), 2 for the next 15 (the Lantanoidi) and 11 for the final 15 elements (the Aktinoidi).)
Line 917: Line 917:
Thus:
Thus:


<lang J> 1 2 29 42 57 58 72 89 { rowcol
<syntaxhighlight lang="j"> 1 2 29 42 57 58 72 89 { rowcol
1 1
1 1
1 18
1 18
Line 925: Line 925:
8 5
8 5
6 4
6 4
9 4</lang>
9 4</syntaxhighlight>




=={{header|Julia}}==
=={{header|Julia}}==
{{trans|Wren}}
{{trans|Wren}}
<lang ruby>const limits = [3:10, 11:18, 19:36, 37:54, 55:86, 87:118]
<syntaxhighlight lang="ruby">const limits = [3:10, 11:18, 19:36, 37:54, 55:86, 87:118]


function periodic_table(n)
function periodic_table(n)
Line 953: Line 953:
println("Atomic number ", lpad(n, 3), " -> ($(rc[1]), $(rc[2]))")
println("Atomic number ", lpad(n, 3), " -> ($(rc[1]), $(rc[2]))")
end
end
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre>
<pre>
Atomic number 1 -> (1, 1)
Atomic number 1 -> (1, 1)
Line 972: Line 972:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Mathematica and the Wolfram language include the period and group in the function ElementData but has slightly different definitions for the lantanides and aktinoides.
Mathematica and the Wolfram language include the period and group in the function ElementData but has slightly different definitions for the lantanides and aktinoides.
<lang Mathematica>ClearAll[FindPeriodGroup]
<syntaxhighlight lang="mathematica">ClearAll[FindPeriodGroup]
FindPeriodGroup[n_Integer] := Which[57 <= n <= 70,
FindPeriodGroup[n_Integer] := Which[57 <= n <= 70,
{8, n - 53}
{8, n - 53}
Line 986: Line 986:
]
]
Row[{"Element ", #, " -> ", FindPeriodGroup[#]}] & /@ {1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113} // Column
Row[{"Element ", #, " -> ", FindPeriodGroup[#]}] & /@ {1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113} // Column
Graphics[Text[#, {1, -1} Reverse@FindPeriodGroup[#]] & /@ Range[118]]</lang>
Graphics[Text[#, {1, -1} Reverse@FindPeriodGroup[#]] & /@ Range[118]]</syntaxhighlight>
{{out}}
{{out}}
<pre>Element 1 -> {1,1}
<pre>Element 1 -> {1,1}
Line 1,006: Line 1,006:
=={{header|Perl}}==
=={{header|Perl}}==
{{trans|Raku}}
{{trans|Raku}}
<lang perl>use strict;
<syntaxhighlight lang="perl">use strict;
use warnings; no warnings 'uninitialized';
use warnings; no warnings 'uninitialized';
use feature 'say';
use feature 'say';
Line 1,020: Line 1,020:
for my $n (<1 2 29 42 57 58 72 89 90 103 118>) {
for my $n (<1 2 29 42 57 58 72 89 90 103 118>) {
printf "%3d: %2d, %2d\n", $n, map { $_+1 } divmod $n-1 + sum(head $span[$n-1], @offset), $b;
printf "%3d: %2d, %2d\n", $n, map { $_+1 } divmod $n-1 + sum(head $span[$n-1], @offset), $b;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 1: 1, 1
<pre> 1: 1, 1
Line 1,034: Line 1,034:


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">match_wp</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">match_wp</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
Line 1,067: Line 1,067:
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"|"</span><span style="color: #0000FF;">}}),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"|"</span><span style="color: #0000FF;">}}),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
With match_wp set to true:
With match_wp set to true:
Line 1,096: Line 1,096:
</pre>
</pre>
===alternate===
===alternate===
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">ptxt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
<span style="color: #008080;">constant</span> <span style="color: #000000;">ptxt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
__________________________________________________________________________
__________________________________________________________________________
Line 1,149: Line 1,149:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Element %d %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">e</span><span style="color: #0000FF;">]})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Element %d %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">e</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 1,171: Line 1,171:
A solution trying hard not to encode too much data about the table.
A solution trying hard not to encode too much data about the table.


<syntaxhighlight lang="python">
<lang Python>
def perta(atomic) -> (int, int):
def perta(atomic) -> (int, int):


Line 1,219: Line 1,219:
print('TEST:{:3d} -> '.format(input) + str(found) + (f' ; ERROR: expected {out}' if found != out else ''))
print('TEST:{:3d} -> '.format(input) + str(found) + (f' ; ERROR: expected {out}' if found != out else ''))


</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
<lang perl6>my $b = 18;
<syntaxhighlight lang="raku" line>my $b = 18;
my @offset = 16, 10, 10, (2×$b)+1, (-2×$b)-15, (2×$b)+1, (-2×$b)-15;
my @offset = 16, 10, 10, (2×$b)+1, (-2×$b)-15, (2×$b)+1, (-2×$b)-15;
my @span = flat ^8 Zxx <1 3 8 44 15 17 15 15>;
my @span = flat ^8 Zxx <1 3 8 44 15 17 15 15>;
Line 1,228: Line 1,228:
for <1 2 29 42 57 58 72 89 90 103> -> $n {
for <1 2 29 42 57 58 72 89 90 103> -> $n {
printf "%3d: %2d, %2d\n", $n, map {$_+1}, ($n-1 + [+] @offset.head(@span[$n-1])).polymod($b).reverse;
printf "%3d: %2d, %2d\n", $n, map {$_+1}, ($n-1 + [+] @offset.head(@span[$n-1])).polymod($b).reverse;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 1: 1, 1
<pre> 1: 1, 1
Line 1,244: Line 1,244:
{{libheader|Wren-fmt}}
{{libheader|Wren-fmt}}
There is a discrepancy between how the periodic table is arranged in the Wikipedia article and how it is arranged in the task description. I've used the latter in the following script.
There is a discrepancy between how the periodic table is arranged in the Wikipedia article and how it is arranged in the task description. I've used the latter in the following script.
<lang ecmascript>import "./fmt" for Fmt
<syntaxhighlight lang="ecmascript">import "./fmt" for Fmt


var limits = [3..10, 11..18, 19..36, 37..54, 55..86, 87..118]
var limits = [3..10, 11..18, 19..36, 37..54, 55..86, 87..118]
Line 1,273: Line 1,273:
var rc = periodicTable.call(n)
var rc = periodicTable.call(n)
Fmt.print("Atomic number $3d -> $d, $-2d", n, rc[0], rc[1])
Fmt.print("Atomic number $3d -> $d, $-2d", n, rc[0], rc[1])
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,293: Line 1,293:


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>proc ShowPosn(N); \Show row and column for element
<syntaxhighlight lang="xpl0">proc ShowPosn(N); \Show row and column for element
int N, M, A, B, I, R, C;
int N, M, A, B, I, R, C;
[A:= [ 1, 2, 5, 13, 57, 72, 89, 104]; \magic numbers
[A:= [ 1, 2, 5, 13, 57, 72, 89, 104]; \magic numbers
Line 1,310: Line 1,310:
[Element:= [1, 2, 29, 42, 57, 58, 72, 89, 90, 103];
[Element:= [1, 2, 29, 42, 57, 58, 72, 89, 90, 103];
for I:= 0 to 10-1 do ShowPosn(Element(I));
for I:= 0 to 10-1 do ShowPosn(Element(I));
]</lang>
]</syntaxhighlight>


{{out}}
{{out}}

Revision as of 01:24, 28 August 2022

Task
Periodic table
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Display the row and column in the periodic table of the given atomic number.

The periodic table

Let us consider the following periodic table representation.

     __________________________________________________________________________ 
    |   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18 |
    |                                                                          |
    |1  H                                                                   He |
    |                                                                          |
    |2  Li  Be                                          B   C   N   O   F   Ne |
    |                                                                          |
    |3  Na  Mg                                          Al  Si  P   S   Cl  Ar |
    |                                                                          |
    |4  K   Ca  Sc  Ti  V   Cr  Mn  Fe  Co  Ni  Cu  Zn  Ga  Ge  As  Se  Br  Kr |
    |                                                                          |
    |5  Rb  Sr  Y   Zr  Nb  Mo  Tc  Ru  Rh  Pd  Ag  Cd  In  Sn  Sb  Te  I   Xe |
    |                                                                          |
    |6  Cs  Ba  *   Hf  Ta  W   Re  Os  Ir  Pt  Au  Hg  Tl  Pb  Bi  Po  At  Rn |
    |                                                                          |
    |7  Fr  Ra  °   Rf  Db  Sg  Bh  Hs  Mt  Ds  Rg  Cn  Nh  Fl  Mc  Lv  Ts  Og |
    |__________________________________________________________________________|
    |                                                                          |
    |                                                                          |
    |8  Lantanoidi* La  Ce  Pr  Nd  Pm  Sm  Eu  Gd  Tb  Dy  Ho  Er  Tm  Yb  Lu |
    |                                                                          |
    |9   Aktinoidi° Ak  Th  Pa  U   Np  Pu  Am  Cm  Bk  Cf  Es  Fm  Md  No  Lr |
    |__________________________________________________________________________|
Example test cases;
  •   1 -> 1 1
  •   2 -> 1 18
  •   29 -> 4 11
  •   42 -> 5 6
  •   57 -> 8 4
  •   58 -> 8 5
  •   72 -> 6 4
  •   89 -> 9 4
Details;

The representation of the periodic table may be represented in various way. The one presented in this challenge does have the following property : Lantanides and Aktinoides are all in a dedicated row, hence there is no element that is placed at 6, 3 nor 7, 3.

You may take a look at the atomic number repartitions here.

The atomic number is at least 1, at most 118.


See also



6502 Assembly

A lookup table is the simplest solution, for the following reasons:

  • The input value is guaranteed to be between 0 and 255
  • The data doesn't fit a pattern that the CPU can easily take advantage of.

Since the 6502 can't index an array larger than 256 bytes, we'll store all the "low bytes" in one table and all the "high bytes" in another. Both tables share the same index, so this lets us store up to 255 possible elements while taking the same amount of memory as a single table of 16-bit values. Right now, we can do this either way, but since we're close to 128 elements, may as well future-proof the code, right?

Lookup:      ;INPUT: X = atomic number of the element of interest.
LDA PeriodicTable_Column,x
STA $20                    ;store column number in memory (I chose $20 arbitrarily, you can store it anywhere)
LDA PeriodicTable_Row,x
STA $21                    ;store row number in memory
RTS

PeriodicTable_Column:
db $ff,$01,$18,$01,$02,$13,$14,$15,$16,$17,$18,...         ;I don't need to write them all out, the concept is self-explanatory enough.
PeriodicTable_Row:
db $ff,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,...

68000 Assembly

A lookup table is the simplest solution, as the data of interest doesn't have a pattern that a computer can take advantage of easily. It's quicker than using a formula, but takes up more memory as a result.

The table consists of 118 16-bit values. The high byte is the row number, the low byte is the column number. Both are stored as binary-coded decimal (i.e. hex values that look like base 10 numbers.)

Lookup:
;input: D0.W = the atomic number of interest.
LEA PeriodicTable,A0
ADD.W D0,D0        ;we're indexing a table of words, so double the index.
MOVE.W (A0,D0),D0  ;D0.W contains row number in the high byte and column number in the low byte.
RTS

PeriodicTable:
DC.W $FFFF ;padding since arrays start at zero in assembly.
DC.W $0101 ;HYDROGEN
DC.W $0118 ;HELIUM
DC.W $0201 ;LITHIUM
DC.W $0202 ;BERYLLIUM
DC.W $0213 ;BORON
DC.W $0214 ;CARBON
DC.W $0215 ;NITROGEN
DC.W $0216 ;OXYGEN
DC.W $0217 ;FLUORINE
DC.W $0218 ;NEON
;etc.

ALGOL 68

BEGIN # display the period and group number of an element, #
      # given its atomic number                            #
    INT max atomic number = 118; # highest known element   #
    # the positions are stored as:                         #
    #     ( group number * group multiplier ) + period     #
    INT group multiplier  = 100;
    [ 1 : max atomic number ]INT position;
    # construct the positions of the elements in the table #
    BEGIN
        STRING periodic table = "-                ="
                              + "--          -----="
                              + "--          -----="
                              + "-----------------="
                              + "-----------------="
                              + "--8--------------="
                              + "--9--------------="
                              ;
        INT period  := 1;
        INT group   := 1;
        INT element := 1;
        FOR t FROM LWB periodic table TO UPB periodic table DO
            CHAR p = periodic table[ t ];
            IF p = "8" OR p = "9" THEN
                # lantanoids or actinoids                   #
                INT series period = IF p = "8" THEN 8 ELSE 9 FI;
                INT series group := 4;
                FOR e TO 15 DO
                    position[ element ] := ( group multiplier * series group ) + series period;
                    element            +:= 1;
                    series group       +:= 1
                OD
            ELIF p /= " " THEN
                # there is a single element here            #
                position[ element ] := ( group multiplier * group ) + period;
                element            +:= 1;
                IF p = "=" THEN
                    # final element of the period           #
                    period +:= 1;
                    group   := 0
                FI
            FI;
            group +:= 1
        OD
    END;
    # display the period and group numbers of test elements #
    []INT test = ( 1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113 );
    FOR t FROM LWB test TO UPB test DO
        INT e = test[ t ];
        IF e < LWB position OR e > UPB position THEN
            print( ( "Invalid element: ", whole( e, 0 ), newline ) )
        ELSE
            INT period = position[ e ] MOD  group multiplier;
            INT group  = position[ e ] OVER group multiplier;
            print( ( "Element ", whole( e,      -3 )
                   , " -> ", whole( period,  0 ), ", ", whole( group,  -2 )
                   , newline
                   )
                 )
        FI
    OD
END
Output:
Element   1 -> 1,  1
Element   2 -> 1, 18
Element  29 -> 4, 11
Element  42 -> 5,  6
Element  57 -> 8,  4
Element  58 -> 8,  5
Element  59 -> 8,  6
Element  71 -> 8, 18
Element  72 -> 6,  4
Element  89 -> 9,  4
Element  90 -> 9,  5
Element 103 -> 9, 18
Element 113 -> 7, 13


BASIC

Applesoft BASIC

This program borrows from the Python solution but only PRINTs the results of the tests shown in the task. Each row and column from the tests are PLOTted in a COLORful table.

0 GR:HOME:COLOR=11:FORR=1TO7:FORC=1TO2:GOSUB7:NEXTC,R:COLOR=7:FORR=4TO7:FORC=3+(R>5)TO12:GOSUB7:NEXTC,R:COLOR=13:FORR=2TO7:FORC=13TO18:GOSUB7:NEXTC,R
1 forr=2to7:forc=13to18:GOSUB7:NEXTC,R:COLOR=14:R=8:FORC=4TO18:GOSUB7:NEXTC:COLOR=12:R=9:FORC=4TO18:GOSUB7:NEXTC:R=9:FORC=4TO18:GOSUB7:NEXTC:Z=2:R=7:C=3:GOSUB7:COLOR=14:R=6:C=3:GOSUB7:COLOR=15
2 S=14:W=18:FORI=1TO7:READN(I),I(I):NEXT:DATA2,0,10,0,18,0,36,0,54,0,86,57,118,89,1,1,1,2,1,18,29,4,11,42,5,6,57,8,4,58,8,5,72,6,4,89,9,4,59,8,6,71,8,18,90,9,5,103,9,18
3 FORT=1TO8:READA,Y,X:GOSUB4:PRINTRIGHT$("  "+STR$(A),3)"->"R" "LEFT$(STR$(C)+"  ",3);:GOSUB7:NEXTT:VTAB23:END
4 N=0:FORR=1TO7:P=N:N=N(R):IFA>NTHEN:NEXTR
5 E=N-P:K=A-P:IFI(R)AND(I(R)<=AANDA<=I(R)+S)THENR=R+2:C=K+1:RETURN
6 E=W-E:L=1+(N>2):C=K+E*(K>L):RETURN
7 K=C+(R=1ANDC=2)*16:VLINR*4+Z,R*4+2ATK*2+1:RETURN

ASIC

Translation of: Nascom BASIC
REM Periodic table
DIM A(7)
DIM B(7)
REM Arrays A, B.
DATA  1,  2,  5, 13, 57, 72, 89, 104
DATA -1, 15, 25, 35, 72, 21, 58,   7
REM Example elements (atomic numbers).
DATA 1, 2, 29, 42, 57, 58, 72, 89, 90, 103

GOSUB SetAB:
FOR J = 0 TO 9
  READ AtomicNum
  GOSUB ShowRowAndColumn:
NEXT J
END

SetAB:
FOR I = 0 TO 7
  READ A(I)
NEXT I
FOR I = 0 TO 7
  READ B(I)
NEXT I
RETURN

ShowRowAndColumn:
I = 7
WHILE A(I) > AtomicNum 
  I = I - 1
WEND
M = AtomicNum + B(I)
R = M / 18 
R = R + 1
C = M MOD 18 
C = C + 1
PRINT AtomicNum;
PRINT " ->";
PRINT R;
PRINT C
RETURN
Output:
     1 ->     1     1
     2 ->     1    18
    29 ->     4    11
    42 ->     5     6
    57 ->     8     4
    58 ->     8     5
    72 ->     6     4
    89 ->     9     4
    90 ->     9     5
   103 ->     9    18

BASIC256

Translation of: FreeBASIC
subroutine MostarPos(N)
    dim A = { 1,  2,  5, 13, 57, 72, 89, 104}
    dim B = {-1, 15, 25, 35, 72, 21, 58,   7}
    I = 7
    while A[I] > N
        I -= 1
    end while
    M = N + B[I]
    R = (M \ 18) +1
    C = (M % 18) +1
    print "Atomic number "; rjust(N,3); "-> "; R ; ", "; C
end subroutine

dim Element = {1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113}
for I = 0 to Element[?]-1
    call MostarPos(Element[I])
next I
Output:
Same as FreeBASIC entry.

FreeBASIC

Translation of: XPL0
Sub MostarPos(N As Integer)
    Dim As Integer M, I, R, C
    Dim As Integer A(0 To 7) = { 1,  2,  5, 13, 57, 72, 89, 104} 'magic numbers
    Dim As Integer B(0 To 7) = {-1, 15, 25, 35, 72, 21, 58,   7}
    I = 7
    While A(I) > N 
        I -= 1
    Wend
    M = N + B(I)
    R = (M \ 18) +1
    C = (M Mod 18) +1
    Print Using "Atomic number ### -> #_, ##"; N; R; C
End Sub

Dim As Integer Element(0 To 12) = {1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113}
For I As Integer = 0 To Ubound(Element)
    MostarPos(Element(I))
Next I
Output:
Atomic number   1 -> 1, 1 
Atomic number   2 -> 1, 18
Atomic number  29 -> 4, 11
Atomic number  42 -> 5, 6 
Atomic number  57 -> 8, 4 
Atomic number  58 -> 8, 5 
Atomic number  59 -> 8, 6 
Atomic number  71 -> 8, 18
Atomic number  72 -> 6, 4 
Atomic number  89 -> 9, 4 
Atomic number  90 -> 9, 5 
Atomic number 103 -> 9, 18
Atomic number 113 -> 7, 13

FutureBasic

Old fashioned way:

include "NSLog.incl"

local fn PeriodicTable( n as NSInteger ) as CFDictionaryRef
NSInteger  i, row = 0, start = 0, finish, limits(6,6)
CFDictionaryRef dict = NULL

if n < 1 or n > 118 then NSLog( @"Atomic number is out of range." ) : exit fn
if n == 1 then dict = @{@"row":@1, @"col":@1}  : exit fn
if n == 2 then dict = @{@"row":@1, @"col":@18} : exit fn
if n >= 57 and n <= 71  then dict = @{@"row":@8, @"col":fn NumberWithInteger( n - 53 )} : exit fn
if n >= 89 and n <= 103 then dict = @{@"row":@9, @"col":fn NumberWithInteger( n - 85 )} : exit fn

limits(0,0) = 3  : limits(0,1) = 10
limits(1,0) = 11 : limits(1,1) = 18
limits(2,0) = 19 : limits(2,1) = 36
limits(3,0) = 37 : limits(3,1) = 54
limits(4,0) = 55 : limits(4,1) = 86
limits(5,0) = 87 : limits(5,1) = 118

for i = 0 to 5
if ( n >= limits(i,0) and n <= limits(i,1) )
row    = i + 2
start  = limits(i,0)
finish = limits(i,1)
break
end if
next

if ( n < start + 2 or row == 4 or row == 5 )
dict = @{@"row":fn NumberWithInteger(row), @"col":fn NumberWithInteger( n - start + 1 )} : exit fn
end if
dict = @{@"row":fn NumberWithInteger(row), @"col":fn NumberWithInteger( n - finish + 18 )}
end fn = dict


local fn BuildTable
NSInteger  i, count
CFArrayRef numbers = @[@1, @2, @29, @42, @57, @58, @59, @71, @72, @89, @90, @103, @113]

count = fn ArrayCount( numbers )

for i = 0 to count -1
CFDictionaryRef coordinates = fn PeriodicTable( fn NumberIntegerValue( numbers[i] ) )
NSLog( @"Atomic number %3d -> (%d, %d)", fn NumberIntegerValue( numbers[i] ), fn NumberIntegerValue( coordinates[@"row"] ), fn NumberIntegerValue( coordinates[@"col"] ) )
next
end fn

fn BuildTable

HandleEvents
Output:
Atomic number   1 -> (1, 1)
Atomic number   2 -> (1, 18)
Atomic number  29 -> (4, 11)
Atomic number  42 -> (5, 6)
Atomic number  57 -> (8, 4)
Atomic number  58 -> (8, 5)
Atomic number  59 -> (8, 6)
Atomic number  71 -> (8, 18)
Atomic number  72 -> (6, 4)
Atomic number  89 -> (9, 4)
Atomic number  90 -> (9, 5)
Atomic number 103 -> (9, 18)
Atomic number 113 -> (7, 13)

Modern way. (Too bad you can no longer upload images to Rosetta Code.)

_window = 1

void local fn BuildPeriodicTableArrays

CFArrayRef periodicArr = @[@"",¬
@"H",  @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"He",¬
@"Li", @"Be", @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"B",  @"C",  @"N",  @"O",  @"F",  @"Ne",¬
@"Na", @"Mg", @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"",   @"Al", @"Si", @"P",  @"S",  @"Cl", @"Ar",¬
@"K",  @"Ca", @"Sc", @"Ti", @"V",  @"Cr", @"Mn", @"Fe", @"Co", @"Ni", @"Cu", @"Zn", @"Ga", @"Ge", @"As", @"Se", @"Br", @"Kr",¬
@"Rb", @"Sr", @"Y",  @"Zr", @"Nb", @"Mo", @"Tc", @"Ru", @"Rh", @"Pd", @"Ag", @"Cd", @"In", @"Sn", @"Sb", @"Te", @"I",  @"Xe",¬
@"Cs", @"Ba", @"Lu", @"Hf", @"Ta", @"W",  @"Re", @"Os", @"Ir", @"Pt", @"Au", @"Hg", @"Tl", @"Pb", @"Bi", @"Po", @"At", @"Rn",¬
@"Fr", @"Ra", @"Lr", @"Rf", @"Db", @"Sg", @"Bh", @"Hs", @"Mt", @"Ds", @"Rg", @"Cn", @"Nh", @"Fl", @"Mc", @"Lv", @"Ts", @"Og",¬
@"",   @"",   @"La", @"Ce", @"Pr", @"Nd", @"Pm", @"Sm", @"Eu", @"Gd", @"Tb", @"Dy", @"Ho", @"Er", @"Tm", @"Yb", @"",   @"",¬
@"",   @"",   @"Ac", @"Th", @"Pa", @"U",  @"NP", @"Pu", @"Am", @"Cm", @"Bk", @"Cf", @"Es", @"Fm", @"Md", @"No", @"",   @""]
AppSetProperty( @"periodicTable", periodicArr )

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


void local fn BuildWindow
NSInteger   i, j, row
CGRect      r
CFArrayRef  periodicArr, numbersArr
CFStringRef tempStr

periodicArr = fn AppProperty( @"periodicTable"   )
numbersArr  = fn AppProperty( @"periodicNumbers" )

window _window, @"Periodic Table", ( 0, 0, 700, 400 )
WindowSetBackgroundColor( _window, fn ColorWhite )

j = 0 : row = 350
r = fn CGRectMake( 10, row, 36, 40 )
for i = 1 to 162
if fn StringIsEqual( periodicArr[i], @"" ) then tempStr = @"" else tempStr = fn StringWithFormat( @"%@\n%@", numbersArr[i], periodicArr[i] )
textfield i,, tempStr, r, _window
TextFieldSetBackgroundColor( i, fn ColorBlue )
TextFieldSetTextColor( i, fn ColorWhite )
ControlSetFontWithName( i, @"Menlo", 12.0 )
ControlSetAlignment(i, NSTextAlignmentCenter )
r = fn CGRectOffset( r, 38, 0 )
j++
if ( j == 18 )
row =  row - 42
r = fn CGRectMake( 10, row, 36, 40 )
j = 0
end if
next

for i = 1 to 162
if fn StringIsEqual( fn ControlStringValue( i ), @"" ) then ViewRemoveFromSuperview( i )
next
end fn

fn BuildPeriodicTableArrays
fn BuildWindow

HandleEvents
Output:
[Sorry, screenshot can't be uploaded.]

Gambas

Sub MostarPos(N As Integer)       'Mostrar fila y columna para el elemento
    Dim M, I, R, C As Integer
    Dim A As Integer[] = [1, 2, 5, 13, 57, 72, 89, 104] 'magic numbers
    Dim B As Integer[] = [-1, 15, 25, 35, 72, 21, 58, 7] 
    I = 7 
    While A[I] > N
        Dec I
    Wend
    M = N + B[I]
    R = (M \ 18) + 1 
    C = (M Mod 18) + 1 
    Print "Atomic number "; Format(N, "###"); " -> "; R; ", "; C 
End 

Public Sub Main()

Dim Element As Integer[] = [1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113]
For e As Integer = 0 To 12
    MostarPos(Element[e])
Next

End
Output:
Same as FreeBASIC entry.

Minimal BASIC

Translation of: Nascom BASIC
Works with: Commodore BASIC version 3.5
10 REM Periodic table
20 GOSUB 200
30 FOR J = 0 TO 9
40 READ N
50 GOSUB 400
60 NEXT J
70 END
190 REM Set arrays A, B.
200 DIM A(7), B(7)
210 FOR I = 0 TO 7
220 READ A(I)
230 NEXT I
240 FOR I = 0 TO 7
250 READ B(I)
260 NEXT I
270 RETURN
390 REM Show row and column for element
400 LET I = 7
410 IF A(I) <= N THEN 440
420 LET I = I-1
430 GOTO 410
440 LET M = N+B(I)
450 LET R = INT(M/18)+1
460 LET C = M-INT(M/18)*18+1
470 PRINT N; "->"; R; C
480 RETURN
990 REM Data.
1000 REM Arrays A, B.
1010 DATA  1,  2,  5, 13, 57, 72, 89, 104
1020 DATA -1, 15, 25, 35, 72, 21, 58,   7
1030 REM Example elements (atomic numbers).
1040 DATA 1, 2, 29, 42, 57, 58, 72, 89, 90, 103

Nascom BASIC

Works with: Nascom ROM BASIC version 4.7
10 REM Periodic table
20 GOSUB 200
30 FOR J=0 TO 9:READ ANUM:GOSUB 400:NEXT J
40 END
190 REM ** Set arrays A, B.
200 DIM A(7),B(7)
210 FOR I=0 TO 7:READ A(I):NEXT I
220 FOR I=0 TO 7:READ B(I):NEXT I
230 RETURN
390 REM ** Show row and column for element
400 I=7
410 IF A(I)>ANUM THEN I=I-1:GOTO 410
420 M=ANUM+B(I)
430 R=INT(M/18)+1
440 C=M-INT(M/18)*18+1
450 PRINT ANUM;"->";R;C
460 RETURN
990 REM  ** Data.
1000 REM ** Arrays A, B.
1010 DATA 1,2,5,13,57,72,89,104
1020 DATA -1,15,25,35,72,21,58,7
1030 REM ** Example elements (atomic numbers).
1040 DATA 1,2,29,42,57,58,72,89,90,103
Output:
 1 -> 1  1
 2 -> 1  18
 29 -> 4  11
 42 -> 5  6
 57 -> 8  4
 58 -> 8  5
 72 -> 6  4
 89 -> 9  4
 90 -> 9  5
 103 -> 9  18

QBasic

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
Translation of: FreeBASIC
SUB MostarPos (N)
    DIM a(7)
    RESTORE a:
    FOR x = 0 TO 7: READ a(x): NEXT x
    DIM b(7)
    RESTORE b:
    FOR x = 0 TO 7: READ b(x): NEXT x

    I = 7
    WHILE a(I) > N
    I = I - 1
    WEND
    M = N + b(I)
    R = (M \ 18) + 1
    C = (M MOD 18) + 1
    PRINT USING "Atomic number ### -> #_, ##"; N; R; C
END SUB

DIM Element(0 TO 12)
RESTORE elements
elements:
DATA 1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113
FOR x = 0 TO 12: READ Element(x): NEXT x

FOR I = 0 TO UBOUND(Element)
    MostarPos (Element(I))
NEXT I

a:
DATA  1,  2,  5, 13, 57, 72, 89, 104
b:
DATA -1, 15, 25, 35, 72, 21, 58,   7
Output:
Same as FreeBASIC entry.

Run BASIC

Works with: Just BASIC
Works with: Liberty BASIC
Translation of: FreeBASIC
dim Element(12)
Element(0) =   1
Element(1) =   2
Element(2) =  29
Element(3) =  42
Element(4) =  57
Element(5) =  58
Element(6) =  59
Element(7) =  71
Element(8) =  72
Element(9) =  89
Element(10) =   90
Element(11) =  103
Element(12) =  113
for e = 0 to 12
    call MostarPos Element(e)
next e

sub MostarPos N
    dim A(7)
    A(0) =   1
    A(1) =   2
    A(2) =   5
    A(3) =  13
    A(4) =  57
    A(5) =  72
    A(6) =  89
    A(7) = 104
    dim B(7)
    B(0) = -1
    B(1) = 15
    B(2) = 25
    B(3) = 35
    B(4) = 72
    B(5) = 21
    B(6) = 58
    B(7) =  7
    
    I = 7
    while A(I) > N
        I = I - 1
    wend
    M = N + B(I)
    R = int(M / 18) +1
    C = (M mod 18) +1
    print "Atomic number "; using("###", N); " -> "; R; ", "; C
end sub
Output:
Same as FreeBASIC entry.

True BASIC

Translation of: FreeBASIC
SUB MostarPos (n)
    DIM a(0 TO 7)
    LET a(0) = 1
    LET a(1) = 2
    LET a(2) = 5
    LET a(3) = 13
    LET a(4) = 57
    LET a(5) = 72
    LET a(6) = 89
    LET a(7) = 104
    DIM b(0 TO 7)
    LET b(0) = -1
    LET b(1) = 15
    LET b(2) = 25
    LET b(3) = 35
    LET b(4) = 72
    LET b(5) = 21
    LET b(6) = 58
    LET b(7) = 7
    LET i = 7
    DO WHILE a(i) > n
       LET i = i - 1
    LOOP
    LET m = n + b(i)
    LET r = IP(m / 18) + 1
    LET c = REMAINDER(m, 18) + 1
    PRINT USING "Atomic number ###": n;
    PRINT " ->"; r; c
END SUB

DIM element(0 TO 12)
LET element(0) = 1
LET element(1) = 2
LET element(2) = 29
LET element(3) = 42
LET element(4) = 57
LET element(5) = 58
LET element(6) = 59
LET element(7) = 71
LET element(8) = 72
LET element(9) = 89
LET element(10) = 90
LET element(11) = 103
LET element(12) = 113
FOR e = 0 TO UBOUND(element)
    CALL MostarPos (element(e))
NEXT e
END
Output:
Similar to FreeBASIC entry.

XBasic

Works with: Windows XBasic
Translation of: FreeBASIC
PROGRAM  "Periodic table"

DECLARE FUNCTION  Entry ()
DECLARE FUNCTION  MostarPos (N)

FUNCTION  Entry ()
  DIM Element[12]
  Element[0] =   1
  Element[1] =   2
  Element[2] =  29
  Element[3] =  42
  Element[4] =  57
  Element[5] =  58
  Element[6] =  59
  Element[7] =  71
  Element[8] =  72
  Element[9] =  89
  Element[10] =   90
  Element[11] =  103
  Element[12] =  113

  FOR e = 0 TO 12 'UBOUND (Element())
    MostarPos (Element[e])
  NEXT

END FUNCTION

FUNCTION  MostarPos (N)
  DIM A[7]
  A[0] =   1
  A[1] =   2
  A[2] =   5
  A[3] =  13
  A[4] =  57
  A[5] =  72
  A[6] =  89
  A[7] = 104
  DIM B[7]
  B[0] = -1
  B[1] = 15
  B[2] = 25
  B[3] = 35
  B[4] = 72
  B[5] = 21
  B[6] = 58
  B[7] =  7
  I = 7
  DO WHILE A[I] > N
    DEC I
  LOOP
  M = N + B[I]
  R = (M \ 18) + 1
  C = (M MOD 18) + 1
  PRINT "Atomic number "; FORMAT$ ("###", N); " ->"; R; ","; C

END FUNCTION
END PROGRAM
Output:
Similar to FreeBASIC entry.

Yabasic

Translation of: FreeBASIC
// Rosetta Code problem: http://rosettacode.org/wiki/Periodic_table
// by Jjuanhdez, 06/2022

dim Element(12)
Element(0) =   1 : Element(1) =   2
Element(2) =  29 : Element(3) =  42
Element(4) =  57 : Element(5) =  58
Element(6) =  59 : Element(7) =  71
Element(8) =  72 : Element(9) =  89
Element(10) =  90
Element(11) =  103 : Element(12) =  113
for e = 0 to arraysize(Element(),1)
    MostarPos (Element(e))
next e
end

sub MostarPos (N)
    dim A(7)
    A(0) =   1 : A(1) =   2
    A(2) =   5 : A(3) =  13
    A(4) =  57 : A(5) =  72
    A(6) =  89 : A(7) = 104
    dim B(7)
    B(0) = -1 : B(1) = 15
    B(2) = 25 : B(3) = 35
    B(4) = 72 : B(5) = 21
    B(6) = 58 : B(7) =  7
    
    I = 7
    while A(I) > N
        I = I - 1
    wend
    M = N + B(I)
    R = int(M / 18) +1
    C = mod(M, 18) +1
    print "Atomic number ", N using("###"), " -> ", R, ", ", C
end sub
Output:
Same as FreeBASIC entry.

Go

Translation of: Wren
package main

import (
    "fmt"
    "log"
)

var limits = [][2]int{
    {3, 10}, {11, 18}, {19, 36}, {37, 54}, {55, 86}, {87, 118},
}

func periodicTable(n int) (int, int) {
    if n < 1 || n > 118 {
        log.Fatal("Atomic number is out of range.")
    }
    if n == 1 {
        return 1, 1
    }
    if n == 2 {
        return 1, 18
    }
    if n >= 57 && n <= 71 {
        return 8, n - 53
    }
    if n >= 89 && n <= 103 {
        return 9, n - 85
    }
    var row, start, end int
    for i := 0; i < len(limits); i++ {
        limit := limits[i]
        if n >= limit[0] && n <= limit[1] {
            row, start, end = i+2, limit[0], limit[1]
            break
        }
    }
    if n < start+2 || row == 4 || row == 5 {
        return row, n - start + 1
    }
    return row, n - end + 18
}

func main() {
    for _, n := range []int{1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113} {
        row, col := periodicTable(n)
        fmt.Printf("Atomic number %3d -> %d, %-2d\n", n, row, col)
    }
}
Output:
Atomic number   1 -> 1, 1 
Atomic number   2 -> 1, 18
Atomic number  29 -> 4, 11
Atomic number  42 -> 5, 6 
Atomic number  57 -> 8, 4 
Atomic number  58 -> 8, 5 
Atomic number  59 -> 8, 6 
Atomic number  71 -> 8, 18
Atomic number  72 -> 6, 4 
Atomic number  89 -> 9, 4 
Atomic number  90 -> 9, 5 
Atomic number 103 -> 9, 18
Atomic number 113 -> 7, 13

J

Basically, here, we want a lookup table. For example:

PT=: (' ',.~[;._2) {{)n
   1   2   3   4  5  6  7  8  9  10 11 12 13 14 15 16 17 18
 1 H                                                     He
 2 Li  Be                                 B  C  N  O  F  Ne
 3 Na  Mg                                 Al Si P  S  Cl Ar
 4 K   Ca  Sc  Ti V  Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
 5 Rb  Sr  Y   Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I  Xe
 6 Cs  Ba  *   Hf Ta W  Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
 7 Fr  Ra  -   Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og
 8 Lantanoidi* La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu
 9  Aktinoidi- Ak Th Pa U  Np Pu Am Cm Bk Cf Es Fm Md No Lr
}}

ptrc=: {{
  tokens=. (#~ (3>#)@> * */@(tolower~:toupper)@>) ~.,;:,PT
  ndx=. (>' ',L:0' ',L:0~tokens) {.@I.@E."1 ,PT
  Lantanoidi=. ndx{+/\'*'=,PT
  Aktinoidi=. ndx{+/\'-'=,PT
  j=. 13|3*Lantanoidi+3*Aktinoidi
  k=. {:$PT
  0,}."1/:~j,.(<.ndx%k),.1+(/:~@~. i. ])k|ndx
}}

rowcol=: ptrc''

In other words, start with a hand crafted representation of the periodic table. Elements here are tokens with 1 or 2 letters. Locate the position of each token in the table. Get an initial row and column number from the character positions in the table. Translate character column to periodic table column by enumerating the unique (sorted) list of column numbers and using the index in that list. Character row was already periodic table row. Most elements here were already in atomic number order, and we can fix the exceptions by temporarily prefixing each row,col value and sorting. (Here, we use 0 for the first 56 elements, 3 for the next 17 elements (after Lantanoidi, before Aktinoidi), 12 for the next 15 (after Aktinoidi), 2 for the next 15 (the Lantanoidi) and 11 for the final 15 elements (the Aktinoidi).)

Thus:

   1 2 29 42 57 58 72 89 { rowcol
1  1
1 18
4 11
5  6
8  4
8  5
6  4
9  4


Julia

Translation of: Wren
const limits = [3:10, 11:18, 19:36, 37:54, 55:86, 87:118]

function periodic_table(n)
    (n < 1 || n > 118) && error("Atomic number is out of range.")
    n == 1 && return [1, 1]
    n == 2 && return [1, 18]
    57 <= n <= 71 && return [8, n - 53]
    89 <= n <= 103 && return [9, n - 85]
    row, limitstart, limitstop = 0, 0, 0
    for i in eachindex(limits)
        if limits[i].start <= n <= limits[i].stop
            row, limitstart, limitstop = i + 1, limits[i].start, limits[i].stop
            break
        end
    end
    return (n < limitstart + 2 || row == 4 || row == 5) ?
        [row, n - limitstart + 1] : [row, n - limitstop + 18]
end

for n in [1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113]
    rc = periodic_table(n)
    println("Atomic number ", lpad(n, 3), " -> ($(rc[1]), $(rc[2]))")
end
Output:
Atomic number   1 -> (1, 1)
Atomic number   2 -> (1, 18)
Atomic number  29 -> (4, 11)
Atomic number  42 -> (5, 6)
Atomic number  57 -> (8, 4)
Atomic number  58 -> (8, 5)
Atomic number  59 -> (8, 6)
Atomic number  71 -> (8, 18)
Atomic number  72 -> (6, 4)
Atomic number  89 -> (9, 4)
Atomic number  90 -> (9, 5)
Atomic number 103 -> (9, 18)
Atomic number 113 -> (7, 13)

Mathematica/Wolfram Language

Mathematica and the Wolfram language include the period and group in the function ElementData but has slightly different definitions for the lantanides and aktinoides.

ClearAll[FindPeriodGroup]
FindPeriodGroup[n_Integer] := Which[57 <= n <= 70,
  {8, n - 53}
  ,
  89 <= n <= 102,
  {9, n - 85}
  ,
  1 <= n <= 118,
  {ElementData[n, "Period"], ElementData[n, "Group"]}
  ,
  True,
  Missing["Element does not exist"]
]
Row[{"Element ", #, " -> ", FindPeriodGroup[#]}] & /@ {1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113} // Column
Graphics[Text[#, {1, -1} Reverse@FindPeriodGroup[#]] & /@ Range[118]]
Output:
Element 1 -> {1,1}
Element 2 -> {1,18}
Element 29 -> {4,11}
Element 42 -> {5,6}
Element 57 -> {8,4}
Element 58 -> {8,5}
Element 59 -> {8,6}
Element 71 -> {6,3}
Element 72 -> {6,4}
Element 89 -> {9,4}
Element 90 -> {9,5}
Element 103 -> {7,3}
Element 113 -> {7,13}

[graphical representation of the periodic table positions]

Perl

Translation of: Raku
use strict;
use warnings; no warnings 'uninitialized';
use feature 'say';
use List::Util <sum head>;

sub divmod { int $_[0]/$_[1], $_[0]%$_[1] }

my $b = 18;
my(@offset,@span,$cnt);
push @span, ($cnt++) x $_ for <1 3 8 44 15 17 15 15>;
@offset = (16, 10, 10, (2*$b)+1, (-2*$b)-15, (2*$b)+1, (-2*$b)-15);

for my $n (<1 2 29 42 57 58 72 89 90 103 118>) {
    printf "%3d: %2d, %2d\n", $n, map { $_+1 } divmod $n-1 + sum(head $span[$n-1], @offset), $b;
}
Output:
  1:  1,  1
  2:  1, 18
 29:  4, 11
 42:  5,  6
 57:  8,  4
 58:  8,  5
 72:  6,  4
 89:  9,  4
 90:  9,  5
103:  9, 18

Phix

with javascript_semantics
constant match_wp = false

function prc(integer n)
    constant t = {0,2,10,18,36,54,86,118,119}
    integer row = abs(binary_search(n,t,true))-1,
            col = n-t[row]
    if col>1+(row>1) then
        col = 18-(t[row+1]-n)
        if match_wp then
            if col<=2 then return {row+2,col+14} end if
        else -- matches above ascii:
            if col<=2+(row>5) then return {row+2,col+15} end if
        end if
    end if
    return {row,col}
end function

sequence pt = repeat(repeat("   ",19),10)
pt[1][2..$] = apply(true,sprintf,{{"%3d"},tagset(18)})  -- column headings
for i=1 to 9 do pt[i+1][1] = sprintf("%3d",i) end for -- row numbers
for i=1 to 118 do
    integer {r,c} = prc(i)
    pt[r+1][c+1] = sprintf("%3d",i)
end for
if not match_wp then -- (ascii only:)
    pt[7][4] = " L*"
    pt[8][4] = " A*"
    pt[9][2..4] = {"Lanthanide:"}
    pt[10][2..4] = {"  Actinide:"}
end if
printf(1,"%s\n",{join(apply(true,join,{pt,{"|"}}),"\n")})
Output:

With match_wp set to true:

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

Or with match_wp false:

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

alternate

constant ptxt = """
 __________________________________________________________________________ 
|   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18 |
|                                                                          |
|1  H                                                                   He |
|                                                                          |
|2  Li  Be                                          B   C   N   O   F   Ne |
|                                                                          |
|3  Na  Mg                                          Al  Si  P   S   Cl  Ar |
|                                                                          |
|4  K   Ca  Sc  Ti  V   Cr  Mn  Fe  Co  Ni  Cu  Zn  Ga  Ge  As  Se  Br  Kr |
|                                                                          |
|5  Rb  Sr  Y   Zr  Nb  Mo  Tc  Ru  Rh  Pd  Ag  Cd  In  Sn  Sb  Te  I   Xe |
|                                                                          |
|6  Cs  Ba  *   Hf  Ta  W   Re  Os  Ir  Pt  Au  Hg  Tl  Pb  Bi  Po  At  Rn |
|                                                                          |
|7  Fr  Ra  +   Rf  Db  Sg  Bh  Hs  Mt  Ds  Rg  Cn  Nh  Fl  Mc  Lv  Ts  Og |
|__________________________________________________________________________|
|                                                                          |
|                                                                          |
|8  Lantanoidi* La  Ce  Pr  Nd  Pm  Sm  Eu  Gd  Tb  Dy  Ho  Er  Tm  Yb  Lu |
|                                                                          |
|9   Aktinoidi+ Ak  Th  Pa  U   Np  Pu  Am  Cm  Bk  Cf  Es  Fm  Md  No  Lr |
|__________________________________________________________________________|
"""

function tablify(string ptxt)
    sequence lines = split(ptxt,"\n"),
             res = {}
    for l in lines do
        integer ln = l[2]-'0', c = 0
        if ln>=1 and ln<=9 then
            res = append(res,{})
            for j=5 to length(l) by 4 do
                c += 1
                if l[j]>='A' and l[j+2]<=' ' then
                    res[$] = append(res[$],{trim(l[j..j+1]),ln,c})
                end if
            end for
        end if
    end for
    res[7][3..2] = res[9]
    res[6][3..2] = res[8]
    res = join(res[1..7],{},{})
    return res
end function

constant pt = apply(true,sprintf,{{"(%s) is at %d, %d"},tablify(ptxt)})

for e in {1,2,29,42,57,58,59,71,72,89,90,103,113} do
    printf(1,"Element %d %s\n",{e,pt[e]})
end for
Output:
Element 1 (H) is at 1, 1
Element 2 (He) is at 1, 18
Element 29 (Cu) is at 4, 11
Element 42 (Mo) is at 5, 6
Element 57 (La) is at 8, 4
Element 58 (Ce) is at 8, 5
Element 59 (Pr) is at 8, 6
Element 71 (Lu) is at 8, 18
Element 72 (Hf) is at 6, 4
Element 89 (Ak) is at 9, 4
Element 90 (Th) is at 9, 5
Element 103 (Lr) is at 9, 18
Element 113 (Nh) is at 7, 13

Python

A solution trying hard not to encode too much data about the table.

def perta(atomic) -> (int, int):

    NOBLES = 2, 10, 18, 36, 54, 86, 118
    INTERTWINED = 0, 0, 0, 0, 0, 57, 89
    INTERTWINING_SIZE = 14
    LINE_WIDTH = 18

    prev_noble = 0
    for row, noble in enumerate(NOBLES):
        if atomic <= noble:  # we are at the good row. We now need to determine the column
            nb_elem = noble - prev_noble  # number of elements on that row
            rank =  atomic - prev_noble  # rank of the input element among elements
            if INTERTWINED[row] and INTERTWINED[row] <= atomic <= INTERTWINED[row] + INTERTWINING_SIZE:  # lantanides or actinides
                row += 2
                col = rank + 1
            else:  # not a lantanide nor actinide
                # handle empty spaces between 1-2, 4-5 and 12-13.
                nb_empty = LINE_WIDTH - nb_elem  # spaces count as columns
                inside_left_element_rank = 2 if noble > 2 else 1
                col = rank + (nb_empty if rank > inside_left_element_rank else 0)
            break
        prev_noble = noble
    return row+1, col



# small test suite

TESTS = {
    1: (1, 1),
    2: (1, 18),
    29: (4,11),
    42: (5, 6),
    58: (8, 5),
    59: (8, 6),
    57: (8, 4),
    71: (8, 18),
    72: (6, 4),
    89: (9, 4),
    90: (9, 5),
    103: (9, 18),
}

for input, out in TESTS.items():
    found = perta(input)
    print('TEST:{:3d} -> '.format(input) + str(found) + (f' ; ERROR: expected {out}' if found != out else ''))

Raku

my $b = 18;
my @offset = 16, 10, 10, (2×$b)+1, (-2×$b)-15, (2×$b)+1, (-2×$b)-15;
my @span   = flat ^8 Zxx <1 3 8 44 15 17 15 15>;

for <1 2 29 42 57 58 72 89 90 103> -> $n {
    printf "%3d: %2d, %2d\n", $n, map {$_+1}, ($n-1 + [+] @offset.head(@span[$n-1])).polymod($b).reverse;
}
Output:
  1:  1,  1
  2:  1, 18
 29:  4, 11
 42:  5,  6
 57:  8,  4
 58:  8,  5
 72:  6,  4
 89:  9,  4
 90:  9,  5
103:  9, 18

Wren

Library: Wren-fmt

There is a discrepancy between how the periodic table is arranged in the Wikipedia article and how it is arranged in the task description. I've used the latter in the following script.

import "./fmt" for Fmt

var limits = [3..10, 11..18, 19..36, 37..54, 55..86, 87..118]

var periodicTable = Fn.new { |n|
    if (n < 1 || n > 118) Fiber.abort("Atomic number is out of range.")
    if (n == 1) return [1, 1]
    if (n == 2) return [1, 18]
    if (n >= 57 && n <= 71)  return [8, n - 53]
    if (n >= 89 && n <= 103) return [9, n - 85]    
    var row
    var start
    var end
    for (i in 0...limits.count) {
        var limit = limits[i]
        if (n >= limit.from && n <= limit.to) {
            row = i + 2
            start = limit.from
            end = limit.to
            break
        }
    }
    if (n < start + 2 || row == 4 || row == 5) return [row, n - start + 1]
    return [row, n - end + 18]
}

for (n in [1, 2, 29, 42, 57, 58, 59, 71, 72, 89, 90, 103, 113]) {
    var rc = periodicTable.call(n)
    Fmt.print("Atomic number $3d -> $d, $-2d", n, rc[0], rc[1])
}
Output:
Atomic number   1 -> 1, 1 
Atomic number   2 -> 1, 18
Atomic number  29 -> 4, 11
Atomic number  42 -> 5, 6 
Atomic number  57 -> 8, 4 
Atomic number  58 -> 8, 5 
Atomic number  59 -> 8, 6 
Atomic number  71 -> 8, 18
Atomic number  72 -> 6, 4 
Atomic number  89 -> 9, 4 
Atomic number  90 -> 9, 5 
Atomic number 103 -> 9, 18
Atomic number 113 -> 7, 13

XPL0

proc ShowPosn(N);       \Show row and column for element
int  N, M, A, B, I, R, C;
[A:= [ 1,  2,  5, 13, 57, 72, 89, 104]; \magic numbers
 B:= [-1, 15, 25, 35, 72, 21, 58,   7];
I:= 7;
while A(I) > N do I:= I-1;
M:= N + B(I);
R:= M/18 +1;
C:= rem(0) +1;
IntOut(0, N);  Text(0, " -> ");
IntOut(0, R);  Text(0, ", ");
IntOut(0, C);  CrLf(0);
];

int Element, I;
[Element:= [1, 2, 29, 42, 57, 58, 72, 89, 90, 103];
for I:= 0 to 10-1 do ShowPosn(Element(I));
]
Output:
1 -> 1, 1
2 -> 1, 18
29 -> 4, 11
42 -> 5, 6
57 -> 8, 4
58 -> 8, 5
72 -> 6, 4
89 -> 9, 4
90 -> 9, 5
103 -> 9, 18