Objectif
Étant donné un entier non négatif, créez une fonction qui renvoie la position de départ du nombre de 1 consécutifs les plus grands dans la valeur binaire de cet entier.
Lorsqu'une entrée est donnée 0
, retournez 0
.
Si le nombre comporte plusieurs séquences de longueur égale, vous devez renvoyer la position de la dernière séquence.
Contribution
Un entier supérieur ou égal à 0.
Sortie
Un entier calculé comme expliqué ci-dessous.
Règles
- C'est le code-golf, donc le code le plus court en octets dans chaque langue gagne.
- Les failles standard sont interdites.
Exemples et cas de test
Exemple 1
- Votre fonction est passée l'entier 142
- 142 est égal à 10001110 en binaire
- La séquence la plus longue est "111" (une séquence de trois séquences)
- La séquence commence à la position 2 ^ 1
- Votre fonction renvoie 1 comme résultat
Exemple 2
- Votre fonction est passée le nombre entier 48
- 48 est égal à 110000 en binaire
- La séquence la plus longue est "11" (une séquence de deux séquences)
- La séquence commence à la position 2 ^ 4
- Votre fonction renvoie 4 comme résultat
Exemple 3
- Votre fonction est passée le nombre entier 750
- 750 est égal à 1011101110 en binaire
- La séquence la plus longue est "111" (une séquence de trois séquences)
- Puisqu'il y a deux séquences de longueur égale, nous renvoyons la dernière séquence.
- La dernière séquence commence à la position 2 ^ 5
- Votre fonction renvoie 5 comme résultat
0
. C'est un cas de test important.Réponses:
Gelée ,
108 octetsEssayez-le en ligne!
Comment ça marche
la source
JavaScript (ES6),
41403634 octets4 octets enregistrés grâce à @ThePirateBay
Cas de test
Afficher l'extrait de code
Comment?
Cas général x> 0
Nous récursivement ET l'entrée x avec x / 2 qui réduit progressivement les modèles de bits consécutifs définis jusqu'à ce qu'il ne reste que le bit le plus à droite de la séquence. Nous conservons une copie de la dernière valeur non nulle et déterminons la position de son bit le plus significatif en arrondissant au sol son logarithme en base 2.
Voici les étapes à suivre pour x = 750 ( 1011101110 en binaire).
Boîtier de bord x = 0
Le cas particulier
x = 0
conduit immédiatement àMath.log2(0) | 0
. Le logarithme de0
évalue à-Infinity
et le bit binaire OU force une coercition à un entier 32 bits. Conformément à la spécification de l'opération abstraite ToInt32 , cela donne les résultats attendus0
:la source
0
, qui fait partie de la plage d'entrée.Math.log2(k)|0
lieu de31-Math.clz32(k)
? Ou est-ce que je manque quelque chose?Math.log2(k)|0
est en fait à la fois plus court et plus simple pour le cas spécialx=0
. Merci. :)code machine x86, 14 octets
Utiliser l'algorithme de @ Arnauld
x &= x>>1
et prendre la position de bit la plus élevée définie à l'étape précédentex
devient0
.Appelable à partir de C / C ++ avec signature
unsigned longest_set(unsigned edi);
dans le x86-64 System V ABI. Les mêmes octets de code machine décoderont de la même manière en mode 32 bits, mais les conventions d'appel standard 32 bits ne mettent pas le premier argumentedi
. (La modification du registre d'entrée versecx
ouedx
pour Windows_fastcall
/_vectorcall
ougcc -mregparm
pourrait se faire sans rien casser.)L'
BSR
instruction de x86 (Bit Scan Reverse) est parfaite pour cela, nous donnant directement l'index binaire, plutôt que de compter les zéros en tête. (bsr
ne produit pas directement 0 pour input = 0 comme le32-lzcnt(x)
ferait, mais nous avons besoin de bsr = 31-lzcnt pour les entrées non nulles, donclzcnt
ne sauverait même pas les instructions, sans parler du nombre d'octets. Mettre à zéro eax avant que la boucle fonctionne à cause debsr
' s comportement semi-officiel consistant à laisser la destination non modifiée lorsque l'entrée est nulle.)Ce serait encore plus court si nous pouvions retourner la position MSB du plus long terme. Dans ce cas,
lea ecx, [rdi+rdi]
(3 octets) copierait + shift gauche vers la place demov
+shr
(4 octets).Voir ce lien TIO pour un appelant asm qui ne
exit(longest_set(argc-1));
Test avec une boucle shell:
la source
Gelée ,
191711 octetsEssayez-le en ligne!
-6 (!) Octets grâce aux vives observations de @ Dennis
Comment ça marche
la source
0
, qui se trouve dans la plage d'entrée.ȯ-µ...
B
renvoie toujours un tableau qui commence par un 1 ,BUṪMṪ’×Ṡ
peut devenirṪBL’
. De plus, vous n'avez pas besoin de laḞ
etḟ0
enregistre un octet de plus¹Ðf
.Python 2 , 45 octets
Essayez-le en ligne!
Beaucoup d'octets enregistrés grâce à Dennis! (Les chefs pour
len(bin(...))-3
au lieu demath.frexp
)Merci à @xnor d'avoir trouvé un bug, qui était heureusement facilement réparable!
la source
x=3
, je pense parce que lesand/or
courts-circuits sont incorrects lorsque la fonction retourne 0.Perl 6 ,
4535 octetsCette version hautement améliorée est une gracieuseté de @nwellnhof.
Essayez-le en ligne!
la source
:g
pour obtenir tous les matchs. Avec l'opérateur de match intelligent, je pouvais le{sort(.base(2).flip~~m:g/1+/).tail.from}
{.msb+1-(.base(2)~~m:g/1+/).max.to}
:g
et je n'ai pas compris comment utiliser l'adverbe avec l'opérateur smartmatch. De plus, la.msb
méthode est très utile ici et je n'en savais rien auparavant.Python 2 ,
8978 octetsEssayez-le en ligne!
EDIT: enregistré 11 octets grâce à M. Xcoder.
la source
05AB1E ,
141211 octetsEssayez-le en ligne! ou exécuter des cas de test .
Explication
la source
J ,
1817 octetsEssayez-le en ligne!
Explication
la source
x
dyade sont toutes 0 et 1, qu'est-ce que cela signifie? Un numéro de base 2 a des chiffres0
et1
donc un1
numéro de base a des chiffres ...0
? alors qu'est-ce qu'un1
moyen dans ce contexte? Et est-ce qu'un0
numéro de base est toujours juste0
?x #. y
calcule d'abordw =: */\. }. x , 1
puis retourne+/ w * y
#.
, car vous comptez sur les détails de mise en œuvre interne plutôt que sur l'api publique?C # (.NET Core) ,
6460 octetsEssayez-le en ligne!
Version AC # de la réponse de @ Arnauld
Remerciements
4 octets enregistrés grâce à Kevin Cruijssen.
C # (.NET Core) ,
131123 + 18 = 141 octetsEssayez-le en ligne!
+18 octets pour
using System.Linq;
Remerciements
8 octets économisés grâce à Grzegorz Puławski.
Dégolfé
C # (.NET Core) ,
164161 octetsEssayez-le en ligne!
Une non-
Linq
solution qui, j'en suis sûr, pourrait être améliorée, bien que rien ne soit immédiatement apparent.Dégolfé
la source
r
dans la première réponse: tio.run/##dY9RS8MwFIWfza/…T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Coque , 12 octets
Essayez-le en ligne!
Explication
la source
Gelée ,
14 13 1211 octetsUn lien monadique prenant et retournant des entiers non négatifs.
Essayez-le en ligne! ou voir la suite de tests .
Comment?
la source
ŒrṪP
sur les préfixes à la place.Gelée , 19 octets
Essayez-le en ligne!
Merci à Jonathan Allan d'avoir économisé
46 octets!J'ai trop travaillé pour abandonner ça, même si c'est un peu long. Je voulais vraiment ajouter une solution qui recherche littéralement la plus longue sous-chaîne de
1
s dans la représentation binaire ...Explication
la source
BŒgḄṀB
placeBwÇɓÇL+ɓBL_‘
Kotlin , 77 octets
Embellie
Tester
la source
Haskell ,
101989675 octetsEssayez-le en ligne! Utilisation:
snd.maximum.(`zip`[0..]).c $ 142
rendements1
.Explication:
c
convertit l'entrée en binaire tout en comptant en même temps la longueur des séquences d'un, en rassemblant les résultats dans une liste.r<-c$div n 2
calcule récursivement le rester
de cette liste, tout ensum[r!!0+1|mod n 2>0]:r
ajoutant la longueur actuelle de la séquence àr
. La compréhension de la liste vérifie simod n 2>0
, c'est-à-dire si le chiffre binaire actuel est un, et si c'est le cas, prend la longueur de la séquence précédente (le premier élément der
) et en ajoute un. Sinon, la compréhension de la liste est vide etsum[]
donne0
. Pour l'exemple d'entrée,c 142
renvoie la liste[0,3,2,1,0,0,0,1,0]
.(`zip`[0..])
ajoute la position à chaque élément de la liste précédente en tant que deuxième composant d'un tuple. Pour l'exemple que cela donne[(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)]
.maximum
trouve le tuple lexicographiquement maximal dans cette liste, c'est-à-dire que les longueurs de séquence sont considérées en premier car elles sont le premier composant, et en cas d'égalité, le deuxième composant, à savoir l'indice le plus grand, décide. Cela donne(3,1)
dans l'exemple etsnd
retourne le deuxième composant du tuple.la source
Python 2 ou 3 , 58 octets
Essayez-le en ligne!
la source
C (gcc) ,
8180 octetsEssayez-le en ligne!
C (gcc) , 43 octets
Version AC de la réponse de @ Arnauld
Essayez-le en ligne!
la source
n<1?0:log2(n)
place de(k=log2(n))<0?0:k
MS SQL Server,
437426407398 octetsSQL Fiddle
Je suis sûr que je pourrais supprimer les sauts de ligne, etc., mais c'est aussi compact que je voulais le faire:
Voici une version plus lisible:
Le vrai truc, c'est que pour autant que je puisse trouver, il n'y a pas de fonctionnalité SQL native pour convertir un nombre de décimal en binaire. En conséquence, j'ai dû coder la conversion en binaire manuellement, puis je pouvais comparer cela en tant que chaîne, un caractère à la fois jusqu'à ce que je trouve le bon nombre.
Je suis sûr qu'il y a une meilleure façon de le faire, mais je n'ai pas vu de réponse (n) SQL, alors j'ai pensé que je la mettrais dehors.
la source
APL (Dyalog Unicode) , 22 caractères = 53 octets
Requiert
⎕IO←0
ce qui est par défaut sur de nombreux systèmes.Essayez-le en ligne!
⎕
invite pour l'entrée⊢
rendement qui (se sépare¯1
de⎕
)2⊥⍣¯1
convertir en base-2, en utilisant autant de positions que nécessaireb←
stocker commeb
(pour b inaire)⌽
sens inverse(
…)
Marquer les positions de départ des éléments suivants en ce que:⊆⍨b
auto-partitionb
(ie les 1-séquence deb
)↑
mix (faire la liste des listes en matrice, remplissage avec des zéros)∨⌿
réduction OR verticale (donne la séquence la plus longue)⍸
ɩ ndices des positions de départ⌽
sens inverse⊃
choisissez le premier (donne zéro si aucun n'est disponible)la source
MATL , 15 octets
Essayez-le en ligne!
Utilise la moitié et l'idée ET. Le
k
n'est nécessaire que pour le terminer1
- pour une raison quelconque, 1 ET 0,5 renvoie 1, provoquant une boucle infinie.(solution alternative:
BtnwY'tYswb*&X>)-
en convertissant en encodage binaire et en longueur)la source
Google Sheets, 94 octets
Non, ce n'est pas très joli. Ce serait vraiment bien de pouvoir stocker
Dec2Bin(A1)
comme variable pour référence.Point clé: Comme Excel, la
Dec2Bin
fonction a une valeur d'entrée maximale de511
. Tout ce qui est plus grand que cela renvoie une erreur, comme indiqué ci-dessous.la source
R, 117 octets
la source
rev
, utilisezReduce(...,T,T)
pour accumuler à partir de la droite (commutationx,y
dans la définition de la fonction). Ensuite, utilisez1+max(z)-which.max(z)
car le résultat est quelque peu différent. Utilisez"if"
plutôt que"ifelse"
puisque nous n'avons pas besoin de la vectorisation; aaet si vous utilisezany(z)
au lieu de!sum(z)
vous laissez tomber un octet.Excel VBA,
5444 octets-10 octets grâce à @EngineerToast
Fonction de fenêtre immédiate VBE anonyme qui prend les entrées de la plage
[A1]
et les sorties vers la fenêtre immédiate VBEla source
C1
toujours là-dedans au lieu deA1
, je pense que vous pouvez produire lesInstr
résultats directement avec un peu de torsion pour la correction d'entrée zéro:?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)
(46 octets). Vrai = -1 car ... VBA.>0
into the[A1]
notationAPL (Dyalog Classic),
2421 bytesTry it online!
la source
Pyth, 17 bytes
This is a recursive function. The link includes
y
in order to call the function on the given input.Verify all test cases.
Pyth, 20 bytes
Verify all test cases.
la source
R, 66 Bytes
Explanation:
la source
a$l
instead ofa[[1]]
anda$v
instead ofa[[2]]
to save some bytes :), as well as>0
instead of==1
.Python 2, 41 bytes
Try it online!
Based on this solution by Mr. Xcoder.
la source
Javascript, 54 chars
i.toString(2)
gets the binary string for the integer..split(0)
gets each sequential ones part in an array element..sort().reverse()
gets us the highest value as first.[0].length
gives us the length of that first value.la source
the starting position of number of largest consecutive 1's
Perl 5, 45 + 1 (-p)
If you write this out on the command line of most shells, you may have to type this as:
The dance of the quotes at the end is just to get perl see a
'
, which would otherwise be consumed by the shell.la source
Retina,
5243 bytesConvert to binary, then replace with the length of what follows the largest string of ones.
Try it online - all test cases
Saved 9 bytes thanks to Martin.
la source
$+
for${1}
. But you can save even more by replacing the last stage with a bunch of stages like this: tio.run/##K0otycxL/K/…${1}
was copied from your tutorial on Github.