Dies ist eine Version der letzten Herausforderung. Ist diese Zahl eine ganzzahlige Potenz von -2? mit einem anderen Satz von Kriterien, um die interessante Natur des Problems hervorzuheben und die Herausforderung zu erschweren. Ich habe einige Überlegungen in sie hier .
Die Herausforderung, die Toby in der verknüpften Frage so wunderbar formuliert hat, ist:
Es gibt clevere Methoden, um festzustellen, ob eine Ganzzahl eine exakte Potenz von 2 ist. Das ist kein interessantes Problem mehr. Lassen Sie uns also feststellen, ob eine bestimmte Ganzzahl eine exakte Potenz von -2 ist . Beispielsweise:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Regeln:
- Eine Ganzzahl ist 64 Bit, vorzeichenbehaftet, Zweierkomplement. Dies ist der einzige Datentyp, mit dem Sie arbeiten können.
- Sie dürfen nur die folgenden Vorgänge ausführen. Jede davon zählt als eine Operation.
n << k
,n >> k
: Links- / Rechtsverschiebungn
umk
Bits. Vorzeichenbit wird bei Rechtsverschiebung verlängert.n >>> k
: Rechtsverschiebung, aber Vorzeichenbit nicht verlängern. Nullen werden verschoben.a & b
,a | b
,a ^ b
: Logisches AND, OR, XOR.a + b
,a - b
,a * b
Addieren, subtrahieren, multiplizieren.~b
: Bitweise invertieren.-b
: Zweierkomplement-Negation.a / b
,a % b
: Dividieren (ganzzahliger Quotient, rundet in Richtung 0) und Modulo.- Das Modulo negativer Zahlen verwendet die in C99 angegebenen Regeln :
(a/b) * b + a%b
muss gleich seina
. So5 % -3
ist2
und-5 % 3
ist-2
: 5 / 3
ist1
,5 % 3
ist2
, als 1 * 3 + 2 = 5.-5 / 3
ist-1
,-5 % 3
ist-2
, als -1 * 3 + -2 = -5.5 / -3
ist-1
,5 % -3
ist2
, als -1 * -3 + 2 = 5.-5 / -3
ist1
,-5 % -3
ist-2
, als 1 * -3 + -2 = -5.- Beachten Sie, dass der
//
Floor Division Operator von Python die Divisionseigenschaft "round towards 0" hier%
nicht erfüllt und der Operator von Python auch nicht die Anforderungen erfüllt.
- Das Modulo negativer Zahlen verwendet die in C99 angegebenen Regeln :
- Aufträge zählen nicht als Vorgang. Wie in C werden Zuweisungen nach der Zuweisung mit dem Wert auf der linken Seite bewertet:
a = (b = a + 5)
setztb
aufa + 5
, setzta
aufb
und zählt als eine Operation. - Verbindung Zuordnungen verwendet werden
a += b
Mittela = a + b
und als eine Operation zählen.
- Sie können Integer-Konstanten verwenden, sie zählen nicht als etwas.
- Klammern zur Angabe der Operationsreihenfolge sind zulässig.
- Sie können Funktionen deklarieren. Funktionsdeklarationen können in jedem für Sie geeigneten Stil vorliegen. Beachten Sie jedoch, dass 64-Bit-Ganzzahlen der einzige gültige Datentyp sind. Funktionsdeklarationen gelten nicht als Operationen, sondern eine Funktion Anruf zählt. Um auch klar zu sein: Funktionen können mehrere
return
Anweisungen enthalten und sindreturn
von jedem Punkt aus erlaubt. Dasreturn
selbst zählt nicht als Operation. - Sie können Variablen kostenlos deklarieren.
- Sie können
while
Schleifen verwenden, jedoch nichtif
oderfor
. In derwhile
Bedingung verwendete Operatoren zählen zu Ihrer Punktzahl.while
Schleifen werden ausgeführt, solange ihre Bedingung einen Wert ungleich Null ergibt (eine "wahrheitsgemäße" 0 in Sprachen mit diesem Konzept ist kein gültiges Ergebnis). Seit früh Rückkehr erlaubt ist, werden Sie nutzenbreak
als auch - Überlauf / Unterlauf ist erlaubt und es erfolgt keine Werteklemmung. Es wird so behandelt, als ob die Operation tatsächlich korrekt ausgeführt und dann auf 64 Bit gekürzt wurde.
Bewertungskriterien / Gewinnkriterien:
Ihr Code muss einen Wert ungleich Null erzeugen, wenn die Eingabe eine Potenz von -2 ist, und ansonsten Null.
Das ist Atomic-Code-Golf . Ihre Punktzahl ist die Gesamtzahl der in Ihrem Code vorhandenen Vorgänge (wie oben definiert), nicht die Gesamtzahl der Vorgänge, die zur Laufzeit ausgeführt werden. Der folgende Code:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Enthält 5 Operationen: zwei in der Funktion und drei Funktionsaufrufe.
Es spielt keine Rolle, wie Sie Ihr Ergebnis präsentieren, was auch immer in Ihrer Sprache angezeigt wird, ob Sie das Ergebnis letztendlich in einer Variablen speichern, von einer Funktion zurückgeben oder was auch immer.
Der Gewinner ist der Beitrag, der nachweislich korrekt ist (ggf. einen beiläufigen oder formellen Beweis vorlegen) und die niedrigste Punktzahl aufweist, wie oben beschrieben.
Bonus Very Hard Mode Challenge!
Senden Sie eine Antwort, ohne while
Schleifen zu verwenden, um eine Chance zu haben, absolut nichts zu gewinnen, außer die potenzielle Fähigkeit, Leute auf Partys zu beeindrucken ! Wenn genug von diesen eingereicht werden, kann ich sogar in Betracht ziehen, die Gewinnergruppen in zwei Kategorien (mit und ohne Schleifen) zu unterteilen.
Hinweis: Wenn Sie eine Lösung in einer Sprache bereitstellen möchten, die nur 32-Bit-Ganzzahlen unterstützt, können Sie dies tun, sofern Sie hinreichend begründen, dass dies für 64-Bit-Ganzzahlen in einer Erläuterung weiterhin korrekt ist.
Außerdem: Bestimmte sprachspezifische Funktionen sind möglicherweise kostenlos zulässig, wenn sie sich nicht den Regeln widersetzen, aber erforderlich sind, um Ihre Sprache dazu zu zwingen, sich gemäß den obigen Regeln zu verhalten . Zum Beispiel (erfunden), erlaube ich ein freies entspricht nicht 0 Vergleich in while
Schleifen, wenn die Bedingung als Ganze angewandt, als Behelfslösung für eine Sprache , die „truthy“ 0 hat. Eindeutige Versuche, diese Art von Dingen auszunutzen, sind nicht zulässig - z. B. gibt es in dem obigen Regelsatz kein Konzept für "wahrheitsgemäße" 0- oder "undefinierte" Werte, und daher kann man sich möglicherweise nicht auf sie verlassen.
m ^= s
es ist immer noch beeindruckend, und ich denke, es wäre völlig in Ordnung, den Ersatz zu machen, um es noch weiter zu verbessern.
while
und break
nicht if
? if (x) { ... }
ist äquivalent zu while (x) { ... break; }
.
break
und frühe Renditen sind der bedauerliche Teil) und ist eine lange Geschichte und eine Lektion in Regeln für zukünftige Herausforderungen. Es gibt immer die "Bonus" -Version! :)
if
und for
sind nicht erlaubt? int x=condition; while (x) { ... x=0; }
ist kostenlos, nur mehr Code. Das Gleiche gilt für C-Style for
.