Enduit de bit alterné

12

introduction

Ce défi nécessite que vous définissiez les zéros de fin d'une représentation binaire entière 010101…, cela est mieux expliqué avec un exemple:

Étant donné l'entier 400, la première étape consiste à le convertir en binaire:

110010000

Comme nous pouvons voir que le cinquième bit est le bit le moins significatif 1, à partir de là, nous remplaçons les zéros inférieurs par 0101:

110010101

Enfin, nous convertissons cela en décimal: 405

Défi

Étant donné un retour / sortie entier positif, la valeur résultante correspondante du processus défini ci-dessus.

Règles

  • Cette séquence n'est définie que pour les entiers avec au moins un 1bit, donc l'entrée sera toujours ≥ 1
  • Vous pouvez prendre la saisie sous forme de chaîne, liste de chiffres (décimal) à la place
  • Vous n'avez pas à gérer les entrées non valides

Cas de test

Voici quelques autres tests avec les étapes intermédiaires (vous n'avez pas besoin de les imprimer / retourner):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298
ბიმო
la source
Pouvons-nous supposer un entier 32 bits?
Arnauld
@Arnauld: Bien sûr!
ბიმო
9
Une idée de golf: si nla puissance maximale de 2 divise l'entrée, alors la réponse est simplement(input) + ceil((2^n - 2)/3)
JungHwan Min

Réponses:

12

Python 3 , 20 octets

lambda n:(n&-n)//3+n

Essayez-le en ligne!

Explication

Prenons 192l'exemple. Sa forme binaire est 11000000, et nous devons la convertir en 11010101.

Nous notons que nous devons ajouter 10101au nombre. Il s'agit d'une série géométrique ( 4^0 + 4^1 + 4^2), qui a une forme fermée comme (4^3-1)/(4-1). C'est la même chose que 4^3//3lorsque //dénote une division entière.

Si c'était le cas 101010, ce serait toujours une série géométrique ( 2×4^0 + 2×4^1 + 2×4^2), ce qui est 2×4^3//3pour les raisons ci-dessus.

Quoi qu'il en soit, 4^3et 2×4^3serait juste le bit le moins significatif, que nous obtenons en n&-n:

On remarque que le complément de nest 00111111. Si nous en ajoutons un, il devient 01000000, et il ne chevauche que n=11000000le chiffre le moins significatif. Notez que «compléter et ajouter un» n'est qu'une négation.

Leaky Nun
la source
6
@ Mr.Xcoder nice sportsmanship
Leaky Nun
1
Fonctionne lambda n:(n&-n)//3+npeut- être aussi? Réussit tous les exemples de cas de test , mais selon mon intuition, il ne devrait pas être valide, non?
M. Xcoder
@ Mr.Xcoder c'est en effet valide.
Leaky Nun
1
Pourquoi ne pas utiliser Python 2 pour enregistrer un octet? TIO
FlipTack
4
@FlipTack Je déteste python 2
Leaky Nun
8

Gelée , 5 octets

&N:3+

Essayez-le en ligne!

Cette fois, un port de l'approche de Leaky Nun (au moins je l'ai aidé à jouer un peu au golf: P)

Gelée , 7 octets

^N+4:6ạ

Essayez-le en ligne!

Utilise l'approche fantastique de JungHwan Min , avec l'aide indirecte de Martin Ender .

M. Xcoder
la source
Dennis a publié, puis supprimé, une solution très similaire à 5 octets juste après avoir effectué cette modification. Quelque chose comme &N:3|. Toutes nos félicitations; vous battez Dennis dans Jelly! (Mais pas tout à fait hors-golf.)
wizzwizz4
@ wizzwizz4 Je n'ai vraiment pas fait grand-chose, à part proposer un petit golf à l'approche de Leaky puis le porter. Mais hein :-)
M. Xcoder
Ceci est la première réponse Jelly ASCII uniquement que j'ai jamais vue.
MD XF
6

Wolfram Language (Mathematica) , 36 28 26 24 octets

-8 octets grâce à @MartinEnder et -2 octets grâce à @ Mr.Xcoder

#+⌊(#~BitAnd~-#)/3⌋&

Essayez-le en ligne!

Nous avons seulement besoin de trouver le nombre de zéros de fin dans l'entrée, de trouver le nombre avec des 0s et des 1s alternants avec une longueur inférieure à cela, et de l'ajouter à l'entrée.

Donc, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

La formule explicite pour nle nombre th avec alternance de 1s et 0s a été donnée dans A000975 sur OEIS. Nous pouvons utiliser le nnombre e car aucun nombre différent ne peut avoir la même longueur en binaire et avoir des chiffres alternés.

JungHwan Min
la source
1
2^#~IntegerExponent~2est(BitXor[#,#-1]+1)/2
Martin Ender
@MartinEnder wow! Et puis je peux simplement combiner les fractions pour réduire plus d'octets
JungHwan Min
1
24 octets . Vous pouvez utiliser à la #+⌊(#~BitAnd~-#)/3⌋&place.
M. Xcoder
@ Mr.Xcoder édité :)
JungHwan Min
5

J , 19 18 octets

+(2|-.i.@#.-.)&.#:

Essayez-le en ligne!

Explication rapide

C'est une vieille réponse, mais elle est de nature très similaire à la réponse actuelle, elle compte simplement les zéros de fin différemment. Voir les commentaires pour un lien expliquant comment cela fonctionne.

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

Autres réponses:

Réponse précédente (19 octets).

+(2|i.@i.&1@|.)&.#:

Plus long qu'il ne devrait l'être car \va de droite à gauche.

+(2|#*-.#.-.)\&.(|.@#:)
cole
la source
1
18 octets+(2|-.i.@#.-.)&.#:
miles
@miles esprit expliquant ce qui se passe avec la conversion de base là-bas? Je suppose que cela a quelque chose à voir avec les zéros, mais je ne suis pas sûr.
cole
#.~ compte le nombre de vérités de fin , donc ce dont nous avons besoin est #.~ -. #:de compter le nombre de zéros de fin
miles
@miles Ah! C'est très, très intelligent.
cole
4

Julia 0,6 , 12 octets

!n=n|n&-n÷3

Essayez-le en ligne!

Dennis
la source
Cela ressemble à une méthode efficace, pouvez-vous expliquer la priorité de l'opérateur? Par exemple, je ne peux pas dire s'il est évalué comme ((!n=(n|n))&-n)/3, ou !n=(((n|n)&(-n))/3), etc.
MD XF
Dans Julia, les opérateurs au niveau du bit ont les mêmes priorités que leurs homologues arithmétiques, donc |c'est pareil +et &c'est pareil *. Par conséquent, n|n&-n÷3est analysé comme n | ((n&-n) ÷3).
Dennis
3

JavaScript (ES6), 40 39 octets

Prend l'entrée comme un entier 32 bits.

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

Cas de test

Arnauld
la source
2

05AB1E , 13 8 5 octets

Enregistré 5 octets grâce à M. Xcoder et la formule soignée de JungHwan Min
Enregistré 3 autres grâce à M. Xcoder

(&3÷+

Essayez-le en ligne!

Explication

(      # negate input
 &     # AND with input
  3÷   # integer divide by 3
    +  # add to input
Emigna
la source
1
Il vaut peut-être la peine de mentionner que le portage de la réponse Mathematica vous donne 8 octets
M. Xcoder
@ Mr.Xcoder: Ooh, c'est une bonne formule.
Emigna
1
05ab1e a-t-il un bit ET? Si c'est le cas, (<bitwise and here>3÷+devrait fonctionner pendant environ 5 octets.
M. Xcoder du
2

R , 71 58 octets

grâce à NofP pour -6 octets

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

Essayez-le en ligne!

Suppose que l'entrée est un entier 32 bits. R n'a de toute façon que des entiers 32 bits signés (transtypage en doublecas de débordement d'un entier) et pas d'entiers 64 bits ou non signés.

Giuseppe
la source
Vous pouvez convertir le which.max(n):1-1pour !cumsum(n)obtenir une solution de 65 octets
NofP
@NofP merci! C'est une bonne idée.
Giuseppe
2

brainfuck , 120 octets

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

Essayez-le en ligne!

Commence par la valeur dans la cellule actuelle et se termine sur la cellule avec la valeur de sortie. Évidemment, cela ne fonctionnera pas sur les nombres supérieurs à 255 car c'est la limite de cellules pour le brainfuck typique, mais cela fonctionnera si vous supposez une taille de cellule infinie.

Jo King
la source
1

PowerShell , 168 octets

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

Essayez-le en ligne!

Aie. La conversion vers / depuis le binaire et le découpage de tableaux ne sont pas vraiment les points forts de PowerShell.

Prend l'entrée $nsous forme de nombre. Nous avons immédiatement convertcela dans une base binaire 2et stocké cela dans $a. Ensuite, nous avons une construction if / else. La clause if teste si un regex Matchcontre 1 ou plusieurs 0s à la fin de la chaîne ( '0+$') a son indexà un emplacement supérieur à 0(c'est-à-dire le début de la chaîne binaire). Si c'est le cas, nous avons quelque chose à travailler, elsenous sortons simplement le nombre.

À l'intérieur de if, nous découpons les xe premiers chiffres et concaténons +les tableaux avec les chiffres restants. Cependant, pour les chiffres restants, nous les parcourons en boucle et sélectionnons a 0ou 1à afficher à la place, en utilisant $i++%2pour choisir. Cela nous donne le 010101...motif au lieu de 0s à la fin. Ensuite, nous les remettons -joinensemble dans une chaîne, et nous les $cretournons dans une Int32base de départ 2.

Dans les deux cas, le nombre est laissé sur le pipeline et la sortie est implicite.

AdmBorkBork
la source
1

APL + WIN, 43 octets

p←+/^\⌽~n←((⌊1+2⍟n)⍴2)⊤n←⎕⋄2⊥((-p)↓n),p⍴0 1

Invite à saisir l'écran

Graham
la source
1

PHP , 47 octets

<?php function b($a){echo(int)(($a&-$a)/3)+$a;}

Essayez-le en ligne!

Vraiment juste un autre port de la solution de @Leaky Nun

NK1406
la source
1

Python 3 , 56 octets

lambda n:eval((bin(n).rstrip("0")+"01"*n)[:len(bin(n))])

Essayez-le en ligne!

Pas vraiment satisfait de ça pour le moment, mais je ne voulais vraiment pas utiliser la formule ... -2 grâce à Rod . -1 merci à Jonathan Frech .

M. Xcoder
la source
eval(...)au lieu de int(...,2)pourrait enregistrer un octet.
Jonathan Frech
1

Rubis , 15 octets

Un autre port de l'approche de Leaky Nun.

->k{(k&-k)/3+k}

Essayez-le en ligne!

Tom Lazar
la source
1

AWK , 24 octets

Un port de la réponse Mathmatica de JungHwan Min

$0=int(and($0,-$0)/3+$0)

Essayez-le en ligne!

Noskcaj
la source
1

JavaScript ES6, 13 octets

n=>(n&-n)/3|n

f = 
n=>(n&-n)/3|n
;
console.log (f(8));
console.log (f(243));
console.log (f(1048576));
console.log (f(33554432));

l4m2
la source
1

C, 56 octets

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;return n|k;}

Essayez-le en ligne!

C (gcc), 50 octets

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;k|=n;}

Essayez-le en ligne!

 51  48 octets utilisant la solution d'Arnauld :

Merci à @ l4m2 pour avoir économisé trois octets!

m;f(n){return n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

Essayez-le en ligne!

43 avec gcc:

m;f(n){m=n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

Essayez-le en ligne!

Steadybox
la source
0xAAAAAAAA=>-1u/3*2
l4m2
0

Gelée , 13 octets

BŒgṪµ2Ḷṁ×CḄ+³

Essayez-le en ligne!

Explication

Prenez 24 comme exemple d'entrée.

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
dylnan
la source