Skip to content

Instantly share code, notes, and snippets.

@subzey
Forked from 140bytes/LICENSE.txt
Created October 20, 2011 12:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subzey/1301066 to your computer and use it in GitHub Desktop.
Save subzey/1301066 to your computer and use it in GitHub Desktop.
Aufbau

Aufbau

Calculates electron configuration for chemical elements using Aufbau principle

Golf request!

This code is based on several for loops and array sorting. And it doesn't fit into 140 bytes. I suppose, this task is untrivial enough to be interesting for 140bytes community.

…and you may learn something new about natural science, hehe.

Is that nerdy thing usable?

Well, yes. Electron configuration of the element isn't just a line of letters and digits. It shows the common properties of the element. See demo in test.html

function(
a /* Ordinal number of chem element. The same: count of electrons */
){
for (
/* Declaring the vars */
var b = "", /* String to be returned */
c = 0, /* Sum of quantum numbers */
d, /* Azimuthal quantum number (orbital type) */
e /* Number of electrons at given orbital */
;
a /* Check if total count of electrons left is not 0 */
;
/* empty */
)
for (
/* d (azimuthal number) cannot be more or equal to principal */
/* So the starting value is floor((c + 1)/2) */
/* At the same time, this is an increment if c (sum) */
d = ++c >> 1
;
d-- && a /* continue while d != 0 and a != 0 */
;
/* (3) build and append chunk of string: */
/* `c` is more, than needed, so we should use something like (c - d) -1 */
/* Fortunately, `c + ~d` is the same, but shorter */
/* (Both operands are numbers, so this will be sum, not concat) */
/* Then, concat orbital name and, finally, the count of electrons */
/* Orbital names list length is enough for 1000 elements, I'm even not sure that amount will ever be discovered */
b += c + ~d + "spdfghijk".charAt(d) + e
)
/* (1) get the "capacity" of current orbital, but not more, than count f electrons left */
/* store it into `e` and subtract it from total count */
a -= e = Math.min(d * 4 + 2, a),
/* (2) add separating space if needed */
b += b&&" "
;
/* When no more electrons left, both loops are terminated and string is returned */
return b
}
function(a){for(var b="",c=0,d,e;a;)for(d=++c>>1;d--&&a;b+=c+~d+"spdfghijk".charAt(d)+e)a-=e=Math.min(d*4+2,a),b+=b&&" ";return b}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 subzey <subzey@immelman.ru>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "aufbau",
"description": "Calculates electron configuration for chemical elements using Aufbau principle",
"keywords": [
"aufbau",
"build-up",
"electrons",
"orbitals",
"chemistry"
]
}
<!DOCTYPE html>
<html>
<head>
<title>Aufbau</title>
<style type="text/css">
body {
background: white;
color: black;
}
body, input {
font: normal normal normal 16px Arial, sans-serif;
}
#e {
width: 150px;
height: 150px;
border: solid 2px;
background: white;
position: relative;
}
#n {
font-size: 40px;
width: 80px;
}
#o {
position: absolute;
top: 3px;
right: 3px;
font-size: 20px;
text-align: center;
}
#a {
font-size: 8px;
}
#a {
font-size: 12px;
}
#e.t1 {background: rgb(255, 102, 102)}
#e.t2 {background: rgb(255, 222, 173)}
#e.t3 {background: rgb(255, 191, 255)}
#e.t4 {background: rgb(255, 153, 204)}
#e.t5 {background: rgb(255, 192, 192)}
#e.t6 {background: rgb(204, 204, 204)}
#e.t7 {background: rgb(204, 204, 153)}
#e.t8 {background: rgb(160, 255, 160)}
#e.t9 {background: rgb(255, 255, 153)}
#e.t10 {background: rgb(192, 255, 255)}
</style>
</head>
<body>
<div>Expected value: <b>1s2 2s2 2p6 3s2 3p6 4s2 3d10 4p6 5s2 4d10 5p6 6s2 4f14 5d10 6p6 7s2 5f14 6d7</b></div>
<div>Actual value: <b id="ret"></b></div>
<script type="text/javascript">
// write a small example that shows off the API for your example
// and tests it in one fell swoop.
var aufbau = function(a){for(var b="",c=0,d,e;a;)for(d=++c>>1;d--&&a;b+=c+~d+"spdfghijk".charAt(d)+e)a-=e=Math.min(d*4+2,a),b+=b&&" ";return b}
document.getElementById( "ret" ).innerHTML = aufbau(109) // Mt
</script>
<h2>Demo</h2>
<p>Type the element name and I'll try to guess its group</p>
<div id="e">
<input type="text" id="n" maxlength="3" value="Mt" />
<span id="o"></span>
<div id="c"></div>
<div id="a"></div>
</div>
<script type="text/javascript">
function getElementByName(name){
return -~"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-La-Ce-Pr-Nd-Pm-Sm-Eu-Gd-Tb-Dy-Ho-Er-Tm-Yb-Lu-Hf-Ta-W-Re-Os-Ir-Pt-Au-Hg-Tl-Pb-Bi-Po-At-Rn-Fr-Ra-Ac-Th-Pa-U-Np-Pu-Am-Cm-Bk-Cf-Es-Fm-Md-No-Lr-Rf-Db-Sg-Bh-Hs-Mt-Ds-Rg-Cn-Uut-Uuq-Uup-Uuh-Uus-Uuo".toUpperCase().split("-").indexOf(name.toUpperCase())||null
}
function showInfo(ord){
document.getElementById('o').innerHTML = ord||'???';
var orbital = ord&&aufbau(ord);
var type = 0;
var match = null;
document.getElementById('a').innerHTML = orbital||'???';
if (/1s1$/.test(orbital)){ // H
type = 8;
} else if (/1s2$/.test(orbital)) { // He
type = 10;
} else if (/4f\d+$/.test(orbital)) {
type = 3;
} else if (/5f\d+$/.test(orbital)) {
type = 4;
} else if (/s1$/.test(orbital)){
type = 1;
} else if (/s2$/.test(orbital)){
type = 2;
} else if (/d\d+$/.test(orbital)){
type = 5;
} else if (/p5$/.test(orbital)){
type = 9;
} else if (/p6$/.test(orbital)) {
type = 10;
} else if (/3p1$/.test(orbital)) { // Al
type = 6;
} else if (match = /(\d+)p(\d+)$/.exec(orbital)){
if (match[1] > +match[2] + 2) {
type = 6;
} else if (match[1] <= match[2]){
type = 8;
} else {
type = 7;
}
}
document.getElementById('c').innerHTML = ['???','Alkali metal', 'Alkaline earth metal', 'Lantanide', 'Actinide', 'Transition metal', 'Post-transition metal', 'Metalloid', 'Non-metal', 'Halogen', 'Noble gas'][type];
document.getElementById('e').className = 't' + type;
}
document.getElementById('e').addEventListener('keypress', function(e){
var trigger = e.srcElement||e.target;
setTimeout(function(){
showInfo(getElementByName(trigger.value));
}, 0);
}, true)
showInfo(getElementByName(document.getElementById("n").value));
document.getElementById("n").select();
</script>
</body>
</html>
@tsaniel
Copy link

tsaniel commented Oct 20, 2011

Save 2 bytes.

function(a){for(var b=[],c=9,d,e="";c--;)for(d=c;d--;b.push([9+c+d,c,d]));for(;c=b.sort().shift(),a;a-=d=Math.min(2+c[2]*4,a),e+=(e&&" ")+c[1]+'spdf'[c[2]]+d);return e}

Sadly, I don't know much about chemistry.

@subzey
Copy link
Author

subzey commented Oct 20, 2011

@tsaniel, thanks for noticing these parens!
I'll update the gist code when annotated.js is out of sync with index.js.

Sorry, if my code and comments aren't clear and transparent enough.

@atk
Copy link

atk commented Oct 20, 2011

Save another character by combining the first two for-loops:

for(var b=[],c=d=8,e='';d--||~(d=--c-1);b.push([9+c+d,c,d]));

Update: sorry, this leaves d in the global scope :-/

@atk
Copy link

atk commented Oct 21, 2011

You could save some bytes if you accept the result as an array instead of a string.

function(a){for(var b=[],c=9,d,e=[];c--;)for(d=c;d--;b.push([9+c+d,c,d]));for(;c=b.sort().shift(),a;a-=d=Math.min(2+c[2]*4,a),e.push(c[1]+'spdf'[c[2]]+d));return e}

@subzey
Copy link
Author

subzey commented Oct 21, 2011

Bingo!

I've tried to make complex for's instead of using array and sorting and got enough bytes to fit it into 140 bytes:

function(a){for(var b="",c=0,d,e;a;)for(d=++c>>1;d--&&a;b+=c+~d+"spdfghijk".charAt(d)+e)a-=e=Math.min(d*4+2,a),b+=b&&" ";return b}

I'll update the gist and give commented version few hours later, excuse me.

@atk
Copy link

atk commented Oct 21, 2011

great - you even took care of old IEs that requires Str.charAt(x) instead of Str[x]...

@tsaniel
Copy link

tsaniel commented Jan 21, 2012

Save 4 bytes.
function(a,b,c,d,e){for(c=b="";a;)for(d=++c>>1;d--&&a;b+=c+~d+"spdfghijk".charAt(d)+e)a-=e=d*4+2<a?d*4+2:a,b+=b&&" ";return b}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment