Piccoli numeri Ramsey


13

Sfondo: il numero di Ramsey indica il numero minimo di vertici nel grafico completo tale che una colorazione del bordo rosso / blu di abbia almeno un rosso o un K_s blu . I limiti per r più grandi sono molto difficili da stabilire.v K v K v K r K s r , sR(r,s)vKvKvKrKsr,s

Il tuo compito è quello di produrre il numero R(r,s) per 1≤r,s≤5 .

Ingresso

Due numeri interi r,s con 1≤r≤5 e 1≤s≤5 .

Produzione

R(r,s) come indicato in questa tabella:

  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

Si noti che e sono intercambiabili: .s R ( r , s ) = R ( s , r )rsR(r,s)=R(s,r)

Per è possibile produrre un numero intero compreso tra e , inclusi. Al momento della pubblicazione di questa domanda, questi sono i limiti più noti.43 48R(5,5)4348


Penso (anche con la gamma per 5,5) che questo possa rientrare nella complessità del kolmogorov (o che si adatti solo un output fisso, non in input?)
— Jonathan Allan,

Quando sono stati esclusi 49 per R (5,5)? (Non sono impegnativo; sembra che mi sia sfuggito un articolo dopo quello di Exoo, McKay e Radziszowski.)
— Eric Towers,


@qwr: grazie! Mi sto divertendo finora.
— Eric Towers,

Risposte:


7

JavaScript (ES6), 51 49 byte

Accetta input nella sintassi del curry (r)(s).

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

Provalo online!

Come?

Come prima approssimazione, usiamo la formula:

(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 abbiamo , aggiungiamo semplicemente :min(r,s)<31

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

Altrimenti, aggiungiamo un valore scelto da una tabella di ricerca la cui chiave è definita da: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

Bello, le prime due righe sono un'espressione ordinata.
— qwr,

5

JavaScript (Node.js) , 56 55 byte

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

Provalo online! Ho notato che la tabella ricorda il triangolo di Pascal ma con fattori di correzione. Modifica: salvato 1 byte grazie a @sundar.


1
Sì, l'identità del triangolo di Pascal deriva da un semplice limite superiore sui numeri di Ramsey (vedi il post di Jonathan Allan)
— qwr

1
È possibile salvare 1 byte sostituendolo x*y>19con x+y>8.
— Sundar - Ripristina Monica il

@sundar Grazie, la mia soluzione originale era di 50 byte prima di rendermi conto che la mia indicizzazione era sbagliata e ho dimenticato di provare a giocare di nuovo dopo averlo risolto.
— Neil,

4

Gelatina ,  17  16 byte

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

Provalo online! O vedi una suite di test .

Sostituire il 0con +, ,, -, ., o /per set pari a 43 , 44 , 45 , 46 , o 47, rispettivamente (anziché 48 qui).R(5,5)434445464748

Come?

Poiché possiamo scoprire che:R(r,S)≤R(r-1,S)+R(r,S-1)

R(r,S)≤(r+S-2r-1)

Questo è ’ScḢƊe produrrebbe:

 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 ne sottraggiamo uno per ogni volta che nove entrano nel risultato ne allineiamo altri tre con il nostro obiettivo (questo si ottiene con _:¥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

I restanti due valori errati, e 63 possono quindi essere tradotti usando gli indici atomici e code-page di Jelly con .3263y“ ı?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 riesci a impostarlo su qualsiasi numero, ti consiglio 43 come ipotizzato da McKay, Radziszowski ed Exoo;)
— qwr

2

Python 2 , 62 byte

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

Provalo online!


Python 2 , 63 byte

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

Provalo online!

È ridicolo, mi pentirò presto di aver postato questo ... Ma eh, ¯ \ _ (ツ) _ / ¯. Rasato di 1 byte grazie al nostro gentile Jonathan Allan :). Probabilmente sarà superato di circa 20 byte a breve però ...



2

Julia 0.6 , 71 61 59 57 byte

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

Provalo online!

Ungolfed (beh, un po 'più leggibile):

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

Che cosa fa?

Accetta input come array Acontenente r e s. Scompone l'array in r e s con il numero più piccolo come r, usando (r,s)=sort(A).


Sr-1S0=1S1=S
r<3?s^(r-1)r<3?s^~-r

Per gli altri, ho iniziato notando che l'output è:

  • 2×3+[0,3,8]
  • 2×4+  [10,17]
  • 2×5+     [35]

(Inizialmente ho lavorato con f (5,5) = 45 per comodità.)

Sembrava un modello potenzialmente utilizzabile: hanno tutti 2rin comune, 17 è 8 * 2 + 1, 35 è 17 * 2 + 1, 10 è 3 * 3 + 1. Ho iniziato con l'estrazione del valore di base da [0, 3, 8], come [0 3 8][s-2](in seguito è diventato il più breve (s^2-4s+3)).

Il tentativo di ottenere valori corretti per r = 3, 4 e 5 con questo ha attraversato molte fasi, tra cui

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

L'espansione di quest'ultimo e la sua semplificazione hanno portato al codice pubblicato.


2

x86, 49 37 byte

Non molto ottimizzato, solo sfruttando le proprietà delle prime tre righe della tabella. Mentre stavo scrivendo questo mi sono reso conto che il codice è sostanzialmente una tabella di salto, quindi una tabella di salto potrebbe salvare molti byte. Input in eaxe ebx, output in eax.

-12 combinando casi di r >= 3in una tabella di ricerca (originariamente solo r >= 4) e usando il suggerimento di Peter Cordes di cmp/ jae/ jnecon le bandiere ancora impostate in modo che r1,r2,r3si distinguano per una sola cmp! Indicizza anche in modo intelligente la tabella usando un offset costante.

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
Non essere così sicuro che una tabella di salto sarebbe ottimale. r1: cmp $2, %al/ jae r2imposterà i flag in modo che tu possa usarli r2: jne r3senza un altro cmp. Il bersaglio del salto in r1può essere un retaltro posto e cadere r2. (Invertire la condizione). A proposito, questa è la prima domanda di code-golf che ho visto dopo aver risposto alla tua domanda sull'utilizzo della tabella di offset a salto corto su SO. Immagino di aver scelto quello giusto da HNQ :)
— Peter Cordes,

1
r4può essere una sola istruzione: mov table-8(%ebx,%eax), %al. IDK perché hai usato un'istruzione separata per spostare l'indirizzo della tabella in un registro. Ma una delle cose chiave è che gli offset costanti dai simboli non costano nulla in più perché si assembla già in un indirizzo assoluto a 32 bit. I formati di file oggetto possono rappresentare i riferimenti a simboli con un offset per quando il linker inserisce l'indirizzo finale in modo che i compilatori non debbano mettere etichette separate su ogni campo di una struttura o su ogni elemento dell'array ...
— Peter Cordes

@PeterCordes Non mi ero nemmeno reso conto di questo fatto HNQ. E sì, per qualche motivo, ho pensato che l'indirizzo della tabella dovesse essere in un registro prima di rendermi conto che avevo la sintassi sbagliata. L'ho corretto qui codegolf.stackexchange.com/a/168503/17360 che è solo una tabella di ricerca. Ma non sapevo dell'offset costante che è utile. Penso che proverò una tabella per le ultime 3 righe invece della moltiplicazione.
— qwr,

1
Nota per sé: è ancora possibile salvare 1 byte usando uno retper r1 e r2.
— qwr

1
Bel aggiornamento, sembra buono. Che cosa succede se sposti il mov %ebx, %eaxto exit, quindi corre sempre dopo r3 e r2 salta lì o cade in r3? Quindi r3 produce il suo risultato in BL con sub %bl, %al/ cmp $10, %al/ jne exit/ add $4, %bl(il cambio di dimensione neutra: cmp vs. add può usare la forma breve al, imm8). Il vantaggio è che rimuove anche retda r2. Hmm no che non funziona, bene forse se neghi le voci della tabella o qualcosa del genere? E questo probabilmente blocca qualcosa di cui hai bisogno. Non ci ho pensato e sfortunatamente non ho tempo per farlo: /
— Peter Cordes,


1

MATL, 25 21 byte

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

Provalo su MATL online

Tentativo di eseguire il porting della risposta Jelly di Jonathan Allan a MATL.

+2-lGqXn - uguale a quella risposta: calcolare (r+S-2r-1)

t8/k - duplicalo, dividi per 8 e piano

- - sottrai quello dal risultato precedente (Sottraiamo quante volte 8 va nel numero, invece di 9 nella risposta Jelly. Il risultato è lo stesso per tutti tranne 35 e 70, che qui danno 31 e 62.)

t20/k - duplicare anche quel risultato, dividerlo per 20 e floor (dà 0 per risultati già corretti, 1 per 31, 3 per 62)

6* - moltiplicalo per 6

- - sottrai quello dal risultato (31-6 = 25, 62-18 = 44)


Più vecchio:

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

Provalo su MATL online




0

Java 8, 62 byte

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

Funzione Lambda, porta della risposta JavaScript di Arnauld . Provalo online qui .

Java, 83 byte

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);}

Funzione ricorsiva, porta della risposta JavaScript di Neil . Provalo online qui .


0

C (gcc), 57 byte

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

Funzione ricorsiva, porta della risposta JavaScript di Neil . Provalo online qui .

C (gcc), 63 byte

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

La risposta JavaScript di Port of Arnauld . Provalo online qui .


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.