Гольф битное плетение


14

Примечание: первая половина этой задачи происходит от предыдущей задачи Мартина Эндера « Визуализация битового переплетения» .

У эзотерического языка программирования зло есть интересная операция над байтовыми значениями, которую он называет «переплетением».

По сути, это перестановка восьми битов байта (не имеет значения, с какого конца мы начинаем считать, поскольку шаблон симметричен):

  • Бит 0 перемещается в бит 2
  • Бит 1 перемещается в бит 0
  • Бит 2 перемещается в бит 4
  • Бит 3 перемещается в бит 1
  • Бит 4 перемещен в бит 6
  • Бит 5 перемещен в бит 3
  • Бит 6 перемещен в бит 7
  • Бит 7 перемещен в бит 5

Для удобства приведем еще три представления перестановки. Как цикл:

(02467531)

Как отображение:

57361402 -> 76543210 -> 64725031

И как список пар сопоставления:

[[0,2], [1,0], [2,4], [3,1], [4,6], [5,3], [6,7], [7,5]]

После 8переплетений байт по существу сбрасывается.

Например, соткать число 10011101(которое находится 157в базе 10) даст 01110110(которое находится 118в базе 10).

вход

Есть только 256допустимые входные данные, а именно все целые числа между 0и 255включительно. Это может быть принято в любой базе, но она должна быть последовательной, и вы должны указать ее, если база, которую вы выбираете, не является базой десять.

Вы не можете дополнять нулями свои входные данные.

Выход

Вы должны вывести результат переплетения битов в любой базе, которая также должна быть последовательной и указана, если не в базовой десятке.

Вы можете обнулять свои выводы.


Связанный: Визуализация битового плетения


5
Забавный факт: это вызов, который я хотел опубликовать изначально. Затем я разработал ASCII-арт для визуализации перестановки, а затем Sp3000 предложил сделать рендеринг более сложным. ;)
Мартин Эндер

2
Может ли выходная база отличаться от входной базы? Когда вы говорите «последовательный», я понимаю это как «любой возможный вклад в одну и ту же базу»
Луис Мендо

Я думаю, что представление в виде цикла было бы более полезным, чем представление отображения.
mbomb007

Я должен сказать, что искусство ASCII определенно веселее.
Безумный

2
Это действительно может использовать еще несколько тестов.
Джеймс

Ответы:


32

Python 2.7, 44 -> 36 байт

lambda x:x/4&42|x*2&128|x*4&84|x/2&1

10
Отличный первый ответ, добро пожаловать в PPCG! :)
Мартин Эндер

10
Если вы используете |вместо +и маску после сдвига, тогда вы можете сбрить 8 байтов, удалив скобки.
PellMell

Поскольку вы новичок, я укажу, что вы можете воспользоваться предложением @ PellMell, чтобы улучшить свой гольф, а затем использовать <strike></strike>свой старый байтовый счет, чтобы показать прогресс :-)
Безумный


16

Зло, 3 персонажа

rew

Попробуйте онлайн!

Входные данные находятся в базе 256 (например, ASCII), например, чтобы ввести цифру 63, введите ASCII 63, которая является ?.

Объяснение:

r          #Read a character
 e         #Weave it
  w        #Display it

Это так похоже на обман.


1
ASCII - это не база 256, а база 128. Какая кодировка используется для порядковых чисел 128-255? Изменить: похоже, он просто использует системную кодировку.
Мего

11

CJam, 15 12 байт

Спасибо FryAmTheEggman за сохранение 3 байта.

l8Te[m!6532=

Вход в базу 2. Выход также в базу 2, дополненный до 8 бит нулями.

Проверьте это здесь.

объяснение

l      e# Read the input.
8Te[   e# Left-pad it to 8 elements with zeros.
m!     e# Generate all permutations (with duplicates, i.e. treating equal elements
       e# in different positions distinctly).
6532=  e# Select the 6533rd, which happens to permute the elements like [1 3 0 5 2 7 4 6].

7

MATL , 14 байтов

&8B[2K1B3D5C])

Ввод в десятичном виде. Выходной файл заполнен нулями.

Попробуйте онлайн!

объяснение

&8B         % Take input number implicitly. Convert to binary array with 8 digits
[2K1B3D5C]  % Push array [2 4 1 6 3 8 5 7]
)           % Index first array with second array. Implicitly display

7

Желе, 11 байт

+⁹BḊŒ!6533ị

Перевод ответа Мартина CJam. Попробуй это здесь.

+⁹BḊ          Translate (x+256) to binary and chop off the MSB.
              This essentially zero-pads the list to 8 bits.
    Œ!        Generate all permutations of this list.
      6533ị   Index the 6533rd one.

1
Мне нравится трюк с заполнением нулями. Элегантный.
Трихоплакс

7

JavaScript (ES6), 30 байт

f=n=>n*4&84|n*2&128|n/2&1|n/4&42

Хорошее злоупотребление приоритетом!
Дрянная Монахиня

1
Конечно, приоритет был разработан, чтобы работать таким образом! Это будет работать даже с битами, но они длиннее.
Нил

6

J, 12 байт

6532 A._8&{.

Использует встроенную перестановку A. перестановку с индексом перестановки, 6532который соответствует операции битового плетения.

использование

Ввод - это список двоичных цифр. Вывод представляет собой заполненный нулями список из 8 двоичных цифр.

   f =: 6532 A._8&{.
   f 1 0 0 1 1 1 0 1
0 1 1 1 0 1 1 0
   f 1 1 1 0 1 1 0
1 1 0 1 1 0 0 1

объяснение

6532 A._8&{.  Input: s
       _8&{.  Takes the list 8 values from the list, filling with zeros at the front
              if the length(s) is less than 8
6532          The permutation index for bit-weaving
     A.       permute the list of digits by that index and return

6

Сетчатка , 39 байт

+`^(?!.{8})
0
(.)(.)
$2$1
\B(.)(.)
$2$1

Вход и выход в базе 2, выход слева.

Попробуйте онлайн!

объяснение

+`^(?!.{8})
0

Это только левый ввод с нулями. +Указывает на то, что этот этап повторяется до тех пор , пока строка перестает изменяться. Он соответствует началу строки, если в ней содержится менее 8 символов, и вставляет 0в эту позицию.

Теперь для фактической перестановки. Прямое решение заключается в следующем:

(.)(.)(.)(.)(.)(.)(.)(.)
$2$4$1$6$3$8$5$7

Однако это мучительно долго и излишне. Я нашел другую формулировку перестановки, которую намного проще реализовать в Retina ( Xпредставляет собой обмен смежными битами):

1 2 3 4 5 6 7 8
 X   X   X   X
2 1 4 3 6 5 8 7
   X   X   X
2 4 1 6 3 8 5 7

Теперь это гораздо проще реализовать:

(.)(.)
$2$1

Это просто соответствует двум символам и меняет их. Поскольку совпадения не перекрываются, это меняет местами все четыре пары.

\B(.)(.)
$2$1

Теперь мы хотим сделать то же самое снова, но мы хотим пропустить первый символ. Самый простой способ сделать это - потребовать, чтобы совпадение не начиналось с границы слова \B.


6

машинный код x86, 20 байт

В шестнадцатеричном виде:

89C22455C1E002D0E0D1E880E2AAC0EA0211D0C3

Это процедура, принимающая ввод и возвращающая результат через регистр AL.

разборка

89 c2                   mov    edx,eax
24 55                   and    al,0x55  ;Clear odd bits
c1 e0 02                shl    eax,0x2  ;Shift left, bit 6 goes to AH...
d0 e0                   shl    al,1     ;...and doesn't affected by this shift
d1 e8                   shr    eax,1    ;Shift bits to their's target positions
80 e2 aa                and    dl,0xaa  ;Clear even bits
c0 ea 02                shr    dl,0x2   ;Shift right, bit 1 goes to CF
11 d0                   adc    eax,edx  ;EAX=EAX+EDX+CF
c3                      ret

5

C (небезопасный макрос), 39 байт

#define w(v)v*4&84|v*2&128|v/2&1|v/4&42

C (функция), 41 байт

w(v){return v*4&84|v*2&128|v/2&1|v/4&42;}

C (полная программа), 59 байт

main(v){scanf("%d",&v);return v*4&84|v*2&128|v/2&1|v/4&42;}

(возвращается через код выхода, поэтому вызывается с помощью echo "157" | ./weave;echo $?)

C (полная программа соответствует стандартам), 86 байт

#include<stdio.h>
int main(){int v;scanf("%d",&v);return v*4&84|v*2&128|v/2&1|v/4&42;}

C (совместимая со стандартами полная программа без предупреждений компилятора), 95 байт

#include<stdio.h>
int main(){int v;scanf("%d",&v);return (v*4&84)|(v*2&128)|(v/2&1)|(v/4&42);}

C (совместимая со стандартами полная программа без предупреждений компилятора, которая может считываться из аргументов или стандартного ввода и включает проверку ошибок / диапазонов), 262 байта

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int v,char**p){v=v<2?isatty(0)&&puts("Value?"),scanf("%d",&v)?v:-1:strtol(p[1],p,10);exit(*p==p[1]||v&255^v?fprintf(stderr,"Invalid value\n"):!printf("%d\n",(v*4&84)|(v*2&128)|(v/2&1)|(v/4&42)));}

Сломать

Практически так же, как многие существующие ответы: сдвиньте биты на свои места с помощью <<2( *4),<<1 ( *2), >>1( /2) и >>2( /4), затем| все вместе.

Остальное - не что иное, как разные вкусы варочной панели.


4

Mathematica, 34 байта

PadLeft[#,8][[{2,4,1,6,3,8,5,7}]]&

Анонимная функция. Принимает список двоичных цифр и выводит дополненный список из 8 двоичных цифр.


3

PowerShell v2 +, 34 байта

("{0:D8}"-f$args)[1,3,0,5,2,7,4,6]

Перевод ответа @ LegionMammal978 . Полная программа. Принимает ввод через аргумент командной строки в виде двоичного числа, выводит в виде двоичного массива с нулевым дополнением.

"{0:D8}"-fЧасть использует стандартные строки числового формата предварять 0к входу $args. Поскольку -fоператор поддерживает использование массива в качестве входных данных, и мы явно сказали использовать первый элемент {0:, нам не нужно делать обычное $args[0]. Мы инкапсулируем эту строку в парены, а затем индексируем в ней [1,3,0,5,2,7,4,6]ткачество. Результирующий массив остается в конвейере и вывод неявный.

Примеры

(по умолчанию .ToString()для массива используется разделитель as `n, поэтому выходные данные разделены символом новой строки)

PS C:\Tools\Scripts\golfing> .\golf-bit-weaving.ps1 10011101
0
1
1
1
0
1
1
0

PS C:\Tools\Scripts\golfing> .\golf-bit-weaving.ps1 1111
0
0
0
1
0
1
1
1

3

Matlab, 49 48 44 байта

s=sprintf('%08s',input(''));s('24163857'-48)

Принимает ввод как строку двоичных значений. Выход дополнен. 4 байта сохранены благодаря @Luis Mendo.

Объяснение:

input('')             -- takes input
s=sprintf('%08s',...) -- pads with zeros to obtain 8 digits
s('24163857'-48)      -- takes positions [2 4 1 6 3 8 5 7] from s (48 is code for '0')

3

V , 17 байт

8é0$7hd|òxplò2|@q

Попробуйте онлайн!

Это берет ввод и вывод в двоичном виде. Большая часть количества байтов происходит от заполнения его нулями. Если заполнение ввода было разрешено, мы могли бы просто сделать:

òxplò2|@q

Благодаря решению Мартина для метода обмена символами, например:

1 2 3 4 5 6 7 8
 X   X   X   X
2 1 4 3 6 5 8 7
   X   X   X
2 4 1 6 3 8 5 7

Объяснение:

8é0                 "Insert 8 '0' characters
   $                "Move to the end of the current line
    7h              "Move 7 characters back
      d|            "Delete until the first character
        ò   ò       "Recursively:
         xp         "Swap 2 characters
           l        "And move to the right
             2|     "Move to the second column
               @q   "And repeat our last recursive command.


2

Pyth, 19 символов

s[@z1.it%2tzP%2z@z6

Вход и выход являются основанием 2.

Далеко не эксперт Pyth, но, поскольку никто еще не ответил, я дал ему шанс.

Объяснение:

s[                # combine the 3 parts to a collection and then join them
  @z1             # bit 1 goes to bit 0
  .i              # interleave the next two collections
    t%2tz         # bits 3,5,7; t is used before z to offset the index by 1
    P%2z          # bits 0,2,4
  @z6             # bit 6 goes to bit 7

Это неверно, так как предполагается, что ввод заполнен нулями.
Утренняя монахиня



1

VI, 27 байт

8I0<ESC>$7hc0lxp<ESC>l"qd0xp3@q03@q

Где <ESC>представляет Escape персонажа. Ввод / вывод в двоичном формате, вывод дополняется. 24 байта в vim:

8I0<ESC>$7hd0xpqqlxpq2@q03@q

<ESC>нужны помехи вокруг него. Я бы отредактировал, но я не могу найти еще 4 байта для изменения ...
Джо

@SirBidenXVII Спасибо, исправлено.
Нил

0

На самом деле, 27 байтов

'08*+7~@tñiWi┐W13052746k♂└Σ

Попробуйте онлайн!

Эта программа выполняет ввод и вывод в виде двоичной строки (выходные данные дополняются нулями до 8 бит).

Объяснение:

'08*+7~@tñiWi┐W13052746k♂└Σ
'08*+                        prepend 8 zeroes
     7~@t                    last 8 characters (a[:~7])
         ñi                  enumerate, flatten
           Wi┐W              for each (i, v) pair: push v to register i
               13052746k     push [1,3,0,5,2,7,4,6] (the permutation order, zero-indexed)
                        ♂└   for each value: push the value in that register
                          Σ  concatenate the strings

0

JavaScript, 98 байт

Ввод принимается в base-2 в виде строки, вывод также в base-2 в виде строки

n=>(n.length<8?n="0".repeat(8-n.length)+n:0,a="13052746",t=n,n.split``.map((e,i)=>t[a[i]]).join``)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.