Teilen Sie mich in zwei Hälften

15

Sie erhalten eine Nummer x, wo 0 <= x <= 2^32 - 1.

Nach der rekursiven Aufteilung im Binärformat sollten Sie eine Liste von Zahlen in Dezimalform ausgeben.

Beispiele:

Beispiel 1:

255 -> 255 15 15 3 3 3 3 1 1 1 1 1 1 1 1

Die aktuelle Liste ist nur 255.

Die binäre Darstellung von 255ist 1111 1111. Wenn wir es aufteilen, bekommen wir 1111und 1111, welche in Dezimalzahlen 15und sind 15.

Wir fügen diese der Liste hinzu, also werden wir haben 255 15 15.

Nun dienen die Nummern 15und 15als Eingaben und diese Nummern sollen aufgeteilt werden.

Es wieder tun, erhalten wir ( 3 3von beiden 15n): 255 15 15 3 3 3 3.

Fortsetzung der Logik, wird die endgültige Liste sein 255 15 15 3 3 3 3 1 1 1 1 1 1 1 1. Und da 1nicht mehr geteilt werden kann, stoppt die Ausgabe.

Beispiel 2:

225 -> 225 14 1 3 2 1 1 1 0

Die Startliste ist 225.

Die binäre Darstellung von 225ist 1110 0001. Wenn wir es aufteilen, bekommen wir 1110und 0001, welche in Dezimalzahlen 14und sind 1.

Wenn wir diese zur Liste hinzufügen, erhalten wir 225 14 1.

Nun dienen die Nummern 14und 1als Eingaben und diese Nummern sollen aufgeteilt werden.

Da 1es keine Aufteilung gibt, wird die Ausgabe sein 225 14 1 3 2.

Beispiel 3:

32 -> 32 4 0 1 0

Bedingungen :

  1. Wenn die Anzahl der Binärziffern ungerade ist, enthält die erste Zahl eine Binärziffer weniger als die nächste. Beispiel 20 (10100)wird als 10und geteilt 100, wobei die Dezimalausgabe 2und ist 4.
  2. Es gelten Standard-Regelungslücken.
  3. 0s und 1s vermehren sich nicht weiter.
  4. Ein Programmabsturz, wenn versucht wird, zu viele Zahlen anzuzeigen, ist eine gültige Beendigungsbedingung.
Strg-Umschalt-Esc
quelle
Nur ein Vorschlag, aber was ist mit den mit 0s aufgefüllten Binärziffern, wenn die Länge ungerade ist?
Caird Coinheringaahing
1
@ Satan'sSon Wenn du vorne auffüllst, entspricht das der Beschreibung.
isaacg
1
Ist die angegebene Ausgabereihenfolge erforderlich oder nur die Werte?
Jonathan Allan
@ Satan'sSon Keine Polsterung mit 0s.
ctrl-shift-esc
1
@JonathanAllan Die angegebene Ausgabereihenfolge ist erforderlich.
ctrl-shift-esc

Antworten:

13

Pyth, 18 Bytes

u+QiR2smc2+0dt#.BM

Testsuite

Dieser Code macht etwas sehr uKniffliges und Kluges mit Pyths Festpunktoperator.

Der Funktionskörper, der alles andere als der ist u, ist ziemlich einfach:

+QiR2smc2+0dt#.BM
+QiR2smc2+0dt#.BMG    Implicit variable
                      G will store the list of numbers from the previous iteration.
              .BMG    Map each number to its binary representation
            t#        Filter out the ones of length 1 (0 and 1)
      m               Map the remaining binary
         +0d          Prefix with a 0
       c2             Chop in half.
                      Since c puts the larger half first, prefixing with a 0
                      makes the chop work out right, and doesn't change the value.
     s                Concatenate
  iR2                 Map back to binary
+Q                    Add the input to the front of the list

Dieser Code entfernt 0s und 1s, teilt jede Zahl und fügt die Eingabe vor.

u Diese Funktion wird mit dem vorherigen Ergebnis der Funktion ausgeführt, bis sich das Ergebnis nicht mehr ändert.

Welcher Anfangswert wird uverwendet? Das ist der clevere Teil: Der Code gibt nicht an, welcher Wert verwendet werden soll, daher wird standardmäßig die Eingabe verwendet. Die Eingabe ist jedoch keine Liste von Zahlen, sondern eine Zahl. Pyth zwingt implizit die Zahl auf der ersten Zeit durch die Schleife in den Bereich der Zahl - [0, 1, ..., Q-1]. Das sieht nicht so aus wie die Ausgabe, die wir bekommen wollen. Glücklicherweise uwird das richtige Ergebnis gefunden, unabhängig davon, was die anfängliche Eingabe ist - die gewünschte Ausgabe ist der einzige feste Punkt der Funktion, und die wiederholte Anwendung wird es immer erreichen.

Schauen wir uns die Zwischenwerte des Programms mit der Eingabe an 7. Ich habe das Präfix des Ergebnisses hervorgehoben, das unabhängig von der anfänglichen Eingabe garantiert korrekt ist:

  1. 7(Implizit [0, 1, 2, 3, 4, 5, 6])

  2. [7,1, 0, 1, 1, 1, 0, 1, 1, 1, 2]

  3. [7, 1, 3,1, 0]

  4. [7, 1, 3, 1, 1]

Welches ist der Ausgang.


Gepackter Pyth, 16 Bytes

Beachten Sie, dass Pyth nur den 0-127-Bereich von ASCII verwendet und daher mit einer 7-Bit-Codierung anstelle einer 8-Bit-Codierung komprimiert werden kann. Somit kann das obige Programm in 16 Bytes gepackt werden. Das resultierende Programm ist:

ꮎ�L����[
    ���4

Hexdump:

0000000: eaae 8e9a 4cb9 edc6 c95b 0c9d 11ae 8534  ....L....[.....4

Der Dolmetscher wird gefunden hier zu finden . Geben Sie die Eingabe als Befehlszeilenargument ein.

Die Codepage dieser Sprache (Packed Pyth) ist der 0-127-Bereich von ASCII, und jedes Zeichen wird mit 7 Bits dargestellt, die am Ende aufgefüllt sind. Somit stellt der obige nicht lesbare Hexdump dar:

u+QiR2smc2+0dt#.BM

Aber in 16 Bytes.

isaacg
quelle
6

05AB1E , 21 20 18 17 Bytes

,¸[Žrbvy0ì2äCʒ=1›

Probieren Sie es online!

Erläuterung

,¸[Žrbvy0ì2äCʒ=1›   Argument n
,¸                  Print n and push n as array
  [Ž                Loop until stack is empty
    r               Reverse stack
     b              Convert elements in array to binary
      v             For each y in array
       y0ì2ä        Prepend '0' to y and split it into 2 elements
                    (the first element will take the additional character)
            C       Convert elements to decimal
             ʒ=1›   Keep only elements greater than 1, while printing each element
kalsowerus
quelle
@ JonathanAllan Yep reparierte es jetzt. Scheint ein Problem zu sein, das die Beispiele nicht behandeln, danke :)
kalsowerus
ʒ- Diese neue Codepage ... Seit wann ist 05AB1E Jelly? Mir gefällt es.
Magic Octopus Urn
4

JavaScript (ES6), 99 Byte

Das sieht ein bisschen zu lang aus. Möglicherweise gibt es einen besseren Weg, um die richtige Reihenfolge zu erhalten.

f=(n,p=(a=[],1),i=33-Math.clz32(n)>>1)=>(a[p]=n)>1?f(n>>i,p*=2)&&f(n&(1<<i)-1,p+1):a.filter(n=>1/n)

Demo

Arnauld
quelle
4

Gelee , 21 bis 20 Bytes

-1 Byte durch Entfernen einer monadischen Kette und anschließendes Behandeln der Konsequenz, dass eine leere Liste aus einer Binärdatei konvertiert wird und später 0 ergibt.

ỊÐḟBUœs€2UḄF
WÇÐĿṖUF

Ein monadischer Link, der eine Nummer aufnimmt und die angegebene Liste zurückgibt.

Probieren Sie es online!

Wie?

ỊÐḟBUœs€2UḄF - Link 1, perform an iteration: list of numbers
 Ðḟ          - filter out if:
Ị            -   insignificant (absolute value <= 1 - hence any 0s or 1s)
   B         - convert to a binary list (vectorises)
    U        - upend (reverse each)
     œs€2    - split €ach into 2 equal chunks (the first half is longer if odd ...hence
         U   - upend (reverse each)         ...this upend and the previous one)
          Ḅ  - convert from binary list to number (vectorises, although when the filter
             -                                     removes everything a zero is yielded)
           F - flatten the resulting list of lists to a single list

WÇÐĿṖUF - Main link: number
W       - wrap in a list
  ÐĿ    - loop and collect results until no change occurs:
 Ç      -   call last link (1) as a monad
    Ṗ   - pop (remove the last element - a list containing a single zero which results
        -     from the effect of Ḅ when link 1's input only contained ones and zeros)
     U  - upend (put the iterations into the required order)
      F - flatten to yield a single list
Jonathan Allan
quelle
Wie funktioniert das?
Caird Coinheringaahing
@ Satan'sSon Ich habe gerade eine Erklärung hinzugefügt
Jonathan Allan
Sie haben es zur gleichen Zeit hinzugefügt, als ich
Folgendes
@ ØrjanJohansen beide Wege haben die gleichen Bytekosten
Jonathan Allan
Oh, ich habe die Pyth-Antwort zuerst nicht gesehen, die diesen Trick bereits angewendet hat.
Ørjan Johansen
2

Java 7, 541 Bytes

import java.util.*;List l=new ArrayList(),L=new ArrayList();String c(int n){l.add(x(n));return a(n+" ",l,n);}String a(String r,List q,Integer n){boolean e=q.equals(l),E=q.equals(L);if(e)L.clear();else l.clear();for(String i:new ArrayList<String>(q)){int s=i.length()/2,a=n.parseInt(i.substring(0,s),2),z=n.parseInt(i.substring(s),2);r+=a+" "+z+" ";if(e&a>1)L.add(x(a));if(e&z>1)L.add(x(z));if(E&a>1)l.add(x(a));if(E&z>1)l.add(x(z));}if(e&L.size()>0)r=a(r,L,n);if(E&l.size()>0)r=a(r,l,n);return r;}String x(Integer n){return n.toString(n,2);}

Die ursprüngliche Bestellung beizubehalten, hat mich über den Haufen geworfen, sonst wäre es nur eine einfache Schleife und ein rekursives Aufrufprinzip. Trotzdem ist es eine lustige Herausforderung, dies herauszufinden, während die Reihenfolge beibehalten wird.

Erläuterung:

import java.util.*;                    // Required import for List and Array List

List l=new ArrayList(),L=new ArrayList(); 
                                       // Two Lists on class-level

String c(int n){                       // Method (1) with integer parameter and String return-type
  l.add(x(n));                         //  Start by adding the binary-String of the input integer to list `l`
  return a(n+" ",l,n);                 //  And let the magic begin in method `a` (2)
}                                      // End of method (1)

String a(String r,List q,Integer n){   // Method (2) with a bunch of parameters and String return-type
  boolean e=q.equals(l),E=q.equals(L); //  Determine which of the two class-level Lists the parameter-List is
  if(e)                                //  If it's `l`:
    L.clear();                         //   Empty `L`
  else                                 //  If it's `L` instead:
    l.clear();                         //   Empty `l`
  for(String i:new ArrayList<String>(q)){
                                       //  Loop over the input list (as new ArrayList to remove the reference)
    int s=i.length()/2,                //   Get the length of the current item in the list divided by 2
                                       //   NOTE: Java automatically floors on integer division,
                                       //   which is exactly what we want for the splitting of odd-length binary-Strings
    a=n.parseInt(i.substring(0,s),2),  //   Split the current binary-String item in halve, and convert the first halve to an integer
    z=n.parseInt(i.substring(s),2);    //   And do the same for the second halve
    r+=a+" "+z+" ";                    //   Append the result-String with these two integers
    if(e&a>1)                          //   If the parameter List is `l` and the first halve integer is not 0:
      L.add(x(a));                     //    Add this integer as binary-String to list `L`
    if(e&z>1)                          //   If the parameter List is `l` and the second halve integer is not 0:
      L.add(x(z));                     //    Add this integer as binary-String to List `L`
    if(E&a>1)                          //   If the parameter List is `L` and the first halve integer is not 0:
      l.add(x(a));                     //    Add this integer as binary-String to List `l`
    if(E&z>1)                          //   If the parameter List is `L` and the second halve integer is not 0:
      l.add(x(z));                     //    Add this integer as binary-String to List `l`
  }                                    //  End of loop
  if(e&L.size()>0)                     //  If the parameter List is `l` and List `L` now contains any items:
    r=a(r,L,n);                        //   Recursive call with List `L` as parameter
  if(E&l.size()>0)                     //  If the parameter List is `L` and List `l` now contains any items:
    r=a(r,l,n);                        //   Recursive call with List `l` as parameter
  return r;                            //  Return the result-String with the now appended numbers
}                                      // End of method (2)

String x(Integer n){                   // Method (3) with Integer parameter and String return-type
  return n.toString(n,2);              //  Convert the integer to its Binary-String
}                                      // End of method (3)

Testcode:

Probieren Sie es hier aus.

import java.util.*;
class M{
  List l=new ArrayList(),L=new ArrayList();String c(int n){l.add(x(n));return a(n+" ",l,n);}String a(String r,List q,Integer n){boolean e=q.equals(l),E=q.equals(L);if(e)L.clear();else l.clear();for(String i:new ArrayList<String>(q)){int s=i.length()/2,a=n.parseInt(i.substring(0,s),2),z=n.parseInt(i.substring(s),2);r+=a+" "+z+" ";if(e&a>1)L.add(x(a));if(e&z>1)L.add(x(z));if(E&a>1)l.add(x(a));if(E&z>1)l.add(x(z));}if(e&L.size()>0)r=a(r,L,n);if(E&l.size()>0)r=a(r,l,n);return r;}String x(Integer n){return n.toString(n,2);}

  public static void main(String[] a){
    M m=new M();
    System.out.println(m.c(255));
    m.l.clear();
    m.L.clear();
    System.out.println(m.c(225));
    m.l.clear();
    m.L.clear();
    System.out.println(m.c(32));
  }
}

Ausgabe:

255 15 15 3 3 3 3 1 1 1 1 1 1 1 1 
225 14 1 3 2 1 1 1 0 
32 4 0 1 0 
Kevin Cruijssen
quelle
2

Python 2 , 110 Bytes

l=[input()];i=1
while i:
 z=0
 for k in l[-i:]:
	if k>1:b=~-len(bin(k))/2;l+=[k>>b,k&2**b-1];z+=2
 i=z
print l

Probieren Sie es online!

ovs
quelle
2

Netzhaut , 142 Bytes

.+
$*
+`(1+)\1
${1}0
01
1
{`.+$
$&¶<$&>
+`;(\d*)>
>;<$1>
<.>

{`(\d)>
>$1
}`<(\d)
$1<
<>
;
\b0+\B

}`^;|;\B

¶
;
;;

1
01
+`10
011
0\B

1+
$.&

Probieren Sie es online!

Neil
quelle
2

PHP, 132 Bytes

for($r=[$argn];""<$n=$r[+$i++];)$n<2?:[$r[]=bindec(substr($d=decbin($n),0,$p=strlen($d)/2)),$r[]=bindec(substr($d,$p))];print_r($r);

Probieren Sie es online!

Jörg Hülsermann
quelle
Dies funktioniert laut dem Online-System "Try it" auf dieser Seite nicht.
Martin Barker
@MartinBarker was meinst du?
Jörg Hülsermann
tio.run/nexus/… => Array( [0] => 225 [1] => 14 [2] => 1 [3] => 3 [4] => 2 [5] => 1 [6] => 1 [7] => 1 [8] => 0 )wenn nicht = 255 15 15 3 3 3 1 1 1 1 1 1 1 1
Martin Barker
@MartinBarker Sie müssen die Eingabe in der Header-Version ändern. Ändern Sie die Variable $argnDiese Variable ist verfügbar, wenn Sie PHP über die Befehlszeile mit der -ROption ausführen. Hier ist ein Beispiel für die Eingabe von 255 Versuchen Sie es online!
Jörg Hülsermann
Das habe ich versucht zu sagen, dass es nicht funktioniert hat, wie im Online-System try it. (in der Post verlinkt)
Martin Barker
1

Ruby , 98 Bytes

f=->*a{a==[]?a:a+=f[*a.flat_map{|i|s='%b'%i;i>1?[s[0...h=s.size/2].to_i(2),s[h..-1].to_i(2)]:[]}]}

Probieren Sie es online!

Einfach eine grundlegende Optimierung der Antwort von Value Ink : Verwenden Sie flat_map anstelle von map ... flatten, und verwenden Sie

a==[]?a Anstatt von a==[]?[]

Jenkar
quelle