Dicht gepackte Dezimalzahl (DPD) bis Dezimalzahl


26

Für Nandgame-Fans: Bitte probieren Sie DPD auch in Logikgattern mit Dezimalstellen aus !

Hintergrund

Dicht gepackte Dezimalstellen (DPD) sind eine Möglichkeit, Dezimalstellen in Binärform effizient zu speichern. Es speichert drei Dezimalstellen (000 bis 999) in 10 Bit, was viel effizienter ist als naives BCD (das eine Stelle in 4 Bit speichert).

Notizen

  • Die Kleinbuchstaben abis isind die Bits, die in die Dezimaldarstellung kopiert werden.
  • 0und 1sind die genauen Bits in den Eingabe- oder Ausgabebitmustern.
  • x Bits werden bei der Konvertierung ignoriert.

Umrechnungstabelle

Das Folgende ist die Umwandlungstabelle von 10 Bit DPD in drei Dezimalstellen. Jede Dezimalstelle wird als 4-Bit-Binärzahl (BCD) dargestellt. Beide Seiten werden von links nach rechts von der höchstwertigen bis zur niedrigsten Stelle geschrieben.

Bits                 =>  Decimal         (Digit range)
a b c d e f 0 g h i  =>  0abc 0def 0ghi  (0-7) (0-7) (0-7)
a b c d e f 1 0 0 i  =>  0abc 0def 100i  (0–7) (0–7) (8–9)
a b c g h f 1 0 1 i  =>  0abc 100f 0ghi  (0–7) (8–9) (0–7)
g h c d e f 1 1 0 i  =>  100c 0def 0ghi  (8–9) (0–7) (0–7)
g h c 0 0 f 1 1 1 i  =>  100c 100f 0ghi  (8–9) (8–9) (0–7)
d e c 0 1 f 1 1 1 i  =>  100c 0def 100i  (8–9) (0–7) (8–9)
a b c 1 0 f 1 1 1 i  =>  0abc 100f 100i  (0–7) (8–9) (8–9)
x x c 1 1 f 1 1 1 i  =>  100c 100f 100i  (8–9) (8–9) (8–9)

Aufgabe

Konvertieren Sie 10 Bit DPD in 3 Dezimalstellen.

Testfälle

DPD           Decimal
0000000101    005
0001100011    063
0001111001    079
0000011010    090
0001011110    098
1010111010    592
0011001101    941
1100111111    879
1110001110    986
0011111111    999
1111111111    999  * Output is same regardless of the `x` bits

Eingang

Das Standardeingabeformat ist eine Liste mit 10 Bits. Die Bits sollten der genauen Reihenfolge oben oder der umgekehrten Reihenfolge folgen. Sie können stattdessen eine äquivalente Zeichenfolge oder eine Ganzzahldarstellung verwenden. Im Gegensatz zu meinen anderen Herausforderungen ist es nicht erlaubt, verschachtelte Strukturen neu anzuordnen oder zu verwenden .

Für die Eingabe [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]sind folgende Formate zulässig:

  • Liste der Bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Zeichenfolge: "1100010100"
  • Binäre Ganzzahl: 788oder0b1100010100
  • Dezimalzahl: 1100010100
  • Umgekehrt: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]und in allen anderen oben genannten Formaten umgekehrt

Die folgenden Formate sind NICHT erlaubt:

  • Beliebige Neuordnung von Bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Verschachtelte Strukturen: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]oder[0b110, 0b001, 0b0100]

Ausgabe

Das Standardausgabeformat ist eine Liste mit 3 Dezimalstellen. Jede Ziffer sollte als 0 bis 9 dargestellt werden, entweder als Ganzzahl oder als Zeichen. Wie bei der Eingabe können Sie eine Zeichenfolge oder eine Ganzzahldarstellung auswählen. Wenn Sie die Ganzzahldarstellung wählen, können führende Nullen weggelassen werden.

Bewertungs & Gewinnkriterium

Es gelten die Standardregeln für . Das kürzeste Programm oder die kürzeste Funktion in Bytes für jede Sprache gewinnt.

Antworten:


12

JavaScript (ES6), 112 Byte

Der Gesamtbetrag für diese kürzere Version geht an @nwellnhof.

Übernimmt die Eingabe als Ganzzahl. Gibt ein Array mit drei Dezimalstellen zurück.

n=>[(x=n>>4,y=x>>3,q=n/2&55,p=q%8)>5&&q-39?8|y&1:y,(p&5^5?x&6:q-23?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p%q<7?y&6:8)|n&1]

Probieren Sie es online!


JavaScript (ES6), 118 bis 117 Byte

Übernimmt die Eingabe als Ganzzahl. Gibt ein Array mit drei Dezimalstellen zurück.

n=>[(x=n>>4&7,y=n>>7,p=n/2&7)>5&&p<7|x/2^2?8|y&1:y,(p<7?p-5?x:8:x/2^1?8:y&6)|x&1,(p<5?p*2:p<6?x&6:p<7|x<2?y&6:8)|n&1]

Probieren Sie es online!

Wie?

Anstatt zu versuchen, den "offiziellen" Algorithmus anzuwenden, basiert dieser Code auf einer Art Reverse Engineering der Muster, die in den erwarteten Ergebnissen zu finden sind.

Mit der eingegebenen Ganzzahl n berechnen wir:

x=n16mod8y=n128p=n2mod8

Beispiel: erste Ziffer (Hunderte)

x     | 0                | 1                | 2                | 3               
n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
p     | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
------+------------------+------------------+------------------+-----------------
y = 0 | 0000000000008888 | 0000000000008888 | 0000000000008888 | 0000000000008888
y = 1 | 1111111111119999 | 1111111111119999 | 1111111111119999 | 1111111111119999
y = 2 | 2222222222228888 | 2222222222228888 | 2222222222228888 | 2222222222228888
y = 3 | 3333333333339999 | 3333333333339999 | 3333333333339999 | 3333333333339999
y = 4 | 4444444444448888 | 4444444444448888 | 4444444444448888 | 4444444444448888
y = 5 | 5555555555559999 | 5555555555559999 | 5555555555559999 | 5555555555559999
y = 6 | 6666666666668888 | 6666666666668888 | 6666666666668888 | 6666666666668888
y = 7 | 7777777777779999 | 7777777777779999 | 7777777777779999 | 7777777777779999

x     | 4                | 5                | 6                | 7               
n & 1 | 0101010101010101 | 0101010101010101 | 0101010101010101 | 0101010101010101
p     | 0011223344556677 | 0011223344556677 | 0011223344556677 | 0011223344556677
------+------------------+------------------+------------------+-----------------
y = 0 | 0000000000008800 | 0000000000008800 | 0000000000008888 | 0000000000008888
y = 1 | 1111111111119911 | 1111111111119911 | 1111111111119999 | 1111111111119999
y = 2 | 2222222222228822 | 2222222222228822 | 2222222222228888 | 2222222222228888
y = 3 | 3333333333339933 | 3333333333339933 | 3333333333339999 | 3333333333339999
y = 4 | 4444444444448844 | 4444444444448844 | 4444444444448888 | 4444444444448888
y = 5 | 5555555555559955 | 5555555555559955 | 5555555555559999 | 5555555555559999
y = 6 | 6666666666668866 | 6666666666668866 | 6666666666668888 | 6666666666668888
y = 7 | 7777777777779977 | 7777777777779977 | 7777777777779999 | 7777777777779999

Algorithmus:

  • Wenn , istp<6d=y
  • Wenn , haben wirp=6d=8+(ymod2)
  • Wenn , haben wirp=7 UND (x<4 ODER x>5)d=8+(ymod2)
  • Wenn , haben wirp=7 UND (x=4 ODER x=5)d=y

Als JS-Code:

p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y

1
Ihr Ansatz ähnelt meiner C-Antwort, die eine andere temporäre Variable verwendet. Nachdem ich meine anfängliche C-Lösung ein bisschen mehr ausprobiert habe, ergibt ein Port auf JavaScript 112 Bytes .
Nwellnhof

10

Python 3 , 229 ... 97 96 Bytes

lambda a:[[a&6,a>>4&6,a>>7&6,8][b"  eW7B]Oys"[~a&8or~a&6or~6|a>>4]%x&3]|a>>x%9&1for x in[7,4,9]]

Probieren Sie es online!

-4 Bytes von @xnor

-6 Bytes von @nwellnhof

Formatiert:

h = lambda a:[
    [a&6, a>>4&6, a>>7&6, 8][              List to take high bits from
        b"  eW7B]Oys"[                     10 char string; where to get high bits for
                                             indicator values 1-8. 0th,1st chars not used.
            ~a&8 or ~a&6 or ~6|a>>4]       Compute indicator (by @nwellnhof)
        %x&3]                              High bits of each digit
    | a >> x%9 & 1                         bitwise OR with low bit of each digit
    for x in [7,4,9]]

Erläuterung

Da ich dies ursprünglich in Jelly implementieren wollte, verfolge ich einen anderen Ansatz als die meisten Antworten hier, der einfach ist und möglicherweise für eine Golfsprache geeignet ist. Obwohl die Golffunktion eine Ganzzahl annimmt, sei die Eingabe eine Bitliste [a0,a1,...,a9]. Dann können wir drei Werte aus der Eingabe ableiten

  • Die niedrigen Bits [a2,a5,a9]: Dies sind immer die niedrigen Bits von [d0,d1,d2].
  • Die hohen Bits [2*a0a1,2*a3a4,2*a7a8,8]: Die hohen Bits jeder Ziffer sind eine davon.
  • Die Indikatorbits [a3,a4,a5,a7,a8]bestimmen, wie die hohen Bits jeder Ziffer abgerufen werden. Wir berechnen den Indikator (zwischen 1 und 8) wie folgt:
    • Wenn a5 == 0, ist der Indikator 8 (ursprünglich 0, aber mit 8 wird stattdessen ein Byte gespeichert)
    • Wenn a3 und a4, ist der Indikator 6 - 2 * a3a4
    • Ansonsten ist der Indikator 2 * a7a8 + 1 (tatsächlich als negative Zahl berechnet).

Dann kann die n-te Ziffer elegant wie high_bits[arr[indicator][n]] | low_bits[n]in der folgenden Tabelle berechnet werden, die zu einer Zeichenfolge komprimiert wird.

arr = [
    [0,1,2],
    [3,1,2],
    [1,3,2],
    [2,1,3],
    [2,3,3],
    [3,2,3],
    [3,3,2],
    [3,3,3]
]

1
Sie können einen Bytestring verwenden b"...", um die Konvertierung durch zu ersetzen ord.
22.

@nwellnhof Ha, ich habe gerade das Gleiche gefunden! Werde es dir trotzdem gutschreiben.
Lirtosiast

b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]spart weitere vier Bytes.
Nwellnhof

@nwellnhof Ich denke, eine Modulo-Kette ist der Weg hierher, aber wenn nicht, würde deine sicherlich funktionieren.
Lirtosiast

9

JavaScript (Node.js) , 126 119 117 112 111 Byte

(a,b,c,d,e,f,g,h,i,j)=>[(g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c,(g&i?h+e-3?8:b:e)+f,(g?h<i?e:h>i*e?b:8:h*4+i*2)+j]

Probieren Sie es online!

-5 Bytes danke @tsh (und 2 von mir) Also lkann man sich mehr Mühe geben als ich erwartet hatte.

-2 weitere Bytes mit @ tshs Technik!

-5 Bytes danke @Arnauld

-1 Byte danke @Neil

Eingabe als Liste mit 10 Bits (als 10 Argumente), Ausgabe als Liste mit 3 Ziffern.


1
(!i|!d|e)-> i+l!=5; (d|e|!h)->h+l!=1
tsh

1
(g?h-i|h&!e?h?b:e:8:h*4+i*2)-> (g?h<i?e:h>i*e?b:8:h*4+i*2)speichert ein weiteres Byte. (Diesmal habe ich nachgesehen ...)
Neil,

8

C (GCC) , 138 129 Bytes

f(w){int t=w/2&55,s=t%8,v=w/16,u=v/8;w=((s<6|t==39?u:8|u%2)*10+v%2+(s&5^5?v&6:t-23?8:u&6))*10+w%2+(s<5?s*2:s<6?v&6:s%t<7?u&6:8);}

Probieren Sie es online!

Extrahiert zuerst einige Bits in Variablen sund t, so dass die acht Zeilen der Konvertierungstabelle identifiziert werden können durch:

1.  s < 4              u v w¹
2.  s = 4              u v 8¹
3.  s = 5              u 8 v
4.  s = 6              8 v u
5.  s = 7, t =  7      8 8 u
6.  s = 7, t = 23      8 u 8
7.  s = 7, t = 39      u 8 8
8.  s = 7, t = 55      8 8 8

¹ Can be computed with s*2

Dann richtet uund vmit Teilungen (rechts verschieben), so dass u, vund den Eingang wenthält die unteren drei BCD - Bits in den Positionen 0-2. Der Rest ist je nach sund ein bisschen schlurfen t. Zwei bemerkenswerte Tricks sind:

s&5^5  // Rows 1, 2 and 4.
s%t<7  // Rows 1-5.

Ein Port der Javascript-Lösung von Shieru Asakoto hat nur 124 Bytes :

f(a,b,c,d,e,f,g,h,i,j){a=(((g&h&i+(b+=a*4+b,e+=d*4+e)!=5?8:b)+c)*10+(g&i?h+e-3?8:b:e)+f)*10+(g?h-i|h&!e?h?b:e:8:h*4+i*2)+j;}

Probieren Sie es online!


Ich denke, es kann verkürzt werden auf:f(b){int a=b/2%8,e=b&110,c=b/16,d=c/8;b=10*(10*(d%2|(6>a|78==e?d:8))+c%2+(3<a&a%2?e-46?8:d&6:c&6))+b%2+(4>a?b&6:a-5?a-6&&e-14?8:d&6:c&6)};
MCCCS

@MCCCS Ihr Code scheint ebenfalls 138 Bytes zu haben.
Nwellnhof

5

Ruby , 153 ... 119 117 Bytes

->n{n+=n&896;a,b,c=n&1536,n&96,n&14;"%x"%n+=c<9?0:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}

Probieren Sie es online!

Wie es funktioniert:

->n{n+=n&896;

Dies ist der Ausgangspunkt: Konvertieren Sie zu BCD, indem Sie 3 Bits nach links verschieben, was für die meisten Muster funktioniert.

a,b,c=n&1536,n&96,n&14;

Holen Sie sich die mittleren Bits jedes Halbbytes (und ein zusätzliches Bit des dritten Halbbytes, aber maskieren Sie das niedrigstwertige Bit).

"%x"%n+=c<9?0

Wenn die dritte Ziffer kleiner als 10 ist (kleiner als 9, weil wir uns sowieso nie um das LSB gekümmert haben), sind wir eingestellt: Dies ist einfaches BCD, wir können das Hex ausgeben, ohne etwas zu ändern

:2036+[b/16-b-1918,r=a>>8,[r+126,a/16-26,a-1978,38][b/32]-a][c/2-5]}

Ansonsten machen Sie etwas schwarze Magie, indem Sie Bits verschieben und magische Zahlen hinzufügen, bis Sie das gewünschte Ergebnis erzielen.


5

Retina 0.8.2 , 191 181 Bytes

(...)(...)
:$1,$2;
..(.),11(.);111
100$1,100$2;100
(10|(..)(.,)01)(.);111
100$3$2$4;100
(..)(.),(00.);111
100$2,1$3;0$1
(..)((.{5});110|(.);101)
100$3$4;$1
1
01
+`10
011
.0+(1*)
$.1

Probieren Sie es online! Link enthält Testfälle. Bearbeiten: Speichert 10 Byte, indem die Ziffern nur bei Bedarf mit 4 Bit aufgefüllt werden. Erläuterung:

(...)(...)
:$1,$2;

Fügen Sie Trennzeichen ein, damit jede Ziffer einzeln in Dezimalzahlen umgewandelt werden kann. Dies behandelt effektiv die ersten beiden Fälle in der Konvertierungstabelle.

..(.),11(.);111
100$1,100$2;100

Behandeln Sie den letzten (achten) Fall in der Umrechnungstabelle.

(10|(..)(.,)01)(.);111
100$3$2$4;100

Behandeln Sie den sechsten und siebten Fall in der Umrechnungstabelle.

(..)(.),(00.);111
100$2,1$3;0$1

Behandeln Sie den fünften Fall in der Umrechnungstabelle.

(..)((.{5});110|(.);101)
100$3$4;$1

Behandeln Sie den dritten und vierten Fall in der Umrechnungstabelle.

1
01
+`10
011
.0+(1*)
$.1

Führen Sie eine Umwandlung von Binär in Dezimal durch.


5

Jelly , 51 48 40 39 Bytes

&\‘f4;s3ɓạ4ḅ-œ?µ/Ḥ
“MY-€-Y¤©¡‘Dịs3Ḅç+ƭ/

Probieren Sie es online!

Algorithmus

Mit Ausnahme der Listenindizes sind alle Ganzzahlen in diesem Abschnitt binär geschrieben.

αβγδεζηθικ[ηη,θι,δε][αβ,δε,θι][γ,ζ,κ]

  1. ηη=0000000111
  2. ηη=11θι<1110001001
  3. ηη=θι=11δε<11
  4. ηη=θι=δε=11

11[ηη,θι,δε]100[αβ,δε,θι]

  1. [[αβ,δε,θι]]
  2. [[100,αβ,δε],[θι]]
  3. [[100,100,αβ],[δε,θι]]=[[100,100,αβ],[δε,11]]
  4. [[100,100,100],[αβ,δε,θι]]=[[100,100,100],[αβ,11,11]]

[γ,ζ,κ][αβγ,δεζ,θικ][100γ,100ζ,100κ]

[100,αβ,δε][100,100,αβ][θι]δε

[100,αβ,δε][100,αβ,δε][100,δε,αβ][αβ,100,δε][αβ,δε,100][δε,100,αβ][δε,αβ,100]

100-θι000110[αβ,δε,100][αβ,100,δε][100,δε,αβ]

[γ,ζ,κ][αβγ,δεζ,100κ][αβγ,100ζ,δεκ][100γ,δεζ,αβκ]

[100,100,αβ][100,100,αβ][100,αβ,100][100,100,αβ][100,αβ,100][αβ,100,100][αβ,100,100]

(100-θι)-(100-δε)=δε-θι=δε-11000110[100,100,αβ][100,αβ,100][αβ,100,100]

[γ,ζ,κ][100γ,100ζ,αβκ][100γ,αβζ,100κ][αβγ,100ζ,100κ]

Code

“MY-€-Y¤©¡‘Dịs3Ḅç+ƭ/  Main link. Argument: A (array of 10 bits)

“MY-€-Y¤©¡‘           Array literal; yield [77, 89, 45, 12, 45, 89, 3, 6, 0].
           D          Decimal; yield
                      [[7,7], [8,9], [4,5], [1,2], [4,5], [8,9], [3], [6], [0]].
            ị         Retrieve the elements of A at those indices.
                      Indexing is 1-based and modular, so 1 is the first index, while
                      0 is the last.
             s3       Split the results 2D array of bits into chunks of length 3.
               Ḅ      Convert the 9 arrays of bits from binary to integer.
                ç+ƭ/  Reduce the resulting array (length 3) once by the helper link,
                      then by addition.


&\‘f4;s3ɓạ4ḅ-œ?µ/Ḥ    Helper link. Arguments: B, C (arrays of three integers each)

&\                    Cumulatively reduce B by bitwise AND.
  ‘                   Increment the results by 1.
   f4                 Filter; keep only integers equal to 4.
     ;                Concatenate the result with C.
      s3              Split the result into (one or two) chunks of length 3.
        ɓ      µ/     Reduce the array of chunks by the following chain.
         ạ4               Take the absolute difference of the integers in the right
                          chunk and the integer 4.
           ḅ-             Convert the resulting array from base -1 to integer, i.e.,
                          map [x] to n = x and [x, y] to n = y - x.
             œ?           Take the n-th permutation of the left chunk.
                 Ḥ    Unhalve; multiply the resulting integers by 2.


2

Sauber , 238 ... 189 Bytes

-2 Bytes dank Neil

import StdEnv
$a b c d e f g h i j=100*(c+2*b+4*a)+10*(f+2*e+4*d)+j+2*i+4*h-2*(h*(99*b+198*a-394)+i*(9*e+18*d+h*(e+2*d-4+(b+2*a-4)*(1-10*e-100*d+110*e*d))-35)-4)*g+0^(e+d)*(2*b+4*a-8*i*h*g)

Probieren Sie es online!

Nimmt eine 'Liste' von 10 Bits in Form von 10 Argumenten auf, wobei eine direkte Formel zur Berechnung des Ergebnisses verwendet wird.


In i*(9*e+19*d+i*...)scheint diese Sekunde i*unnötig.
Neil

@ Neil Du hast recht, es ist, danke.
Οurous

1

Perl 5, 195 Bytes

sub f{$n=shift;@p=((map{($n>>$_&3)*2}(8,5,1)),8);for(16390,28935,29005,227791,29108,225788,226803,228863){return 2*$n&256|$n&17|$p[$_>>4&3]<<8|$p[$_/4&3]<<4|$p[$_&3]if($_>>12&$n/2)==($_>>6&63);}}

Probieren Sie es online aus

Ich weiß, 195 Bytes sind viel zu viel für diesen Wettbewerb, aber ich hatte keine Ahnung, wie ich den Perl-Code weiter komprimieren soll. Vorschläge?

Erklärung des Codes

In einer besser lesbaren Version sollte die Codeabsicht offensichtlich werden:

sub dpd {
  my $n = shift;
  my $v=2*($n&128)|$n&17;
  my @p=((map{($n>>$_&3)*2}(8,5,1)),8);
  for (16390,28935,29005,227791,29108,225788,226803,228863) {
    return $v |$p[$_>>4&3]<<8|$p[$_>>2&3]<<4|$p[$_&3]
      if(($_>>12&$n/2)==($_>>6&63));
  }
}

In den Regeln für die DPD-Codierung wird jede Zeile in einen 18-Bit-Wert codiert und in (6,6, (2,2,2)) Bits segmentiert.

  • Die ersten 6 Bits sind eine geeignete Bitmaske für die Bits 1 (= h) bis 6 (= d) des Eingangs (Bit 4 = f ist redundant, vereinfacht jedoch den Auswertungscode, damit er enthalten ist).
  • Die nächsten 6 Bits sind die Wertbits für diese Bitmaske. Die Werte werden an allen Stellen geprüft, an denen die Bitmaske den Wert 1 hat.
  • Die folgenden 3 * 2 Bits enthalten die Indizes für das Array @pfür die 3-Bit-Sequenzen, die in die Bits 11-9, 7-5 und 3-1 des Ergebnisses gespleißt werden sollen.
  • Das Array @pbesteht aus den Bits 9-8, 6-5, 3-2 der Eingabe und der Zahl 8als viertem Element
  • Die Bits an Position 7,4 und 0 des Eingangs werden direkt in die Bits 8,4 und 0 des Ergebnisses übertragen.

Zum Beispiel die erste Zahl in der Liste, 16390 die 100000000000110als Bitfeld vorliegt, die folgenden Informationen:

000100 : bit mask says: only consider bit 3 of the input
000000 : bit values say: bit 3 should be 0
00     : use '0ab' as higher bits of first digit
01     : use '0de' as higher bits of second digit
10     : use '0gh' as higher bits of third digit

1

05AB1E , 84 Bytes

Hafen von KimOyhus 'Antwort auf 05AB1E.

•4’7þ2Ô€iΘEuĆΣk4Ѐ:ΘΛs‡CaΔʒì₁3¶rdiMß¡þи иø-˜)Â∍DY—WûQ@—Mā}Γ¤ÒÙ]p•44в2ôvÐyèP≠«}4ôC3.£

Probieren Sie es online!

Grobe Erklärung:

•yadayada•44в2ô   # encoded list of nand gates
v                 # for each gate
 ÐyèP≠            # compute the output of the gate
      «           # append it to the input
       }          # end of the loop
4ô                # split the list of bits in groups of 4
  C               # convert each from binary to decimal
   3.£            # keep the last 3 numbers
                  # implicit output

0

05AB1E , 104 103 101 Bytes

•3γã•S£©4èUXтÌ‹XSPVY®2èDˆTQ*~i0®нëт}®1èY¯`*i0®нëY_Xт>Ê*i0¯`ëт]®3èY¯`_*X110Q~i0®нëXт›iYiтë0¯`ëX]®θJ4ôC

Auf jeden Fall nicht die richtige Sprache für diese Art von Herausforderung, aber na ja.
Eingabe als Zeichenfolge, Ausgabe als dreistellige Liste.

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

Erläuterung:

Wir müssen die folgenden acht Szenarien berücksichtigen:

     1st 2nd 3rd 4th 5th 6th                          1st digit    2nd digit    3rd digit
1.   ab  c   de  f   0gh i   →   0abc 0def 0ghi   →   '0'+1st 2nd  '0'+3rd 4th  5th     6th
2.   ab  c   de  f   100 i   →   0abc 0def 100i   →   '0'+1st 2nd  '0'+3rd 4th  5th     6th
3.   ab  c   gh  f   101 i   →   0abc 100f 0ghi   →   '0'+1st 2nd  '100'   4th  '0'+3rd 6th
4.   gh  c   de  f   110 i   →   100c 0def 0ghi   →   '100'   2nd  '0'+3rd 4th  '0'+1st 6th
5.   gh  c   00  f   111 i   →   100c 100f 0ghi   →   '100'   2nd  '100'   4th  '0'+1st 6th
6.   de  c   01  f   111 i   →   100c 0def 100i   →   '100'   2nd  '0'+1st 4th  '100'   6th
7.   ab  c   10  f   111 i   →   0abc 100f 100i   →   '0'+1st 2nd  '100'   4th  '100'   6th
8.   xx  c   11  f   111 i   →   100c 100f 100i   →   '100'   2nd  '100'   4th  '100'   6th

Ich teile zuerst die (implizite) Eingabe in Abschnitte von Größe auf [2,1,2,1,3,1]und speichere diese Liste im Register:

3γã•     # Push compressed integer 212131
     S    # Convert it to a list of digits
      £   # Split the (implicit) input in chunks of that size
       ©  # Store it in the register (without popping)

Sehen Sie sich meinen Tipp 05AB1E (Abschnitt Wie komprimiere ich große ganze Zahlen? ) An, um zu verstehen, warum dies so •3γã•ist212131

Jetzt werden zuerst die Nullen und Einsen für die erste Ziffer der Ausgabe erstellt. Szenarien 1,2,3,7 verwenden '0'+1st+2nd; und Szenarien 4,5,6,8 verwenden '100'+2nd:

4è                  # Take the 5th item of the list
  U                 # Pop and store it in variable `X`
XтÌ‹                #  Check if `X` is below 102
                ~   # OR
   XSP              #  `X` is equal to 111
      VY            #  And store that result in variable `Y`
               *    #  and
        ®2è         #  Get the 3rd item from the list of the register
           Dˆ       #  Push it to the global array
             TQ     #  And check if it's equal to 10
i                   # If the combined check above is truthy (exactly 1):
 0                  #  Push 0 to the stack
 ®н                 #  Push the 1st item of the list to the stack
ë                   # Else:
 т                  #  Push 100 to the stack
}                   # Close the if-else
®1è                 # And push the 2nd item of the list to the stack

Dann werden wir die Nullen und Einsen für die zweite Ziffer der Ausgabe bilden. Szenarien 1,2,4 verwenden '0'+3rd+4th; Szenarien 3,5,7,8 Verwendung '100'+4th; und Szenario 6 verwendet '0'+1st+4th:

Y                # Push `Y` (check if `X` equals 111)
   *             # and
 ¯`              # Push the item from the global array (3rd item of the list)
i                # If both checks above are truthy (exactly 1):
 0               #  Push 0 to the stack
 ®н              #  Push the 1st item of the list to the stack
ë                # Else:
 Y_              #  Push inverted `Y` (check if `X` does NOT equal 111)
       *         #  and
   Xт>Ê          #  Check if `X` (5th item of the list) does NOT equal 101
 i               #  If both checks above are truthy (exactly 1):
  0              #   Push 0 to the stack
  ¯`             #   Push the item from the global array (3rd item of the list)
 ë               #  Else:
  т              #   Push 100 to the stack
]                # Close both if-else cases
®3è              # And push the 4th item of the list to the stack

Dann werden wir die Nullen und Einsen für die dritte Ziffer der Ausgabe bilden. Szenarien 1,2 verwenden 5th+6th; Szenario 3 verwendet '0'+3rd+6th; Szenarien 4,5 verwenden '0'+1st+6th; und Szenarien 6,7,8 verwenden '100'+6th:

Y           #  Push `Y` (check if `X` equals 111)
    *       #  and
 ¯`_        #  Check if the item from the global array (3rd item of the list) is exactly 0
         ~  # OR
    X110Q   #  Check if `X` (5th item of the list) equals 110
i           # If the combined check above is truthy (exactly 1):
 0          #  Push 0 to the stack
 ®н         #  Push the 1st item of the list to the stack
ë           # Else:
 Xт›i       #  If `X` (5th item of the list) is larger than 100 (so 101/110/111):
     Yi     #   If `Y` (if `X` equals 111):
       т    #    Push 100 to the stack
      ë     #   Else:
       0    #    Push 0 to the stack
       ¯`   #    Push the item from the global array (3rd item of the list)
    ë       #  Else:
     X      #   Push `X` (5th item of the list) to the stack
]           # Close all if-else cases
®θ          # And push the last (6th) item of the list to the stack

Jetzt haben wir alle Nullen und Einsen auf dem Stapel, sodass wir sie in die drei ausgegebenen Ziffern konvertieren können:

J     # Join the entire stack together
 4ô   # Split it into parts of size 4
   C  # Convert each part from binary to an integer (and output implicitly)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.