Este es un tipo diferente de desafío de compresión. En un desafío de complejidad de kolmogorov normal , debe recrear una lista exactamente. Aquí, puede redondear los valores de la forma que desee. ¿Cuál es el truco? Su puntaje se penaliza en función de cuán incorrecto sea su rendimiento.
Al final de esta pregunta hay una lista de las primeras energías de ionización para los primeros 108 elementos. Su programa, una vez ejecutado, debería generar una copia razonablemente precisa de esta lista. No habrá aportes ni argumentos. Para fines de puntuación, su salida debe ser determinista (la misma salida cada vez).
Formato de salida
Su programa / función debe generar una lista de 108 números, ordenados en orden creciente de número atómico. Esta lista puede estar en cualquier formato apropiado. La fuente de datos a continuación se proporciona en el orden correcto, desde hidrógeno hasta hassio.
Tanteo
Su puntaje será la longitud de su programa en bytes más una penalización por redondeo. Se calcula una penalización de redondeo para cada elemento y se suma para obtener la penalización total.
Como ejemplo, tomemos el número 11.81381
. Digamos que su programa genera un valor incorrecto de 11.81299999
.
En primer lugar, ambos números se multiplican por la misma potencia de 10 de tal manera que ya no hay un punto decimal en el valor verdadero:
1181381, 1181299.999
. Los ceros finales en el valor verdadero se consideran significativos.A continuación, se toma la diferencia absoluta para determinar el error absoluto:
81.001
.Finalmente, calculamos la penalización de este elemento como
max(0, log10(err * 4 - 1)) -> 2.50921
. Esta fórmula se eligió de manera tal que un error <0.5 no da penalización (ya que la respuesta es correcta dentro del redondeo), al tiempo que brinda una probabilidad asintótica del 50% de que redondear el número a cualquier decimal en particular proporcionaría un beneficio neto en el puntaje (suponiendo que no otra compresión).
Aquí hay una implementación de Try-It-Online de un programa de cálculo de penalizaciones. La entrada a este programa se proporciona como una lista de números, uno por línea. El resultado de este programa es la penalización total y un desglose de puntuación por elemento.
Datos
La lista de números a continuación son los datos objetivo, en el orden correcto del número atómico 1 al 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
Líneas de base y consejos
Los datos de origen anteriores son 906 bytes, con ciertas herramientas de compresión capaces de llevarlos a menos de 500 bytes. Las soluciones interesantes son aquellas que intentan realizar redondeos inteligentes, usan fórmulas algebraicas u otras técnicas para generar valores aproximados en menos bytes que la compresión sola. Sin embargo, es difícil juzgar estas compensaciones entre idiomas: para algunos idiomas, la compresión por sí sola puede ser óptima, mientras que muchos otros idiomas pueden carecer de herramientas de compresión, por lo que espero una amplia variación en la puntuación entre idiomas. Esto está bien, ya que sigo la filosofía de "competencia dentro de los idiomas, no entre ellos".
Anticipo que podría ser útil intentar aprovechar las tendencias en la tabla periódica. A continuación se muestra un gráfico que encontré de las energías de ionización, para que pueda ver algunas de estas tendencias.
fuente
Respuestas:
Limpio , 540 bytes + 64.396 Penalización = 604.396
Nota: en aras de la legibilidad, he escapado de cada byte en el
[Char]
literal ya que la mayoría de ellos no son imprimibles. Sin embargo, se cuentan como un solo byte por escape (excepto el nulo, la comilla y las nuevas líneas) ya que Clean toma naturalmente los archivos de origen de forma independiente de la codificación (excepto los nulos).Pruébalo en línea!
Este es el primer desafío en el que he podido utilizar la capacidad de compresión genérica de Clean (técnicamente no es realmente compresión, es serialización binaria) para obtener un beneficio real.
Comencé con una
[Real]
... una lista de números de coma flotante de 64 bits, los de la pregunta. Después de serializar esta lista, simplifiqué los 10 bits superiores (que eran los mismos para cada número) y la configuración óptima de los 32 bits inferiores en la constante7<<29+2^62
. Los 22 bits restantes por número se tradujeron a 2,75 caracteres cada uno y se codificaron en una cadena.Esto deja toda la constante comprimida en solo 302 bytes , ¡incluyendo cada escape!
fuente
Python 3 ,
355 +202353 bytes + 198 penalización = 551Pruébalo en línea!
Utilicé
0xffff (65535)
como límite superior porque es el valor máximo que se puede almacenar en un solo carácter unicode de 3 bytes.Dado que la energía de ionización más alta es ~ 24.587, eso da una relación de
2665
.Para generar la cadena en sí, utilicé el fragmento
''.join([chr(int(round(n*2665)))for n in ionization_energies])
(en python2 necesita usarunichr
), su consola puede o no puede imprimir los caracteres.Caracteres de 4 bytes, 462 bytes + 99 de penalización = 561
Pruébalo en línea!
La misma idea, pero el valor máximo es
0x110000
fuente
0x100**2
valores y no0x100**3
?C, 49 bytes + 626.048 penalización = 675.048
Pruébalo en línea!
fuente
f(i){for(i=0;i++<108;)printf("6\n");}
; pena: 625.173330827107; total = 662,173330827f(i){for(i=0;i<108;)puts("6");}
hace lo mismo en 31 bytes.i++
(en el "31"), perof(i){for(i=108;i;i--)puts("6");}
hace 32.f(i){for(i=108;i--;)puts("6");}
lo vuelve a bajar a 31.CJam (389 bytes + 33.09 penalización => 422.09)
codificado xxd:
Básicamente esto es
Esto utiliza un formato de punto flotante de ancho variable personalizado para almacenar los números. Dos bits son suficientes para el exponente; la mantisa obtiene de 5 a 47 bits, en múltiplos de 7. El bit restante por byte sirve como separador.
Parece que hay algo de corrupción cuando copio la cadena mágica para hacer una demostración en línea , de modo que obtiene unos 2 puntos de penalización más. Tendré que descubrir cómo construir la URL directamente ...
Programa de generación:
Demostración en línea
fuente
"
aumenta el error demasiado para que valga la pena?Gelatina ,
379361360 bytes + 0 Penalización = 360-18 utilizando una observación de Peter Taylor (los valores del orden 10 tienen los primeros 1 o 2, mientras que los valores del orden 1 no).
Pruébalo en línea!
¿Cómo?
Crea estas dos constantes (también conocidas como nilas):
Luego los usa para reconstruir representaciones de coma flotante de los números.
El programa completo es de esta forma:
(donde
...
están los números codificados para construir B y A)y funciona así:
fuente
Jelly , 116 bytes + 429,796016684433 Penalty = 545,796016684433
Pruébalo en línea!
Nada particularmente espectacular, una lista de índice de página de códigos,
“...‘
(números entre 0 y 249), a cada uno de los cuales le sumamos 47 ,+47
y se divide por 12 ,÷12
.fuente
Jelly , 164 bytes + 409.846 = 573.846
Pruébalo en línea!
Hay un número comprimido allí que es la concatenación de los primeros tres dígitos de cada energía (incluidos los ceros finales). Obtengo una lista de estos números de tres dígitos y
Ds3Ḍ
luego divido cada uno entre 100 con÷³
. Algunos de los números solo deben dividirse entre 10, por lo que multiplico algunos de estos por 10 para mejorar ligeramente la puntuación (×⁵$2R;6r⁵¤¤;15r18¤¤¦
).Versión anterior :
Jelly , 50 bytes + 571,482 pena = 621,482
Pruébalo en línea!
Redondeó cada energía a su entero de un solo dígito más cercano. Concatenados juntos esto da
995989999958689999467777788889689999466777777889679999456656666666666657888899996778994556666666666677567888
.“¡9;ẋkñ¬nƑḳ_gÐ.RḊụʠṁṬl⁾l>ɼXZĖSṠƈ;cḶ=ß³ṾAiʠʠɼZÞ⁹’
es un número base 250 que produce esto.DY
une los dígitos de este número con nuevas líneas.fuente
Java 8, 48 bytes + 625.173330827107 Penalización = 673.173330827107
Pruébalo en línea.
Versión inicial que imprime 108 veces
6
. Intentaré mejorar desde aquí.fuente
J , 390 bytes + 183.319 Penalización = 573.319
Pruébalo en línea!
Redondeé los números a cuatro dígitos decimales y los dividí en una lista para las partes enteras, una lista para los primeros 2 dígitos de la fracción y una para los segundos 2 dígitos de la fracción. Codifiqué cada número con un carácter imprimible. Para la decodificación, simplemente extraigo las partes del ingerer y la fracción de un número de las listas de caracteres asociadas y las vuelvo a armar para flotar.
J , 602 bytes + 0 Penalización = 602
Pruébalo en línea!
Esta vez fui por un enfoque ligeramente diferente. Divido los números en 2 secuencias: la primera contiene las partes enteras que simplemente están codificadas con un solo carácter imprimible. La segunda corriente contiene todas las partes fraccionarias. Eliminé todos los intervalos entre los dígitos y antepuse cada subcadena con su longitud 1-9 (modifiqué la primera fracción, que tiene 13 dígitos). Luego codifiqué esta lista como un número base 94, la presenté como una lista de caracteres.
Se pueden guardar unos 20 bytes si el verbo se reescribe como tácito.
fuente
Chicle , 403 + 9.12 = 412.12
Pruébalo en línea!
fuente