Décomposer le binaire en sous-séquences alternées


30

Cela a été inspiré par le problème 13 - Binaire non répétitif de la récente compétition de HP CodeWars.

Prenons un nombre décimal aléatoire, disons

727429805944311

et regardez sa représentation binaire:

10100101011001011111110011001011101010110111110111

Maintenant, divisez cette représentation binaire en sous-séquences où les chiffres 0et 1alternent.

1010 010101 10 0101 1 1 1 1 1 10 01 10 0101 1 1010101 101 1 1 1 101 1 1

Et reconvertissez chaque sous-séquence en décimal.

10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

La tâche

Prenez un seul entier positif comme entrée et sortez la séquence d'entiers positifs obtenue par le processus ci-dessus.

Détails

  • L'entrée et la sortie doivent être décimales ou unaires.
  • Les nombres dans la sortie doivent être séparés d'une manière sensible et lisible par l'homme, et ils doivent être décimaux ou unaires. Aucune restriction sur l'espace blanc. Styles de sortie valides: [1,2,3], 1 2 3, 1\n2\n3\nsont les nouvelles lignes littérales, etc.

Cas de test

 Input | Output
     0 | 0
     1 | 1
     2 | 2
     3 | 1 1
     4 | 2 0
     5 | 5
     6 | 1 2
     7 | 1 1 1
     8 | 2 0 0
     9 | 2 1
    10 | 10
    50 | 1 2 2
   100 | 1 2 2 0
  1000 | 1 1 1 1 10 0 0
 10000 | 2 1 1 2 0 2 0 0 0
 12914 | 1 2 2 1 1 2 2
371017 | 5 42 10 2 1

Remarque supplémentaire: tous les nombres dans la sortie doivent être de la forme (2^k-1)/3ou 2*(2^k-1)/3. Autrement dit, 0 1 2 5 10 21, 42, 85, 170, ...qui est A000975 dans l'OEIS.


@DigitalTrauma: Hmmm ...... non, je ne pense pas que ce soit dans l'esprit du défi.
El'endia Starman

D'accord. |tacrestera dans ma réponse alors :)
Digital Trauma

Réponses:


11

Pyth, 17 16 octets

1 octet grâce à Jakube

iR2cJ.BQx1qVJ+dJ

Manifestation

Une belle solution intelligente. Utilise certaines fonctionnalités moins connues de Pyth, comme x<int><list>et c<str><list>.

iR2cJ.BQx1qVJ+dJ
                    Q = eval(input())
    J.BQ            Store in J the input in binary.
          qV        Vectorize equality function over
            J+dJ    J and J with a leading dummy char, to get the offset right.
                    This calculates whether each element matches its successor.
        x1          Find all of the indexes of 1 (True) in this list.
   cJ                Chop J at those locations.
iR2                  Convert from binary back to base ten and output.

1
Si vous remplacez tJpar +dJvous pouvez supprimer hM.
Jakube

@Jakube Nice one!
isaacg

7

Mathematica, 47 octets

#+##&~Fold~#&/@#~IntegerDigits~2~Split~Unequal&

Non golfé:

FromDigits[#,2]&/@Split[IntegerDigits[#,2],Unequal]&

Split[list,f]divise une liste en plusieurs listes, la rupture à la position entre aet bsi siff f[a,b]ne revient pas True.

FromDigits[n,2] => Fold[#+##&,n]est une astuce soignée des alephalpha.


7

Python, 86 octets

Depuis que je me suis horriblement surpassé en Pyth, faisons-le à nouveau en Python.

import re
lambda n:[int(s,2)for s in re.sub("(?<=(.))(?=\\1)"," ",bin(n)[2:]).split()]

Essayez-le ici!

Explication

Nous commençons par convertir le numéro d'entrée nen une chaîne binaire. bin(n)[2:]s'occupe de ça. Nous devons supprimer les 2 premiers caractères de cette chaîne, car bin()renvoie la chaîne au format 0b10101.
Ensuite, nous devons identifier les frontières des sous-séquences. Cela peut être fait avec l'expression régulière (?<=(.))(?=\1)qui correspond aux positions de longueur nulle dans la chaîne qui ont le même nombre à gauche et à droite.
La manière la plus évidente d'obtenir une liste de toutes les sous-séquences serait d'utiliser re.split()ce qui sépare une chaîne sur une certaine expression régulière. Malheureusement, cette fonction ne fonctionne pas pour les correspondances de longueur nulle. Mais heureusement re.sub(), nous remplaçons simplement ces correspondances de longueur nulle par des espaces et divisons la chaîne sur celles après cela.
Ensuite, nous devons simplement analyser chacune de ces sous-séquences en un nombre décimal avec int(s,2)et nous avons terminé.


4

Gelée, 12 octets

BI¬-ẋż@BFṣ-Ḅ

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

BI¬-ẋż@BFṣ-Ḅ  Main link. Argument: n

B             Convert n to base 2.
 I            Compute the increments, i.e., the differences of consecutive digits.
  ¬           Apply logical NOT.
   -ẋ         Repeat -1 that many times, for the logical NOT of each difference.
              [0, 0] / [1, 1] ->   0    -> 1 -> [-1]
              [0, 1] / [1, 0] -> 1 / -1 -> 0 -> []
       B      Yield n in base 2.
     ż@       Zip the result to the right with the result to the left.
        F     Flatten the resulting list of pairs.
         ṣ-   Split at occurrences of -1.
           Ḅ  Convert each chunk from base 2 to integer.

Sûrement 12 caractères mais 20 octets. Ou utilisez-vous un système avec CHAR_BIT >> 8?
James Youngman

1
@JamesYoungman Jelly n'utilise pas UTF-8 par défaut. En fait, il a sa propre page de codes qui code chacun des 256 caractères qu'il comprend chacun comme un seul octet.
Dennis

4

Utilitaires Bash + GNU, 51

dc -e2o?p|sed -r ':;s/(.)\1/\1 \1/;t'|dc -e2i?f|tac

Entrée provenant de STDIN.

  • dc -e2o?p lit l'entier d'entrée de STDIN et sort une chaîne de base 2
  • sed -r ':;s/(.)\1/\1 \1/;t' divise la chaîne de base 2 avec un espace partout, il y a les mêmes chiffres consécutifs
  • dc -e2i?flit le binaire divisé en une fois, en plaçant chaque partie sur la pile, puis fvide la dcpile entière (numéros de sortie dans l'ordre inverse) ...
  • ... qui est corrigé par tac.

4

JavaScript (ES6) 58 62 63

modifier 1 octet enregistré thx @ETHproductions

Modifier 4 octets enregistrés thx @Neil

x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

f=x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

 
console.log=x=>O.textContent+=x+'\n'

;[
[     0,'0'],
[     1,'1'],
[     2,'2'],
[     3,'1 1'],
[     4,'2 0'],
[     5,'5'],
[     6,'1 2'],
[     7,'1 1 1'],
[     8,'2 0 0'],
[     9,'2 1'],
[    10,'10'],
[    50,'1 2 2'],
[   100,'1 2 2 0'],
[  1000,'1 1 1 1 10 0 0'],
[ 10000,'2 1 1 2 0 2 0 0 0'],
[ 12914,'1 2 2 1 1 2 2'],
[371017,'5 42 10 2 1']
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
  console.log(i+' -> '+r+(r.trim()==k.trim() ? ' ok':'ko (should be '+k+')'))
})
<pre id=O></pre>


Pourriez-vous enregistrer deux octets avec l'expression régulière /(01)*0?|(10)*1?/g, ou est-ce que cela gâcherait quelque chose ??
ETHproductions

1
De plus, je pense que vous pourriez faire x=>'0b'+x-0+' 'pour enregistrer un octet.
ETHproductions du

@ETHproductions J'ai essayé l'expression rationnelle plus courte, pas bon :(. Thx pour l'autre indice
edc65

Le Leadboard indique que vous avez une réponse de 1 octet. Je suppose que c'est parce que vous avez le numéro corrigé (62) avant l'ancien numéro (63) plutôt qu'après.
Kyle Kanos

Je pense que l'expression /((.)(?!\2))*./grégulière vous fait économiser 4 octets.
Neil

3

Pyth, 26 octets

iR2c:.BQ"(?<=(.))(?=\\1)"d

Essayez-le ici!

Explication

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = numéro d'entrée

     .BQ # Convertir l'entrée en binaire
    : "(? <= (.)) (? = \\ 1)" d # insère un espace entre les sous-séquences
   chaîne de partage c # sur les espaces blancs
iR2 # convertit chaque sous-séquence en décimal

Étant donné que la fonction split () de Python ne se divise pas sur les correspondances de longueur nulle, je dois remplacer ces correspondances par un espace et diviser le résultat à ce sujet.


3

Pyth, 22 21 octets

&Qu?q%G2H&
GH+yGHjQ2Z

Essayez-le en ligne: Démonstration

Vraiment une tâche fastidieuse en Pyth.

Explication:

&Qu?q%G2H&\nGH+yGHjQ2Z   implicit: Q = input number
                  jQ2    convert Q to base 2
  u               jQ2Z   reduce ^: for each digit H update the variable G=0:
   ?q%G2H                   if G%2 == H:
          \nG                  print G
         &   H                 then update G with H
              +yGH           else: update G with 2*G+H
  u                      print the last G also
&Q                       handle Q=0 special: only print 0 once

3

05AB1E , 18 octets

Code:

b2FNð«N«Dð-s:}ð¡)C

Explication:

b                   # Convert input to binary
 2F          }      # Do the following twice ( with N as range variable)
   Nð«N«            #    N + space + N
        D           #    Duplicate this
         ð-         #    Delete spaces from the duplicate string
           s        #    Swap the top two elements
            :       #    Replace the first string with the second
              ð¡    # Split on spaces
                )   # Wrap into an array
                 C  # Convert all element back to decimal

Essayez-le en ligne!

Utilise l' encodage CP-1252 .


3

MATL , 18 17 octets

YBTyd~Thhfd1wY{ZB

Essayez-le en ligne!

YB      % input number. Convert to binary string
T       % push true value
y       % duplicate binary string and push it at the top of the stack
d~      % true for each value that equals the previous one
T       % push true value
hh      % concatenate: true, indices, true
f       % find indices of true values
d       % consecutive differences: lenghts of alternating sequences
1wY{    % split binary string according to those lengths
ZB      % convert each substring into decimal number

3

zsh, 67 63 55 octets

for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i]

Je ne sais pas pourquoi, mais cela ne fonctionne pas dans Bash.

Merci à Dennis pour 8 octets!


C'est la forsyntaxe. ... Attendez, non for?
CalculatorFeline

L'expansion arithmétique de Bash ne vous permet pas de spécifier une base de sortie. Pour vous débarrasser des xargs, vous pouvez utiliser for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i].
Dennis

2

PHP, 171 168 162 160 158 121 120 131 124 118 116 113 113 112 bytes

function d($i){for(;$d<$l=strlen($b=decbin($i));){$c.=$u=$b[$d];echo$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"";}}
Vue éclatée
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

Utilisez d(int)et vous êtes désactivé, la sortie est une echochaîne ed de ints séparés par un espace.

Modifications:
-3:$b définition déplacée dans l' strlen()appel.
-6: Suppression de l' $cinstanciation.
-2: Finalement corrigé le problème de concaténation.
-2: Pas de crochets pour une seule ligne for().
-37: Révision totale. Aller avec des Arraychunklets au lieu d' appels répétés Array-> String-> Array.
-1:$c Réinitialisation sournoise .
+11: Bugfix. Il manquait le dernier morceau. Pas plus.
-7: Vous n'avez pas du tout besoin d'instancier $d? Agréable.
-6: return -> echo.
-2: Crunching $c.
-3:Ternary, mon premier amour.
-1: Sournois sournois $u.


Je pense que vous pouvez enregistrer 2 octets: function d($i){for(;$d<$l=strlen($b=decbin($i));print$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"")$c.=$u=$b[$d];}.
Blackhole

2

Convexe 0,2+, 25 octets

Convex est un nouveau langage que je développe qui est fortement basé sur CJam et Golfscript. L'interprète et l'IDE peuvent être trouvés ici . L'entrée est un entier dans les arguments de la ligne de commande. Il utilise l' encodage CP-1252 .

2bs®(?<=(.))(?=\\1)"ö2fbp

Explication:

2bs                         Convert to binary string
   ®(?<=(.))(?=\\1)"        Regex literal
                    ö       Split string on regex
                     2fb    Convert each split string into decimal integer
                        p   Print resulting array

2

Java 8, 127 119 octets

l->new java.util.ArrayList<Long>(){{for(String s:l.toBinaryString(l).split("(?<=(.))(?=\\1)"))add(l.parseLong(s,2));}};

Il existe probablement une meilleure expression régulière pour diviser la chaîne. Je ne suis pas compétent en regex, mais je continuerai d'expérimenter.

-8 octets grâce à @FryAmTheEggman


2

APL (APL) , 21 25 octets

Gère désormais 0 également.

{0::0⋄2⊥¨⍵⊂⍨1,2=/⍵}2⊥⍣¯1⊢

Essayez-le en ligne!

2⊥⍣¯1⊢ convertir en base-2, en utilisant autant de bits que nécessaire (conversion inversée par rapport à la base-2)

{}  Appliquer la fonction anonyme suivante

0:: en cas d'erreur:

  0 retour 0

 Essayez maintenant:

  2=/⍵ égalité par paire de l'argument (échouera la représentation binaire de longueur 0 de 0)

  1, ajouter 1

  ⍵⊂⍨ utiliser cela pour partitionner l'argument (commence une nouvelle section sur chaque 1)

  2⊥¨ convertir chacun de base-2


1
est vraiment utile ici. Je devrais ajouter ça à Jelly.
Dennis

@Dennis Soyez conscient des deux versions de R←X⊂Y: Avec ⎕ML<3(c'est-à-dire le style Dyalog), une nouvelle partition est démarrée dans le résultat correspondant à chaque 1 dans X jusqu'à la position avant que le 1 suivant dans X (ou le dernier élément de X) devienne les éléments successifs de R. Avec ⎕ML=3(ie style IBM), une nouvelle partition est démarrée dans le résultat chaque fois que l'élément correspondant dans X est supérieur au précédent. Les éléments en Y correspondant à 0 en X ne sont pas inclus dans le résultat. ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7Est donc équivalent à ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⍳7`
Adám

2

Japt , 7 octets

¤ò¥ mn2

Essaye-le


Explication

¤ò¥ mn2
           :Implicit input of integer U.
¤          :Convert to binary string.
 ò¥        :Split to an array by checking for equality.
    m      :Map over array.
     n2    :Convert to base-10 integer.

1

Python 3, 115 octets

def f(s):
 s=bin(s);r=[s[2]]
 for i in s[3:]:
  if i==r[-1][-1]:r+=[i]
  else:r[-1]+=i
 return[int(x,2)for x in r]

Explication

def f(s):
 s=bin(s)                   # convert input in binary
 r=[s[2]]                   # initialize the result with the first char after the 'b' in binary string
 for i in s[3:]:            # loop on other element
  if i==r[-1][-1]:          # if the last element of the last string equal the current element 
   r+=[i]                   # we add the current element in a new string
  else:
   r[-1]+=i                 # we add the current element to the last sting
 return[int(x,2)for x in r] # convert binary string in integer 

Résultats

>>> [print(i,f(i)) for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100, 1000, 10000, 12914, 371017]]
0 [0]
1 [1]
2 [2]
3 [1, 1]
4 [2, 0]
5 [5]
6 [1, 2]
7 [1, 1, 1]
8 [2, 0, 0]
9 [2, 1]
10 [10]
50 [1, 2, 2]
100 [1, 2, 2, 0]
1000 [1, 1, 1, 1, 10, 0, 0]
10000 [2, 1, 1, 2, 0, 2, 0, 0, 0]
12914 [1, 2, 2, 1, 1, 2, 2]
371017 [5, 42, 10, 2, 1]

solution précédente (118 octets)

def f(s):
 s=bin(s);r=s[2]
 for i in s[3:]:
  if i==r[-1]:r+='a'+i
  else:r+=i
 return[int(x,2)for x in r.split('a')]

1

Haskell, 147 , 145 octets

x%[]=[x]
x%(y:z)|or.(zipWith(==)<*>tail)$y:x=x:[]%(y:z)|1<2=(y:x)%z
b x|x<2=[x]|1<2=b(div x 2)++[mod x 2]
map(sum.zipWith((*).(2^))[0..]).([]%).b

map(sum.zipWith((*).(2^))[0..]).([]%).b est une fonction sans nom qui calcule la liste.

Moins golfé:

alternating :: Eq a => [a] -> Bool
alternating = or . (zipWith (==) <*> tail)

-- (%) is the partitioning function
(%) :: Eq a => [a] -> [a] -> [[a]]
x % [] = [x]

x % (y:z) | alternating (y : x) = x : [] % (y:z)
          | otherwise = (y : x) % z

bits :: Integral t => t -> [t]
bits x | x < 2     = [x] 
       | otherwise = bits (div x 2) ++ [mod x 2]

unBits :: Num c => [c] -> c
unBits = sum . zipWith ((*) . (2^)) [0..]

f :: Integer -> [Integer]
f = map unBits . ([]%) . bits

1

Perl, 53 octets

Comprend +1 pour -p

Courir avec le numéro sur STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

$_=sprintf"0b%b",$_;s/(.)\K(?=\1)/ 0b/g;s/\S+/$&/eeg

1

PowerShell, 103 octets

[regex]::Matches([convert]::ToString($args[0],2),"(01)+0?|(10)+1?|.").Value|%{[convert]::toint32($_,2)}

Puisque je suis horrible à regex, j'utilise la même expression que la réponse d'edc65 .

Absolument détruit par les longs appels .NET pour effectuer la conversion vers / depuis le binaire et l'appel .NET pour obtenir les correspondances d'expression régulière. Sinon, c'est assez simple. Prend l'entrée $args[0], converts en binaire, l'introduit dans Matches, prend le .Values résultant , les canalise à travers une boucle |%{...}et convertrenvoie ces valeurs à int. La sortie est laissée sur le pipeline et implicitement imprimée avec des retours à la ligne.


Pour un crédit supplémentaire - une version (principalement) non regex à 126 octets

$l,$r=[char[]][convert]::ToString($args[0],2);$l+-join($r|%{(" $_",$_)[$l-bxor$_];$l=$_})-split' '|%{[convert]::toint32($_,2)}

Nous prenons à nouveau l'entrée $args[0]et convertle binaire. Nous avons recréé en tant que tableau de caractères, stockant le premier caractère dans $let les caractères restants dans $r. Nous envoyons ensuite à $rtravers une boucle |%{...}où chaque itération que nous sélectionnons à partir du caractère précédé d'un espace ou simplement du caractère, en fonction du résultat d'un xor binaire avec $l, puis défini comme $légal au caractère. Cela garantit effectivement que si nous avons le même caractère deux fois de suite, nous ajoutons un espace entre eux.

La sortie de la boucle est -joinéditée ensemble et ajoutée au premier caractère $l, puis -splitsur les espaces (qui est techniquement une expression régulière, mais je ne vais pas le compter). Nous faisons ensuite la même boucle que la réponse régulière convertet la sortie des entiers.


1

Java 345 octets

package com.ji.golf;
import java.util.regex.*;
public class Decompose {
  public static String decompose(long l) {
    String o="";
    String s=Long.toBinaryString(l);
    Matcher m=Pattern.compile("(01)+(0)?|(10)+(1)?|(1)|(0)").matcher(s);
    while(m.find()){String c=s.substring(m.start(),m.end());o+=Integer.parseInt(c, 2)+" ";}
    return o;
  }
}

Tester

package com.ji.golf;
public class DecompseTest {
  public static void main(String[] args) {
    String[] inOut = new String[]{
        "0,0",
        "1,1",
        "2,2",
        "3,1 1",
        "4,2 0",
        "5,5",
        "6,1 2",
        "7,1 1 1",
        "8,2 0 0",
        "9,2 1",
        "10,10",
        "50,1 2 2",
        "100,1 2 2 0",
        "1000,1 1 1 1 10 0 0",
        "10000,2 1 1 2 0 2 0 0 0",
        "12914,1 2 2 1 1 2 2",
        "371017,5 42 10 2 1"
    };
    for (String s : inOut) {
      String[] io = s.split(",");
      String result = Decompose.decompose(Long.parseLong(io[0]));
      System.out.println("in: " + io[0] + ", reusult: [" +  result.trim() + "], validates? " + result.trim().equals(io[1].trim()));
    }
  }
}

Sortie

in: 0, reusult: [0], validates? true
in: 1, reusult: [1], validates? true
in: 2, reusult: [2], validates? true
in: 3, reusult: [1 1], validates? true
in: 4, reusult: [2 0], validates? true
in: 5, reusult: [5], validates? true
in: 6, reusult: [1 2], validates? true
in: 7, reusult: [1 1 1], validates? true
in: 8, reusult: [2 0 0], validates? true
in: 9, reusult: [2 1], validates? true
in: 10, reusult: [10], validates? true
in: 50, reusult: [1 2 2], validates? true
in: 100, reusult: [1 2 2 0], validates? true
in: 1000, reusult: [1 1 1 1 10 0 0], validates? true
in: 10000, reusult: [2 1 1 2 0 2 0 0 0], validates? true
in: 12914, reusult: [1 2 2 1 1 2 2], validates? true
in: 371017, reusult: [5 42 10 2 1], validates? true

4
Bienvenue sur Programmation Puzzles & Code Golf! Puisqu'il s'agit d'une compétition de code-golf , vous devez rendre votre code aussi court que possible. Voici quelques conseils pour jouer au golf à Java. Vous pouvez commencer par définir votre fonction sans le passe-partout packageet class, et supprimer les espaces inutiles. Faites moi savoir si vous avez des questions!
Alex A.

1

Julia, 70 57 octets

n->map(i->parse(Int,i,2),split(bin(n),r"(?<=(.))(?=\1)"))

Il s'agit d'une fonction anonyme qui accepte un entier et renvoie un tableau d'entiers. Pour l'appeler, affectez-le à une variable.

L'approche ici est similaire à la jolie réponse Python de DenkerAffe . Nous obtenons la représentation binaire de l' nutilisation bin(n)et divisons la chaîne résultante à toutes les correspondances de l'expression régulière (?<=(.))(?=\1). C'est en fait une correspondance de longueur nulle; (?<=(.))est un lookbehind positif qui trouve n'importe quel caractère, et (?=\1)est un lookahead positif qui trouve le caractère correspondant dans le lookbehind. Cela localise les endroits où un nombre est suivi de lui-même dans la représentation binaire. Juste parsechacun comme un entier dans la base 2 en utilisant mapet le tour est joué!


1

C, 137 129 octets

main(){unsigned long a,b=scanf("%lu",&a),c=!!a;while(a>=b*2)b*=2;while(b)b/=2,c=c*(~(a^a/2)&b|!b?!printf("%lu\n",c):2)+!!(a&b);}

L'entrée et la sortie sont sur les flux standard.


Je ne pense pas que vous en ayez besoin puts, même si ce serait désagréable à utiliser, la spécification ne nécessite pas de retour à la ligne.
FryAmTheEggman

@FryAmTheEggman Je préfère ne pas générer une dernière ligne incomplète. Mais pour le coût d'un octet (toujours une réduction nette), je peux changer le séparateur de l'espace en nouvelle ligne.
Fox

1

J , 16 octets

#:#.;.1~1,2=/\#:

Essayez-le en ligne!

Explication

#:#.;.1~1,2=/\#:  Input: integer n
              #:  Convert from decimal to list of binary digits
          2  \    For each overlapping sublist of size 2
           =/       Reduce using equals
        1,        Prepend 1
#:                Binary digits
    ;.1~          Partition those binary digits at the 1s in the previous list
  #.                Convert each partition from a list of binary digits to decimal

1

q / kdb +, 52 octets

Solution:

{2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}

Exemples:

q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}0
,0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}1
,1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}3
1 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}8
2 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}10000
2 1 1 2 0 2 0 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}12914
1 2 2 1 1 2 2
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}371017
5 42 10 2 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}727429805944311
10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

Explication:

q est interprété de droite à gauche.

Transtypez les entrées en binaire, coupez les zéros en tête, trouvez les indices où différents, inversez pour obtenir les indices où les mêmes, divisez la liste sur ces indices, reconvertissez en base-10. Semble un peu lourd par rapport à la solution APL ...

{2 sv'cut[0,where not differ a]a:(63^first where a)_a:0b vs x} / ungolfed solution
{                                                            } / lambda function
      cut[                    ]                                / cut a list at indices, cut[indices]list
                                                      0b vs x  / converts to 64bit binary representation
                                                    a:         / save as a
                                                   _           / drop 'n' elements from a
                                 (                )            / evaluate this
                                     first where a             / returns first occurance of true in list a
                                  63^                          / fill result with 63 if null (to handle input of 0)
                               a:                              / save as a, we've stripped off all the left-most 0s
                      differ a                                 / whether or not item in list a is different to previous
                  not                                          / the inversion of this result
            where                                              / these are the points where we have 00 or 11
          0,                                                   / add the first index too!
  2 sv'                                                        / 2 sv converts binary back to base-10, ' for each list

0

PHP, 147

$b=decbin($argv[1]);$a=[$t=$b[0]];$k=0;for($i=1;$i<strlen($b);$i++){$v=$b[$i];if($v==$t)$k++;$t=$v;$a[$k].=$v;}foreach($a as$c)echo bindec($c).' ';

Besoin de mettre de l'espace supplémentaire à la fin de la sortie car il n'y a aucune restriction. Les avis sont affichés pour un codage court.

Version non golfée

$n=$argv[1];
$b=decbin($n);
$l=strlen($b);
$t=$b[0];
$a=[0=>$t];$k=0;
for($i=1;$i<$l;$i++){
    $v=$b[$i];
    if($v==$t){
        $k++;
    }
    $t=$v;$a[$k].=$v;    
}
foreach($a as $c){
    echo bindec($c).' ';
}

0

Rétine, 60

+`(1+)\1
$1a
a1
1
(?<=(.))(?=\1)
¶
+`1(a*)\b
a$.1$*1;
a

;
1

Essayez-le en ligne! Ou essayez une version légèrement modifiée pour tous les cas de test (avec E / S décimales).

Malheureusement, les correspondances de longueur nulle semblent avoir deux "côtés", ce qui entraîne une duplication lorsqu'elles sont utilisées avec l'expression régulière de la troisième étape. Cependant, cela ne coûte qu'un octet.

Prend l'entrée comme unaire, les sorties comme unaire. Pas vraiment sûr d'utiliser différentes valeurs unaires d'entrée / sortie, mais cela économiserait 4 octets.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.