Compressing the Atomic Ionization Energies This is a different type of compression challenge.  In a normal kolmogorov-complexity challenge, you are required to recreate a list exactly.  Here, you are allowed to round the values in any way you wish.  What's the catch?  Your score is penalized based on how wrong your output is.

At the bottom of this question is a list of the first ionization energies for the first 108 elements.  Your program, upon execution, should output a reasonably accurate copy of this list.  There will be no input or arguments. For scoring purposes your output should be deterministic (same output every time). 

Output format

Your program/function must output a list of 108 numbers, sorted in order of increasing atomic number. This list can be in any appropriate format. The source data below is provided in the correct order, from hydrogen to hassium.

Scoring

Your score will be your program's length in bytes plus a rounding penalty.  A rounding penalty is calculated for each element and summed to give the total penalty.

As an example, let's take the number 11.81381. Let's say that your program outputs an incorrect value of 11.81299999.  


First, both numbers are multiplied by the same power of 10 such that there is no longer a decimal point in the true value: 1181381, 1181299.999. Trailing zeros in the true value are considered significant.
Then, the absolute difference is taken to determine the absolute error: 81.001.  
Finally, we calculate this element's penalty as max(0, log10(err * 4 - 1)) -&gt; 2.50921.  This formula was chosen such that an error &lt; 0.5 gives no penalty (since the answer is correct within rounding), while also giving an asymptotic 50% chance that rounding the number to any particular decimal place would provide a net benefit in score (assuming no other compression).  


Here is a Try-It-Online implementation of a penalty-calculating program.  The input to this program is provided as a list of numbers, one per line.  The output of this program is the total penalty and a per-element breakdown of scoring.

Data

The list of numbers below is the target data, in the correct order from atomic number 1 to 108.

Source

13.598434005136
24.587387936
5.391714761
9.322699
8.2980190
11.260296
14.53413
13.618054
17.42282
21.564540
5.1390767
7.646235
5.985768
8.151683
10.486686
10.36001
12.96763
15.7596112
4.34066354
6.11315520
6.56149
6.82812
6.746187
6.76651
7.434018
7.9024678
7.88101
7.639877
7.726380
9.3941990
5.9993018
7.899435
9.7886
9.752392
11.81381
13.9996049
4.177128
5.69486720
6.21726
6.63390
6.75885
7.09243
7.11938
7.36050
7.45890
8.33686
7.576234
8.993822
5.7863552
7.343917
8.608389
9.00966
10.45126
12.1298431
3.893905548
5.211664
5.5769
5.5386
5.473
5.5250
5.582
5.64371
5.670385
6.14980
5.8638
5.93905
6.0215
6.1077
6.18431
6.254159
5.425871
6.825069
7.549571
7.86403
7.83352
8.43823
8.96702
8.95883
9.225553
10.437504
6.1082871
7.4166796
7.285516
8.414
9.31751
10.7485
4.0727409
5.278424
5.380226
6.3067
5.89
6.19405
6.2655
6.0258
5.9738
5.9914
6.1978
6.2817
6.3676
6.50
6.58
6.65
4.90
6.01
6.8
7.8
7.7
7.6


Baselines &amp; Tips

The source data above is 906 bytes, with certain compression tools able to get it to sub-500 bytes. Interesting solutions are those that attempt to perform intelligent rounding, use algebraic formulas, or other techniques to output approximate values in fewer bytes than compression alone. It is difficult, however, to judge these tradeoffs across languages: for some languages compression alone might be optimal, while many other languages might lack compression tools altogether, so I expect a wide variation in score across languages. This is fine, as I'm going by the "competition within languages, not between them" philosophy.

I anticipate that it might be useful to attempt to take advantage of trends in the periodic table.  Below is a graph I found of ionization energies, so that you can see some of these trends.
Clean, 540 bytes + 64.396 Penalty = 604.396

Note: for the sake of readability, I've escaped every byte in the [Char] literal as most of them are non-printable. However, they are counted as only one byte per escape (except the null, quote, and newlines) as Clean naturally takes source files encoding-independently (except nulls).

import StdEnv,GenLib
c[h:t]=[(toInt h&gt;&gt;i)rem 2\\i&lt;-[0..7]]++c t
c[]=[]
r[]=[]
r l=[7&lt;&lt;29+2^62+sum[d&lt;&lt;p\\d&lt;-l&amp;p&lt;-[32..53]]:r(drop 22l)]
u::Maybe[Real]
u=uncompress{e\\e&lt;-[108:r(c['\145\062\353\227\045\336\021\131\341\224\212\225\230\140\121\241\231\027\321\306\361\254\075\154\161\041\144\255\346\110\371\126\172\155\361\127\152\023\350\222\117\116\341\222\155\357\351\072\341\153\315\025\171\317\141\367\076\232\377\323\206\301\257\235\103\154\157\274\035\010\347\167\142\370\355\074\172\320\347\036\165\262\210\364\177\025\144\176\303\223\143\116\340\270\012\172\062\377\257\141\265\320\342\261\225\347\215\165\044\152\017\011\133\251\027\347\243\307\231\304\165\351\325\035\036\053\010\341\344\131\363\207\072\045\327\012\130\347\167\023\312\023\210\013\347\244\236\020\172\153\362\370\142\123\276\116\226\341\211\245\105\136\145\146\130\367\123\026\312\244\225\347\152\225\145\142\207\164\227\145\360\105\140\201\041\271\141\273\274\230\020\101\166\101\133\171\063\155\302\062\036\061\335\147\130\365\175\201\203\035\357\341\272\172\270\067\047\002\200\223\342\156\230\253\152\347\105\322\335\117\203\220\242\342\316\137\311\247\004\155\164\124\131\205\325\203\116\306\365\170\325\032\143\337\017\331\232\006\266\122\176\305\334\137\214\312\130\035\110\306\206\227\001\000\150\353\121\132\146\246\226\231\071\365\050\140\063\063\333\314\314\307\314\354\231\231\171'])]}


Try it online!

This is the first challenge where I've been able to utilize Clean's generic compression ability (technically not actually compression, it's binary serialization) to gain an actual benefit.

I started with a [Real] - a list of 64-bit floating-point numbers, those from the question. After serializing this list, I simplified the top 10 bits (which were the same for each number), and the optimal configuration of the bottom 32 bits into the constant 7&lt;&lt;29+2^62. The remaining 22 bits per number were translated into 2.75 characters each, and encoded in a string.

This leaves the entire compressed constant at only 302 bytes, including every escape!