Este é um tipo diferente de desafio de compactação. Em um desafio normal da complexidade de kolmogorov , é necessário recriar uma lista exatamente. Aqui, você pode arredondar os valores da maneira que desejar. Qual é o problema? Sua pontuação é penalizada com base no quão errado é o seu resultado.
No final desta pergunta, há uma lista das primeiras energias de ionização para os primeiros 108 elementos. Seu programa, após a execução, deve gerar uma cópia razoavelmente precisa dessa lista. Não haverá entrada ou argumentos. Para fins de pontuação, sua saída deve ser determinística (sempre a mesma saída).
Formato de saída
Seu programa / função deve gerar uma lista de 108 números, classificados em ordem crescente de número atômico. Essa lista pode estar em qualquer formato apropriado. Os dados da fonte abaixo são fornecidos na ordem correta, do hidrogênio ao hésio.
Pontuação
Sua pontuação será o comprimento do seu programa em bytes mais uma penalidade de arredondamento. Uma penalidade de arredondamento é calculada para cada elemento e somada para fornecer a penalidade total.
Como exemplo, vamos pegar o número 11.81381
. Digamos que seu programa produz um valor incorreto de 11.81299999
.
Em primeiro lugar, ambos os números são multiplicados pelo mesmo poder de 10 de tal modo que já não existe um ponto decimal no verdadeiro valor:
1181381, 1181299.999
. Zeros à direita no valor verdadeiro são considerados significativos.Então, a diferença absoluta é levado para determinar o erro absoluto:
81.001
.Por fim, calculamos a penalidade desse elemento como
max(0, log10(err * 4 - 1)) -> 2.50921
. Essa fórmula foi escolhida de forma que um erro <0,5 não dê penalidade (já que a resposta está correta no arredondamento), além de oferecer 50% de chance assintótica de que arredondar o número para qualquer casa decimal em particular traria um benefício líquido na pontuação (supondo que não outra compressão).
Aqui está uma implementação do Try-It-Online de um programa de cálculo de penalidade. A entrada para este programa é fornecida como uma lista de números, um por linha. A saída deste programa é a penalidade total e uma discriminação por elemento da pontuação.
Dados
A lista de números abaixo é dos dados de destino, na ordem correta do número atômico 1 a 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
Linhas de base e dicas
Os dados de origem acima são 906 bytes, com certas ferramentas de compactação capazes de chegar a menos de 500 bytes. Soluções interessantes são aquelas que tentam executar arredondamentos inteligentes, usam fórmulas algébricas ou outras técnicas para gerar valores aproximados em menos bytes do que apenas a compactação. É difícil, no entanto, julgar essas compensações entre idiomas: para alguns idiomas, a compactação sozinha pode ser ótima, enquanto muitas outras linguagens podem não ter ferramentas de compactação, por isso espero uma grande variação na pontuação entre os idiomas. Isso é bom, já que estou seguindo a filosofia da "competição dentro das línguas, não entre elas".
Antecipo que pode ser útil tentar tirar proveito das tendências na tabela periódica. Abaixo está um gráfico que encontrei das energias de ionização, para que você possa ver algumas dessas tendências.
fonte
Respostas:
Limpo , 540 bytes + 64,396 Penalidade = 604.396
Nota: para facilitar a leitura, eu escapei de todos os bytes no
[Char]
literal, pois a maioria deles não é imprimível. No entanto, eles são contados como apenas um byte por escape (exceto nulo, aspas e novas linhas), pois o Clean limpa naturalmente os arquivos de origem, independentemente da codificação (exceto nulos).Experimente online!
Este é o primeiro desafio em que pude utilizar a capacidade de compactação genérica do Clean (tecnicamente não compactação, é serialização binária) para obter um benefício real.
Comecei com uma
[Real]
- uma lista de números de ponto flutuante de 64 bits, os da pergunta. Depois de serializar essa lista, simplifiquei os 10 bits principais (que eram iguais para cada número) e a configuração ideal dos 32 bits inferiores na constante7<<29+2^62
. Os 22 bits restantes por número foram traduzidos para 2,75 caracteres cada e codificados em uma sequência.Isso deixa toda a constante compactada em apenas 302 bytes , incluindo todas as saídas!
fonte
Python 3 ,
355 + 202353 bytes + 198 penalidade = 551Experimente online!
Eu usei
0xffff (65535)
como limite superior porque é o valor máximo que pode ser armazenado em um único caractere unicode de 3 bytes.Como a energia de ionização mais alta é ~ 24.587, isso dá uma razão de
2665
.Para gerar a string em si, usei o trecho
''.join([chr(int(round(n*2665)))for n in ionization_energies])
(no python2 você precisa usarunichr
), seu console pode ou não conseguir imprimir os caracteres.Caracteres de 4 bytes, 462 bytes + 99 de penalidade = 561
Experimente online!
A mesma ideia, mas o valor máximo é
0x110000
fonte
0x100**2
valores e não0x100**3
?C, 49 bytes + 626.048 de penalidade = 675.048
Experimente online!
fonte
f(i){for(i=0;i++<108;)printf("6\n");}
; penalidade: 625.173330827107; total = 662,173330827f(i){for(i=0;i<108;)puts("6");}
faz a mesma coisa em 31 bytes.i++
(no "31"), masf(i){for(i=108;i;i--)puts("6");}
precisa de 32.f(i){for(i=108;i--;)puts("6");}
recebe-lo de volta para 31.CJam (389 bytes + 33,09 de penalidade => 422,09)
codificado em xxd:
Basicamente isso é
Isso usa um formato de ponto flutuante de largura variável personalizado para armazenar os números. Dois bits são suficientes para o expoente; a mantissa varia de 5 a 47 bits, em múltiplos de 7. O bit restante por byte serve como separador.
Parece haver alguma corrupção acontecendo quando eu copio a seqüência mágica para fazer uma demonstração online , de modo que isso gera cerca de 2 pontos a mais. Vou ter que descobrir como criar o URL diretamente ...
Programa de geração:
Demonstração online
fonte
"
aumenta muito o erro para valer a pena?Geléia ,
379 361360 bytes + 0 Penalidade = 360-18 usando uma observação de Peter Taylor (os valores da ordem 10 têm 1 ou 2 à esquerda, enquanto os valores da ordem 1 não).
Experimente online!
Quão?
Cria essas duas constantes (AKA nilads):
Em seguida, usa-os para reconstruir representações de números flutuantes.
O programa completo é desta forma:
(onde
...
estão os números codificados para a construção de B e A)e funciona assim:
fonte
Geléia , 116 bytes + 429.796016684433 Pena = 545.796016684433
Experimente online!
Nada de particularmente espectacular, uma lista índice de código páginas,
“...‘
(números entre 0 e 249), a cada um dos que acrescentamos 47 ,+47
e depois dividir por 12 ,÷12
.fonte
Jelly , 164 bytes + 409,846 = 573.846
Experimente online!
Há um número compactado lá que é a concatenação dos três primeiros dígitos de cada energia (incluindo zeros à direita). Eu recebo uma lista desses números de três dígitos e, em
Ds3Ḍ
seguida, divido cada um por 100÷³
. Alguns dos números devem ser divididos apenas por 10, por isso multiplico alguns por 10 para melhorar um pouco a pontuação (×⁵$2R;6r⁵¤¤;15r18¤¤¦
).Versão anterior :
Geléia , 50 bytes + 571.482 de penalidade = 621.482
Experimente online!
Arredonde cada energia para o número inteiro mais próximo de um dígito. Concatenados juntos, isso dá
995989999958689999467777788889689999466777777889679999456656666666666657888899996778994556666666666677567888
.“¡9;ẋkñ¬nƑḳ_gÐ.RḊụʠṁṬl⁾l>ɼXZĖSṠƈ;cḶ=ß³ṾAiʠʠɼZÞ⁹’
é um número de base 250 que gera isso.DY
une os dígitos desse número com novas linhas.fonte
Java 8, 48 bytes + 625.173330827107 Pena = 673.173330827107
Experimente online.
Versão inicial que imprime 108 vezes
6
. Vai tentar melhorar a partir daqui.fonte
J , 390 bytes + 183,319 Pena = 573.319
Experimente online!
Arredondei os números para quatro dígitos decimais e os dividi em uma lista para partes inteiras, uma lista para os 2 primeiros dígitos da fração e uma para os 2 dígitos da segunda fração. Codifiquei cada número com um caractere imprimível. Para decodificar, simpy, extraio as partes do ingerer e da fração de um número das listas de caracteres associadas e as monte novamente para flutuar.
J , 602 bytes + 0 Penalidade = 602
Experimente online!
Dessa vez, optei por uma abordagem um pouco diferente. Dividi os números em 2 fluxos - o primeiro contém as partes inteiras que são simplesmente codificadas com um único caractere imprimível. O segundo fluxo contém todas as partes fracionárias. Eu removi todos os intervalos entre os dígitos e coloquei cada substring com seu comprimento de 1 a 9 (ajustei a primeira fração, que tem 13 dígitos). Então codifiquei esta lista como um número base 94, apresentei como uma lista de caracteres.
Podem ser salvos cerca de 20 bytes se o verbo for reescrito como um tácito.
fonte
Bubblegum , 403 + 9,12 = 412,12
Experimente online!
fonte