Espressione più breve per {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}


24

Elenco di numeri interi {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}. Per coloro che sono interessati questi numeri vengono utilizzati nel calcolo dei giorni feriali.

Weekday = (m[n] + d + y + y>>2 + y/400 - y/100) % 7;, dove m[n]- espressione che sto cercando, d- giorno del mese, y- year - (month <= 2).

Costruisci un'espressione composta da operatori aritmetici, logici e bit per bit, che produrrà un numero nintero positivo in mmodo che sia m % 7uguale all'n-esimo numero nell'elenco.

Non sono consentiti rami, operatori ternari, ricerche di tabella e puntatori.

Punteggio:
1 - per gli | & ^ ~ >> <<operatori
1.1 - per gli + - < > <= >= == != ! && ||operatori
1.2 - per gli *operatori
1.4 - per gli / %operatori

Rispondi con il punteggio più basso vince.

Personalmente ho trovato:

(41*n)>>4+((n+61)>>4)<<2con punteggio 6.4. Ho pensato che sarebbe stato difficile trovare un'espressione così fornita per cominciare.


Suppongo che la dereferenziazione dell'array (e la parentela) non sia consentita?
John Dvorak,

Oh, sì, certo, ho modificato la domanda.
Somnium,

6
La domanda sarebbe notevolmente migliorata da qualche motivazione. Da dove vengono quei numeri?
Peter Taylor,

table lookups
Frase

4
Perché non contare% 7 nel punteggio? Forse c'è un'altra soluzione che non utilizza%. Lo zero è positivo , negativo, entrambi o niente?
Thomas Weller,

Risposte:


34

2 2.2

Adoro l'aritmetica di precisione arbitraria.

0x4126030156610>>(n<<2)

Oppure, se non ti piace hex,

1146104239711760>>(n<<2)

Test:

print([(0x4126030156610>>(n<<2))%7 for n in range(1,13)])
[0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]

Potresti forse creare una tabella di ricerca con 4*ne salvare 0,2 punti scrivendola come n<<2?
xnor

@xnor Absolutely! Solo per passare dall'ottale all'esadecimale. Proprio come il sec.
Isaacg,

Freddo. Sono abbastanza convinto che nulla possa fare di meglio perché richiederebbe l'utilizzo di una sola operazione, e tutti sembrano avere troppe modifiche alla struttura 7. Il mio miglior candidato per la divisione dei piani interi si const/nscontra con n=4e n=8.
xnor

@xnor Un altro vicino è const%nche potrebbe soddisfare tutto tranne n = 1,2 e 3.
isaacg

Avrei fatto la stessa cosa, ma mi hai battuto ...
ɐɔıʇǝɥʇuʎs

32

2.0

(127004 >> i) ^ 60233

oppure (punteggio 2.2):

(i * 3246) ^ 130159

Tutto trovato con forza bruta :-)


Dato che questo ha lo stesso punteggio della risposta di isaacg, ma non usa numeri interi a 64 bit, sto scegliendo questo come risposta accettata. Grazie per la risposta!
Somnium,

8
@ user2992539 Sebbene sia bello che questa risposta utilizzi numeri interi a 32 bit, non hai specificato questo criterio nella tua sfida, il che rende la risposta di isaacg perfettamente valida. Pertanto, le due risposte pareggiano e penso che sia giusto accettare il primo che ha ottenuto questo punteggio. (Complimenti a Super Chafouin, però, +1!)
Martin Ender,

@ m.buettner Sono d'accordo con te. La prossima volta, starò più attento con la descrizione e la selezione della risposta.
Somnium,

Per gli altri, potresti approfondire come hai fatto il calcolo della forza bruta?
Thomas Weller,

@Thomas Ho appena fatto un doppio forgiro, testando tutti i valori p, q per la formula (p >> i) ^ q, poi sono andato a prendere un caffè e 10 minuti dopo sono venuto a leggere i risultati.
Arnaud,

8

35.3

Sospetto che questo potrebbe essere il metodo meno efficiente per creare l'elenco:

1.7801122128869781e+003 * n - 
1.7215267321373362e+003 * n ^ 2 + 
8.3107487075415247e+002 * n ^ 3 - 
2.0576746235987866e+002 * n ^ 4 + 
1.7702949291688071e+001 * n ^ 5 + 
3.7551387326116981e+000 * n ^ 6 - 
1.3296432299817251e+000 * n ^ 7 + 
1.8138635864087030e-001 * n ^ 8 - 
1.3366764519057219e-002 * n ^ 9 + 
5.2402527302299116e-004 * n ^ 10 - 
8.5946393615396631e-006 * n ^ 11 -
7.0418841304671321e+002

Ho appena calcolato la regressione polinomiale. Sono tentato di vedere quale altro terribile metodo potrebbe essere tentato.

In particolare, potrei risparmiare 3,3 punti se il risultato fosse arrotondato. A questo punto, non penso che sia importante.


5

3.2

Soluzione a base zero:

7 & (37383146136 >> (i*3))

Una soluzione basata:

7 & (299065169088 >> (i*3))

Inizialmente pensavo che anche l' %7operazione sarebbe stata conteggiata ed %essendo un'operazione costosa qui, ho provato a risolverlo senza di essa.

Sono arrivato a un risultato di 3.2 come questo:

// Construction of the number
// Use 3 bits per entry and shift to correct place
long c = 0;
int[] nums = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
for (int i = nums.Length - 1; i >= 0; i--)
{
    c <<= 3;
    c += nums[i];
}
// c = 37383146136

// Actual challenge
for (int i = 0; i < 13; i++)
{
    Console.Write("{0} ",7 & 37383146136 >> i*3);
}

Sarei interessato alle ottimizzazioni usando questo approccio (senza %). Grazie.


Questo è bello, forse questo mi aiuterà un giorno) Come pensi, forse dovrei creare una domanda separata per la minimizzazione dell'intera formula?
Somnium,

1
Che ne dici (0426415305230 >> (i*3)) & 7? È possibile visualizzare le cifre in uscita in ordine inverso.
CJ Dennis,

@CJDennis: Penso che non ci siano numeri ottali in C #.
Thomas Weller,

Pensavo fosse solo C? Non riesco a vedere nessun altro riferimento a C #.
CJ Dennis,

0

Python (3)

Dato che oggigiorno ci sono alcune di queste domande, ho deciso di creare un programma per risolverle automaticamente in 3 (o 2) token. Ecco il risultato per questa sfida:

G:\Users\Synthetica\Anaconda\python.exe "C:/Users/Synthetica/PycharmProjects/PCCG/Atomic golfer.py"
Input sequence: 0 3 2 5 0 3 5 1 4 6 2 4
f = lambda n: (72997619651120 >> (n << 2)) & 15
f = lambda n: (0x426415305230L >> (n << 2)) & 15
f = lambda n: (0b10000100110010000010101001100000101001000110000 >> (n << 2)) & 15

Process finished with exit code 0

Prova che funziona:

f = lambda n: (72997619651120 >> (n << 2)) & 15

for i in range(12):
   print i, f(i)

0 0
1 3
2 2
3 5
4 0
5 3
6 5
7 1
8 4
9 6
10 2
11 4

In che modo il tuo risolutore considera il costo degli operandi?
Thomas Weller,

@ThomasW. Non lo farà, utilizzerà sempre uno spostamento a destra, possibilmente uno a sinistra (se i valori non sono 1 bit) e un &.
Julıʇǝɥʇuʎs
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.