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.