Zerlegen Sie Binärdateien in alternierende Teilsequenzen

30

Dies wurde inspiriert von Problem 13 - Non-Repeating Binary der letzten Konkurrenz von HP CodeWars.

Nehmen wir zum Beispiel eine zufällige Dezimalzahl

727429805944311

und schauen Sie sich seine binäre Darstellung an:

10100101011001011111110011001011101010110111110111

Teilen Sie nun diese Binärdarstellung in Teilfolgen auf, in denen sich die Ziffern 0und 1abwechseln.

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

Und konvertiere jede Teilsequenz zurück in eine Dezimalzahl.

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

Die Aufgabe

Nehmen Sie eine einzelne positive Ganzzahl als Eingabe und geben Sie die Folge positiver Ganzzahlen aus, die durch den obigen Prozess erhalten wurden.

Einzelheiten

  • Eingabe und Ausgabe müssen dezimal oder unär sein.
  • Zahlen in der Ausgabe müssen sinnvoll und für den Menschen lesbar getrennt und dezimal oder unär sein. Keine Einschränkung des Leerraums. Gültige Ausgabestile: [1,2,3], 1 2 3, 1\n2\n3wo \nsind wörtliche Zeilenumbrüche usw.

Testfälle

 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

Zusätzlicher Hinweis: Alle Zahlen in der Ausgabe sollten die Form (2^k-1)/3oder haben 2*(2^k-1)/3. Das heißt, 0 1 2 5 10 21, 42, 85, 170, ...das ist A000975 im OEIS.

El'endia Starman
quelle
@DigitalTrauma: Hmmm ...... nein, ich glaube nicht, dass das im Geiste der Herausforderung liegt.
El'endia Starman
Okay. |tacwerde dann in meiner antwort bleiben :)
Digital Trauma

Antworten:

11

Pyth, 17 16 Bytes

1 Byte danke an Jakube

iR2cJ.BQx1qVJ+dJ

Demonstration

Eine schöne, clevere Lösung. Verwendet einige weniger bekannte Funktionen von Pyth, wie x<int><list>und 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.
isaacg
quelle
1
Wenn Sie ersetzen tJdurch +dJkönnen Sie entfernen hM.
Jakube
@ Jakube Schöne!
isaacg
7

Mathematica, 47 Bytes

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

Ungolfed:

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

Split[list,f]Teilt eine Liste in mehrere Listen auf und bricht an der Position zwischen aund biff f[a,b]kehrt nicht zurück True.

FromDigits[n,2] => Fold[#+##&,n]ist ein guter Tipp von Alephalpha.

Feersum
quelle
7

Python, 86 Bytes

Da ich mich in Pyth fürchterlich geärgert habe, lass es uns einfach wieder in Python machen.

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

Probieren Sie es hier aus!

Erläuterung

Wir beginnen mit der Umwandlung der eingegebenen Zahl nin eine Binärzeichenfolge. bin(n)[2:]kümmert sich darum. Wir müssen die ersten 2 Zeichen dieser Zeichenfolge verwerfen, da bin()die Zeichenfolge im Format zurückgegeben wird 0b10101.
Als nächstes müssen wir die Grenzen der Teilsequenzen identifizieren. Dies kann mit dem regulären Ausdruck erfolgen, der mit den (?<=(.))(?=\1)Positionen der Länge Null in der Zeichenfolge übereinstimmt, die links und rechts die gleiche Nummer haben.
Die naheliegende Möglichkeit, eine Liste aller Teilsequenzen zu erhalten, besteht darin, re.split()eine Zeichenfolge in einem bestimmten regulären Ausdruck aufzuteilen. Leider funktioniert diese Funktion nicht für Übereinstimmungen mit der Länge Null. Glücklicherweise re.sub()ersetzen wir diese Übereinstimmungen mit der Länge Null durch Leerzeichen und teilen die Zeichenfolge danach auf.
Dann müssen wir nur noch jede dieser Teilsequenzen in eine Dezimalzahl umwandeln int(s,2)und fertig.

Denker
quelle
4

Gelee, 12 Bytes

BI¬-ẋż@BFṣ-Ḅ

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

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.
Dennis
quelle
Sicher 12 Zeichen aber 20 Bytes. Oder verwenden Sie ein System mit CHAR_BIT >> 8?
James Youngman
1
@JamesYoungman Jelly verwendet standardmäßig kein UTF-8. Tatsächlich verfügt es über eine eigene Codepage , die jedes der 256 Zeichen, die es versteht, als ein einzelnes Byte codiert.
Dennis
4

Bash + GNU-Dienstprogramme, 51

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

Eingabe von STDIN.

  • dc -e2o?p Liest eine Ganzzahl aus STDIN und gibt einen String zur Basis 2 aus
  • sed -r ':;s/(.)\1/\1 \1/;t' Teilt die Zeichenfolge der Basis 2 mit einem Leerzeichen, wenn dieselben aufeinander folgenden Ziffern vorhanden sind
  • dc -e2i?fLiest die geteilte Binärdatei auf einmal, legt jeden Teil auf den Stapel und gibt dann fden gesamten dcStapel aus (Ausgabenummern in umgekehrter Reihenfolge) ...
  • ... was korrigiert wird von tac.
Digitales Trauma
quelle
4

JavaScript (ES6) 58 62 63

Bearbeite 1 Byte gespeichert dank @ETHproductions

Bearbeite 4 Bytes gespeichert als @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>

edc65
quelle
Könnten Sie mit der Regex zwei Bytes sparen /(01)*0?|(10)*1?/g, oder würde das etwas durcheinander bringen?
ETHproductions
1
Außerdem denke ich, dass Sie tun könnten x=>'0b'+x-0+' ', um ein Byte zu speichern.
ETHproductions
@ETHproductions Ich habe versucht, die kürzere Regexp, nicht gut :(. Thx für den anderen Hinweis
edc65
Das Leadboard gibt an, dass Sie eine 1-Byte-Antwort haben. Ich nehme an, es liegt daran, dass Sie die korrigierte Nummer (62) vor der alten Nummer (63) anstatt nachher haben.
Kyle Kanos
Ich denke, die Regex /((.)(?!\2))*./gspart dir coole 4 Bytes.
Neil
3

Pyth, 26 Bytes

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

Probieren Sie es hier aus!

Erläuterung

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

     .BQ # Konvertiert die Eingabe in eine Binärdatei
    : "(? <= (.)) (? = \\ 1)" d # füge ein Leerzeichen zwischen den Untersequenzen ein
   C # -String in Leerzeichen teilen
iR2 # konvertiert jede Teilsequenz in eine Dezimalzahl

Da die split () - Funktion von Python bei Übereinstimmungen mit Länge Null nicht aufgeteilt wird, muss ich diese Übereinstimmungen durch ein Leerzeichen ersetzen und das Ergebnis darauf aufteilen.

Denker
quelle
3

Pyth, 22 21 Bytes

&Qu?q%G2H&
GH+yGHjQ2Z

Probieren Sie es online aus: Demonstration

Wirklich eine mühsame Aufgabe in Pyth.

Erläuterung:

&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
Jakube
quelle
3

05AB1E , 18 Bytes

Code:

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

Erläuterung:

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

Probieren Sie es online!

Verwendet CP-1252- Codierung.

Adnan
quelle
3

MATL , 18 17 Bytes

YBTyd~Thhfd1wY{ZB

Probieren Sie es online!

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
Luis Mendo
quelle
3

zsh, 67 63 55 Bytes

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

Ich weiß nicht warum, aber das funktioniert in Bash nicht.

Danke an Dennis für 8 Bytes!

Türknauf
quelle
Es ist die forSyntax. ... Warte, nein fors?
CalculatorFeline
Mit der arithmetischen Erweiterung von Bash können Sie keine Ausgabebasis angeben. Um die Xargs loszuwerden, könnten Sie verwenden 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 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=" ":"";}}
Explosionszeichnung
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

Verwenden d(int)Sie und Sie sind ausgeschaltet, die Ausgabe ist eine durch ein Leerzeichen getrennte echoZeichenfolge int.

Bearbeitungen:
-3:$b Definition in strlen()Aufruf verschoben .
-6: Entfernte $cInstanziierung.
-2: Schließlich die Verkettung Problem behoben.
-2: Keine Klammern für einzeilige for().
-37: Generalüberholung. ArrayIch gehe mit Chunklets anstatt wiederholter Array-> String-> ArrayAnrufe.
-1: Sneaky $cReset.
+11: Bugfix. Fehlte der letzte Teil. Nicht mehr.
-7: Müssen Sie überhaupt nicht instanziieren $d? Nett.
-6: return -> echo.
-2: Knirschen $c.
-3:Ternary, meine erste Liebe.
-1: Hinterhältig hinterhältig $u.

Ricdesi
quelle
Ich glaube , Sie 2 Bytes speichern können: 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

Konvex 0,2+, 25 Bytes

Convex ist eine neue Sprache, die ich entwickle und die stark auf CJam und Golfscript basiert. Den Interpreter und die IDE finden Sie hier . Die Eingabe ist eine Ganzzahl in die Befehlszeilenargumente. Dies verwendet die CP-1252- Codierung.

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

Erläuterung:

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

Java 8, 127 119 Bytes

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

Es gibt wahrscheinlich einen besseren regulären Ausdruck, um die Zeichenfolge aufzuteilen. Ich beherrsche Regex nicht, aber ich werde weiter experimentieren.

-8 Bytes dank @FryAmTheEggman

TNT
quelle
2

APL (APL) , 21-25 Bytes

Behandelt jetzt auch 0.

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

Probieren Sie es online!

2⊥⍣¯1⊢ konvertiere nach Base-2, benutze so viele Bits wie nötig (lit. inverse from-Base-2-Konvertierung)

{} Wenden folgende anonyme Funktion an

0:: Wenn ein Fehler auftritt:

  0 0 zurückgeben

 jetzt versuchen:

  2=/⍵ paarweise Gleichheit des Arguments (wird eine 0 Länge-0 Binärdarstellung fehlschlagen)

  1, voranstellen 1

  ⍵⊂⍨ Verwenden Sie das, um das Argument zu partitionieren (beginnt neuen Abschnitt auf jeder 1)

  2⊥¨ konvertieren Sie jeweils von Basis-2

Adam
quelle
1
ist hier wirklich nützlich. Ich sollte das zu Jelly hinzufügen.
Dennis
@Dennis Beachten Sie die beiden Versionen von R←X⊂Y: Mit ⎕ML<3(dh Dyalog-Stil) wird eine neue Partition im Ergebnis gestartet, die jeweils 1 in X bis zur Position vor der nächsten 1 in X (oder dem letzten Element von X) entspricht die aufeinanderfolgenden Elemente von R. Mit ⎕ML=3(dh IBM-Stil) wird eine neue Partition im Ergebnis gestartet, wenn das entsprechende Element in X größer als das vorherige ist. Elemente in Y, die 0en in X entsprechen, werden nicht in das Ergebnis einbezogen. Das ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7entspricht also ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⊂7`
Adám
2

Japt , 7 Bytes

¤ò¥ mn2

Probier es aus


Erläuterung

¤ò¥ 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.
Zottelig
quelle
1

Python 3, 115 Bytes

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]

Erläuterung

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 

Ergebnisse

>>> [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]

vorherige Lösung (118 Bytes)

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')]
Erwan
quelle
1

Haskell, 147 , 145 Bytes

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 ist eine unbenannte Funktion, die die Liste berechnet.

Weniger golfen:

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
Michael Klein
quelle
1

Perl, 53 Bytes

Beinhaltet +1 für -p

Führen Sie mit der Nummer auf STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

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

PowerShell, 103 Byte

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

Da ich bei Regex schrecklich bin, verwende ich den gleichen Ausdruck wie die Antwort von edc65 .

Absolut zerstört durch die langwierigen .NET-Aufrufe zum Konvertieren in / aus Binärdateien und den .NET-Aufruf zum Abrufen der Regex-Übereinstimmungen. Ansonsten ziemlich unkompliziert. Übernimmt die Eingabe $args[0], stellt convertsie auf binär um, speist sie ein Matches, nimmt die resultierenden .Values auf, leitet sie durch eine Schleife |%{...}und gibt convertdiese Werte zurück an int. Die Ausgabe bleibt in der Pipeline und wird implizit mit Zeilenumbrüchen gedruckt.


Für zusätzliches Guthaben - eine (meist) nicht reguläre Version mit 126 Bytes

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

Wir nehmen wieder Eingang $args[0]und convertes binär. Wir wandeln es in ein Zeichen-Array um, in dem das erste Zeichen $lund die restlichen Zeichen gespeichert werden $r. Wir $rdurchlaufen dann eine Schleife, |%{...}in der wir bei jeder Iteration entweder das Zeichen mit vorangestelltem Leerzeichen oder nur das Zeichen auswählen, je nach Ergebnis eines binären X oder mit $lund dann $lgleich dem Zeichen setzen. Dies stellt effektiv sicher, dass, wenn wir zweimal hintereinander dasselbe Zeichen haben, ein Leerzeichen dazwischen eingefügt wird.

Die Ausgabe der Schleife wird -joinzusammengefügt und an das erste Zeichen angehängt $l, dann -splitan Leerzeichen (was technisch ein regulärer Ausdruck ist, aber ich werde es nicht zählen). Wir machen dann die gleiche Schleife wie die Regex-Antwort convertund geben ganze Zahlen aus.

AdmBorkBork
quelle
1

Java 345 Bytes

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;
  }
}

Prüfung

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()));
    }
  }
}

Ausgabe

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
Jeff I
quelle
4
Willkommen bei Programming Puzzles & Code Golf! Da dies ein Code-Golf- Wettbewerb ist, sollten Sie Ihren Code so kurz wie möglich halten. Hier einige Tipps zum Golfen in Java. Sie können damit beginnen, Ihre Funktion ohne das Boilerplate packageund zu definieren classund unnötige Leerzeichen zu entfernen. Lassen Sie mich wissen, wenn Sie Fragen haben!
Alex A.
1

Julia, 70 57 Bytes

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

Dies ist eine anonyme Funktion, die eine Ganzzahl akzeptiert und ein Ganzzahl-Array zurückgibt. Um es aufzurufen, weisen Sie es einer Variablen zu.

Der Ansatz hier ähnelt DenkerAffes netter Python- Antwort . Wir erhalten die binäre Darstellung von nusing bin(n)und teilen den resultierenden String bei allen Übereinstimmungen des regulären Ausdrucks (?<=(.))(?=\1). Es ist eigentlich eine Übereinstimmung mit der Länge Null. (?<=(.))ist ein positiver Lookbehind, der ein einzelnes Zeichen findet, und (?=\1)ein positiver Lookahead, der das übereinstimmende Zeichen im Lookbehind findet. Dies lokalisiert die Stellen, an denen eine Zahl in der binären Darstellung von selbst gefolgt wird. Nur parsejeweils als Ganzzahl in Basis 2 mit mapund voila!

Alex A.
quelle
1

C 137 129 Bytes

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);}

Ein- und Ausgabe erfolgen über die Standard-Streams.

Fuchs
quelle
Ich glaube nicht, dass Sie das brauchen puts, obwohl es unangenehm wäre, es zu benutzen, erfordert die Spezifikation kein nachgestelltes Newline.
FryAmTheEggman
@FryAmTheEggman Ich möchte lieber keine unvollständige letzte Zeile generieren. Aber für die Kosten von einem Byte (immer noch eine Nettoreduktion) kann ich das Trennzeichen von Leerzeichen zu Zeilenumbruch ändern.
Fox
1

J , 16 Bytes

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

Probieren Sie es online!

Erläuterung

#:#.;.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
Meilen
quelle
1

q / kdb +, 52 Bytes

Lösung:

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

Beispiele:

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

Erläuterung:

q wird von rechts nach links interpretiert.

Eingaben in Binärdaten umwandeln, führende Nullen abschneiden, Indizes finden, bei denen sie unterschiedlich sind, invertieren, um Indizes zu erhalten, bei denen sie gleich sind, Liste auf diese Indizes aufteilen, zurück zur Basis 10 konvertieren. Sieht im Vergleich zur APL-Lösung allerdings etwas schwer aus ...

{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
Streetster
quelle
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).' ';

Sie müssen bei der letzten Ausgabe zusätzlichen Speicherplatz angeben, da dies keine Einschränkung darstellt. Hinweise werden für die Kurzkodierung angezeigt.

Ungolfed-Version

$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).' ';
}
kuldeep.kamboj
quelle
0

Netzhaut, 60

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

;
1

Probieren Sie es online! Oder versuchen Sie es mit einer leicht geänderten Version für alle Testfälle (mit dezimaler E / A).

Leider scheinen Übereinstimmungen mit einer Länge von Null zwei "Seiten" zu haben, was zu Duplikaten führt, wenn sie mit dem regulären Ausdruck aus der dritten Stufe verwendet werden. Kostet allerdings nur ein Byte.

Nimmt Eingaben als unär, Ausgaben als unär. Ich bin mir nicht sicher, ob ich unterschiedliche unäre Ein- / Ausgabewerte verwenden soll, aber das spart 4 Bytes.

FryAmTheEggman
quelle