Décimal densément emballé (DPD) en décimal

26

Pour les fans de nandgame: veuillez également essayer DPD en décimal dans les portes logiques !

Contexte

La décimale dense (DPD) est un moyen de stocker efficacement les chiffres décimaux en binaire. Il stocke trois chiffres décimaux (000 à 999) sur 10 bits, ce qui est beaucoup plus efficace que BCD naïf (qui stocke un chiffre sur 4 bits).

Notations

  • Les lettres minuscules aà isont les bits copiés dans la représentation décimale.
  • 0et 1sont les bits exacts dans les modèles de bits d'entrée ou de sortie.
  • x les bits sont ignorés dans la conversion.

Table de conversion

Ce qui suit est la table de conversion de 10 bits de DPD à trois chiffres décimaux. Chaque chiffre décimal est représenté en binaire 4 bits (BCD). Les deux côtés sont écrits de gauche à droite du chiffre le plus significatif au moins.

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)

Tâche

Convertissez 10 bits de DPD en 3 chiffres décimaux.

Cas de 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

Contribution

Le format d'entrée par défaut est une liste de 10 bits. Les bits doivent suivre l'ordre exact ci-dessus, ou l'inverse. Vous pouvez choisir d'utiliser une chaîne équivalente ou une représentation entière à la place. Contrairement à mes autres défis, la réorganisation ou l'utilisation de structures imbriquées n'est pas autorisée .

Pour l'entrée [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], les formats suivants sont autorisés:

  • Liste de bits: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Chaîne: "1100010100"
  • Entier binaire: 788ou0b1100010100
  • Entier décimal: 1100010100
  • Inversé: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]et inversé dans tous les autres formats ci-dessus

Les formats suivants ne sont PAS autorisés:

  • Réorganisation arbitraire des bits: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Structures imbriquées: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]ou[0b110, 0b001, 0b0100]

Sortie

Le format de sortie par défaut est une liste de 3 chiffres décimaux. Chaque chiffre doit être représenté de 0 à 9, soit un entier soit un caractère. Comme en entrée, vous pouvez choisir une représentation sous forme de chaîne ou d'entier. Si vous choisissez une représentation entière, les zéros non significatifs peuvent être omis.

Critère de notation et de victoire

Les règles de standard s'appliquent. Le programme ou la fonction la plus courte en octets pour chaque langue gagne.

Bubbler
la source

Réponses:

12

JavaScript (ES6), 112 octets

Tous les crédits pour cette version plus courte vont à @nwellnhof.

Prend l'entrée comme un entier. Renvoie un tableau de trois chiffres décimaux.

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]

Essayez-le en ligne!


JavaScript (ES6), 118 117 octets

Prend l'entrée comme un entier. Renvoie un tableau de trois chiffres décimaux.

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]

Essayez-le en ligne!

Comment?

Au lieu d'essayer d'appliquer l'algorithme «officiel», ce code est basé sur une sorte de rétro-ingénierie des modèles qui peuvent être trouvés dans les résultats attendus.

Étant donné l'entier , nous calculons:n

x=n16mod8y=n128p=n2mod8

Exemple: premier chiffre (centaines)

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

Algorithme:

  • Si , on ap<6d=y
  • Si , nous avonsp=6d=8+(ymod2)
  • Si , nous avonsp=7 AND (x<4 OR x>5)d=8+(ymod2)
  • Si , nous avonsp=7 AND (x=4 OR x=5)d=y

Comme code JS:

p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y
Arnauld
la source
1
Votre approche est similaire à ma réponse C qui utilise une autre variable temporaire. Après avoir joué un peu plus à ma solution C initiale, un portage vers JavaScript donne 112 octets .
nwellnhof
10

Python 3 , 229 ... 97 96 octets

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

Essayez-le en ligne!

-4 octets par @xnor

-6 octets par @nwellnhof

Formaté:

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

Explication

Parce que je voulais à l'origine l'implémenter dans Jelly, j'adopte une approche différente de la plupart des réponses ici, qui est simple et peut-être adaptée à un langage de golf. Bien que la fonction golfed prenne un entier, laissez l'entrée sous forme de liste de bits [a0,a1,...,a9]. Ensuite, nous pouvons dériver trois valeurs de l'entrée

  • Les bits bas [a2,a5,a9]: ce seront toujours les bits bas de [d0,d1,d2]respectivement.
  • Les bits hauts [2*a0a1,2*a3a4,2*a7a8,8]: les bits hauts de chaque chiffre seront l'un d'entre eux.
  • Les bits indicateurs,, [a3,a4,a5,a7,a8]déterminant comment obtenir les bits hauts de chaque chiffre. Nous calculons l'indicateur (entre 1 et 8) comme suit:
    • Si a5 == 0, l'indicateur est 8 (à l'origine 0, mais l'utilisation de 8 à la place enregistre un octet)
    • Si a3 et a4, l'indicateur est 6-2 * a3a4
    • Sinon, l'indicateur est 2 * a7a8 + 1 (en fait calculé comme un nombre négatif).

Ensuite, le nième chiffre peut être calculé avec élégance comme high_bits[arr[indicator][n]] | low_bits[n]dans le tableau ci-dessous, qui est compressé en une chaîne.

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]
]
lirtosiast
la source
1
Vous pouvez utiliser un bytestring b"..."pour remplacer la conversion par ord.
xnor
@nwellnhof Ha, je viens de trouver la même chose! Vous créditera de toute façon.
lirtosiast
b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]enregistre quatre autres octets.
nwellnhof
@nwellnhof Je pense qu'une chaîne modulo est le chemin à parcourir ici, mais sinon la vôtre fonctionnerait certainement.
lirtosiast
9

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

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

Essayez-le en ligne!

-5 octets merci @tsh (et 2 par moi-même) Donc, je lpeux faire plus d'efforts que prévu.

-2 octets de plus en utilisant la technique de @ tsh!

-5 octets merci @Arnauld

-1 octet merci @Neil

Entrée sous forme de liste de 10 bits (sous forme de 10 arguments), sortie sous forme de liste de 3 chiffres.

Shieru Asakoto
la source
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)enregistre un autre octet. (J'ai vérifié cette fois ...)
Neil
8

C (gcc) , 138 129 octets

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

Essayez-le en ligne!

Extrait d'abord quelques bits en variables set t, afin que les huit lignes de la table de conversion puissent être identifiées par:

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

Ensuite, configure uet vavec des divisions (décalages à droite), de sorte que u, vet l'entrée wcontient les trois bits BCD inférieurs aux positions 0-2. Le reste est un peu aléatoire selon set t. Deux astuces notables sont:

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

Un portage de la solution Javascript de Shieru Asakoto ne fait que 124 octets :

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

Essayez-le en ligne!

nwellnhof
la source
Je pense qu'il peut être raccourci à: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 Votre code semble également être de 138 octets.
nwellnhof
5

Ruby , 153 ... 119 117 octets

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

Essayez-le en ligne!

Comment ça marche:

->n{n+=n&896;

C'est le point de départ: convertir en BCD en décalant de 3 bits vers la gauche, ce qui fonctionne pour la plupart des motifs.

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

Obtenez les bits du milieu de chaque quartet (et un bit supplémentaire du troisième quartet, mais masquez le bit le moins significatif).

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

Si le troisième chiffre est inférieur à 10 (inférieur à 9 car nous ne nous sommes jamais souciés du LSB de toute façon), nous sommes définis: c'est du BCD simple, nous pouvons sortir l'hex sans rien changer

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

Sinon, faites de la magie noire en déplaçant les bits et en ajoutant des nombres magiques jusqu'à ce que nous obtenions le résultat que nous voulons.

GB
la source
5

Retina 0.8.2 , 191 181 octets

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

Essayez-le en ligne! Le lien inclut des cas de test. Edit: enregistré 10 octets en ne remplissant pas les chiffres à 4 bits, sauf si nécessaire. Explication:

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

Insérez des séparateurs afin que chaque chiffre puisse être converti en décimal séparément. Cela gère efficacement les deux premiers cas dans la table de conversion.

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

Gérez le dernier (huitième) cas dans la table de conversion.

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

Gérez les sixième et septième cas dans la table de conversion.

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

Gérez le cinquième cas dans la table de conversion.

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

Gérez les troisième et quatrième cas dans la table de conversion.

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

Effectuez une conversion binaire en décimale.

Neil
la source
5

Gelée , 51 48 40 39 octets

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

Essayez-le en ligne!

Algorithme

À l'exception des index de liste, tous les entiers de cette section sont écrits en binaire.

Étant donné l'entrée , nous construisons d'abord les tableaux , et .αβγδεζηθικ[ηη,θι,δε][αβ,δε,θι][γ,ζ,κ]

  1. Si , les trois chiffres de sortie sont faibles ( à ).ηη=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.
Dennis
la source
2

Python 2 , 157 octets

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

Essayez-le en ligne!

TFeld
la source
2

Nettoyer , 238 ... 189 octets

-2 octets grâce à 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)

Essayez-le en ligne!

Prend une «liste» de 10 bits sous la forme de 10 arguments, en utilisant une formule directe pour calculer le résultat.

Οurous
la source
Dans i*(9*e+19*d+i*...), cette seconde i*semble inutile.
Neil
@Neil Tu as raison, ça l'est, merci.
Novurous
1

Perl 5, 195 octets

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

Essayez-le en ligne

Je sais que 195 octets, c'est beaucoup trop pour ce concours, mais je ne savais pas comment compresser davantage le code Perl. Suggestions?

Explication du code

Dans une version plus lisible, l'intention du code devrait devenir évidente:

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

Dans les règles de codage DPD, chaque ligne est codée en une valeur de 18 bits, segmentation en (6,6, (2,2,2)) bits.

  • Les 6 premiers bits sont un masque de bits approprié pour les bits 1 (= h) à 6 (= d) de l'entrée (le bit 4 = f est redondant, mais il simplifie le code d'évaluation pour l'inclure).
  • Les 6 bits suivants sont les bits de valeur pour ce masque de bits. Les valeurs sont vérifiées à tous les endroits où le masque de bits a une valeur 1.
  • Les 3 * 2 bits suivants contiennent les indices de la matrice @ppour les séquences de 3 bits qui doivent être épissées en bits 11-9, 7-5 et 3-1 du résultat.
  • Le tableau @pest construit à partir des bits 9-8, 6-5, 3-2 de l'entrée et du nombre en 8tant que quatrième membre
  • Les bits aux positions 7,4 et 0 de l'entrée sont transférés directement dans les bits 8,4 et 0 du résultat.

Par exemple, le premier nombre de la liste, 16390qui est 100000000000110un champ de bits, contient les informations suivantes:

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
rplantiko
la source
1

05AB1E , 84 octets

Réponse du port de KimOyhus au 05AB1E.

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

Essayez-le en ligne!

Explication grossière:

•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
Grimmy
la source
0

05AB1E , 104 103 101 octets

•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

Certainement pas la bonne langue pour ce genre de défi, mais ah bien ..
Entrée sous forme de chaîne, sortie sous forme de liste de trois chiffres.

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

Explication:

Nous avons les huit scénarios suivants à considérer:

     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

J'ai d'abord divisé l'entrée (implicite) en morceaux de taille [2,1,2,1,3,1]et stocke cette liste dans le registre:

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)

Voir cette astuce de mes 05AB1E (section Comment compresser les grands entiers? ) Pour comprendre pourquoi •3γã•est212131

Maintenant, nous allons d'abord construire les 0 et les 1 pour le premier chiffre de la sortie. Utilisation des scénarios 1,2,3,7 '0'+1st+2nd; et les scénarios 4,5,6,8 utilisent '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

Ensuite, nous allons construire les 0 et les 1 pour le deuxième chiffre de la sortie. Utilisation des scénarios 1,2,4 '0'+3rd+4th; utilisation des scénarios 3,5,7,8 '100'+4th; et le scénario 6 utilise '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

Ensuite, nous allons construire les 0 et les 1 pour le troisième chiffre de la sortie. Scénarios 1,2 utilisation 5th+6th; utilisations du scénario 3 '0'+3rd+6th; scénarios 4,5 utilisation '0'+1st+6th; et les scénarios 6,7,8 utilisent '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

Maintenant, nous avons tous les 0 et les 1 sur la pile, nous pouvons donc les convertir en trois chiffres de sortie:

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)
Kevin Cruijssen
la source