CJam, 87 83 82 80 байт
$ base64 -d > electrons.cjam <<< Isy1oxr3vQcbJs5zFlWHCCfSZVRmrME4/96V2Ip3bU4NE9+7t8aMrmsyTbnxfLnxvGgtilwi5lwi4dfJgLqlXWQkRwuqeMkTpQplQQjz7uMuWJIZXxqA/NkwO1GZxxtRugyKPH3wYB7VHOcvMxbIH+bfJHXRUeavOLT3sWN3FI3TabyZnqWYVlPncfdIdnokp9xcIvymVQUw4gPWqO8an+QDxqBeYL4BK8oSg9RkaT2nLsxZXgy7abAZHeHyU+Qbbm3MRdMfzDy3G1/KyNCU/gXqrtyYnppHpvo6DsNF7zFhoHyAVZpdeq+OUehcecQiMjU2YjM4YiIkEiMgXCISIQgAAiI6aTIve18wPV8pMzM/YUBcL1wqfS8wYS9saSg9YA==
$ cksum electrons.cjam
3109698089 289 electrons.cjam
$ LANG=en_US cjam electrons.cjam <<< 42; echo
[2 8 18 13 1]
$ for i in {1..118}; do LANG=en_US cjam electrons.cjam <<< $i; echo; done | md5sum
d09cb34c282ee52c2466a6b80aa30d22 -
Приведенный выше код содержит непечатаемые символы.
Попробуйте онлайн в CJam-переводчик. Если ссылка у вас не работает, скопируйте отсюда вставить.
Фон
Чтобы получить электронную конфигурацию N-й атом, мы начинаем с атома без электронов и применяем Н преобразования в нем.
Чтобы уменьшить количество байтов реализации, мы представляем электронную конфигурацию атома как целое число. Каждая цифра этого целого числа по основанию 33 соответствует количеству электронов в определенных оболочках; младшая цифра представляет внешнюю оболочку.
Например, электронная конфигурация молибдена (42) имеет вид [2 8 18 13 1]. Это соответствует целому числу 2 × 334 + 8 × 333 + 18 × 332 + 13 × 33 + 1 = 26,79,370.
Палладий (48) представляет собой частный случай, который мы рассматриваем как [2 8 18 18 0] вместо [2 8 18 18].
Это удобное представление сводит вышеупомянутые преобразования к простой арифметике:
-
2 8 18 32
(add an electron to the outer shell)
-
0000000: 22 cc b5 a3 1a f7 bd 07 1b 26 ce 73 16 55 87 08 "........&.s.U..
0000010: 27 d2 65 54 66 ac c1 38 ff de 95 d8 8a 77 6d 4e '.eTf..8.....wmN
0000020: 0d 13 df bb b7 c6 8c ae 6b 32 4d b9 f1 7c b9 f1 ........k2M..|..
0000030: bc 68 2d 8a 5c 22 e6 5c 22 e1 d7 c9 80 ba a5 5d .h-.\".\"......]
0000040: 64 24 47 0b aa 78 c9 13 a5 0a 65 41 08 f3 ee e3 d$G..x....eA....
0000050: 2e 58 92 19 5f 1a 80 fc d9 30 3b 51 99 c7 1b 51 .X.._....0;Q...Q
0000060: ba 0c 8a 3c 7d f0 60 1e d5 1c e7 2f 33 16 c8 1f ...<}.`..../3...
0000070: e6 df 24 75 d1 51 e6 af 38 b4 f7 b1 63 77 14 8d ..$u.Q..8...cw..
0000080: d3 69 bc 99 9e a5 98 56 53 e7 71 f7 48 76 7a 24 .i.....VS.q.Hvz$
0000090: a7 dc 5c 22 fc a6 55 05 30 e2 03 d6 a8 ef 1a 9f ..\"..U.0.......
00000a0: e4 03 c6 a0 5e 60 be 01 2b ca 12 83 d4 64 69 3d ....^`..+....di=
00000b0: a7 2e cc 59 5e 0c bb 69 b0 19 1d e1 f2 53 e4 1b ...Y^..i.....S..
00000c0: 6e 6d cc 45 d3 1f cc 3c b7 1b 5f ca c8 d0 94 fe nm.E...<.._.....
00000d0: 05 ea ae dc 98 9e 9a 47 a6 fa 3a 0e c3 45 ef 31 .......G..:..E.1
00000e0: 61 a0 7c 80 55 9a 5d 7a af 8e 51 e8 5c 79 c4 22 a.|.U.]z..Q.\y."
00000f0: 32 35 36 62 33 38 62 22 24 12 23 20 5c 22 12 21 256b38b"$.# \".!
0000100: 08 00 02 22 3a 69 32 2f 7b 5f 30 3d 5f 29 33 33 ...":i2/{_0=_)33
0000110: 3f 61 40 5c 2f 5c 2a 7d 2f 30 61 2f 6c 69 28 3d ?a@\/\*}/0a/li(=
0000120: 60 <
(add an electron to the second outer shell)
-
0000000: 4061 3d75 6e70 6163 6b27 432a 272c 2710 @a=unpack'C*','.
0000010: 4142 1352 3314 5334 1573 5435 1674 5536 AB.R3.S4.sT5.tU6
0000020: 273b 6966 2828 242d 3d3c 3e29 7e7e 5b75 ';if(($-=<>)~~[u
0000030: 6e70 6163 6b27 432a 272c 2718 1d29 2a2c npack'C*','..)*,
0000040: 2d2e 2f39 3a40 4e4f 595a 5b5c 5d60 6727 -./9:@NOYZ[\]`g'
0000050: 5d29 7b24 2e2b 3d28 242d 7e7e 5b34 362c ]){$.+=($-~~[46,
0000060: 3930 5d29 3b24 703d 322b 242d 2f33 333b 90]);$p=2+$-/33;
0000070: 242d 3e38 377c 242d 7e7e 5b35 372e 2e36 $->87|$-~~[57..6
0000080: 345d 2626 2824 2e2a 3d2d 3129 3b24 6f5b 4]&&($.*=-1);$o[
0000090: 2470 5d2b 3d24 2e2c 246f 5b24 702b 315d $p]+=$.,$o[$p+1]
00000a0: 2d3d 242e 7d24 253d 2824 253d 2461 5b24 -=$.}$%=($%=$a[$
00000b0: 715d 2f38 293e 242d 3f24 2d3a 2425 2c24 q]/8)>$-?$-:$%,$
00000c0: 6f5b 2461 5b24 712b 2b5d 2637 5d2b 3d24 o[$a[$q++]&7]+=$
00000d0: 2577 6869 6c65 2824 2d2d 3d24 2529 3b24 %while($--=$%);$
00000e0: 2c3d 2422 3b73 6179 406f ,=$";say@o
(add two electrons to the second outer shell; remove one from the first)
-
$_=<>;
# For each byte, the first 5 bits are the number of spaces to fill at a time, the next 3 bits represent the shell number, minus 1.
# Values: 10 41 42 13 52 33 14 53 34 15 73 54 35 16 74 55 36
# The 1st shell takes 2 electrons
# Then the 2nd shell take 8, then the third takes 8...
@a=unpack'C*','ABR3S4sT5tU6';
# Contains the atomic numbers of abnormal elements
# Values: 18 1d 29 2a 2c 2d 2e 2f 39 3a 40 4e 4f 59 5a 5b 5c 5d 60 67
@b=unpack'C*',')*,-./9:@NOYZ[\]`g';
# if abnormal
if($_~~@b){
# All abnormals, except element 46 and 90, only displace 1 electron
$y=1+($_~~[46,90]);
# Abnormals with atomic number less than 33 involve switches between shells 3 and 4
# 33-65: 4 and 5
# 66-98: 5 and 6
# 99+ : 6 and 7
$p = (3 + ~~($_/33)) - 1;
# abnormals in these ranges move electrons from lower to higher
# abnormals elsewhere do higher to lower
if($_ >= 88 || $_ ~~ [57..64]){
$y *= -1;
}
# move electrons
$o[$p] += $y;
$o[$p+1] -= $y;
}
# extract max number of electrons to fill shell with
# >> 3 is equivalent to /8 for integers; $% is always an integer.
$% = $a[$q] / 8,
# do not overfill
$% = $% > $_ ? $_ : $%,
# add electrons to shell
$o[ $a[$q++] & 7 ] += $%
# reduce number of electrons left to fill shells with
while($_ -= $%);
# set list separator to space
$, = $";
# print list representing shells
say @o
(add an electron to the third outer shell)
-
@a=unpack'C*','ABR3S4sT5tU6';if(($-=<>)~~[unpack'C*',')*,-./9:@NOYZ[\]`g']){$.+=($-~~[46,90]);$p=2+$-/33;$->87|$-~~[57..64]&&($.*=-1);$o[$p]+=$.,$o[$p+1]-=$.}$%=($%=$a[$q]/8)>$-?$-:$%,$o[$a[$q++]&7]+=$%while($--=$%);$,=$";say@o
(add two electrons to the third outer shell; remove one from the second)
-
2 3
(add a new shell containing a single electron)
Осталось лишь каким-то образом закодировать, какое преобразование необходимо применить для перехода от одного атома к следующему. Различия целочисленных представлений двух последовательных атомов заключаются в следующем:
5
Уникальные различия в этом массиве заключаются в следующем:
2 8 18 32 32 18 7
Все, кроме первых 5, соответствуют случаям добавления новой оболочки; их можно опустить, поскольку умножение на 33 и прибавление 1 дает тот же результат, что и сложение разницы.
Поскольку нам нужно добавить новую оболочку тогда и только тогда, когда текущий атом имеет ровно восемь электронов во внешней оболочке (за исключением Он (2) ↦ Ли (3), который можно закодировать как добавить 65), мы можем закодировать эти преобразования как добавить 1 и определить необходимость умножения на лету.
Таким образом, если мы определим
117
электронная конфигурация N-й атом можно вычислить следующим образом:
2 8 18 32 17 1
Как это работает
78
Пример запуска
2 8 18 9 2
||answer||
Гольфскрипт (96 байт)
Вывод имеет форму
39
Здесь используется магическая строка, содержащая непечатаемые символы, поэтому я даю сценарий в формате xxd:
inc 1 until 2
inc 2 until 8
inc 3 until 8
inc 4 until 2
inc 3 until 11
pulldown 4
inc 3 until 16
pulldown 4
inc 4 until 8
inc 5 until 2
inc 4 until 10
pulldown 5
inc 4 until 13
inc 5 until 2
pulldown 5
inc 4 until 16
pulldown 5
inc 5 until 8
inc 6 until 2
inc 5 until 9
inc 4 until 19
pulldown 5
inc 4 until 25
inc 5 until 9
pulldown 5
inc 4 until 32
inc 5 until 15
pulldown 6
inc 5 until 18
inc 6 until 8
inc 7 until 2
inc 6 until 10
pulldown 6
inc 5 until 22
pulldown 6
inc 5 until 25
inc 6 until 9
pulldown 6
inc 5 until 32
pulldown 7
inc 7 until 2
inc 6 until 16
pulldown 7
inc 7 until 8
Для онлайн-тестирование Я пишу волшебную строку с экранированием:
N = 0
но это эквивалентно тому, что вы не сталкиваетесь с проблемами вставки символов в текстовые области браузера.
Суть подхода заключается в создании виртуальной машины с семью инструкциями, каждая из которых манипулирует списком счетчиков электронов. Тогда для элемента pulldown
we start with an electron count list of 0
и запусти первый N
instructions from the list encoded by the magic string.
Инструкции:
- Добавьте новую оболочку с 1 электроном:
D
- Добавьте электрон на внешнюю оболочку:
pulldown D (i.e. pull down one electron from valence D, thereby decrementing it by 1
and incrementing valence D-1 by 2)
- Добавьте электрон на ближайшую к внешней оболочке:
inc D until N (i.e. increment valence D by 1; advance to next instruction when D = N)
- Объедините две внешние оболочки и добавьте один электрон:
stdout
. (This is used only for palladium).
- Объедините две внешние оболочки и создайте новую оболочку с 1 электроном:
stdin
- Добавьте электрон в третью оболочку:
0e 39 3a 11 4f 03 72 03 3b 12 49 04 5e 12 04 73
04 3c 13 43 88 04 b2 43 04 e3 6d 05 82 3d 14 4b
05 9e 05 b3 44 05 e4 06 14 75 06 3e
- Добавьте электрон в третью оболочку и переместите один из второй оболочки в третью. Это происходит только тогда, когда внешняя оболочка имеет 2 электрона, поэтому это реализуется как
i = 1;
a = fread( fopen( 'a' ) );
b = fix( a/7 );
a = a-7*b+1;
d = 0*a;
for n = 1:input('')
A = a(i);
if b(i)
m = 1;
i = i + (d(A)+2 > b(i));
else
A = A - [1; 0];
m = [2; -1];
i = i + 1;
end
d(A) = d(A) + m;
end
fprintf( '%d ', d(~~d) );
rather than the longer i=1;a=fread(fopen('a'));b=fix(a/7);a=a-7*b+1;d=0*a;for n=1:input(''),A=a(i);if b(i),m=1;i=i+(d(A)+2>b(i));else A=A-[1;0];m=[2;-1];i=i+1;end;d(A)=d(A)+m;end;fprintf('%d ',d(~~d));