Números pequenos de Ramsey


13

Antecedentes: o número de Ramsey R(r,s) fornece o número mínimo de vértices v no gráfico completo Kv modo que uma coloração de borda vermelha / azul de Kv tenha pelo menos um vermelho Krou um azul Ks. Limites para maiores r,ssão muito difíceis de estabelecer.

Sua tarefa é gerar o número R(r,s) para 1r,s5 .

Entrada

Dois inteiros r,s com 1r5 e 1s5 .

Resultado

R(r,s) conforme indicado nesta tabela:

  s   1    2    3    4      5
r +--------------------------
1 |   1    1    1    1      1
2 |   1    2    3    4      5
3 |   1    3    6    9     14
4 |   1    4    9   18     25
5 |   1    5   14   25  43-48

Observe que r e s são intercambiáveis: R(r,s)=R(s,r) .

Para você pode gerar qualquer número inteiro entre 43 e 48 , inclusive. No momento em que esta pergunta foi publicada, esses são os limites mais conhecidos.R(5,5)4348.


Eu acho que (mesmo com o intervalo para 5,5) que este pode caber sob Kolmogorov-complexidade (ou faz apenas uma não-entrada, ajuste de saída fixa?)
Jonathan Allan

Quando 49 foi excluído para R (5,5)? (Eu não estou desafiando, eu parecem ter perdido um papel após Exoo de e McKay e Radziszowski de.)
Eric Torres


@qwr: Obrigado! Estou gostando até agora.
Eric Towers

Respostas:


7

JavaScript (ES6), 51 49 bytes

Recebe entrada na sintaxe de currying (r)(s).

r=>s=>--r*--s+[9,1,,13,2,,3,27,6][r<2|s<2||r*s%9]

Experimente online!

Quão?

Como primeira aproximação, usamos a fórmula:

(r-1)(s-1)
 0  0  0  0  0
 0  1  2  3  4
 0  2  4  6  8
 0  3  6  9 12
 0  4  8 12 16

Se tivermos , basta adicionar 1 :min(r,s)<31

 1  1  1  1  1
 1  2  3  4  5
 1  3  -  -  -
 1  4  -  -  -
 1  5  -  -  -

Caso contrário, adicionamos um valor escolhido em uma tabela de pesquisa cuja chave é definida por:k

k=(r-1)(s-1)mod9
 k:                    table[k]:           (r-1)(s-1):         output:
 -  -  -  -  -         -  -  -  -  -       -  -  -  -  -       -  -  -  -  -
 -  -  -  -  -         -  -  -  -  -       -  -  -  -  -       -  -  -  -  -
 -  -  4  6  8   -->   -  -  2  3  6   +   -  -  4  6  8   =   -  -  6  9 14
 -  -  6  0  3         -  -  3  9 13       -  -  6  9 12       -  -  9 18 25
 -  -  8  3  7         -  -  6 13 27       -  -  8 12 16       -  - 14 25 43

Bom, as duas primeiras linhas são uma expressão clara.
Qd

5

JavaScript (Node.js) , 56 55 bytes

f=(x,y)=>x<2|y<2||f(x,y-1)+f(x-1,y)-(x*y==12)-7*(x+y>8)

Experimente online! Notei que a tabela se assemelha ao triângulo de Pascal, mas com fatores de correção. Editar: salvou 1 byte graças a @sundar.


1
Yep, identidade triângulo de Pascal vem de um simples limite superior sobre os números de Ramsey (ver post de Jonathan Allan)
QWR

1
Você pode salvar 1 byte substituindo x*y>19por x+y>8.
sundar - Restabelece Monica

@ sundar Obrigado, minha solução original foi de 50 bytes antes que eu percebesse que minha indexação estava errada e esqueci de tentar jogar novamente depois de corrigir isso.
Neil

4

Geléia ,  17  16 bytes

’ScḢƊ_:¥9“ ı?0‘y

Experimente online! Ou veja uma suíte de testes .

Substituir o 0com +, ,, -, ., ou /ao conjunto igual a 43 , 44 , 45 , 46 , ou 47 , respectivamente, (em vez de a 48 aqui).R(5,5)43444546.4748.

Quão?

Como podemos encontrar que:R(r,s)R(r-1,s)+R(r,s-1)

R(r,s)(r+s-2r-1)

Isso é ’ScḢƊe produziria:

 1  1  1  1  1
 1  2  3  4  5
 1  3  6 10 15
 1  4 10 20 35
 1  5 15 35 70

Se subtrairmos um para cada vez que nove entrarem no resultado, alinharemos mais três com nosso objetivo (isso é alcançado com _:¥9):

 1  1  1  1  1
 1  2  3  4  5
 1  3  6  9 14
 1  4  9 18 32
 1  5 14 32 63

Os dois valores incorretos restantes, e 63, podem ser traduzidos usando o átomo de Jelly e os índices da página de código com .32.63.y“ ı?0‘y

’ScḢƊ_:¥9“ ı?0‘y - Link: list of integers [r, s]
’                - decrement              [r-1, s-1]
    Ɗ            - last 3 links as a monad i.e. f([r-1, s-1]):
 S               -   sum                  r-1+s-1 = r+s-2
   Ḣ             -   head                 r-1
  c              -   binomial             r+s-2 choose r-1
        9        - literal nine
       ¥         - last 2 links as a dyad i.e. f(r+s-2 choose r-1, 9):
      :          -   integer division     (r+s-2 choose r-1)//9
     _           -   subtract             (r+s-2 choose r-1)-((r+s-2 choose r-1)//9)
         “ ı?0‘  - code-page index list   [32,25,63,48]
               y - translate              change 32->25 and 63->48

Se você pode configurá-lo para qualquer número que eu recomendo 43 como conjecturado por McKay, Radziszowski e Exoo;)
QWR

2

Python 2 , 62 bytes

def f(c):M=max(c);u=M<5;print[48,25-u*7,3*M+~u-u,M,1][-min(c)]

Experimente online!


Python 2 , 63 bytes

def f(c):M=max(c);print[48,M%2*7+18,3*~-M+2*(M>4),M,1][-min(c)]

Experimente online!

Isso é ridículo, em breve me arrependo de ter postado isso ... Mas eh, ¯ \ _ (ツ) _ / ¯. Raspou 1 byte graças ao nosso tipo Jonathan Allan :). Provavelmente será superado em cerca de 20 bytes em breve ...



2

Julia 0.6 , 71 61 59 57 bytes

A->((r,s)=sort(A);r<3?s^~-r:3r+(s^2-4s+3)*((r==s)+r-2)-3)

Experimente online!

Ungolfed (bem, um pouco mais legível):

function f_(A)
  (r, s) = sort(A)

  if r < 3
    result = s^(r-1)
  else
    result = 3*r + 
               (s^2 - 4*s + 3) * ((r == s) + r - 2) -
               3
  end

  return result
end

O que isso faz?

Recebe a entrada como uma matriz Acontendo re es. Descompacta a matriz em re es com o número menor como r, usando(r,s)=sort(A) .


sr-1s0 0=1s1=s
r<3?s^(r-1)r<3?s^~-r

Para os outros, comecei percebendo que a saída é:

  • 2×3+[0 0,3,8]
  • 2×4+  [10,17] (para s = 4, 5 respectivamente)
  • 2×5+     [35]

(Inicialmente trabalhei com f (5,5) = 45 por conveniência.)

Parecia um padrão potencialmente utilizável - todos eles têm 2rem comum, 17 é 8 * 2 + 1, 35 é 17 * 2 + 1, 10 é 3 * 3 + 1. Comecei com a extração do valor base de [0, 3, 8], pois [0 3 8][s-2](mais tarde isso se tornou mais curto (s^2-4s+3)).

A tentativa de obter valores corretos para r = 3, 4 e 5 com isso passou por vários estágios, incluindo

2r+[0 3 8][s-2]*(r>3?3-s+r:1)+(r-3)^3+(r>4?1:0)

e

2r+(v=[0 3 8][s-2])+(r-3)*(v+1)+(r==s)v

Expandir o último e simplificá-lo levou ao código publicado.


2

x86, 49 37 bytes

Não é muito otimizado, apenas explorando as propriedades das três primeiras linhas da tabela. Enquanto escrevia isso, percebi que o código é basicamente uma tabela de salto, portanto uma tabela de salto poderia salvar muitos bytes. Entrada eaxe ebxsaída em eax.

-12 combinando casos de r >= 3em uma tabela de pesquisa (originalmente apenas r >= 4) e usando a sugestão de Peter Cordes de cmp/ jae/ jnecom os sinalizadores ainda configurados para que r1,r2,r3sejam distinguidos por apenas um cmp! Também indexando na tabela de maneira inteligente usando um deslocamento constante.

start:
        cmp     %ebx, %eax
        jbe     r1
        xchg    %eax, %ebx              # ensure r <= s

r1:
        cmp     $2, %al             
        jae     r2                      # if r == 1: ret r
        ret

r2:     
        jne     r3                      # if r == 2: ret s 
        mov     %ebx, %eax
        ret

r3:
        mov     table-6(%ebx,%eax),%al  # use r+s-6 as index
        sub     %al, %bl                # temp = s - table_val
        cmp     $-10, %bl               # equal if s == 4, table_val == 14
        jne     exit
        add     $4, %al                 # ret 18 instead of 14 

exit:
        ret                        

table:
        .byte   6, 9, 14, 25, 43

Hexdump

00000507  39 d8 76 01 93 3c 02 73  01 c3 75 03 89 d8 c3 8a  |9.v..<.s..u.....|
00000517  84 03 21 05 00 00 28 c3  80 fb f6 75 02 04 04 c3  |..!...(....u....|
00000527  06 09 0e 19 2b                                    |....+|

2
Não tenha certeza de que uma mesa de salto seria ideal. r1: cmp $2, %al/ jae r2definirá sinalizadores para que você possa usar r2: jne r3sem outro cmp. O alvo do salto r1pode estar retem outro lugar e cair para r2. (Inverta a condição). BTW, esta é a primeira pergunta sobre código-golfe que eu examinei depois de responder à sua pergunta sobre o uso da tabela de deslocamento de salto curto no SO. Eu acho que eu escolhi o caminho certo a partir HNQ :)
Peter Cordes

1
r4pode ser uma instrução: mov table-8(%ebx,%eax), %al. IDK: por que você usou uma instrução separada para mover o endereço da tabela para um registro? Mas uma das principais coisas é que deslocamentos constantes de símbolos não custam nada extra, pois já são montados em um endereço absoluto de 32 bits. Formatos de arquivo objeto pode representar refs símbolo com um deslocamento para quando os preenchimentos vinculador no endereço final para compiladores não tem que colocar rótulos separados em todos os campos de uma estrutura, ou cada elemento da matriz ...
Peter Cordes

@ PeterCordes Eu nem percebi que isso fazia HNQ. E sim, por algum motivo, pensei que o endereço da tabela estivesse em um registro antes de perceber que a sintaxe estava errada. Corrigi -o aqui codegolf.stackexchange.com/a/168503/17360, que é apenas uma tabela de pesquisa. Mas eu não sabia sobre o deslocamento constante, o que é útil. Acho que vou tentar uma tabela para as últimas 3 linhas em vez da multiplicação.
Qd #

1
Nota para si mesmo: ainda é possível economizar 1 byte usando um retpara r1 e r2.
Qr19

1
Atualização agradável, parece ser bom. E se você mover o mov %ebx, %eaxpara exit, para que ele sempre corra atrás de r3 e r2 salte para lá ou caia em r3? Então r3 produz seu resultado em BL com sub %bl, %al/ cmp $10, %al/ jne exit/ add $4, %bl(alteração de tamanho neutro: cmp vs. add pode usar a forma abreviada imm8). O ganho é que ele também remove o retR2. Hmm não, isso não funciona, bem, talvez se você negar as entradas da tabela ou algo assim? E isso provavelmente derruba algo que você precisa. Eu não pensei sobre isso e, infelizmente, não tenho tempo para fazê-lo: /
Peter Cordes


1

MATL, 25 21 bytes

+2-lGqXnt8/k-t20/k6*-

Experimente no MATL Online

Tente portar a resposta Jelly de Jonathan Allan para o MATL.

+2-lGqXn - o mesmo que a resposta: calcular (r+s-2r-1)

t8/k - duplicar isso, dividir por 8 e andar

- - subtraia isso do resultado anterior (subtraímos quantas vezes 8 vai no número, em vez de 9 na resposta Jelly. O resultado é o mesmo para todos, exceto os 35 e 70, que aqui dão 31 e 62.)

t20/k - duplique esse resultado também, divida-o por 20 e reduza (dá 0 para resultados já corretos, 1 para 31, 3 para 62)

6* - multiplique isso por 6

- - subtraia isso do resultado (31 - 6 = 25, 62 - 18 = 44)


Mais velho:

+t2-lGqXntb9<Q3w^/k-t20>+

Experimente no MATL Online




0

Java 8, 62 bytes

(r,s)->--r*--s+new int[]{9,1,0,13,2,0,3,27,6}[r<2|s<2?1:r*s%9]

Função Lambda, porta da resposta JavaScript de Arnauld . Experimente online aqui .

Java, 83 bytes

int f(int x,int y){return x<2|y<2?1:f(x,y-1)+f(x-1,y)-(x*y==12?1:0)-7*(x+y>8?1:0);}

Função recursiva, porta da resposta JavaScript de Neil . Experimente online aqui .


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.