Aufgabenbeschreibung
Tauschen Sie bei einer Ganzzahl das (2k – 1) -te und das 2k -te niedrigstwertige Bit für alle Ganzzahlen k> 0 aus . Dies ist die Sequenz A057300 im OEIS.
(Es wird angenommen, dass die Zahl "unendlich viele" führende Nullen hat. In der Praxis bedeutet dies einfach, ein einzelnes 0-Bit vor Zahlen ungerader Länge zu setzen.)
Das ist Code-Golf , also gewinnt der kürzeste Code (in Bytes).
Testfälle
0 -> 0
1 -> 2
9 -> 6
85 -> 170
220 -> 236
1827 -> 2835
47525 -> 30298
unsigned char array_of_bytes[1024]
wie erwartet funktionieren (dh ein Bitfeld mit 1024 *CHAR_BIT
Einträgen sein). Ich würde mir vorstellen, dass die meisten Antworten, die Eingaben beliebiger Länge unterstützen,CHAR_BIT
gerade sind, da das Verschieben von Bits zwischen Bytes umständlich ist. Sie können also durchausk
verlangen, dass bis zu einer konstanten Größe wie 256 oder etwas, das für AES angemessen ist, unterstützt wird, und Sprachen ohne 256-Bit-Integer-Typen müssten Schleifen verwenden. Das könnte SIMD-Vektoren für eine x86-asm-Antwort in Betracht ziehen: PAntworten:
Jelly ,
1097 BytesProbieren Sie es online! oder überprüfen Sie alle Testfälle .
Wie es funktioniert
quelle
Python 2, 26 Bytes
Bit-Tricks!
Sprich
n
hat Form...ghfedcba
in binär. Dann können wir es in zwei Teile aufteilenDann kann das bitvermittelte Ergebnis
s
ausgedrückt werden alss=2*o+e
.Wir wollen lieber nur eines von
e
und berechneno
, also drücken wir auso=n-2*e
und ersetzenSo, jetzt bleibt es
e
in Bezug auf auszudrückenn
. Die ZahlM=4**n/3
hat eine...10101010101
binäre Form , die als Maske für die ungeraden Ziffern dient. Der Exponentn
sorgt dafür, dassM
das lang genug ist. Das bitweise Nehmenand
vonn/2
und dieser Wert ergibte
wie gewünscht.Wir können stattdessen
e
in Begriffen ausdrückeno
e=(n-o)/2
, was gibts=(n+o*3)/2
, was dank einer Optimierung von xsot ein Byte spart.quelle
n
. Ich bevorzuge jedoch die entgegengesetzte "ungerade" oder "gerade" Bitbenennungskonvention. Das LSB ist Bit 0, das gerade ist (obwohl es das erste Bit ist). Bei der SIMD-Programmierung, bei der Shuffles häufig Elemente mit einem Index auswählen, werden die Indizes von 0 an gezählt. Daher ist es normal, das niedrige Element als gerade Elemente zu betrachten. zB[ 3 2 1 0 ]
lambda n:n+(n&4**n/3)*3>>1
f(x){return x+((x&~0U/3)*3)>>1;}
Gibt 1 für Eingabe 2 zurück .calc
(aka apcalc) getestet, nicht in C. Ich dachte, ich wäre in Ordnung, da ich keine Kürzung auf 32-Bit oder das Zweierkomplement benötigte. Ich dachte nicht, dass der Ausdruck richtig aussah, also war ich bereit, meine falschen Tests zu glauben. Trotzdem brauche ich eine bessere REPL für die Entwicklung von Bithacks. Irgendwelche Vorschläge? (Idealerweise Linux-Befehlszeile, wiebc -l
odercalc
, aber tatsächlich verfügbar machenint32_t
/uint32_t
oder etwas, nicht erweiterte Präzision.)C-Funktion, 38
Bit-Twiddling:
Ideone.
Oder zum Spaß:
C rekursive Funktion, 43
Gemäß der OEIS Formel ,
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
oder
Ideone.
quelle
CJam,
161413 BytesTeste es hier.
Erläuterung
quelle
Pyth, 9 Bytes
Probieren Sie es im Pyth-Compiler aus .
Wie es funktioniert
quelle
JavaScript (ES6),
32-30BytesFunktioniert aufgrund der Einschränkungen der JavaScript-Ganzzahlen nur bis 1073741823.
3836 Bytes funktioniert bis zu 4294967295:Bearbeiten: 2 Bytes dank @ user81655 gespeichert.
51 Bytes funktioniert bis zu 4503599627370495:
quelle
n<<1
seinn*2
?n/2
! Ich weiß nicht, warum ich vorher nicht daran gedacht habe.>>>
... was ist das?>>>
aber es macht eine vorzeichenlose Verschiebung.>>>0
Grundsätzlich wird in eine 32-Bit-Ganzzahl ohne Vorzeichen konvertiert.x86 asm-Funktion: 14 Byte Maschinencode
uint64_t version: 24 bytes
x86-64-SysV-Aufrufkonvention (
x
inedi
), aber dieser Computercode funktioniert auch im 32-Bit-Modus. (Wobei derlea
Wille als dekodiertlea eax, [edi + eax*2]
, was identische Ergebnisse ergibt ).0x4f - 0x40
= 14 BytesDies ist die Compiler-Ausgabe , wenn die einmalige Masken-Idee von xnor umgekehrt verwendet wird. (Und entgegengesetzte Terminologie: Das niedrige Bit ist Bit 0, das gerade und nicht ungerade ist.)
Ich habe keine Verbesserungen gegenüber dem Compiler gefunden. Ich hätte es vielleicht als
mov eax, 0x555...
/ geschriebenand eax, edi
, aber das ist die gleiche Länge.Dieselbe Funktion für 64-Bit-Ganzzahlen benötigt 24 Byte (siehe Godbolt-Link). Ich sehe keinen Weg, der kürzer als 10 Byte ist
movabs rax, 0x55...
, um die Maske in einem Register zu erzeugen. (Diediv
Anweisung von x86 ist klobig, daher hilft eine Division der Einsen durch drei ohne Vorzeichen nicht.)Ich habe mir eine Schleife ausgedacht, um die Maske in Rax zu generieren, aber es sind 10 Bytes (genau die gleiche Länge wie die
mov imm64
).Wenn wir wüssten, dass keines der vorhandenen Bytes
rax
sein niedriges Bit gesetzt hat, könnten wir das überspringenxor
, und dies wäre 8 Bytes lang.Eine frühere Version dieser Antwort hatte eine 10-Byte-Schleife mit dem
loop
Befehl insn, aber die Laufzeit der0xFFFFFFFFFFFFFF08
Iterationen war im schlimmsten Fall , da ich nur festgelegt habecl
.quelle
Oasis , 17 Bytes (nicht konkurrierend)
Probieren Sie es online!
Oasis ist eine Sprache von Adnan, die auf Sequenzen spezialisiert ist.
Gegenwärtig kann diese Sprache eine Rekursion und eine geschlossene Form ausführen.
Wir verwenden diese Formel:
a(4n+k) = 4a(n) + a(k), 0 <= k <= 3
Den Basisfall zu spezifizieren ist einfach: das bedeutet
3120
am Ende einfach dasa(0)=0, a(1)=2, a(2)=1, a(3)=3
.quelle
MATL , 10 Bytes
Probieren Sie es online!
Geänderte Version zur Generierung der ersten Terme der Sequenz ( OEIS A057300 ).
Erläuterung
quelle
zsh, 28 Bytes
Nimmt Eingaben als Befehlszeilenargument und gibt sie auf STDOUT aus.
Es ist nicht Bash-kompatibel, da es die zsh-spezifische Basiskonvertierungssyntax verwendet.
quelle
Netzhaut, 70 Bytes
Testsuite. (Leicht verändert.)
Nur zum Spaß: 7 Bytes
Nimmt Base-4 als Eingabe und Ausgänge als Base-4.
Probieren Sie es online!
quelle
05AB1E, 8 Bytes
Vielen Dank an @Adnan für -5 Bytes!
Verwendet die CP-1252-Codierung.
Probieren Sie es online!
Erläuterung:
quelle
1 2‚2 1‚
mit12Â
für 8 Bytes ersetzen .4в2‰íJJC
C
323029 BytesAlgorithmus kopiert aus xsots Kommentar zur Python-Antwort von xnor . Anstatt beide Wege zu maskieren, maskieren Sie einen Weg und kombinieren Sie.
Dies kompiliert auf dieselbe Weise wie die letzte von mir getestete Version und funktioniert (für x bis
0x3FFFFFFF
und für x darüber, solange Bit 30 nicht gesetzt ist, siehe unten). Im Maschinencode entspricht es der Länge meiner vorhandenen asm-Antwort.Die obige Version löscht immer das hohe Bit des Ergebnisses . Die beste sichere Version ist 32 Bytes:
Die Python-Version hat dieses Problem nicht, da Python bei Bedarf Integer-Typen mit willkürlicher Genauigkeit verwendet , anstatt auf eine feste Obergrenze zu kürzen.
quelle
>>
das so gering war. Ich spiele nicht oft genug Golf, um mich genau an die Regeln zu erinnern, da Compiler-Warnungen, die in gefährlichen Fällen auf Parens hindeuten, mich in echtem Code retten. : PJavascript (ES6),
113109 Bytes4 Bytes gespart dank Upgoat
Wie es funktioniert
quelle
+('0b"+binary_string_here)
anstelle von "parseInt (..., 2)J, 20 Bytes
Verwendung
Wo
>>
ist STDIN und<<
ist STDOUT.Ungolfed
Drei Gabeln.
Randnotiz
Im offiziellen Interpreter
^:_1
kann durchinv
1 Byte erspart werden.Keiner der Online-Dolmetscher setzt dies jedoch um.
quelle
C #, 44 Bytes
Basierend auf der C-Implementierung
int f(int n)=>n>3?4*f(n/4)+f(n%4):n%2*2+n/2;
Probieren Sie es hier aus: C # Pad
quelle
INTERCAL , 60 Bytes
Probieren Sie es online!
Funktioniert für 16-Bit-Ganzzahlen, wobei E / A im natürlichsten Format für INTERCAL ausgeführt wird: Die Eingabe ist eine Reihe von Dezimalstellen, die in einer von mehreren natürlichen oder konstruierten Sprachen geschrieben sind, und die Ausgabe erfolgt in "geschlachteten römischen Ziffern".
Dies ist eine der seltenen Herausforderungen, bei denen die binären Operatoren von INTERCAL überhaupt intuitiv verwendet werden können, da es um das Neupositionieren von Bits geht. Select (
~
) nimmt die Bits aus seinem ersten Argument, die den Einsen in seinem zweiten Argument entsprechen, und füllt sie rechts mit Nullen auf, und mingle ($
) verschachtelt die Bits aus seinen Argumenten, sodass die Bits aus dem ersten Argument signifikanter sind. Die einfache Lösung besteht also darin, die niederwertigen alternierenden Bits (.1~#21845
) und die höherwertigen alternierenden Bits ( ) auszuwählen..1~#43690
), und verschachteln Sie sie in umgekehrter Reihenfolge. Zum Glück für die Byteanzahl haben die INTERCAL-Operatoren zwar keine definierte Priorität (da die Sprache keine Präzedenzfälle haben soll), es stellt sich jedoch heraus, dass C-INTERCAL auf TIO für diesen bestimmten Ausdruck keine große Gruppierung erfordert und nur ein Byte kostet'.
kann abgekürzt werden!
.Mit Unterstützung für 32-Bit-Ganzzahlen:
INTERCAL , 67 Bytes
Probieren Sie es online!
INTERCAL erlaubt keine 32-Bit-Literale, was das Lesen tatsächlich ein wenig erleichtert , da die magischen Konstanten für die Auswahl alternierender Bits konstruiert werden müssen, indem zwei 16-Bit-Literale miteinander gemischt werden, wobei einer alle Nullen und der andere alle Nullen enthält alle. (Selbst wenn es 32-Bit-Literale gäbe, wäre diese immer noch kürzer. Sie
#0$#65535
ist zwei Bytes entfernt#1431655765
, und das Gleiche gilt für die andere.) Dadurch wird der gesamte Prozess für INTERCAL unnatürlich gut kommuniziert.Ein alternativer Ansatz mit umständlicher Verwendung der Operandenüberladung :
INTERCAL , 71 Bytes
Probieren Sie es online!
Dies beseitigt die Auswahl insgesamt, indem deklariert wird, dass
:1
mit.2
gemischt wird.3
,:1
auf den Eingang gesetzt wird und dann mit gemischt.3
ausgegeben wird.2
. Since:1
wurde überladen als.2$.3
,DO :1 <- :2
weist Werte zu.2
und.3
so zu, dass:1
der Wert von erfasst wird:2
, was dazu führt, dass die höherwertigen.2
Wechselbits von:2
und.3
die niederwertigen Wechselbits enthalten sind. Dies wäre die kürzere der beiden 32-Bit-Lösungen um vier Bytes, wennPLEASE WRITE IN :1
sie durchPLEASE WRITE IN :2 DO :1 <- :2
überlastete ersetzt werden könnten:1
, aberCALCULATING
erweist sich als notwendig für die Verwendung von Überladung. Ich habe auch das Gefühl, dass es einen kürzeren Weg gibt, das Überladen selbst durchzuführen, als das Programm zu startenDO:1<-:1/.2$.3
, aber da dies INTERCAL ist, habe ich auch das Gefühl, dass es keinen geben kann.quelle
Mathematica, 44 Bytes
Gleicher Ansatz wie meine CJam-Antwort: In Base-4 konvertieren, 1s und 2s tauschen, zurück konvertieren. Es wird auch der alephalpha-Trick verwendet, um ihn
FromDigits
durch eineFold
Operation zum Speichern eines Bytes zu ersetzen .quelle
Eigentlich 16 Bytes
Probieren Sie es online!
Erläuterung:
quelle
J, 22 Bytes
Alternativer Ansatz basierend auf Array-Manipulation anstelle des Basis-4-Tricks.
Verwendung
Erläuterung
quelle
REXX, 88 Bytes
quelle