Плотно упакованный десятичный (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<6 , мы имеем d=Y
  • Если p=6 , мы имеем d=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, я придерживаюсь подхода, отличного от большинства приведенных здесь ответов, который прост и, возможно, подходит для языка игры в гольф. Хотя функция golfed принимает целое число, пусть вход будет в виде списка битов [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
ТШ

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содержат нижние три КОРА бит в позициях 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

Рубин , 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

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-θιмы карту 00, 01, а также 10 до четырех, трех и двух, выбирая перестановки [αβ,δε,100], [αβ,100,δε], а также [100,δε,αβ],

После архивирования результата с [γ,ζ,κ], мы получаем [αβγ,δεζ,100κ], [αβγ,100ζ,δεκ], или [100γ,δεζ,αβκ],

В третьем случае перестановки (с дубликатами) [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

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

В более читаемой версии намерение кода должно стать очевидным:

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.