Calculer la plus longue série de 1 dans la valeur binaire d'un entier

32

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
De facto
la source
1
Vous avez besoin d'un critère gagnant, comme code-golf
Okx
@Okx Il avait été mentionné dans le corps lui-même, j'ai donc ajouté la balise.
totalement humain
Assurez-vous que les gens testent 0. C'est un cas de test important.
mbomb007
2
Au lieu de "dernière séquence" ou "dernière séquence", je suggère "séquence avec la plus grande valeur de position".
aschepler
@Okx Pourquoi un critère gagnant est-il nécessaire? Pourquoi ne peut-il pas être simplement un casse-tête?
corsiKa

Réponses:

21

Gelée , 10 8 octets

Ba\ÐƤṀċ¬

Essayez-le en ligne!

Comment ça marche

Ba\ÐƤṀċ¬  Main link. Argument: n


B         Binary; convert n to base 2.

   ÐƤ     Apply the link to the left to all postfixes of the binary array.
 a\         Cumulatively reduce by logical AND.

          For example, the array

          [1, 0, 1, 1, 1, 0, 1, 1, 1, 0]

          becomes the following array of arrays.

          [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
             [0, 0, 0, 0, 0, 0, 0, 0, 0]
                [1, 1, 1, 0, 0, 0, 0, 0]
                   [1, 1, 0, 0, 0, 0, 0]
                      [1, 0, 0, 0, 0, 0]
                         [0, 0, 0, 0, 0]
                            [1, 1, 1, 0]
                               [1, 1, 0]
                                  [1, 0]
                                     [0]

     Ṁ    Take the lexicographical maximum, i.e., the array with the most 1's at
          the beginning, breaking ties by length.

       ¬  Yield the logical NOT of n, i.e., 0 if n > 0 and 1 if n = 0.

      ċ   Count the occurrences of the result to the right in the one to the left.
Dennis
la source
Toutes nos félicitations!
Defacto
24

JavaScript (ES6), 41 40 36 34 octets

4 octets enregistrés grâce à @ThePirateBay

f=x=>(k=x&x/2)?f(k):Math.log2(x)|0

Cas de test

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).

    1011101110 --.
,----------------'
'-> 1011101110
AND 0101110111
    ----------
=   0001100110 --.
,----------------'
'-> 0001100110
AND 0000110011
    ----------
=   0000100010 --.  --> output = position of MSB = 5  (0000100010)
,----------------'                                         ^
'-> 0000100010
AND 0000010001
    ----------
=   0000000000

Boîtier de bord x = 0

Le cas particulier x = 0conduit immédiatement à Math.log2(0) | 0. Le logarithme de 0évalue à -Infinityet 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 attendus 0:

Si le nombre est NaN , +0 , −0 , + ∞ ou −∞ , retourne +0

Arnauld
la source
Cette erreur pour l'entrée 0, qui fait partie de la plage d'entrée.
Justin Mariner
@JustinMariner Fixed.
Arnauld
Et au Math.log2(k)|0lieu de 31-Math.clz32(k)? Ou est-ce que je manque quelque chose?
@ThePirateBay Math.log2(k)|0est en fait à la fois plus court et plus simple pour le cas spécial x=0. Merci. :)
Arnauld
1
Très bel algorithme et bonne explication. Je l'ai implémenté dans 14 octets de code machine x86 .
Peter Cordes
12

code machine x86, 14 octets

Utiliser l'algorithme de @ Arnauldx &= x>>1 et prendre la position de bit la plus élevée définie à l'étape précédente xdevient 0.

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 argument edi. (La modification du registre d'entrée vers ecxou edxpour Windows _fastcall/ _vectorcallou gcc -mregparmpourrait se faire sans rien casser.)

   address   machine-code
             bytes
                         global longest_set
 1                       longest_set:
 2 00000000 31C0             xor  eax, eax    ; 0 for input = 0
 3                       
 4                       .loop:               ; do{
 5 00000002 0FBDC7           bsr  eax, edi    ;  eax = position of highest set bit
 6                           ;; bsr leaves output unmodified when input = 0 (and sets ZF)
 7                           ;; AMD documents this; Intel manuals say unspecified but Intel CPUs implement it
 8 00000005 89F9             mov  ecx, edi
 9 00000007 D1E9             shr  ecx, 1
10 00000009 21CF             and  edi, ecx
11 0000000B 75F5             jnz .loop        ; } while (x &= x>>1);
12                       
13 0000000D C3               ret

L' BSRinstruction 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. ( bsrne produit pas directement 0 pour input = 0 comme le 32-lzcnt(x)ferait, mais nous avons besoin de bsr = 31-lzcnt pour les entrées non nulles, donc lzcntne sauverait même pas les instructions, sans parler du nombre d'octets. Mettre à zéro eax avant que la boucle fonctionne à cause de bsr' 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 de mov+ shr(4 octets).

Voir ce lien TIO pour un appelant asm qui neexit(longest_set(argc-1));

Test avec une boucle shell:

l=(); for ((i=0;i<1025;i++));do 
    ./longest-set-bitrun "${l[@]}";   # number of args = $i
    printf "$i %#x: $?\n" $i; 
    l+=($i); 
done | m

0 0: 0
1 0x1: 0
2 0x2: 1
3 0x3: 0
4 0x4: 2
5 0x5: 2
6 0x6: 1
7 0x7: 0
8 0x8: 3
9 0x9: 3
10 0xa: 3
11 0xb: 0
12 0xc: 2
13 0xd: 2
14 0xe: 1
15 0xf: 0
16 0x10: 4
17 0x11: 4
18 0x12: 4
19 0x13: 0
20 0x14: 4
21 0x15: 4

...

747 0x2eb: 5
748 0x2ec: 5
749 0x2ed: 5
750 0x2ee: 5
751 0x2ef: 0
752 0x2f0: 4
753 0x2f1: 4
754 0x2f2: 4
Peter Cordes
la source
1
Agréable! Une note pour ceux qui (comme moi) sont plus familiers avec les autres dialectes d'assemblage: le mnémonique x86 BSR signifie "Bit Scan Reverse", pas "Branch to SubRoutine".
Arnauld
@Arnauld: bon point, édité pour décoder la mnémonique ainsi que d'avoir un lien vers l'entrée manuelle de référence insn.
Peter Cordes
5

Gelée , 19 17 11 octets

HÐĿ&\ḟ0ṪBL’

Essayez-le en ligne!

-6 (!) Octets grâce aux vives observations de @ Dennis

Comment ça marche

HÐĿ&\ḟ0ṪBL’
HÐĿ         - halve repeatedly until reaching 0 due to rounding
   &\       - cumulative AND
     ḟ0Ṫ    - final non-zero, or 0 if all elements are 0
        BL  - length of binary representation (log base 2). 0->[0]->1
          ’ - decrement
fireflame241
la source
Erreurs pour 0, qui se trouve dans la plage d'entrée.
M. Xcoder du
@ Mr.Xcoder Fixed
fireflame241
Vous pouvez enregistrer un octet pour le correctif avecȯ-µ...
Jonathan Allan
@JonathanAllan Je ne comprends pas comment l'OR pourrait aider. Avez-vous du code?
fireflame241
1
Puisque Brenvoie toujours un tableau qui commence par un 1 , BUṪMṪ’×Ṡpeut devenir ṪBL’. De plus, vous n'avez pas besoin de la et ḟ0enregistre un octet de plus ¹Ðf.
Dennis
5

Python 2 , 45 octets

f=lambda x:f(x&x/2)if x&x/2else len(bin(x))-3

Essayez-le en ligne!

Beaucoup d'octets enregistrés grâce à Dennis! (Les chefs pourlen(bin(...))-3 au lieu de math.frexp)

Merci à @xnor d'avoir trouvé un bug, qui était heureusement facilement réparable!

M. Xcoder
la source
Cela semble donner de mauvaises réponses comme pour x=3, je pense parce que les and/orcourts-circuits sont incorrects lorsque la fonction retourne 0.
xnor
@xnor Merci de l'avoir remarqué! C'est réparé.
M. Xcoder
4

Perl 6 ,45 35 octets

Cette version hautement améliorée est une gracieuseté de @nwellnhof.

{.msb+1-(.base(2)~~m:g/1+/).max.to}

Essayez-le en ligne!

Ramillies
la source
Vous pouvez simplement faire correspondre avec :gpour obtenir tous les matchs. Avec l'opérateur de match intelligent, je pouvais le {sort(.base(2).flip~~m:g/1+/).tail.from}
jouer
Et à 35 octets:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof
@nwellnhof, merci beaucoup. J'ai en quelque sorte manqué le :get je n'ai pas compris comment utiliser l'adverbe avec l'opérateur smartmatch. De plus, la .msbméthode est très utile ici et je n'en savais rien auparavant.
Ramillies
3

Python 2 , 89 78 octets

m=t=i=j=0
for c in bin(input()):
 t=-~t*(c>'0');i+=1
 if t>m:j=i;m=t
print i-j

Essayez-le en ligne!

EDIT: enregistré 11 octets grâce à M. Xcoder.

Chas Brown
la source
86 octets
M. Xcoder
78 octets
M. Xcoder
@ Mr.Xcoder J'ai aussi pensé à cela, bien que la question demande spécifiquement d'écrire une fonction.
Jonathan Frech
@JonathanFrech Je ne pense pas que l'OP voulait vraiment dire fonction . Probablement juste un terme générique.
M. Xcoder
@ Mr.Xcoder Veuillez expliquer cela. Merci,
lifebalance
3

05AB1E , 14 12 11 octets

bDγàŠrkrJgα

Essayez-le en ligne! ou exécuter des cas de test .

Explication

bDγàŠrkrJgα  Implicit input (ex: 750)
bD           Convert input to binary string and duplicate
                 '1011101110', '1011101110'
  γ          Split into groups of 1s or 0s
                 '1011101110', ['1', '0', '111', '0', '111', '0']
   à         Pull out max, parsing each as an integer
                 '1011101110', ['1', '0', '0', '111', '0'], '111'
    Šrk      Rearrange stack and get first index of max run of ones
                 ['1', '0', '0', '111', '0'], 2
       rJg   Reverse stack, join the array to a string, and get its length
                 2, 7
          α  Get absolute difference
                 5
Justin Mariner
la source
3

J , 18 17 octets

(#-0{#\\:#.~\)@#:

Essayez-le en ligne!

Explication

(#-0{#\\:#.~\)@#:  Input: integer n
               #:  Binary
     #\            Length of each prefix
       \:          Sorted down using
         #.~\      Mixed base conversion on each prefix
   0{              Get the value at index 0
  -                Subtract from
 #                 Length
milles
la source
Très lisse. Je ne suis pas sûr de bien comprendre ce qui se passe avec la conversion de base mixte. Pourquoi compte-t-il le nombre de consécutifs à la fin de la chaîne? De plus, si les bases spécifiées sur la xdyade sont toutes 0 et 1, qu'est-ce que cela signifie? Un numéro de base 2 a des chiffres 0et 1donc un 1numéro de base a des chiffres ... 0? alors qu'est-ce qu'un 1moyen dans ce contexte? Et est-ce qu'un 0numéro de base est toujours juste 0?
Jonah
@Jonah C'est plus dû à la façon dont la conversion de base mixte est implémentée. x #. ycalcule d'abord w =: */\. }. x , 1puis retourne+/ w * y
miles
considérez-vous cela comme un hack de golf plutôt que comme une utilisation légitime #., car vous comptez sur les détails de mise en œuvre interne plutôt que sur l'api publique?
Jonah
3

C # (.NET Core) , 64 60 octets

T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)

Essayez-le en ligne!

Version AC # de la réponse de @ Arnauld

Remerciements

4 octets enregistrés grâce à Kevin Cruijssen.

C # (.NET Core) , 131 123 + 18 = 141 octets

a=>{string s=Convert.ToString(a,2),t=s.Split('0').OrderBy(x=>x.Length).Last();return a<1?0:s.Length-s.IndexOf(t)-t.Length;}

Essayez-le en ligne!

+18 octets pour using System.Linq;

Remerciements

8 octets économisés grâce à Grzegorz Puławski.

Dégolfé

a=>{
    string s=Convert.ToString(a,2),      // Convert to binary
    t=s.Split('0')                       // get largest group of 1's
       .OrderBy(x=>x.Length)
       .Last();
    return 
        a<1?0:                          // handle 0 case
        s.Length-s.IndexOf(t)-t.Length; // get position in reversed string
}

C # (.NET Core) , 164 161 octets

a=>{var s=Convert.ToString(a,2);int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;for(;i>=0;i--){if(s[i]>'0'){if(i==j||s[i+1]<'1'){p=i;c=0;}if(++c>=l){l=c;k=p;}}}return j-k;}

Essayez-le en ligne!

Une non- Linqsolution qui, j'en suis sûr, pourrait être améliorée, bien que rien ne soit immédiatement apparent.

Dégolfé

a=>{
    var s=Convert.ToString(a,2); // Convert to binary
    int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;
    for(;i>=0;i--)               // Loop from end of string
    {
        if(s[i]>'0')             // if '1'
        {
            if(i==j||s[i+1]<'1') // if first digit or previous digit was '0'
            {
                p=i;             // set the position of the current group
                c=0;             // reset the count
            }
            if(++c>=l)           // if count is equal or greater than current largest count
            {
                l=c;             // update largest count
                k=p;             // store position for this group
            }
        }
    }
    return j-k;                  // as the string is reversed, return string length minus position of largest group
}
Ayb4btu
la source
1
Vous pouvez économiser 8 octets en abandonnant rdans la première réponse: tio.run/##dY9RS8MwFIWfza/…
Grzegorz Puławski
Vous pouvez enregistrer deux octets dans votre port d' Arnauld comme ceci:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen
1
Ou même deux octets supplémentaires enregistrés ( 60 octets ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen
2

Coque , 12 octets

→S§-€¤≠Lo▲gḋ

Essayez-le en ligne!

Explication

                 Implicit input, e.g                           750
           ḋ     Convert to binary                             [1,0,1,1,1,0,1,1,1,0]
          g      Group equal elements                          [[1],[0],[1,1,1],[0],[1,1,1],[0]]
        o▲       Maximum                                       [1,1,1]
    €            Index of that substring in the binary number  3
     ¤≠L         Absolute difference of lengths                abs (3 - 10) = 7
 S§-             Subtract the two                              7 - 3 = 4
→                Increment                                     5
H.PWiz
la source
2

Gelée ,  14 13 12  11 octets

Bµṣ0Ṫ$ƤMḢạL

Un lien monadique prenant et retournant des entiers non négatifs.

Essayez-le en ligne! ou voir la suite de tests .

Comment?

Bµṣ0Ṫ$ƤMḢạL - Main link: number, n                   e.g. 750
B           - convert to a binary list                    [1,0,1,1,1,0,1,1,1,0]
 µ          - monadic chain separation, call that b
      Ƥ     - map over prefixes:  (i.e. for [1], [1,0], [1,0,1], [1,0,1,1],...)
     $      -   last two links as a monad:                e.g.: [1,0,1,1,1,0,1,1]
   0        -     literal zero                                   0
  ṣ         -     split (prefix) at occurrences of (0)           [[1],[1,1,1],[1,1]]
    Ṫ       -     tail                                                        [1,1]
       M    - maximal indices                             [5,9]
        Ḣ   - head                                        5
          L - length (of b)                               10
         ạ  - absolute difference                         5
Jonathan Allan
la source
J'avais une solution similaire mais utilisée ŒrṪPsur les préfixes à la place.
miles
2

Gelée , 19 octets

BŒgḄṀB
BwÇɓÇL+ɓBL_‘

Essayez-le en ligne!

Merci à Jonathan Allan d'avoir économisé  4  6 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 de1 s dans la représentation binaire ...

Explication

BŒgḄṀB - Lien d'aide monadique. Sera utilisé avec Ç dans le lien suivant.

B - Représentation binaire.
 Œg - Exécutions groupées d'éléments égaux consécutifs.
   Ḅ - Convertir du binaire en entier.
    Ṁ - Valeur maximale.
     B - Conversion d'un entier en binaire.


BwÇɓÇL + ɓBL_ '- Lien principal.

B - Représentation binaire (de l'entrée).
  Ç - Dernier lien en tant que monade. Prend l'entier d'entrée.
 w - Premier indice de sous-liste.
   ɓ - Commencez une chaîne dyadique distincte. Inverse les arguments.
    Ç - Dernier lien en tant que monade.
     L - Longueur.
      + - Addition
       ɓ - Commencez une chaîne dyadique distincte. Inverse les arguments.
        B - Binaire.
         L - Longueur.
          _ '- Soustrayez et incrémentez le résultat (car Jelly utilise l'indexation 1).
              - Sortie implicite.
M. Xcoder
la source
Votre lien d'aide pourrait être à la BŒgḄṀBplace
Jonathan Allan
@JonathanAllan Oh wow merci!
M. Xcoder
Votre lien principal pourrait êtreBwÇɓÇL+ɓBL_‘
Jonathan Allan
@JonathanAllan Wow, merci encore!
M. Xcoder
2

Kotlin , 77 octets

{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}

Embellie

{
    val b = it.toString(2)
    // Find the left position of the first instance of
    b.reversed().lastIndexOf(
            // The largest group of 1s
            b.split(Regex("0+")).max()!!)
}

Tester

var s:(Int)->Int =
{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}
fun main(args: Array<String>) {
    r(0, 0)
    r(142, 1)
    r(48, 4)
    r(750, 5)
}

fun r(i: Int, i1: Int) {
    var v = s(i)
    println("$i -> $v [$i1] ${i1 == v}")
}
jrtapsell
la source
Je n'ai pas testé mais je pense que cela fonctionne aussi en scala.
V. Courtois
2

Haskell , 101 98 96 75 octets

snd.maximum.(`zip`[0..]).c
c 0=[0]
c n|r<-c$div n 2=sum[r!!0+1|mod n 2>0]:r

Essayez-le en ligne! Utilisation: snd.maximum.(`zip`[0..]).c $ 142rendements 1.

Explication:

  • cconvertit 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 2calcule récursivement le rester de cette liste, tout en sum[r!!0+1|mod n 2>0]:rajoutant la longueur actuelle de la séquence à r. La compréhension de la liste vérifie si mod 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 de r) et en ajoute un. Sinon, la compréhension de la liste est vide et sum[]donne 0. Pour l'exemple d'entrée, c 142renvoie 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)].

  • maximumtrouve 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 et sndretourne le deuxième composant du tuple.

Laikoni
la source
2

C (gcc) , 81 80 octets

i,l,c,r;f(n){for(i=l=c=r=0;n;n/=2,i++)c=n&1?c+1:c>=l?r=i-(l=c),0:0;n=c<l?r:i-c;}

Essayez-le en ligne!

C (gcc) , 43 octets

Version AC de la réponse de @ Arnauld

k;f(n){n=(k=n&n/2)?f(k):(k=log2(n))<0?0:k;}

Essayez-le en ligne!

cleblanc
la source
Mlle le retour n; ou retourner k; de position
RosLuP
Suggérer à la n<1?0:log2(n)place de(k=log2(n))<0?0:k
plafondcat
2

MS SQL Server, 437 426 407 398 octets

SQL Fiddle

Je suis sûr que je pourrais supprimer les sauts de ligne, etc., mais c'est aussi compact que je voulais le faire:

create function j(@ int)
returns int
as BEGIN
declare @a varchar(max)='',@b int,@c int=0,@d int=0,@e int=0,@f int=0,@g int=0,@h int=0
while @>0 BEGIN SELECT @a=cast(@%2 as char(1))+@a,@=@/2
END
SET @b=len(@a)
while @<@b
BEGIN
select @c=@d,@d=cast(substring(@a,@b-@,1)as int)
IF @d=1
BEGIN IF @c=0
SELECT @e=@,@g=1
else SET @g+=1 END
IF @g>=@h BEGIN select @h=@g,@f=@e END
SET @+=1
END
return @f
END

Voici une version plus lisible:

create function BinaryString(@id int)
returns int
as BEGIN
  declare @bin varchar(max)
  declare @binLen int
  declare @pVal int = 0
  declare @Val int = 0
  declare @stC int = 0 --start of current string of 1s
  declare @stB int = 0 --start of biggest string of 1s
  declare @lenC int = 0 --length of current string of 1s
  declare @lenB int = 0 --length of biggest string of 1s

  set @bin = ''

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin
        SET @id = @id/2
      END

    SET @binLen = len(@bin)

    while @id<@binLen
      BEGIN
        set @pVal = @Val
        set @Val = cast(substring(@bin,@binLen-@id,1) as int)
        IF @Val = 1 and @pVal = 0
          BEGIN 
            SET @stC = @id
            SET @lenC = 1
          END
        IF @Val = 1 and @pVal = 1
          BEGIN 
            SET @lenC = @lenC + 1
          END
        IF @lenC >= @lenB
          BEGIN
            set @lenB = @lenC
            set @StB = @StC
          END

        SET @id = @id + 1 
      END

  return @StB
END

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.

phroureo
la source
Si vous pouvez jouer au golf plus, veuillez le faire. Mais sinon, c'est super! Bienvenue chez PPCG!
NoOneIsHere
@NoOneIsHere merci! J'ai réalisé que je pouvais aussi raccourcir le nom de ma fonction;)
phroureo
2

APL (Dyalog Unicode) , 22 caractères = 53 octets

Requiert ⎕IO←0ce qui est par défaut sur de nombreux systèmes.

⊃⌽⍸(∨⌿↑⊆⍨b)⍷⌽b2⊥⍣¯1⊢⎕

Essayez-le en ligne!

 invite pour l'entrée

 rendement qui (se sépare ¯1de )

2⊥⍣¯1 convertir en base-2, en utilisant autant de positions que nécessaire

b← stocker comme b(pour b inaire)

 sens inverse

() Marquer les positions de départ des éléments suivants en ce que:

⊆⍨b auto-partition b(ie les 1-séquence de b)

 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)

Adam
la source
vous manquez un ∇ dans le pied de page sur tio
ngn
@ngn Vous avez raison.
Adám
1

MATL , 15 octets

`tt2/kZ&t]xBnq&

Essayez-le en ligne!

Utilise la moitié et l'idée ET. Le kn'est nécessaire que pour le terminer 1- 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)

B. Mehta
la source
1

Google Sheets, 94 octets

=Len(Dec2Bin(A1))-Find(MAX(Split(Dec2Bin(A1),0)),Dec2Bin(A1))-Len(MAX(Split(Dec2Bin(A1),0)))+1

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 Dec2Binfonction a une valeur d'entrée maximale de 511. Tout ce qui est plus grand que cela renvoie une erreur, comme indiqué ci-dessous.

Results

Ingénieur Toast
la source
1

R, 117 octets

z=rev(Reduce(function(x,y)ifelse(y==1,x+y,y),strtoi(intToBits(scan())),,,T));ifelse(!sum(z),0,33-which.max(z)-max(z))
Zahiro Mor
la source
104 octets! Au lieu de rev, utilisez Reduce(...,T,T)pour accumuler à partir de la droite (commutation x,ydans la définition de la fonction). Ensuite, utilisez 1+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 utilisez any(z)au lieu de !sum(z)vous laissez tomber un octet.
Giuseppe
Je pense que nous devrions être en mesure d'obtenir cela à moins de 100 octets.
Giuseppe
@giuseppe Je me sens un peu tricheur d'être ici avant vous! Fera fois tnx un tas!
Zahiro Mor
Mais une belle approche non?
Zahiro Mor
1
Oh, pas de soucis, j'ai vu ça plus tôt mais je n'ai pas eu envie d'y répondre parce que R est si mauvais aux opérations de bits ... Ouais, bon travail, tu as mon +1
Giuseppe
1

Excel VBA, 54 44 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 VBE

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]
Taylor Scott
la source
1
Outre la surveillance ayant C1toujours là-dedans au lieu de A1, je pense que vous pouvez produire les Instrré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.
Ingénieur Toast
@EngineerToast - Sweet! I should have seen that; I was able to drop it down 2 bytes by bringing the >0 into the [A1] notation
Taylor Scott
0

R, 66 Bytes

function(i){a=rle(intToBits(i));max(0,a[[1]][which(a[[2]]==1)])}

Explanation:

function(i){
  a = rle(                  # Run-length encode
    intToBits(i)            # The bits in i
  );                        # And assign it to a.
  max(0,                    # Return the maximum of zero and
      a[[1]][               # The lengths of a,
        which(a[[2]]==1)    # But only those where the repeated bit is 1
        ])
}
Julian Zucker
la source
1
This returns the length of the longest streak, not its position. Check against the test cases and the specs at the top.
user2390246
I will change my downvote to an upvote once this answer is corrected. Also, note that you can use a$l instead of a[[1]] and a$v instead of a[[2]] to save some bytes :), as well as >0 instead of ==1.
Giuseppe
0

Javascript, 54 chars

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) gets the binary string for the integer.
  • The .split(0) gets each sequential ones part in an array element.
  • .sort().reverse() gets us the highest value as first.
  • The [0].length gives us the length of that first value.
nl-x
la source
the starting position of number of largest consecutive 1's
L3viathan
0

Perl 5, 45 + 1 (-p)

(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'

If you write this out on the command line of most shells, you may have to type this as:

perl -pE'(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'"'"

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
0

Retina, 52 43 bytes

Convert to binary, then replace with the length of what follows the largest string of ones.

.*
$*
+`(1+)\1
$+0
01
1

$'¶
O`
A-3`
^1+

.

Try it online - all test cases

Saved 9 bytes thanks to Martin.

mbomb007
la source
You can use $+ for ${1}. But you can save even more by replacing the last stage with a bunch of stages like this: tio.run/##K0otycxL/K/…
Martin Ender
@MartinEnder Ok. The ${1} was copied from your tutorial on Github.
mbomb007