Переход от строки к биту

10

задача

При наличии входной строки из одного или нескольких символов ASCII, кодовые точки которых находятся в диапазоне от 0 до 128 (исключая), выполните следующие действия:

  1. Преобразуйте каждый символ в его 7-битный код ASCII (если код ASCII меньше 7 бит, ставьте начальные нулевые биты)
  2. Объединить все биты (это приводит к 7*nбитам, где nколичество символов)
  3. Для каждого бита в этом битовом потоке выведите 1, если он отличается от предыдущего бита, и выведите 0 в противном случае. Первый выходной бит всегда равен 1.

пример

Входные данные:

Hi

Вывод:

11011001011101

Объяснение:

Строка «Привет» имеет коды ASCII

72 105

которые в битах:

1001000 1101001

И индикаторы битов перехода:

11011001011101

Это код гольф. Побеждает младший счетчик байтов.

Тестовые случаи

Тестовый пример 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Контрольный пример 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Тестовый пример 3 (кредит Луису Мендо):

##
11100101110010

Поздравляем Луиса Мендо за самое короткое решение с 9 байтами в MATL!

justhalf
источник
2
Предлагаемый тестовый пример ##(ведущий 0бит; некоторые ответы в настоящее время терпят неудачу из-за этого)
Луис Мендо
4
Как это дублирует вызов манчестерского кодирования? Я что-то пропустил?
гастропнер
2
Другая задача заключается в преобразовании входного потока битов в выходной поток с двойной скоростью, причем каждый вход «1» транслируется в «01», а каждый вход «0» транслируется в «10» . Так что не обманывайте по моему. Если большое количество людей оставит комментарий @ gastropner выше, я могу отключить (или любого другого пользователя с такой способностью)
Луис Мендо
1
@Shaggy: Оба теста содержат пробел, в котором установлен только один бит, а не 7-й. Поэтому я не думаю, что постановка задачи гарантирует, что каждый код ascii будет иметь длину ровно 7 бит.
рекурсивный
1
@SmileAndNod Если подумать, я думаю, вам не нужно обрабатывать пустую строку.
полугодие

Ответы:

4

MATL , 9 байт

Hj7&B!hdg

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

объяснение

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display
Луис Мендо
источник
1
Это самый короткий пока. +1. Это весело иметь встроенный для последовательных различий.
Половина
4

Japt -P , 11 байт

Использует тот факт, что 0в JavaScript можно приводить пробелы при попытке выполнить математическую или, в данном случае, побитовую операцию над ним.

c_¤ù7Ãä^ i1

Попробуйте или запустите все тесты

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
  ¤             :  Convert to binary string
   ù7           :  Left pad with spaces to length 7
     Ã          :End map
      ä^        :XOR consecutive pairs
         i1     :Prepend 1
                :Implicitly join and output
мохнатый
источник
7-бит означает, что если это 32 (для пробела), это будет 0100000. Также символ% (37) будет0100101
полугодие
Теперь работает. +1
полугодие
2

CJam , 21 байт

1q{i2b7Te[}%e__(;.^);

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

объяснение

Показ стека с примером ввода 5:

1 q      e# Push 1 and then the whole input: 1 "5"
{
  i      e# Convert to its char code: 1 [53]
  2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
  7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
         e# Stack implicitly printed: 1101111

Чтобы увидеть, отличается ли бит от предыдущего бита, мы делаем вектор (поэлементно) xor между битовым массивом и битовым массивом без первого элемента. Мы также удаляем последний бит результата, потому что это всегда последний бит длинного массива без изменений.

NinjaBearMonkey
источник
2

APL (Dyalog Unicode) , 16 байтов SBCS

Полная программа. Запрашивает строку из стандартного ввода.

1,2≠/∊1↓¨11DR¨⍞

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

 подсказка для ввода («цитата в консоли»)

11⎕DR¨ изменить каждый символ битового булевой D ата R epresentation

1↓¨ отбросить первый бит от каждого

ε NLIST (Flatten)

2≠/ попарная разница

1, готовить один

Адам
источник
2

Древесный уголь , 25 байт

⭆θ◧⍘℅鲦⁷←Wⅈ←I﹪⍘KD²←01 ²1

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

⭆θ◧⍘℅鲦⁷←

Преобразуйте все символы в двоичные и добавьте их к длине 7, а затем напечатайте их, но оставьте курсор над последней цифрой.

Wⅈ

Повторяйте, пока курсор не окажется над первой цифрой.

←I﹪⍘KD²←01 ²

Рассчитайте, отличаются ли цифры, и замените каждую цифру разницей.

1

Перезапишите первую цифру с помощью 1.

Нил
источник
2

PowerShell , 73 56 49 байт

$args|%{$b=+$_
6..0}|%{+($c-ne($c=($b-shr$_)%2))}

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

-17 байт благодаря маззи :)

Андрей Одегов
источник
1
-17 байт : D
mazzy
Круто, ты должен опубликовать это сам.
Андрей Одегов
этот ответ для вас. моя принцесса в другом замке :))))
Маззи
1
@ mazzy, еще -7 байт :)
Андрей Одегов
офигенно и гениально!
Ma
2

Октава , 36 30 байт

Исправить благодаря Луису Мендо

-2 байта благодаря Sanchises

@(a)[1;~~diff(de2bi(a,7)'(:))]

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

Истекшие данные
источник
Вы можете, вероятно, сбрить довольно много байтов с de2bi.
Санчиз
До @sanchises у меня не работал, но я еще раз посмотрю, когда смогу
данные
1

Python 2 , 104 байта

lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]

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

Быстрый удар в это.

Час Браун
источник
Умный трюк с a*128+ord(c)! Но не является reduceи своего lambdaрода дорого?
Половина
1

Дротик , 213 168 байт

f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}

Предыдущая однострочная

f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);

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

Это многословие и отсутствие простых встроенных модулей действительно убивают этого. Все же удалось вытащить один лайнер, хотя.

  • -45 байтов, не используя один вкладыш и используя цикл for
Elcan
источник
1

Котлин , 182 байта

var l='6'
fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}}
fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)

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

Надеюсь, я смогу улучшить это в ближайшее время, я чувствую, что должно быть несколько мест для улучшения, но я не могу сейчас думать

Quinn
источник
1

C (gcc (MinGW)), 90 байтов

Требуется предоставление компилятора itoa().

n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}
gastropner
источник
88 байт
floorcat
1

Рубин -p , 50 байтов

gsub(/./){"%07b"%$&.ord}
gsub(/./){$`=~/#$&$/?0:1}

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

объяснение

Первая строка, такая же, как ответ Value Ink :

gsub(/./){       $&    }   # Replace each character $&…
                   .ord    # …with its ASCII code…
                %          # …formatted as…
          "%07b"           # …binary digits padded to 7 places.

Вторая линия:

gsub(/./){      $&      }  # Replace each character $&…
          $`               # …if the text to its left…
            =~             # …matches…
              /#  $/       # …the Regexp /c$/ where "c" is the character…
                    ?0:1   # …with 0, or 1 otherwise.

В Ruby вы можете использовать интерполяцию в литералах Regexp, например /Hello #{name}/, и для переменных, которые начинаются с $или @вы можете опустить фигурные скобки, поэтому, если, например, $&есть, "0"то grawlixy /#$&$/становится /0$/.

Иордания
источник
1

K (нгн / к) , 9 13 байт

Решение:

~=':,/(7#2)\'

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

Объяснение:

~=':,/(7#2)\' / the solution
           \' / convert each
      (   )   / do this together
       7#2    / 2 2 2 2 2 2 2
    ,/        / flatten
 =':          / equal to each-previous?
~             / not

Ноты:

  • +4 байта для поддержки строк, состоящих только из 6-битных символов
streetster
источник
Это, кажется, не работает для ввода #(например, выход имеет только 6 бит)
Луис Мендо
@streetster, вы хотите опубликовать фиксированную версию?
Половина
1

Эмоджикод , 263 байта

🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉

Попробуйте это онлайн здесь.

Ungolfed:

🏁 🍇  💭 Main code block
    🔤🔤 ➡️ 🖍 🆕 s  💭 Start with s as the empty string
    🔂 b 📇 🆕 🔡 👂🏼  💭 For each byte b in the input ...
    ❗️ ❗️ 🍇
        🍪 s  💭 ... append ...
           🔪 🔡 🔢 b ❗️ ➕ 128  💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ...

                 2  💭 ... in binary ...
              ❗️
              1 7  💭 ... without the leading one ...
           ❗️
        🍪
        ➡️ 🖍 s  💭 ... to s
    🍉
    🔤?🔤 ➡️ 🖍 🆕 p  💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one
    🔂 b s 🍇  💭 For each character in s:
        ↪️ b 🙌 p 🍇  💭 If it is the same as the previous character ...
            👄 🔤0🔤 ❗️  💭 ... output a zero ...
        🍉 🙅 🍇  💭  ... else ...
            👄 🔤1🔤 ❗️ 💭 ... output a one
        🍉
        b ➡️ 🖍 p  💭 And the current character becomes the new previous character.
    🍉
🍉
OOBalance
источник
1

Python3.8 , 72 байта

Решение:

lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]

Объяснение:

С тех пор, как в Python 3.8 были введены выражения присваивания (а не стандартные операторы присваивания), я хотел использовать их в понимании списка, которое должно помнить последний элемент. Это не лучший способ сделать это, но демонстрирует интересный способ использования выражения присваивания.

Код создает лямбда-функцию, которая принимает требуемый аргумент - строку для преобразования. При вызове функция работает следующим образом. Каждый символ в a преобразуется в свой символьный код, к которому добавляется 128 для работы с 6-битными символами (двоичное представление всегда будет 8-битным, и мы можем отрубить первый бит). Это число преобразуется в двоичный файл, и заголовок (0x) и начальная 1 от добавления 128 обрезаются. Эти новые строки затем объединяются в одну большую строку.

Для каждого символа в этой новой строке (которая содержит сцепленное 7-битное представление текста) проверяется, совпадает ли символ с предыдущим символом. Что происходит с первым персонажем? Первый символ результата всегда должен быть «1», поэтому мы просто должны убедиться, что все, что находится в последней символьной переменной, не является ни «1», ни «0». Мы делаем это путем повторного использования исходного параметра, поскольку мы больше его не используем. Это может быть проблемой, если исходная строка была одним «0» (просто «1» просто работает), но мы проигнорируем это.

Во время сравнения предыдущий символ вычислялся первым, поэтому, когда мы используем выражение присваивания, чтобы установить для предыдущей символьной переменной текущий символ, это не влияет на оценку выражений сравнения.

Сравнение дает либо Истинный, либо Ложный, который также может использоваться как 1 или 0 соответственно в Python, поэтому они используются для поиска «1» или «0» в строке

infinityCoding
источник
Вы можете сохранить несколько байтов, используя строковые литералы: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica
1

Tcl , 215 167 140 байт

{{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}

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

Использует сдвиг на единицу и эксклюзив или для обнаружения переходов. Переносит lsb текущего символа в msb следующего символа. Объединяет вывод для каждого символа, объединяя список, возвращаемый lmap.

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

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

SmileAndNod
источник
1

05AB1E (наследие) , 12 байтов

Çb7jð0:¥ÄJ1ì

Использует унаследованную версию 05AB1E, поскольку jнеявно объединяет строки, что требует явного Jпосле jновой версии 05AB1E.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

Ç             # Convert the (implicit) input-string to a list of ASCII code-points
              #  i.e. "Hi#" → [72,105,35]
 b            # Convert each integer to a binary string
              #  → ["1001000","1101001","100011"]
  7j          # Prepend each with spaces to make them length 7,
              # and join everything together to a single string implicitly
              #  → "10010001101001 100011"
    ð0:       # Replace all those spaces with 0s
              #  → "100100011010010100011"
       ¥      # Get the deltas of each pair of 1s/0s
              #  → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0]
        Ä     # Get the absolute value of this
              #  → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0]
         J    # Join them all together
              #  → "10110010111011110010"
          1ì  # And prepend a 1
              #  → "110110010111011110010"
              # (after which the result is output implicitly)
Кевин Круйссен
источник
1

Haskell , 137 байт

import Data.Char
b 0=[]
b n=odd n:b(n`div`2)
d x|x='1'|1<2='0'
c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)

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

Самая большая проблема здесь - преобразование логических значений (результат XOR) в «0» / «1».

Lamdba
источник
1

Python 3 , 88 84 байта

l=2;s=''
for c in''.join(f'{ord(c):07b}'for c in input()):s+='01'[l!=c];l=c
print(s)

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

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

Обновить:

  • -4 байта благодаря movatica
justhalf
источник
1
84 байта
movatica