Desimal padat dikemas (DPD) ke desimal

26

Untuk penggemar nandgame: Silakan coba DPD ke desimal di gerbang logika juga!

Latar Belakang

Desimal padat dikemas (DPD) adalah cara untuk secara efisien menyimpan angka desimal dalam biner. Ini menyimpan tiga angka desimal (000 hingga 999) dalam 10 bit, yang jauh lebih efisien daripada BCD naif (yang menyimpan satu digit dalam 4 bit).

Notasi

  • Huruf kecil auntuk ibit yang disalin ke representasi desimal.
  • 0dan 1bit-bit yang tepat dalam pola bit input atau output.
  • x bit diabaikan dalam konversi.

Tabel konversi

Berikut ini adalah tabel konversi dari 10 bit DPD ke tiga angka desimal. Setiap digit desimal direpresentasikan sebagai biner 4-bit (BCD). Kedua sisi ditulis dari kiri ke kanan dari digit paling signifikan ke yang terkecil.

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)

Tugas

Ubah 10 bit DPD menjadi 3 digit desimal.

Uji kasus

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

Memasukkan

Format input default adalah daftar 10 bit. Bit harus mengikuti urutan tepat di atas, atau kebalikannya. Anda dapat memilih untuk menggunakan representasi string atau integer yang setara. Tidak seperti tantangan saya yang lain, pemesanan ulang atau menggunakan struktur bersarang tidak diperbolehkan .

Untuk input [1, 1, 0, 0, 0, 1, 0, 1, 0, 0], format berikut diizinkan:

  • Daftar bit: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Tali: "1100010100"
  • Binary integer: 788atau0b1100010100
  • Bilangan bulat desimal: 1100010100
  • Terbalik: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]dan terbalik dalam format lain di atas

Format berikut ini TIDAK diizinkan:

  • Penataan ulang bit secara sewenang-wenang: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Struktur bersarang: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]atau[0b110, 0b001, 0b0100]

Keluaran

Format output default adalah daftar 3 digit desimal. Setiap digit harus direpresentasikan sebagai 0 hingga 9, baik bilangan bulat atau karakter. Seperti pada input, Anda dapat memilih representasi string atau integer. Jika Anda memilih representasi integer, angka nol di depan dapat dihilangkan.

Kriteria penilaian & menang

Aturan standar berlaku. Program atau fungsi terpendek dalam byte untuk setiap bahasa menang.

Bubbler
sumber

Jawaban:

12

JavaScript (ES6), 112 byte

Semua kredit untuk versi yang lebih pendek ini jatuh ke @nwellnhof.

Mengambil input sebagai integer. Mengembalikan array tiga digit desimal.

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]

Cobalah online!


JavaScript (ES6), 118 117 byte

Mengambil input sebagai integer. Mengembalikan array tiga digit desimal.

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]

Cobalah online!

Bagaimana?

Alih-alih mencoba menerapkan algoritma 'resmi', kode ini didasarkan pada semacam rekayasa balik pola yang dapat ditemukan dalam hasil yang diharapkan.

Diberikan integer input n , kami menghitung:

x=n16mod8y=n128p=n2mod8

Contoh: digit pertama (ratusan)

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

Algoritma:

  • Jika , kita memilikip<6d=y
  • Jika , kita memilikihal=6d=8+(ymod2)
  • Jika , kita memilikihal=7 DAN (x<4 ATAU x>5)d=8+(ymod2)
  • Jika , kita memilikihal=7 DAN (x=4 ATAU x=5)d=y

Sebagai kode JS:

p > 5 && p < 7 | x / 2 ^ 2 ? 8 | y & 1 : y
Arnauld
sumber
1
Pendekatan Anda mirip dengan jawaban C saya yang menggunakan variabel sementara lainnya. Setelah bermain golf solusi C awal saya sedikit lebih banyak, port ke hasil JavaScript dalam 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]]

Cobalah online!

-4 byte oleh @xnor

-6 bytes oleh @nwellnhof

Diformat:

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

Penjelasan

Karena saya awalnya ingin menerapkan ini dalam Jelly, saya mengambil pendekatan berbeda dari sebagian besar jawaban di sini, yang sederhana dan mungkin cocok untuk bahasa golf. Meskipun fungsi golf mengambil bilangan bulat, biarkan input sebagai daftar bit [a0,a1,...,a9]. Kemudian kita dapat memperoleh tiga nilai dari input

  • Bit rendah [a2,a5,a9]: Ini akan selalu menjadi bit rendah [d0,d1,d2]masing - masing.
  • Bit tinggi [2*a0a1,2*a3a4,2*a7a8,8]: Bit tinggi setiap digit akan menjadi salah satunya.
  • Bit indikator [a3,a4,a5,a7,a8], menentukan cara mendapatkan bit tinggi dari setiap digit. Kami menghitung indikator (antara 1 dan 8) sebagai berikut:
    • Jika a5 == 0, indikatornya adalah 8 (aslinya 0, tetapi menggunakan 8 bukan menyimpan satu byte)
    • Jika a3 dan a4, indikatornya adalah 6 - 2 * a3a4
    • Kalau tidak, indikatornya adalah 2 * a7a8 +1 (sebenarnya dihitung sebagai angka negatif).

Kemudian digit ke-n dapat dihitung secara elegan seperti high_bits[arr[indicator][n]] | low_bits[n]pada tabel di bawah ini, yang dikompres menjadi string.

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
sumber
1
Anda dapat menggunakan bytestring b"..."untuk mengganti konversi dengan ord.
xnor
@nwellnhof Ha, saya baru saja menemukan hal yang sama! Akankah kredit Anda tetap.
lirtosiast
b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]menyimpan empat byte lagi.
nwellnhof
@nwellnhof Saya pikir rantai modulo adalah cara untuk pergi ke sini, tetapi jika tidak milikmu pasti akan bekerja.
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]

Cobalah online!

-5 byte terima kasih @tsh (dan 2 sendiri) Jadi lbisa melakukan lebih banyak usaha dari yang saya harapkan.

-2 byte lebih banyak menggunakan teknik @ tsh!

-5 byte terima kasih @Arnauld

-1 byte terima kasih @Neil

Input sebagai daftar 10 bit (sebagai 10 argumen), output sebagai daftar 3 digit.

Shieru Asakoto
sumber
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)menyimpan byte lain. (Saya memeriksa kali ini ...)
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);}

Cobalah online!

Pertama mengekstrak beberapa bit ke dalam variabel sdan t, sehingga delapan baris tabel konversi dapat diidentifikasi oleh:

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

Kemudian atur udan vdengan divisi (shift kanan), sehingga u, vdan input wberisi tiga bit BCD yang lebih rendah di posisi 0-2. Sisanya agak mengocok tergantung pada sdan t. Dua trik penting adalah:

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

Port solusi Javascript Shieru Asakoto hanya 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;}

Cobalah online!

nwellnhof
sumber
Saya pikir itu bisa disingkat menjadi: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 Kode Anda juga tampaknya 138 byte.
nwellnhof
5

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

Cobalah online!

Bagaimana itu bekerja:

->n{n+=n&896;

Ini adalah titik awal: konversikan ke BCD dengan menggeser 3 bit ke kiri, yang berfungsi untuk sebagian besar pola.

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

Dapatkan bit tengah dari masing-masing nibble (dan satu bit ekstra dari nibble ketiga, tetapi sembunyikan bit yang paling tidak signifikan).

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

Jika digit ketiga kurang dari 10 (kurang dari 9 karena kita tidak pernah merawat LSB), kita ditetapkan: ini adalah BCD biasa, kita dapat menampilkan hex tanpa mengubah apa pun

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

Kalau tidak, lakukan beberapa ilmu hitam dengan menggeser bit sekitar dan menambahkan angka ajaib sampai kita mendapatkan hasil yang kita inginkan.

GB
sumber
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

Cobalah online! Tautan termasuk kasus uji. Sunting: Disimpan 10 byte dengan tidak menambahkan digit ke 4 bit kecuali jika perlu. Penjelasan:

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

Masukkan pemisah sehingga setiap digit dapat dikonversi ke desimal secara terpisah. Ini secara efektif menangani dua kasus pertama dalam tabel konversi.

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

Tangani case (kedelapan) terakhir dalam tabel konversi.

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

Tangani case keenam dan ketujuh dalam tabel konversi.

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

Tangani case kelima di tabel konversi.

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

Tangani case ketiga dan keempat di tabel konversi.

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

Lakukan konversi biner ke desimal.

Neil
sumber
5

Jelly , 51 48 40 39 byte

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

Cobalah online!

Algoritma

Dengan pengecualian indeks daftar, semua bilangan bulat di bagian ini ditulis dalam biner.

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

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

Kode

“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
sumber
2

Python 2 , 157 byte

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

Cobalah online!

TFeld
sumber
2

Bersih , 238 ... 189 byte

-2 byte terima kasih kepada 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)

Cobalah online!

Mengambil 'daftar' 10 bit dalam bentuk 10 argumen, menggunakan rumus langsung untuk menghitung hasilnya.

Suram
sumber
Dalam i*(9*e+19*d+i*...), yang kedua i*terlihat tidak perlu.
Neil
@ Neil Kau benar, benar, terima kasih.
Kamis
1

Perl 5, 195 byte

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

Cobalah online

Saya tahu 195 byte terlalu banyak untuk kontes ini, tetapi saya tidak tahu bagaimana cara mengompres kode Perl lebih jauh. Saran?

Penjelasan kode

Dalam versi yang lebih mudah dibaca, niat kode harus menjadi jelas:

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

Dalam aturan untuk pengkodean DPD, setiap baris dikodekan ke dalam nilai 18 bit, segmentasi ke dalam (6,6, (2,2,2)) bit.

  • 6 bit pertama adalah bit mask yang sesuai untuk bit 1 (= h) hingga 6 (= d) dari input (bit 4 = f adalah redundan, tetapi menyederhanakan kode evaluasi untuk memasukkannya).
  • 6 bit berikutnya adalah bit nilai untuk topeng bit ini. Nilai-nilai diperiksa di semua tempat di mana bit mask memiliki nilai 1.
  • Bit 3 * 2 berikut berisi indeks untuk array @puntuk urutan 3-bit yang akan disambung menjadi bit 11-9, 7-5 dan 3-1 dari hasilnya.
  • Array @pdibangun dari bit 9-8, 6-5, 3-2 dari input, dan angka 8sebagai anggota keempat
  • Bit pada posisi 7,4 dan 0 dari input ditransfer langsung ke bit 8,4 dan 0 dari hasilnya.

Misalnya, nomor pertama dalam daftar 16390,, yang 100000000000110sebagai bidang bit, membawa informasi berikut:

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
sumber
1

05AB1E , 84 byte

Jawaban Port of KimOyhus untuk 05AB1E

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

Cobalah online!

Penjelasan kasar:

•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
sumber
0

05AB1E , 104 103 101 byte

•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

Jelas bukan bahasa yang tepat untuk tantangan semacam ini, tapi ah well ..
Input sebagai string, output sebagai daftar tiga digit.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

Kami memiliki delapan skenario berikut untuk dipertimbangkan:

     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

Saya pertama-tama membagi input (implisit) menjadi potongan ukuran [2,1,2,1,3,1]dan menyimpan daftar itu dalam 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)

Lihat ini 05AB1E ujung tambang (bagian Cara kompres bilangan bulat besar? ) Untuk memahami mengapa •3γã•adalah212131

Sekarang kita akan membangun 0s dan 1s untuk digit pertama dari output. Skenario 1,2,3,7 digunakan '0'+1st+2nd; dan skenario 4,5,6,8 gunakan '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

Kemudian kita akan membangun 0s dan 1s untuk digit kedua dari output. Skenario 1,2,4 digunakan '0'+3rd+4th; skenario 3,5,7,8 digunakan '100'+4th; dan skenario 6 menggunakan '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

Kemudian kita akan membangun 0s dan 1s untuk digit ketiga dari output. Skenario 1,2 digunakan 5th+6th; penggunaan skenario 3 '0'+3rd+6th; skenario 4,5 digunakan '0'+1st+6th; dan skenario 6,7,8 digunakan '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

Sekarang kita memiliki semua 0s dan 1s pada stack, jadi kita dapat mengubahnya menjadi tiga digit output:

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
sumber