Duas dúzias de aproximações de números de beijos

26

Dado um número de 1 a 24, imprima o número de beijo com o melhor conhecimento atual (alguns números terão mais de uma saída aceitável). O conhecimento da geometria não é essencial, pois as saídas estão todas listadas abaixo.

Na página da Wikipedia sobre o problema do número de beijos :

um número de beijo é definido como o número de esferas unitárias não sobrepostas que podem ser organizadas de modo que cada uma toque outra esfera unitária

Ou seja, dada uma esfera unitária, quantas esferas unitárias podem tocá-la sem que nenhuma delas se sobreponha? A pergunta será feita no espaço N dimensional, onde uma esfera é entendida como uma esfera dimensional N-1.

Por exemplo:

  • no espaço bidimensional, um círculo unitário pode tocar em outros 6 círculos unitários.
  • no espaço tridimensional, uma esfera unitária pode tocar em outras 12 esferas unitárias.

A página da Wikipedia lista valores para 1 a 24 espaços dimensionais. No entanto, algumas delas ainda não são conhecidas com precisão, portanto, apenas um limite inferior e superior são dados. A tabela é reproduzida aqui para permanecer fixa, independentemente de qualquer restrição futura dos intervalos devido a novas provas. As soluções são julgadas nessa tabela fixa, mesmo que a página da Wikipedia seja modificada no futuro.

Tabela de limites

Dimension   Lower bound     Upper bound
1           2               2
2           6               6
3           12              12
4           24              24
5           40              44
6           72              78
7           126             134
8           240             240
9           306             364
10          500             554
11          582             870
12          840             1357
13          1154            2069
14          1606            3183
15          2564            4866
16          4320            7355
17          5346            11072
18          7398            16572
19          10668           24812
20          17400           36764
21          27720           54584
22          49896           82340
23          93150           124416
24          196560          196560

Entrada

A dimensão: um número inteiro de 1 a 24 (inclusive).

Aqui "inteiro" indica que a entrada não terá parte fracionária - pode ser 2ou 3mas nunca 2.5. Uma solução ainda pode receber a entrada como um flutuador ou uma string, por exemplo.

Saída

Um número no intervalo relevante, do limite inferior ao limite superior dessa entrada (inclusive).

A saída deve ser determinística (sempre a mesma para a mesma entrada).

A saída deve ser inteira. Por exemplo, para a entrada de 5possíveis saídas válidas são 40, 41, 42, 43, 44. Observe que isso é uma restrição ao valor, não ao tipo. É aceitável retornar um flutuador, desde que ele tenha zero parte fracionária. Por exemplo, 41.5não seria válido, mas 41.0seria válido.

Pontuação

Isso é . Sua pontuação é o número de bytes no seu código. Para cada idioma, o vencedor é a solução com a menor pontuação.

Trichoplax
fonte
6
Problema de aproximação muito legal.
Qd

Respostas:

11

Julia 0,6 , 52 bytes

n->ceil(n<8?3.7exp(.51n)-5.1:n<24?9exp(.41n):196560)

Experimente online!

Quão?

Aprendizado de máquina! (Meio. Talvez. Na verdade não. )

umaebK+cc

umaebK+cceil

sundar - Restabelecer Monica
fonte
6
Eu não consideraria uma pesquisa em grade um aprendizado de máquina. É força bruta, se alguma coisa.
Qd
5
Mas está dentro MLBase!!! Bem, as linhas em torno de ML estão borradas como sempre, mas isso provavelmente é básico demais para merecer o aprendizado de máquina de etiquetas. Por outro lado, é sempre útil obter uma palavra da moda!
sundar - Restabelece Monica
quando dizemos Machine Learning, pensamos principalmente de polinômios com n = 2 ou regexps
aaaaa diz Reintegrar Monica
2
quando digo aprendizagem de máquina, eu penso em redes neurais, árvores de decisão, HMMs, perceptron ...
QWR
@qwr Estou muito atrasado, mas a regressão é de fato considerada parte do aprendizado de máquina, além de todas essas coisas. (E mais SVMs, etc.!)
Quintec
7

x86, 62 59 53 50 bytes

Minha solução usa uma tabela de pesquisa de bytes e muda em 2 (sem cálculos de FP). As dimensões 9 a 23 fornecem margem de manobra suficiente para a mudança. Entrada eaxe saída ecx.

-3 trocando eaxe ecxjá que cmp $imm, %alé menor que cmp $imm, %cl.

-4 não tratando o caso N = 24 separadamente, mas aplicando o ajuste a todos os tempos 1024 casos.

-2 por não retornar cedo (estúpido)

-3 usando a tabela como deslocamento e em movzblvez de zerar comxor

start:
        dec     %eax                # 1-indexed table

        movzbl  table(%eax), %ecx   # return byte directly
        cmp     $8, %al
        jl      exit

        sal     $6, %ecx            # * 64 
        cmp     $19, %al
        jl      exit

        sal     $4, %ecx            # * 16
        sub     $48, %ecx

exit:   
        ret

#.data
table:  .byte   2, 6, 12, 24, 40, 72, 126, 240              # * 1
        .byte   5, 8, 10, 14, 19, 26, 41, 68, 84, 116, 167  # * 64  
        .byte   18, 28, 49, 92, 192                         # * 1024 - 48

Hexdump (tabela em .textvez de .data)

00000502  48 0f b6 88 1c 05 00 00  3c 08 7c 0d c1 e1 06 3c  |H.......<.|....<|
00000512  13 7c 06 c1 e1 04 83 e9  30 c3 02 06 0c 18 28 48  |.|......0.....(H|
00000522  7e f0 05 08 0a 0e 13 1a  29 44 54 74 a7 12 1c 31  |~.......)DTt...1|
00000532  5c c0                                             |\.|
qwr
fonte
1
A tabela é somente leitura, então normalmente você a colocaria .rodata, de .dataqualquer maneira. (Ou no Windows, aparentemente .rdata). A .rodataseção é vinculada como parte do segmento de texto.
Peter Cordes
1
E, BTW, pessoas normais escrevem shl, especialmente quando seu número não está assinado (você usoumovzbl carregá-lo, não movsbl). Claro que salé apenas outro nome para o mesmo opcode. o gcc emite sal, mas é muito raro vê-lo em código escrito à mão.
Peter Cordes
7

JavaScript (ES6), 60 bytes

f=(n,k=2)=>n<24?--n?f(n,k*24/(17+~'_8443223'[n])):~~k:196560

Experimente online!

Quão?

O último termo uma24=196560

Todos os outros termos são computados recursivamente, usando:

{uma1=2uman+1=uman×24qn

Onde qn

{q1=8q2=12q3=12q4=13q5=14q6=14q7=13qn=16,para n>7

levando aos seguintes rácios:

3,2,2,2413,127,127,2413,32,32,...,32

O resultado final é eventualmente encerrado e retornado.

Resumo dos resultados

Os resultados aproximados são fornecidos com 2 casas decimais.

  n |   a(n-1) | multiplier |      a(n) | output |          expected
----+----------+------------+-----------+--------+-------------------
  1 |      n/a |        n/a |         2 |      2 |                2
----+----------+------------+-----------+--------+-------------------
  2 |        2 |          3 |         6 |      6 |                6
  3 |        6 |          2 |        12 |     12 |               12
  4 |       12 |          2 |        24 |     24 |               24
  5 |       24 |      24/13 |     44.31 |     44 |        [40,..,44]
  6 |    44.31 |       12/7 |     75.96 |     75 |        [72,..,78]
  7 |    75.96 |       12/7 |    130.21 |    130 |      [126,..,134]
  8 |   130.21 |      24/13 |    240.39 |    240 |              240
  9 |   240.39 |        3/2 |    360.58 |    360 |      [306,..,364]
 10 |   360.58 |        3/2 |    540.87 |    540 |      [500,..,554]
 11 |   540.87 |        3/2 |    811.31 |    811 |      [582,..,870]
 12 |   811.31 |        3/2 |   1216.97 |   1216 |     [840,..,1357]
 13 |  1216.97 |        3/2 |   1825.45 |   1825 |    [1154,..,2069]
 14 |  1825.45 |        3/2 |   2738.17 |   2738 |    [1606,..,3183]
 15 |  2738.17 |        3/2 |   4107.26 |   4107 |    [2564,..,4866]
 16 |  4107.26 |        3/2 |   6160.89 |   6160 |    [4320,..,7355]
 17 |  6160.89 |        3/2 |   9241.34 |   9241 |   [5346,..,11072]
 18 |  9241.34 |        3/2 |  13862.00 |  13862 |   [7398,..,16572]
 19 | 13862.00 |        3/2 |  20793.01 |  20793 |  [10668,..,24812]
 20 | 20793.01 |        3/2 |  31189.51 |  31189 |  [17400,..,36764]
 21 | 31189.51 |        3/2 |  46784.26 |  46784 |  [27720,..,54584]
 22 | 46784.26 |        3/2 |  70176.40 |  70176 |  [49896,..,82340]
 23 | 70176.40 |        3/2 | 105264.59 | 105264 | [93150,..,124416]
----+----------+------------+-----------+--------+-------------------
 24 |           (hard-coded)            | 196560 |           196560 
Arnauld
fonte
1
A primeira coisa que vi foram operadores bit a bit dentro de uma função JavaScript recursiva; a primeira coisa que pensei foi "O que é Arnauld até ..."
Matth
Mesa muito boa. Você fez isso manualmente?
QWR
1
@qwr Sim, isso é principalmente uma edição do Notepad ++. Eu apenas usei um script para gerar os valores nas 4 primeiras colunas.
23918 Arnauld
4

Geléia , 29 26 bytes

“~D=ⱮziEc+y’Dḣ+⁵÷7PĊ«“£#;’

Experimente online!

Como funciona

“~D=ⱮziEc+y’Dḣ+⁵÷7PĊ«“£#;’  Main link. Argument: n

“~D=ⱮziEc+y’                Set the return value to 485523230101001100011122.
            D               Decimal; convert the return value to base 10.
             ḣ              Head; take the first n elements of the digit list.
              +⁵            Add 10 to each element.
                ÷7          Divide the sums by 7.
                  P         Take the product.
                   Ċ        Ceil; round up to the nearest integer.
                     “£#;’  Yield 196560.
                    «       Take the minimum.
Dennis
fonte
1

JavaScript (Node.js) , 120 99 bytes

Eliminados 21 bytes. Redução de graças grandes para a sugestão de TSH para adicionar um buraco para o início da matriz (economia de dois bytes indo de n-1a n, e apontando para números redondos dentro dos superior limites baixos e, portanto, encolhendo-os de notação de ponto fixo, como 1154a notação exponencial gostar2e3 .

Novamente, meu objetivo original era mostrar o quão leve seria o modo "burro" (por exemplo, não usar nenhuma matemática real, como a resposta de Arnauld. É impressionante que ainda houvesse espaço para reduzi-lo sem nenhuma transformação ou cálculo.

n=>[,2,6,12,24,40,72,126,240,306,500,582,840,2e3,2e3,3e3,5e3,6e3,8e3,2e4,2e4,3e4,5e4,1e6,196560][n]

Experimente online!

O dobro da duração da resposta de Arnauld, 0 da complexidade.

JavaScript (Node.js) , 129 128 bytes

(-1 byte, graças à sugestão de usar deslocamento de bits)

f=(n)=>[2,6,12,24,40,72,126,240].concat([5,8,10,14,19,26,41,68,84,116,167].map(x=>x<<6),[17,28,49,91].map(x=>x<<10),196560)[n-1]

Experimente online!

Para atender às demandas de ser interessante, roubei a lógica da resposta x86 e construí a matriz a partir disso. Tornando 9 bytes mais longos. Mas um pouco mais interessante.

Anthony
fonte
bocejos , pelo menos, tentar algo interessante
QWR
Eu pensei que demonstrar a abordagem mais direta (e, portanto, tecnicamente o maior comprimento razoável) fosse bastante interessante. O Arnauld's é possivelmente o mais curto que você pode obter em JS, mas o maior é apenas o dobro dos bytes.
Anthony
1
O objetivo da tabela de pesquisa de bytes é talvez usar uma bytestring ou apenas algo como "02060c1828487ef0", em que cada entrada tem um byte ou 2 caracteres em hexadecimal, se preferir. Armazenar os números diretamente em decimal leva até 3 caracteres. Também use bitshifting ...
qwr 13/07/18
2
Você deve pelo menos remover f=, alterar (x)para x, adicionar um furo e alterar x-1para x. TIO ; e talvez arredondá-los TIO 99 bytes
tsh
5
Bem-vindo ao PPCG! :)
Salsicha
1

Rúnico, 173 bytes

>i:8(?D5X1+1C,*212,+16,+1c2*,+1cX,+Sp3X7+a,*5X1+a,-1+kn$;
      R:c2*(?D4X1+1C,*212,+16,+1c2*,+Sp9*1+:4XY(?Dkn$;
             R`196560`r@;              ;$*C1nk,C1L

(Observe que o canto inferior direito deve ser contado em bytes: eles estão implicitamente preenchidos com espaços.)

O exe do TIO precisa de uma atualização em que esta resposta seja válida (e eu estou consertando outros buracos antes de pedir a Dennis para reconstruir). Mas insira um valor (certifique-se de adicionar espaço em branco nas linhas 2 e 3 se estiver usando mais de um caractere para o valor na primeira linha). Aqui está a maneira mais fácil de escrever os valores necessários:

0-9,a-f  ->  1-15
2Xn+     ->  20+n

Experimente online!

Funcionalmente, essa é uma porta da resposta Julia do sundar (mas o Runic não tem um comando para enviar epara a pilha (ou realmente, qualquer valor decimal), portanto, era necessária uma aproximação). A aproximação para eentradas menores que 8 é mais precisa, pois a perda de precisão resultou em valores fora do intervalo permitido de saídas (por exemplo 7, produziria 125).Ceil()foi realizado convertendo-se em um caractere e depois retornando a um número (isso falhou em valores excepcionalmente grandes, então a 40k eu o dividi por 100, faça a conversão para e para trás e multiplique por 100 novamente).

Provavelmente há espaço para simplificar o arranjo (por exemplo, executar o ponto de entrada na vertical, abaixo ou encontrar uma maneira de comprimir as aproximações e), mas estou feliz por poder fazer o cálculo.

/?D5X1+1C,*212,+16,+1c2*,+1cX,+Sp3X7+a,*5X1+a,-1+kn$;
  R:c2*(?D4X1+1C,*212,+16,+1c2*,+Sp9*1+:4XY(?Dkn$;
\(8:i<   R`196560`r@;              ;$*C1nk,C1L

161 bytes.

Atualização do intérprete:

Com a leitura da entrada de fixação por push , o Runic agora tem várias funções matemáticas e a capacidade de analisar seqüências de caracteres como dobras. Isso simplificará bastante essa resposta, mas deixarei como está para mostrar o esforço que coloco nela (adicionei as funções matemáticas de argumento único e a análise de string logo após a postagem: eu já tinha Sin / Cos / Tan no minha lista de tarefas, mas não tinha considerado Exp, Abs, Log etc. e estava ficando sem caracteres). O TIO deve ser atualizado nas próximas 24 a 48 horas, dependendo de quando Dennis o vir.

212,+16,+1c2*,+1cX,+reduziria para -> 1'eAcom esta atualização de intérprete. Aexibe um caractere e um valor e executa uma operação matemática nesse valor com base no caractere exibido ( enesse caso, é Exp()e Exp(1)retorna e ).

Draco18s
fonte