Qual è il numero di bit inverso (binario)?


33

Quindi ti viene dato un numero POSITIVO di base 10 (decimale). Il tuo compito è di invertire le cifre binarie e restituire quel numero di base 10.

Esempi:

1 => 1 (1 => 1)
2 => 1 (10 => 01)
3 => 3 (11 => 11)
4 => 1 (100 => 001)
5 => 5 (101 => 101)
6 => 3 (110 => 011)
7 => 7 (111 => 111)
8 => 1 (1000 => 0001)
9 => 9 (1001 => 1001)
10 => 5 (1010 => 0101)

Questa è una sfida di , quindi vince la soluzione che utilizza il minor numero di byte.

Questo è A030101 nell'OEIS.


2
"Invertire i bit" significa invertire le sue cifre binarie? A volte può anche significare invertire ogni bit .
ETHproductions

Sì. Scusa se non sono chiaro.
juniorRubyist

Questo e questo sono molto simili.
Geobits il


1
"base 10" Qualche motivo particolare per cui?
Calcolatrice

Risposte:


20

Python , 29 byte

lambda n:int(bin(n)[:1:-1],2)

Provalo online!

Questa è una funzione anonima e senza nome che restituisce il risultato.


Innanzitutto, bin(n)converte l'argomento in una stringa binaria. Normalmente invertiremmo questo con la notazione di sezione [::-1]. Questo legge la stringa con un passo di -1 , cioè all'indietro. Tuttavia, le stringhe binarie in Python sono precedute da un 0b, e quindi diamo il secondo argomento dello slicing come 1 , dicendo a Python di leggere all'indietro terminando all'indice 1 , quindi non leggendo gli indici 1 e 0 .

Ora che abbiamo la stringa binaria all'indietro, la passiamo int(...)con il secondo argomento come 2 . Questo legge la stringa come un intero di base 2, che viene quindi implicita restituita dall'espressione lambda.


2
Batti di 9 secondi.
mbomb007,


6
@ mbomb007 quindi la mia risposta non è valida perché hai fatto clic sul pulsante Invia 9 secondi prima? Solo perché raggiungiamo lo stesso golf allo stesso tempo non significa che dobbiamo eliminare alcuna risposta. Semmai, biasima la domanda dello sforzo 0.
FlipTack

3
Non invalido, ma sicuramente inutile. Se fossi stato più lento, avrei semplicemente cancellato il mio e avrei pubblicato un commento su quello più veloce che mi è venuto in mente.
mbomb007,

1
@steenbergh Chi se ne frega? Stesso codice, stesso punteggio.
mbomb007,


13

JavaScript (ES6), 30 28 byte

Salvato 2 byte grazie a @Arnauld

f=(n,q)=>n?f(n>>1,q*2|n%2):q

Questo in sostanza calcola il contrario di un bit alla volta: iniziamo con q = 0 ; mentre n è positivo, moltiplichiamo q per 2, separiamo l'ultimo bit di n con n>>1e lo aggiungiamo a q con |n%2. Quando n raggiunge 0, il numero è stato invertito correttamente e restituiamo q .

Grazie ai lunghi nomi incorporati di JS, la risoluzione di questa sfida nel modo più semplice richiede 44 byte:

n=>+[...n.toString(2),'0b'].reverse().join``

Usando la ricorsione e una stringa, puoi ottenere una soluzione a 32 byte che fa la stessa cosa:

f=(n,q='0b')=>n?f(n>>1,q+n%2):+q

f=(n,q)=>n?f(n>>1,q*2|n%2):qquasi funziona. Ma purtroppo non per n=0.
Arnauld,

@Arnauld OP non ha ancora risposto se l'input sarà sempre positivo, ma in tal caso, non è necessario gestire 0.
FlipTack

Questo è un follow-up tardivo, ma ora è noto che l'input è sempre positivo.
Arnauld,

@Arnauld Grazie!
ETHproductions

10

Java 8, 53 47 46 45 byte

  • -4 byte grazie a Tito
  • -1 byte grazie a Kevin Cruijssen

Questa è un'espressione lambda che ha lo stesso principio della risposta di ETH (anche se la ricorsione sarebbe stata troppo verbosa in Java, quindi invece facciamo un ciclo):

x->{int t=0;for(;x>0;x/=2)t+=t+x%2;return t;}

Provalo online!

Questo può essere assegnato con IntFunction<Integer> f = ...e quindi chiamato con f.apply(num). Espanso, non golfato e commentato, si presenta così:

x -> { 
    int t = 0;           // Initialize result holder   
    while (x > 0) {      // While there are bits left in input:
        t <<= 1;         //   Add a 0 bit at the end of result
        t += x%2;        //   Set it to the last bit of x
        x >>= 1;         //   Hack off the last bit of x
    }              
    return t;            // Return the final result
};

1
Salva 3 byte con t*2invece di (t<<1)un altro con lo spostamento di quel calcolo dalla testa del loop al corpo del loop. Puoi usare xinvece che x>0per la condizione?
Tito

2
@Titus non senza un cast esplicito in un booleano, ma grazie per gli altri suggerimenti! Anche appena realizzato che x>>=1può essere sostituito con x/=2come sarà automaticamente la divisione intera.
FlipTack

45 byte (modificato t=t*2+in t+=t+.)
Kevin Cruijssen,

@KevinCruijssen nice one!
FlipTack,

9

J, 6 byte

|.&.#:

|. inverso

&. sotto

#: base 2




7

Labyrinth, 23 byte

?_";:_2
  :   %
 @/2_"!

Bene, questo è imbarazzante ... questo restituisce il numero BINARY inverso ... Grazie @Martin Ender per aver segnalato sia il mio errore che il mio errore ID 10T. Quindi questo non funziona, dovrò trovare un'altra soluzione.


1
Benvenuti in PPCG e bel primo post! Basta completare una sfida in una lingua come Labyrinth può essere molto difficile. Da queste parti, di solito facciamo il prefisso della prima riga di una risposta con uno o due hash, per farla mostrare come intestazione:# Labyrinth, 89 bytes
ETHproductions

1
Hai accidentalmente omesso uno spazio iniziale dalla seconda fila? Così com'è, il programma rimbalzerebbe avanti e indietro sulla prima riga perché si _trovano sulle giunzioni.
Martin Ender,

Sfortunatamente, ho appena notato che questo non è valido a prescindere, perché la sfida richiede la rappresentazione in base 10 del numero invertito, non la sua rappresentazione binaria.
Martin Ender,

6

C, 48 44 43 42 byte

-1 byte grazie a gurka e -1 byte grazie ad anatolyg:

r;f(n){for(r=n&1;n/=2;r+=r+n%2);return r;}

Precedente 44 byte soluzione:

r;f(n){r=n&1;while(n/=2)r=2*r+n%2;return r;}

Precedente soluzione a 48 byte:

r;f(n){r=0;while(n)r=2*(r+n%2),n/=2;return r/2;}

Ungolfed e utilizzo:

r;
f(n){
 for(
  r=n&1;
  n/=2;
  r+=r+n%2
 );
 return r;}
}


main() {
#define P(x) printf("%d %d\n",x,f(x))
P(1);
P(2);
P(3);
P(4);
P(5);
P(6);
P(7);
P(8);
P(9);
P(10);
}

rQui non è già inizializzato a zero r;f(n){r=0;, ad esempio r=0;non è necessario? Anche piccolo errore di battitura: " Soluzione precedente 48 byte"
simon

1
@gurka La funzione dovrebbe essere riutilizzabile.
Karl Napf,

1
Penso che i forloop siano sempre brevi almeno quanto i whileloop e spesso più brevi.
Anatolyg

@anatolyg qualcosa come: r;f(n){for(r=n&1;n/=2;r=2*r+n%2);return r;}? 1 byte più corto, ma non sono sicuro che sia valido C (C99).
simon,

Sì; inoltre, trasformalo =in +=per renderlo più corto e più offuscato
anatolyg

5

Rubino, 29 28 byte

->n{("%b"%n).reverse.to_i 2}

"% b"% n formatta l'ingresso n come una stringa binaria, inverte, quindi converte nuovamente in un numero

Casi d'uso / test:

m=->n{("%b"%n).reverse.to_i 2}
m[1] #=> 1
m[2] #=> 1
m[3] #=> 3
m[4] #=> 1
m[5] #=> 5
m[6] #=> 3
m[7] #=> 7
m[8] #=> 1
m[9] #=> 9
m[10] #=> 5

@Titus Penso che tu abbia frainteso la risposta. 2è la base in cui si sta convertendo ed nè l'input. ->args{return value}è la sintassi del rubino lambda
Cyoce,

Can you remove the parentheses in .to_i(2)?
Cyoce

@Cyoce sure enough, thanks.
Alexis Andersen


4

Java (OpenJDK), 63 bytes

a->a.valueOf(new StringBuffer(a.toString(a,2)).reverse()+"",2);

Try it online!

Thanks to poke for -12 bytes and to Cyoce for -8 bytes!


Even though REPL submissions are allowed, they still follow the rule that you can't assume input is in predefined variables (like a in this context)
FlipTack

@FlipTack Oops. It was originally a function before I remembered the repl existed
Pavel

1
Also, in the future, use print instead of println for golfing :)
FlipTack

1
StringBuffer saves a byte over StringBuilder
Poke

1
Could you do +"" instead of .toString()?
Cyoce

3

Perl 6, 19 bytes

{:2(.base(2).flip)}

Where is the input?
Titus

This is a function that takes a single parameter $_. It isn't mentioned by name, but the base method is called on it.
Sean

2
@Titus in Perl 6 a Block is a type of Code, which is to say it's a callable object. The above is an expression that you can take and assign to a variable like a function or lambda in another language, or call directly — {:2(.base(2).flip)}(10) at the REPL will print 5. So it meets the standard code-golf criteria for a function.
hobbs

3

Haskell, 36 bytes

0!b=b
a!b=div a 2!(b+b+mod a 2)
(!0)

Same algorithm (and length!) as ETHproductions’ JavaScript answer.



3

PHP, 33 bytes

<?=bindec(strrev(decbin($argn)));

convert to base2, reverse string, convert to decimal. Save to file and run as pipe with -F.

no builtins:

iterative, 41 bytes

for(;$n=&$argn;$n>>=1)$r+=$r+$n%2;echo$r;

While input has set bits, pop a bit from input and push it to output. Run as pipe with -nR.

recursive, 52 bytes

function r($n,$r=0){return$n?r($n>>1,$r*2+$n%2):$r;}

@JörgHülsermann The 44 bytes have $r+=$r. But I actually don´t remember why I put that in front.
Titus

2

MATL, 4 bytes

BPXB

Try it online!

Explanation

B     % Input a number implicitly. Convert to binary array
P     % Reverse array
XB    % Convert from binary array to number. Display implicitly



2

Scala, 40 bytes

i=>BigInt(BigInt(i)toString 2 reverse,2)

Usage:

val f:(Int=>Any)=i=>BigInt(BigInt(i)toString 2 reverse,2)
f(10) //returns 5

Explanation:

i =>          // create an anonymous function with a parameter i
  BigInt(       //return a BigInt contructed from
    BigInt(i)     //i converted to a BigInt
    toString 2    //converted to a binary string
    reverse       //revered
    ,           
    2             //interpreted as a binary string
  )



1

CJam, 8 bytes

ri2bW%2b

Try it online!

Explanation

ri          e# Read integer
  2b        e# Convert to binary array
    W%      e# Reverse array
      2b    e# Convert from binary array to number. Implicitly display

1

Batch, 62 bytes

@set/an=%1/2,r=%2+%1%%2
@if %n% gtr 0 %0 %n% %r%*2
@echo %r%

Explanation: On the first pass, %1 contains the input parameter while %2 is empty. We therefore evaluate n as half of %1 and r as +%1 modulo 2 (the % operator has to be doubled to quote it). If n is not zero, we then call ourselves tail recursively passing in n and an expression that gets evaluated on the next pass effectively doubling r each time.


1

C#, 98 bytes

using System.Linq;using b=System.Convert;a=>b.ToInt64(string.Concat(b.ToString(a,2).Reverse()),2);

1

R, 55 bytes

sum(2^((length(y<-rev(miscFuncs::bin(scan()))):1)-1)*y)

Reads input from stdin and consequently uses the bin function from the miscFuncs package to convert from decimal to a binary vector.


1

Pushy, 19 bytes

No builtin base conversion!

$&2%v2/;FL:vK2*;OS#

Try it online!

Pushy has two stacks, and this answer makes use of this extensively.

There are two parts two this program. First, $&2%v2/;F, converts the number to its reverse binary representation:

            \ Implicit: Input is an integer on main stack.
$      ;    \ While i != 0:
 &2%v       \   Put i % 2 on auxiliary stack
     2/     \   i = i // 2 (integer division)
        F   \ Swap stacks (so result is on main stack)

Given the example 10, the stacks would appear as following on each iteration:

1: [10]
2: []

1: [5]
2: [0]

1: [2]
2: [0, 1]

1: [1]
2: [0, 1, 0]

1: [0]
2: [0, 1, 0, 1]

We can see that after the final iteration, 0, 1, 0, 1 has been created on the second stack - the reverse binary digits of 10, 0b1010.

The second part of the code, L:vK2*;OS#, is taken from my previous answer which converts binary to decimal. Using the method decsribed and explained in that answer, it converts the binary digits on the stack into a base 10 integer, and prints the result.


0

k, 18 bytes

{2/:|X@&|\X:0b\:x}

Example:

k){2/:|X@&|\X:0b\:x}6
3

0

C#, 167 bytes

 for(int i = 1; i <= 10; i++)
 {
 var bytes= Convert.ToString(i, 2);
 var value= Convert.ToInt32(byteValue.Reverse()); 
 console.WriteLine(value);
}

Explanation:

Here I will iterate n values and each time iterated integer value is convert to byte value then reverse that byte value and that byte value is converted to integer value.


1
Welcome to the site! I don't know much about C# but you most certainly have a good deal of extra whitespace I would recommend removing. It also is not clear how I/O is dealt with in this submission. It is standard to either write a function or to use STDIN (I think that is console.Read() but you would probably know better than I would) and STDOUT. Anyway, welcome to the site if you want more experienced advice in golfing C# I would recommend codegolf.stackexchange.com/questions/173/…
Wheat Wizard

I've downvoted this answer, because it doesn't work at all. .Reverse() returnes IEnumerable<char>. As Convert.ToInt32 doesn't have an overload for IEnumerable it throws an exception. Also the answer doesn't follow the rules for code golf: 1)As nothing is specified the submission has to be a full program or function not just a snippet. 2)using statements must be included in the byte count
raznagul

0

c/c++ 136 bytes

uint8_t f(uint8_t n){int s=8*sizeof(n)-ceil(log2(n));n=(n&240)>>4|(n&15)<<4;n=(n&204)>>2|(n&51)<<2;n=(n&172)>>1|(n&85)<<1;return(n>>s);}

It's not going to win, but I wanted to take a different approach in c/c++ 120 bytes in the function

#include <math.h>
#include <stdio.h>
#include <stdint.h>

uint8_t f(uint8_t n){
    int s=8*sizeof(n)-ceil(log2(n));
    n=(n&240)>>4|(n&15)<<4;
    n=(n&204)>>2|(n&51)<<2;
    n=(n&172)>>1|(n&85)<<1;
    return (n>>s);
}

int main(){
    printf("%u\n",f(6));
    return 0;
}

To elaborate on what I am doing, I used the log function to determine the number of bits utilized by the input. Than a series of three bit shifts left/right, inside/outside, even/odd which flips the entire integer. Finally a bit shift to shift the number back to the right. Using decimals for bit shifts instead of hex is a pain but it saved a few bytes.


You do need to include the function declaration, so this is actually 163 bytes. Although, if you remove the extraneous whitespace, you could shorten it to 136.
DJMcMayhem
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.