Kürzester Ausdruck für {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}

24

Gegebene Liste von ganzen Zahlen {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}. Für Interessenten werden diese Zahlen in der Wochentagsberechnung verwendet.

Wochentag = (m[n] + d + y + y>>2 + y/400 - y/100) % 7;, wo m[n]- Ausdruck ich suche, d- Tag des Monats, y- year - (month <= 2).

Konstruieren Sie einen Ausdruck, der aus arithmetischen, logischen und bitweisen Operatoren besteht, die für eine positive ganze nZahl ausgegeben werden, msodass die m % 7n-te Zahl in der Liste entspricht.

Verzweigungen, ternäre Operatoren, Tabellensuchen und Zeiger sind nicht zulässig.

Punktzahl:
1 - für | & ^ ~ >> <<Bediener
1.1 - für + - < > <= >= == != ! && ||Bediener
1.2 - für *Bediener
1.4 - für / %Bediener

Antwort mit der niedrigsten Punktzahl gewinnt.

Persönlich habe ich gefunden:

(41*n)>>4+((n+61)>>4)<<2mit Punktzahl 6.4. Ich dachte, dass es schwierig sein wird, einen eigenen Ausdruck zu finden.

Somnium
quelle
Ich denke, Array-Dereferenzierung (und die Verwandtschaft) ist auch nicht erlaubt?
John Dvorak
Oh ja, natürlich habe ich die Frage bearbeitet.
Somnium
6
Die Frage würde durch eine gewisse Motivation erheblich verbessert. Woher kommen diese Zahlen?
Peter Taylor
table lookupsInteressante Formulierungen, nehme ich an ...
Julıɐɔuʇǝɥʇs
4
Warum nicht die% 7 in der Punktzahl zählen? Vielleicht gibt es eine andere Lösung, die% nicht verwendet. Ist Null positiv , negativ, beides oder nichts?
Thomas Weller

Antworten:

34

2 2.2

Ich liebe willkürliche Präzisionsarithmetik.

0x4126030156610>>(n<<2)

Oder, wenn du kein Hex magst,

1146104239711760>>(n<<2)

Prüfung:

print([(0x4126030156610>>(n<<2))%7 for n in range(1,13)])
[0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
isaacg
quelle
Könnten Sie vielleicht 4*nstattdessen eine Nachschlagetabelle mit erstellen und 0,2 Punkte sparen, indem Sie sie als schreiben n<<2?
Xnor
@xnor Auf jeden Fall! Nur um von oktal zu hexadezimal zu wechseln. Genauso wie sek.
isaacg
Cool. Ich bin ziemlich davon überzeugt, dass nichts besser sein kann, da es nur eine Operation erfordern würde und sie alle zu viele Strukturmodifikationen zu haben scheinen 7. Mein bester Kandidat der Integer Floor Division const/nstößt auf einen Widerspruch mit n=4und n=8.
xnor
@xnor Ein weiteres enges ist, const%ndas alles außer n = 1,2 und 3 erfüllen könnte.
isaacg
Ich wollte das Gleiche tun, aber du hast mich geschlagen ...
ɐɔı 17us
32

2,0

(127004 >> i) ^ 60233

oder (Punktzahl 2.2):

(i * 3246) ^ 130159

Alles mit roher Gewalt gefunden :-)

Arnaud
quelle
Da dies die gleiche Punktzahl wie die Antwort von isaacg hat, aber keine 64-Bit-Ganzzahlen verwendet, wähle ich diese als akzeptierte Antwort. Danke für die Antwort!
Somnium
8
@ user2992539 Obwohl es schön ist, dass diese Antwort 32-Bit-Ganzzahlen verwendet, haben Sie dieses Kriterium in Ihrer Abfrage nicht angegeben, wodurch die Antwort von isaacg vollkommen gültig ist. Daher stimmen die beiden Antworten überein, und ich denke, es ist nur fair, die erste zu akzeptieren , die diese Punktzahl erreicht hat. (Ein großes Lob an Super Chafouin, +1!)
Martin Ender
@m.buettner da muss ich dir zustimmen. Beim nächsten Mal werde ich mit der Beschreibung und der Auswahl der Antworten vorsichtiger sein.
Somnium
Können Sie anderen erläutern, wie Sie die Brute-Force-Berechnung durchgeführt haben?
Thomas Weller
@Thomas Ich habe gerade eine Doppelschleife gemacht for, indem ich alle Werte p, q für die Formel getestet habe (p >> i) ^ q, dann einen Kaffee getrunken habe und 10 Minuten später gekommen bin , um die Ergebnisse zu lesen.
Arnaud
8

35.3

Ich vermute, dass dies die am wenigsten effiziente Methode ist, um die Liste zu erstellen:

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

Ich habe gerade die polynomiale Regression berechnet. Ich bin versucht zu sehen, welche andere schreckliche Methode versucht werden könnte.

Insbesondere könnte ich 3,3 Punkte sparen, wenn das Ergebnis gerundet wäre. An diesem Punkt denke ich nicht, dass das wichtig ist.

Lochok
quelle
5

3.2

Nullbasierte Lösung:

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

Einseitige Lösung:

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

Ich dachte zunächst, dass die %7Operation mitgezählt würde und% sie hier teuer ist, habe ich versucht, sie ohne sie zu lösen.

Ich kam zu einem Ergebnis von 3.2 wie folgt:

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

Ich würde mich für Optimierungen mit diesem Ansatz interessieren (ohne %). Vielen Dank.

Thomas Weller
quelle
Das ist cool, vielleicht hilft mir das eines Tages.) Wie denkst du, sollte ich eine separate Frage für die Minimierung der gesamten Formel erstellen?
Somnium
1
Wie wäre es (0426415305230 >> (i*3)) & 7? Sie können die Ausgabestellen in umgekehrter Reihenfolge sehen.
CJ Dennis
@ CJDennis: Ich denke, es gibt keine Oktalzahlen in C #.
Thomas Weller
Ich dachte es wäre nur c? Ich kann keinen anderen Verweis auf C # sehen.
CJ Dennis
0

Python (3)

Da es heutzutage einige dieser Fragen gibt, habe ich beschlossen, ein Programm zu erstellen, um sie automatisch in 3 (oder 2) Token zu lösen. Hier ist das Ergebnis für diese Herausforderung:

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

Beweis, dass dies funktioniert:

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
ɐɔıɐɔuʇǝɥʇs
quelle
Wie bewertet Ihr Löser die Kosten von Operanden?
Thomas Weller
@ThomasW. Tut es nicht, es wird immer eine Rechtsverschiebung, möglicherweise eine Linksverschiebung (wenn die Werte nicht 1 Bit sind) und ein &.
Julıɐɔuʇǝɥʇs