Decimale impacchettato densamente (DPD) in decimale


26

Per i fan di nandgame: prova DPD a decimale anche nelle porte logiche !

sfondo

Il decimale densamente compresso (DPD) è un modo per memorizzare in modo efficiente le cifre decimali in binario. Memorizza tre cifre decimali (da 000 a 999) in 10 bit, il che è molto più efficiente del BCD ingenuo (che memorizza una cifra in 4 bit).

notazioni

  • Le lettere minuscole aai sono i bit che vengono copiati nella rappresentazione decimale.
  • 0 e 1 sono i bit esatti nei modelli di bit di input o output.
  • x i bit vengono ignorati nella conversione.

Tabella di conversione

Di seguito è riportata la tabella di conversione da 10 bit di DPD a tre cifre decimali. Ogni cifra decimale è rappresentata come binario a 4 bit (BCD). Entrambe le parti sono scritte da sinistra a destra dalla cifra più significativa alla minima.

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)

Compito

Converti 10 bit di DPD in 3 cifre decimali.

Casi test

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

Ingresso

Il formato di input predefinito è un elenco di 10 bit. I bit devono seguire l'ordine esatto sopra, o viceversa. È possibile scegliere invece di utilizzare una stringa equivalente o una rappresentazione intera. A differenza delle altre mie sfide, non è consentito riordinare o utilizzare strutture nidificate .

Per l'input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], sono consentiti i seguenti formati:

  • Elenco di bit: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Stringa: "1100010100"
  • Numero intero binario: 788o0b1100010100
  • Numero intero decimale: 1100010100
  • Invertito: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]e invertito in qualsiasi altro formato sopra

I seguenti formati NON sono consentiti:

  • Riordinamento arbitrario dei bit: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Strutture nidificate: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]o[0b110, 0b001, 0b0100]

Produzione

Il formato di output predefinito è un elenco di 3 cifre decimali. Ogni cifra deve essere rappresentata da 0 a 9, sia un numero intero che un carattere. Come in input, puoi scegliere la rappresentazione in stringa o intera. Se si sceglie la rappresentazione intera, è possibile omettere gli zeri iniziali.

Punteggio e criterio di vincita

Si applicano le regole standard del . Vince il programma o la funzione più breve in byte per ogni lingua.

Risposte:


12

JavaScript (ES6), 112 byte

Tutto il merito di questa versione più breve va a @nwellnhof.

Accetta l'input come numero intero. Restituisce un array di tre cifre decimali.

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]

Provalo online!


JavaScript (ES6), 118 117 byte

Accetta l'input come numero intero. Restituisce un array di tre cifre decimali.

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]

Provalo online!

Come?

Invece di provare ad applicare l'algoritmo "ufficiale", questo codice si basa su una sorta di reverse engineering dei pattern che si possono trovare nei risultati previsti.

Dato il numero intero di input n , calcoliamo:

x=n16mod8y=n128p=n2mod8

Esempio: prima cifra (centinaia)

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

Algoritmo:

  • Se p<6 , abbiamo d=y
  • Se p=6 , abbiamo d=8+(ymod2)
  • Se p=7 AND (x<4 OR x>5) , abbiamo d=8+(ymod2)
  • Se p=7 AND (x=4 OR x=5) , abbiamod=y

Come codice JS:

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

1
Il tuo approccio è simile alla mia risposta C che utilizza un'altra variabile temporanea. Dopo aver golfato un po 'di più la mia soluzione C iniziale, una porta su JavaScript risulta in 112 byte .
nwellnhof

10

Python 3 , 229 ... 97 96 byte

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

Provalo online!

-4 byte di @xnor

-6 byte di @nwellnhof

formattato:

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

Spiegazione

Poiché inizialmente volevo implementarlo in Jelly, ho adottato un approccio diverso dalla maggior parte delle risposte qui, che è semplice e forse adatto a un linguaggio del golf. Sebbene la funzione golfed richieda un numero intero, lascia che l'ingresso sia un elenco di bit [a0,a1,...,a9]. Quindi possiamo derivare tre valori dall'input

  • I bit bassi [a2,a5,a9]: questi saranno sempre i bit bassi [d0,d1,d2]rispettivamente.
  • I bit alti [2*a0a1,2*a3a4,2*a7a8,8]: i bit alti di ogni cifra saranno uno di questi.
  • I bit dell'indicatore [a3,a4,a5,a7,a8], che determinano come ottenere i bit alti di ogni cifra. Calcoliamo l'indicatore (tra 1 e 8) come segue:
    • Se a5 == 0, l'indicatore è 8 (originariamente 0, ma utilizzando 8 invece si salva un byte)
    • Se a3 e a4, l'indicatore è 6 - 2 * a3a4
    • Altrimenti l'indicatore è 2 * a7a8 + 1 (effettivamente calcolato come un numero negativo).

Quindi l'ennesima cifra può essere elegantemente calcolata come high_bits[arr[indicator][n]] | low_bits[n]dalla tabella seguente, che viene compressa in una stringa.

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
È possibile utilizzare un bytestring b"..."per sostituire la conversione con ord.
xnor

@nwellnhof Ha, ho appena trovato la stessa cosa! Ti accrediterà comunque.
lirtosiast,

b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]salva altri quattro byte.
nwellnhof,

@nwellnhof Penso che una catena di moduli sia la strada da percorrere qui, ma in caso contrario la tua funzionerebbe sicuramente.
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]

Provalo online!

-5 byte grazie @tsh (e 2 da solo) Quindi lposso fare più sforzo di quanto mi aspettassi.

-2 byte in più usando la tecnica di @ tsh!

-5 byte grazie @Arnauld

-1 byte grazie @Neil

Input come un elenco di 10 bit (come 10 argomenti), output come un elenco di 3 cifre.


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)salva un altro byte. (Ho controllato questa volta ...)
Neil

8

C (gcc) , 138 129 byte

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

Provalo online!

Prima estrae alcuni bit in variabili se t, in modo che le otto righe della tabella di conversione possano essere identificate da:

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

Quindi imposta ue vcon divisioni (spostamenti a destra), in modo che u, ve l'ingresso wcontenga i tre bit BCD inferiori nelle posizioni 0-2. Il resto è un po 'mischiante a seconda di se t. Due trucchi notevoli sono:

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

Un port della soluzione Javascript di Shieru Asakoto è di soli 124 byte :

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

Provalo online!


Penso che possa essere abbreviato in: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 Anche il tuo codice sembra essere di 138 byte.
nwellnhof,

5

Rubino , 153 ... 119 117 byte

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

Provalo online!

Come funziona:

->n{n+=n&896;

Questo è il punto di partenza: converti in BCD spostando 3 bit a sinistra, che funziona per la maggior parte dei modelli.

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

Ottieni i bit centrali di ogni bocconcino (e un bit in più del terzo bocconcino, ma maschera il bit meno significativo).

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

Se la terza cifra è inferiore a 10 (meno di 9 perché non ci siamo mai preoccupati per l'LSB), siamo impostati: questo è un semplice BCD, possiamo emettere l'esagono senza cambiare nulla

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

Altrimenti fai un po 'di magia nera spostando i bit in giro e aggiungendo numeri magici fino a ottenere il risultato che vogliamo.


5

Retina 0.8.2 , 191 181 byte

(...)(...)
:$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

Provalo online! Il link include casi di test. Modifica: salvato 10 byte non riempiendo le cifre a 4 bit tranne dove necessario. Spiegazione:

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

Inserire i separatori in modo che ogni cifra possa essere convertita in decimale separatamente. Questo gestisce efficacemente i primi due casi nella tabella di conversione.

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

Gestire l'ultimo (ottavo) caso nella tabella di conversione.

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

Gestire il sesto e il settimo caso nella tabella di conversione.

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

Gestire il quinto caso nella tabella di conversione.

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

Gestire il terzo e il quarto caso nella tabella di conversione.

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

Esegue la conversione binaria in decimale.


5

Gelatina , 51 48 40 39 byte

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

Provalo online!

Algoritmo

Ad eccezione degli indici di elenco, tutti i numeri interi in questa sezione sono scritti in binario.

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

  1. Se ηη=00, tutte e tre le cifre in uscita sono basse (0000 a 0111).
  2. Se ηη=11 ma θι<11, esattamente una cifra in uscita è alta (1000 o 1001).
  3. Se ηη=θι=11 ma δε<11, esattamente due cifre in uscita sono alte.
  4. Se ηη=θι=δε=11, tutte e tre le cifre in uscita sono alte.

Se contiamo il numero di lead 11'S [ηη,θι,δε], crea una matrice con un numero corrispondente di 100, concatenalo con [αβ,δε,θι]e suddividendo il risultato in sottogruppi di lunghezza tre, otteniamo i seguenti risultati in ciascun caso.

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

In the first and last case, we just have to zip the first array with [γ,ζ,κ], yielding [αβγ,δεζ,θικ] in the first case and [100γ,100ζ,100κ] in the last.

The remaining two cases are similar, but the arrays [100,αβ,δε] and [100,100,αβ] have to be reordered, according on the values of [θι] and possibly δε.

In the second case, the six permutations of [100,αβ,δε] are [100,αβ,δε], [100,δε,αβ], [αβ,100,δε], [αβ,δε,100], [δε,100,αβ], and [δε,αβ,100].

By computing 100θι, we map 00, 01, and 10 to four, three and two, selecting the permutations [αβ,δε,100], [αβ,100,δε], and [100,δε,αβ].

After zipping the result with [γ,ζ,κ], we get [αβγ,δεζ,100κ], [αβγ,100ζ,δεκ], or [100γ,δεζ,αβκ].

In the third case, the permutations (with duplicates) of [100,100,αβ] are [100,100,αβ], [100,αβ,100], [100,100,αβ], [100,αβ,100], [αβ,100,100] and [αβ,100,100].

By computing (100θι)(100δε)=δεθι=δε11, we map 00, 01, and 10 to three, four, and five modulo six, selecting the permutations [100,100,αβ], [100,αβ,100], and [αβ,100,100].

After zipping the result with [γ,ζ,κ], we get [100γ,100ζ,αβκ], [100γ,αβζ,100κ], or [αβγ,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

Python 2, 157 bytes

lambda a,b,c,d,e,f,g,h,i,j:[c+[a*4+b*2,8][g*h*~(d*~e*i)],f+[d*4+e*2,8,a*4+b*2][g*i+(d<e)*g*i*h],j+[h*4+i*2,[8,[a*4+b*2,d*4+e*2][h<i]][h^i or(h&i-(d|e))]][g]]

Try it online!


2

Clean, 238 ... 189 bytes

-2 bytes thanks to 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)

Try it online!

Takes a 'list' of 10 bits in the form of 10 arguments, using a direct formula to compute the result.


In i*(9*e+19*d+i*...), that second i* looks unnecessary.
Neil

@Neil You're right, it is, thanks.
Ο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);}}

Try it online

I know 195 bytes is far too much for this contest, but I had no idea how to further compress the Perl code. Suggestions?

Explanation of the code

In a more readable version, the code intention should become apparent:

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 the rules for DPD encoding, each line is encoded into a 18 bit value, segmentation into (6,6,(2,2,2)) bits.

  • The first 6 bits are an appropriate bit mask for the bits 1 (=h) to 6 (=d) of the input (bit 4 = f is redundant, but it simplifies the evaluation code to have it included).
  • The next 6 bits are the value bits for this bit mask. The values are checked on all places where the bit mask has a 1 value.
  • The following 3*2 bits contain the indices for the array @p for the 3-bit sequences which are to spliced into bits 11-9, 7-5 and 3-1 of the result.
  • The array @p is constructed from bits 9-8, 6-5, 3-2 of the input, and the number 8 as fourth member
  • The bits at position 7,4 and 0 of the input are transferred directly into bits 8,4 and 0 of the result.

For example, the first number in the list, 16390, which is 100000000000110 as a bit field, carries the following information:

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

Port of KimOyhus' answer to 05AB1E.

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

Try it online!

Rough explanation:

•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

Definitely not the right language for this kind of challenge, but ah well..
Input as string, output as list of three digits.

Try it online or verify all test cases.

Explanation:

We have the following eight scenarios to consider:

     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

I first split the (implicit) input into chunks of size [2,1,2,1,3,1] and store that list in the 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)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why •3γã• is 212131

Now we're first going to built the 0s and 1s for the first digit of the output. Scenarios 1,2,3,7 use '0'+1st+2nd; and scenarios 4,5,6,8 use '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

Then we're going to built the 0s and 1s for the second digit of the output. Scenarios 1,2,4 use '0'+3rd+4th; scenarios 3,5,7,8 use '100'+4th; and scenario 6 uses '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

Then we're going to built the 0s and 1s for the third digit of the output. Scenarios 1,2 use 5th+6th; scenario 3 uses '0'+3rd+6th; scenarios 4,5 use '0'+1st+6th; and scenarios 6,7,8 use '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

Now we have all 0s and 1s on the stack, so we can convert it to the three output digits:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.