Щільно упакований десятковий (DPD) до десяткового


26

Для шанувальників nandgame: Будь ласка, спробуйте також DPD для десяткового розміру в логічних воротах !

Фон

Щільно упакований десятковий (DPD) - це спосіб ефективно зберігати десяткові цифри у двійкових. Він зберігає три десяткових цифри (000 до 999) в 10 біт, що набагато ефективніше, ніж наївний BCD (який зберігає одну цифру в 4 біти).

Позначення

  • Малі літери aв iті біти, які копіюються в десятковому поданні.
  • 0і 1є точними бітами у вхідних або вихідних бітах.
  • x біти ігноруються при перетворенні.

Таблиця переходів

Далі наведена таблиця перетворення від 10 біт DPD до трьох десяткових цифр. Кожна десяткова цифра представлена ​​у вигляді 4-розрядних двійкових (BCD). Обидві сторони записуються зліва направо від найбільш значущої цифри до найменшої.

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)

Завдання

Перетворіть 10 біт DPD в 3 цифри десяткової.

Тестові справи

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

Вхідні дані

Формат введення за замовчуванням - це список з 10 біт. Біти повинні дотримуватися точного порядку, зазначеного вище, або реверсу його. Ви можете замість цього використати еквівалентне рядкове або ціле представлення. На відміну від інших моїх проблем, переупорядкування та використання вкладених структур не дозволяється .

Для введення [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]дозволені наступні формати:

  • Список бітів: [1, 1, 0, 0, 0, 1, 0, 1, 0, 0]
  • Рядок: "1100010100"
  • Двійкове ціле число: 788або0b1100010100
  • Десяткове ціле число: 1100010100
  • Зворотний: [0, 0, 1, 0, 1, 0, 0, 0, 1, 1]і перевернутий у будь-якому іншому форматі вище

Наступні формати НЕ дозволені:

  • Довільне упорядкування бітів: [0, 0, 0, 0, 0, 1, 1, 1, 0, 1]
  • Вкладені структури: [[1, 1, 0], [0, 0, 1], [0, 1, 0, 0]]або[0b110, 0b001, 0b0100]

Вихідні дані

Типовий вихідний формат - це список з 3-х десяткових цифр. Кожна цифра повинна бути представлена ​​як 0 до 9, або ціле число, або символ. Як і при введенні, ви можете обрати рядкове або ціле подання. Якщо ви вибрали ціле представлення, провідні нулі можна опустити.

Критерій оцінки та виграшу

Діють стандартні правила . Виграє найкоротша програма або функція в байтах для кожної мови.

Відповіді:


12

JavaScript (ES6), 112 байт

Вся заслуга за цю коротшу версію належить @nwellnhof.

Вводиться як ціле число. Повертає масив з трьох десяткових цифр.

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]

Спробуйте в Інтернеті!


JavaScript (ES6), 118 117 байт

Вводиться як ціле число. Повертає масив з трьох десяткових цифр.

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]

Спробуйте в Інтернеті!

Як?

Замість того, щоб намагатися застосувати "офіційний" алгоритм, цей код базується на певній звороті інженерії шаблонів, які можна знайти в очікуваних результатах.

З огляду на вхідне ціле число , обчислюємо:n

x=n16mod8y=n128p=n2mod8

Приклад: перша цифра (сотні)

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

Алгоритм:

  • Якщо , маємоp<6d=y
  • Якщо , маємоp=6d=8+(ymod2)
  • Якщо , маємоp=7 AND (x<4 OR x>5)d=8+(ymod2)
  • Якщо , маємоp=7 AND (x=4 OR x=5)d=y

Як код JS:

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

1
Ваш підхід схожий на мою відповідь C, яка використовує іншу тимчасову змінну. Після того, як я трохи більше пограв на моєму початковому рішенні, порт для JavaScript приводить до 112 байт .
nwellnhof

10

Python 3 , 229 ... 97 96 байт

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

Спробуйте в Інтернеті!

-4 байти від @xnor

-6 байт від @nwellnhof

Відформатовано:

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

Пояснення

Оскільки я спочатку хотів здійснити це в Jelly, я використовую інший підхід від більшості відповідей тут, який простий і, можливо, підходить для мови гольфу. Хоча функція гольфу займає ціле число, нехай вхід є бітовим списком [a0,a1,...,a9]. Тоді ми можемо отримати три значення з вхідних даних

  • Низькі біти [a2,a5,a9]: Це завжди будуть низькі біти [d0,d1,d2]відповідно.
  • Високі біти [2*a0a1,2*a3a4,2*a7a8,8]: Високі біти кожної цифри будуть одним із них.
  • Індикатор бітів, [a3,a4,a5,a7,a8]визначаючи, як отримати високі біти кожної цифри. Ми обчислюємо показник (від 1 до 8) наступним чином:
    • Якщо a5 == 0, показник дорівнює 8 (спочатку 0, але використання 8 замість цього зберігає байт)
    • Якщо a3 nand a4, показник дорівнює 6 - 2 * a3a4
    • В іншому випадку показник 2 * a7a8 + 1 (насправді обчислюється як від’ємне число).

Тоді n-ту цифру можна обчислити елегантно, як показано в high_bits[arr[indicator][n]] | low_bits[n]таблиці нижче, яка стискається в рядок.

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
b"..."Для заміни конвертації можна скористатись бітестрінгом ord.
xnor

@nwellnhof Ха, я щойно знайшов те саме! Позику вам все одно.
lirtosiast

b"$>6;-/'?"[a&8and(~a&6or a>>4&6|1)]зберігає ще чотири байти.
nwellnhof

@nwellnhof Я думаю, що модульний ланцюг - це шлях до цього, але якби не ваш, звичайно, спрацює.
lirtosiast

9

JavaScript (Node.js) , 126 119 117 112 111 байт

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

Спробуйте в Інтернеті!

-5 байт дякую @tsh (і 2 власноруч) Тож lможна докласти більше зусиль, ніж я очікував.

Ще 2 байти, використовуючи техніку @ tsh!

-5 байт дякую @Arnauld

-1 байт дякую @Neil

Введіть як список 10 біт (як 10 аргументів), виведіть у вигляді списку з 3 цифр.


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)зберігає ще один байт. (Я перевірив цього разу ...)
Ніл

8

C (gcc) , 138 129 байт

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

Спробуйте в Інтернеті!

Спочатку витягує кілька бітів у змінні, sі tтак, щоб вісім рядків таблиці перетворення можна було ідентифікувати за:

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

Потім встановлюється uі vз поділами (правий зсув), таким чином u, vі вхід wмістить три нижніх біта BCD в позиціях 0-2. Решта трохи перемішується залежно від sі t. Два помітних хитрощі:

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

Порт Javascript для рішення Шиєру Асакото складає всього 124 байти :

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

Спробуйте в Інтернеті!


Я думаю, що це можна скоротити до: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 Здається, що ваш код також становить 138 байт.
nwellnhof

5

Ruby , 153 ... 119 117 байт

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

Спробуйте в Інтернеті!

Як це працює:

->n{n+=n&896;

Це вихідна точка: перетворити в BCD, змістивши 3 біти вліво, що працює для більшості шаблонів.

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

Отримайте середні шматочки кожного кусача (і один зайвий біт третього грибка, але замаскуйте найменш значущий біт).

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

Якщо третя цифра менше 10 (менше 9, тому що ми ніколи не піклувалися про LSB), ми встановлюємо: це звичайний BCD, ми можемо виводити шістнадцятковий, не змінюючи нічого

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

В іншому випадку зробіть чорну магію, зміщуючи біти навколо і додаючи магічні числа, поки не отримаємо потрібний результат.


5

Сітківка 0,8.2 , 191 181 байт

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

Спробуйте в Інтернеті! Посилання включає тестові випадки. Редагувати: Збережено 10 байт, не додаючи цифр до 4 біт, за винятком випадків, коли це необхідно. Пояснення:

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

Виконувати перетворення двійкового в десятковий.


5

Желе , 51 48 40 39 байт

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

Спробуйте в Інтернеті!

Алгоритм

За винятком індексів списку, всі цілі числа в цьому розділі записуються у двійковій формі.

З огляду на введення , спочатку побудуємо масиви , та .αβγδεζηθικ[ηη,θι,δε][αβ,δε,θι][γ,ζ,κ]

  1. Якщо , усі три вихідні цифри низькі ( до ).ηη=0000000111
  2. Якщо але , точнісінько одна вихідна цифра є високою ( або ).ηη=11θι<1110001001
  3. Якщо але , точні два цифри виходу є високими.ηη=θι=11δε<11
  4. Якщо , усі три вихідні цифри високі.ηη=θι=δε=11

Якщо порахувати кількість провідних 's , створимо масив відповідного числа ' s, з'єднаємо його з і розділивши результат на підрядні довжини три, отримаємо наступні результати у кожному випадку.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κ]

Код

“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

Чистота , 238 ... 189 байт

-2 байти завдяки Нілу

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)

Спробуйте в Інтернеті!

Бере "список" з 10 бітів у вигляді 10 аргументів, використовуючи пряму формулу для обчислення результату.


У тому i*(9*e+19*d+i*...), що друге i*виглядає непотрібним.
Ніл

@Neil Ви маєте рацію, це дякую.
Οurous

1

Perl 5, 195 байт

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

Спробуйте в Інтернеті

Я знаю, що 195 байт - це занадто багато для цього конкурсу, але я не мав уявлення, як далі стиснути код Perl. Пропозиції?

Пояснення коду

У більш читаній версії намір коду повинен стати очевидним:

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

У правилах кодування DPD кожен рядок кодується у 18-бітове значення, сегментація на (6,6, (2,2,2)) біти.

  • Перші 6 біт є відповідною бітовою маскою для бітів 1 (= h) до 6 (= d) вхідного сигналу (біт 4 = f є зайвим, але це спрощує код оцінки для включення його).
  • Наступні 6 біт - це біти значення для цієї бітової маски. Значення перевіряються у всіх місцях, де бітова маска має значення 1.
  • Наступні 3 * 2 біти містять індекси для масиву @pдля 3-бітових послідовностей, які слід сплайнувати на біти 11-9, 7-5 та 3-1 результату.
  • Масив @pпобудований з бітів 9-8, 6-5, 3-2 вхідного числа та числа 8як четвертого члена
  • Біти в положенні 7,4 і 0 вводу передаються безпосередньо в біти 8,4 і 0 результату.

Наприклад, перше число у списку, 16390яке є 100000000000110бітовим полем, містить таку інформацію:

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 байти

Відповідь порту КімОйгуса на 05AB1E.

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

Спробуйте в Інтернеті!

Грубе пояснення:

•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 байт

•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

Однозначно не потрібна мова для подібного виклику, але ну добре.
Введіть як рядок, виведіть як список трьох цифр.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

Ми маємо розглянути наступні вісім сценаріїв:

     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

Я спершу розділив (неявний) вхід на шматки розміру [2,1,2,1,3,1]і зберігаю цей список у реєстрі:

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)

Дивіться цей мінний наконечник 05AB1E (розділ Як стискати великі цілі числа? ), Щоб зрозуміти, чому •3γã•це так212131

Тепер ми спочатку збираємося до 0 і 1 для першої цифри виводу. Сценарії 1,2,3,7 використання '0'+1st+2nd; та сценарії 4,5,6,8 використовують '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

Тоді ми збираємося побудувати 0 і 1 для другої цифри виводу. Сценарії 1,2,4 використання '0'+3rd+4th; сценарії 3,5,7,8 використання '100'+4th; та сценарій 6 використовує '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

Тоді ми збираємося побудувати 0 і 1 для третьої цифри виводу. Сценарії 1,2 використання 5th+6th; сценарій 3 використання '0'+3rd+6th; сценарії 4,5 '0'+1st+6th; та сценарії 6,7,8 використання '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

Тепер у нас є всі 0 і 1 на стеці, тому ми можемо перетворити його на три вихідні цифри:

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.