Dies ist eine andere Art der Komprimierung. Bei einer normalen Herausforderung mit Kolmogorov-Komplexität müssen Sie eine Liste exakt neu erstellen. Hier können Sie die Werte beliebig runden. Was ist der Haken? Ihre Punktzahl wird bestraft, je nachdem, wie falsch Ihre Ausgabe ist.
Am Ende dieser Frage befindet sich eine Liste der ersten Ionisierungsenergien für die ersten 108 Elemente. Ihr Programm sollte bei der Ausführung eine einigermaßen genaue Kopie dieser Liste ausgeben. Es wird keine Eingabe oder Argumente geben. Für Bewertungszwecke sollte Ihre Ausgabe deterministisch sein (jedes Mal dieselbe Ausgabe).
Ausgabeformat
Ihr Programm / Ihre Funktion muss eine Liste von 108 Zahlen ausgeben, die in der Reihenfolge der aufsteigenden Ordnungszahl sortiert sind. Diese Liste kann in jedem geeigneten Format vorliegen. Die folgenden Quelldaten werden in der richtigen Reihenfolge von Wasserstoff bis Kalium angegeben.
Wertung
Ihre Punktzahl ergibt sich aus der Länge Ihres Programms in Bytes zuzüglich einer Rundungsstrafe. Für jedes Element wird eine Rundungsstrafe berechnet und zur Gesamtstrafe aufsummiert.
Nehmen wir als Beispiel die Nummer 11.81381
. Nehmen wir an, Ihr Programm gibt einen falschen Wert von aus 11.81299999
.
Zunächst werden die beiden Zahlen , die durch die gleiche Leistung von 10 , so multipliziert , daß es nicht mehr ein Dezimalpunkt in dem wahren Wert:
1181381, 1181299.999
. Nachgestellte Nullen im wahren Wert werden als signifikant betrachtet.Dann wird die absolute Differenz der absoluten Fehler zu bestimmen genommen:
81.001
.Schließlich berechnen wir die Strafe dieses Elements als
max(0, log10(err * 4 - 1)) -> 2.50921
. Diese Formel wurde so gewählt, dass ein Fehler <0,5 keine Strafe bedeutet (da die Antwort innerhalb der Rundung korrekt ist), während bei einer asymptotischen Wahrscheinlichkeit von 50% das Runden der Zahl auf eine bestimmte Dezimalstelle einen Nettovorteil in der Punktzahl ergibt (vorausgesetzt, nein andere Komprimierung).
Hier ist eine Try-It-Online- Implementierung eines Strafkalkulationsprogramms. Die Eingabe für dieses Programm erfolgt als Liste von Zahlen, eine pro Zeile. Die Ausgabe dieses Programms ist die Gesamtstrafe und eine pro Element aufgeschlüsselte Wertung.
Daten
Die Liste der Zahlen unten enthält die Zieldaten in der richtigen Reihenfolge von Ordnungszahl 1 bis 108.
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 & Tipps
Die obigen Quelldaten sind 906 Bytes, mit bestimmten Komprimierungswerkzeugen können sie auf unter 500 Bytes gebracht werden. Interessante Lösungen sind solche, die versuchen, intelligentes Runden durchzuführen, algebraische Formeln oder andere Techniken verwenden, um ungefähre Werte in weniger Bytes als nur Komprimierung auszugeben. Es ist jedoch schwierig, diese Kompromisse zwischen den Sprachen zu beurteilen: Für einige Sprachen ist die Komprimierung möglicherweise allein optimal, während es vielen anderen Sprachen möglicherweise überhaupt an Komprimierungswerkzeugen mangelt. Das ist in Ordnung, da ich von der Philosophie "Wettbewerb innerhalb der Sprachen, nicht zwischen ihnen" ausgehe.
Ich gehe davon aus, dass es nützlich sein könnte, Trends im Periodensystem auszunutzen. Unten ist eine Grafik, die ich über Ionisierungsenergien gefunden habe, damit Sie einige dieser Trends sehen können.
quelle
Antworten:
Sauber , 540 Bytes + 64,396 Penalty = 604,396
Hinweis: Aus Gründen der Lesbarkeit habe ich jedes Byte im
[Char]
Literal ausgeblendet, da die meisten davon nicht druckbar sind. Sie werden jedoch nur als ein Byte pro Escape gezählt (mit Ausnahme von Null, Anführungszeichen und Zeilenumbrüchen), da Clean Quelldateien natürlich unabhängig von der Codierung annimmt (mit Ausnahme von Nullen).Probieren Sie es online!
Dies ist die erste Herausforderung, bei der ich die generische Komprimierungsfunktion von Clean (technisch gesehen keine eigentliche Komprimierung, sondern binäre Serialisierung) nutzen konnte, um einen tatsächlichen Vorteil zu erzielen.
Ich begann mit einer
[Real]
- Liste von 64-Bit-Gleitkommazahlen, die aus der Frage stammen. Nachdem ich diese Liste serialisiert hatte, vereinfachte ich die oberen 10 Bits (die für jede Zahl gleich waren) und die optimale Konfiguration der unteren 32 Bits in die Konstante7<<29+2^62
. Die restlichen 22 Bits pro Nummer wurden in jeweils 2,75 Zeichen übersetzt und in einer Zeichenfolge codiert.Dadurch bleibt die gesamte komprimierte Konstante bei nur 302 Bytes , einschließlich jedes Escape!
quelle
Python 3 ,
355 + 202353 Bytes + 198 Penalty = 551Probieren Sie es online!
Ich habe es
0xffff (65535)
als obere Grenze verwendet, weil es der Maximalwert ist, der in einem einzelnen 3-Byte-Unicode-Zeichen gespeichert werden kann.Da die höchste Ionisierungsenergie ~ 24,587 beträgt, ergibt sich ein Verhältnis von
2665
.Um die Zeichenfolge selbst zu generieren, habe ich das Snippet verwendet
''.join([chr(int(round(n*2665)))for n in ionization_energies])
(auf Python2 müssen Sie es verwendenunichr
). Möglicherweise kann Ihre Konsole die Zeichen drucken oder nicht.4-Byte-Zeichen, 462 Byte + 99 Strafe = 561
Probieren Sie es online!
Gleiche Idee, aber der Maximalwert ist
0x110000
quelle
0x100**2
Werte speichern und nicht0x100**3
?C, 49 Bytes + 626,048 Strafe = 675,048
Probieren Sie es online!
quelle
f(i){for(i=0;i++<108;)printf("6\n");}
:; Strafe: 625.173330827107; total = 662,173330827f(i){for(i=0;i<108;)puts("6");}
macht dasselbe in 31 Bytes.i++
auch (in der "31"), macht aberf(i){for(i=108;i;i--)puts("6");}
32.f(i){for(i=108;i--;)puts("6");}
bringt es zurück auf 31.CJam (389 Bytes + 33.09 Strafe => 422.09)
xxd-codiert:
Grundsätzlich ist dies
Dies verwendet ein benutzerdefiniertes Gleitkommaformat mit variabler Breite, um die Zahlen zu speichern. Für den Exponenten genügen zwei Bits; Die Mantisse wird in Vielfachen von 7 auf 5 bis 47 Bit gesetzt. Das verbleibende Bit pro Byte dient als Trennzeichen.
Es scheint eine gewisse Korruption zu geben, wenn ich die magische Zeichenfolge kopiere, um eine Online-Demo zu erstellen , sodass etwa 2 Strafpunkte mehr erzielt werden. Ich muss herausfinden, wie man die URL direkt erstellt ...
Generierungsprogramm:
Online-Demo
quelle
"
den Fehler zu sehr, um ihn wert zu sein?Jelly ,
379 361360 Bytes + 0 Penalty = 360-18 unter Verwendung einer Beobachtung von Peter Taylor (Werte der Ordnung 10 haben führende 1 oder 2, Werte der Ordnung 1 nicht).
Probieren Sie es online!
Wie?
Erstellt diese beiden Konstanten (AKA-Niladen):
Verwenden Sie diese dann, um Gleitkommadarstellungen der Zahlen zu rekonstruieren.
Das vollständige Programm hat folgende Form:
(Wo
...
sind codierte Zahlen für die Konstruktion von B und A)und funktioniert wie folgt:
quelle
Jelly , 116 Bytes + 429.796016684433 Penalty = 545.796016684433
Probieren Sie es online!
Nichts besonders spektakulär, eine Code-Seite Indexliste,
“...‘
(Zahlen zwischen 0 und 249), an denen jeweils fügen wir 47 ,+47
und dann teilen , indem er 12 ,÷12
.quelle
Jelly , 164 Bytes + 409,846 = 573,846
Probieren Sie es online!
Dort befindet sich eine komprimierte Zahl, die die Verkettung der ersten drei Ziffern jeder Energie (einschließlich nachfolgender Nullen) darstellt. Ich bekomme eine Liste dieser dreistelligen Zahlen mit
Ds3Ḍ
dann dividiere jede durch 100 mit÷³
. Einige der Zahlen sollten nur durch 10 geteilt werden, daher multipliziere ich einige mit 10, um die Punktzahl leicht zu verbessern (×⁵$2R;6r⁵¤¤;15r18¤¤¦
).Vorherige Version :
Jelly , 50 Bytes + 571,482 Strafe = 621,482
Probieren Sie es online!
Rundete jede Energie auf die nächste einstellige Ganzzahl. Zusammengefasst ergibt dies
995989999958689999467777788889689999466777777889679999456656666666666657888899996778994556666666666677567888
.“¡9;ẋkñ¬nƑḳ_gÐ.RḊụʠṁṬl⁾l>ɼXZĖSṠƈ;cḶ=ß³ṾAiʠʠɼZÞ⁹’
ist eine Basis-250-Zahl, die dies ergibt.DY
Verbindet die Ziffern dieser Nummer mit Zeilenumbrüchen.quelle
Java 8, 48 Bytes + 625.173330827107 Penalty = 673.173330827107
Probieren Sie es online aus.
Ursprüngliche Version, die 108 Mal druckt
6
. Wird versuchen, sich von hier aus zu verbessern.quelle
J , 390 Bytes + 183,319 Penalty = 573,319
Probieren Sie es online!
Ich habe die Zahlen auf vier Dezimalstellen gerundet und sie in eine Liste für ganzzahlige Teile, eine Liste für die ersten beiden Nachkommastellen und eine für die zweiten beiden Nachkommastellen aufgeteilt. Ich habe jede Zahl mit einem druckbaren Zeichen verschlüsselt. Zum Entschlüsseln extrahiere ich einfach die Ingerer- und Bruchteile einer Zahl aus den zugehörigen Zeichenlisten und setze sie wieder zu Float zusammen.
J , 602 Bytes + 0 Penalty = 602
Probieren Sie es online!
Diesmal habe ich einen etwas anderen Ansatz gewählt. Ich teile die Zahlen in 2 Streams auf - der erste enthält die ganzzahligen Teile, die einfach mit einem einzelnen druckbaren Zeichen codiert sind. Der zweite Strom enthält die gesamten Bruchteile. Ich habe alle Intervalle zwischen den Ziffern entfernt und jedem Teilstring die Länge 1-9 vorangestellt (ich habe den ersten Bruch, der 13 Ziffern lang ist, optimiert). Dann verschlüsselte ich diese Liste als Basis 94-Nummer und präsentierte sie als Liste von Zeichen.
Etwa 20 Bytes können gespeichert werden, wenn das Verb als stillschweigend umgeschrieben wird.
quelle
Bubblegum , 403 + 9,12 = 412,12
Probieren Sie es online!
quelle