Codegolf - Кому Нужно 8 Бит На Один Символ?

  • Автор темы Blackcoffer
  • Обновлено
  • 21, Oct 2024
  • #1

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

Например, учитывая строку

 
 
 
 function encode(str, encoderChars) {

const maxBitCount = Math.ceil(Math.log2(encoderChars.length + 1));

const charToBit = Object.fromEntries(encoderChars.map((c, i) => [c, (i + 1).toString(2).padStart(maxBitCount, "0")]));

const bits = [...str].map((c) => charToBit[c]).join("");

const bytes = bits.match(/.{1,8}/g) || [];

return bytes.map((x) => parseInt(x.padEnd(8, '0'), 2));
}
 
and the encoder characters String: "the fox", encoder characters: " abcdefghijklmnopqrstuvwxyz" => [170, 76, 19, 195, 32] String: "971428563", encoder characters: "123456789" => [151, 20, 40, 86, 48] String: "the quick brown fox jumps over the lazy dog", encoder characters: " abcdefghijklmnopqrstuvwxyz" => [170, 76, 25, 89, 68, 96, 71, 56, 97, 225, 60, 50, 21, 217, 209, 160, 97, 115, 76, 53, 73, 130, 209, 111, 65, 44, 16] String: "abc", encoder characters: "abc" => [108] String: "aaaaaaaa", encoder characters: "a" => [255] String: "aaaabbbb", encoder characters: "ab" => [85, 170] , вывод должен быть 1 => 001 3 => 010 5 => 011 7 => 100 9 => 101 .

Но как?

Во-первых, вам нужно сопоставить каждый символ кодера с несколькими битами. Если у нас есть символы кодирования 13579 , then we can map the characters to bits, by mapping the character to the position of the character in binary, like this:

a => 01 b => 10 c => 11

С abc , we would map it like this:

[170, 76, 19, 195, 32]

Обратите внимание, что мы добавляем нули в начале столько, сколько необходимо.

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

Обратный вызов здесь.

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

" abcdefghijklmnopqrstuvwxyz"

Правила

  • Входные данные могут быть строкой, списком или даже списком кодов символов. Это не имеет значения, ввод-вывод очень гибок для решения этой задачи.
  • Ввод всегда будет действительным, например. строка никогда не будет включать символы, не входящие в символы кодера, и т. д.
  • Символы кодировщика всегда будут содержать **менее 256 символов.
  • Ни один вход никогда не будет пустым.
  • Это , поэтому побеждает самый короткий ответ в байтах для каждого языка.
  • Применяются стандартные правила ввода-вывода..
  • Лазейки по умолчанию запрещены.

Эталонная реализация на JavaScript

"the fox"

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

#code-golf #code-golf #string #binary #compression

Blackcoffer


Рег
12 Nov, 2019

Тем
80

Постов
216

Баллов
646
  • 26, Oct 2024
  • #2

Виксал, 19 байты

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
def f(s,e,o=0):

for x in s:o<<=(l:=len(f"{len(e):b}"));o-=~e.find(x)

l*=len(s);return[*(o<<-l%8).to_bytes(l+7>>3,'big')]

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

lambda s,e,o=0:[*sum(-~e.find(x)<<8*(L:=(l:=len(f"{len(e):b}"))*len(s)+7>>3)-(o:=o+l)for x in s).to_bytes(L,'big')]
||answer||

JavaScript (ES7), 124 122 117 байт

Ожидает

 
 
 
 
 
 
 
 
 
 
 
 
 f(s,e)=digits(fromdigits([[i|i<-[1..#e],e[i]==c][1]|c<-s],2^l=#binary(#e))<<(-l*#s%8),256) 
, where ->s,x{s.map{(x.index(_1)+1).to_s(2).rjust Math.log2(x.size+1).ceil,?0}.join.scan(/.{1,8}/).map{_1.ljust(8,?0).to_i 2}} передается как массив символов.

only(::RegexMatch)

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

 

OsteogNom


Рег
15 Mar, 2015

Тем
60

Постов
204

Баллов
564
  • 26, Oct 2024
  • #3

Желе, 21 байт

e

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

s ||answer||

сетчатка, 90 байт

s\e=parse.(Int,only.(eachmatch(r"(.{8})",join(string.(findlast.(s,e);base=2,pad=floor(Int,log2(2length(e)))))*"0"^7)),base=2)

Попробуйте онлайн! Объяснение:

2⊥⍉(m,8)⍴(8×m←⌈(⍴n)÷8)↑n←,⍉((⌈2⍟⌈/n)⍴2)⊤n←⎕⍳⎕

Получите индексы с индексом 1 для всех символов входной строки в символах кодера, а также количество символов кодера.

B

Преобразование в двоичный формат с использованием специальных символов преобразования базы. &m2Gt&mBwY)!8e!XB .

g=[1...Q][c=s[floor(i/q)+1]][1] Q=c.length+1 q=ceil(log_2Q) l=[floor(log_2g)...0] k=\{q=l[1]+1:[],[2...q-l[1]]0\} d=[join(k,mod(floor(g/2^l),2))[mod(i,q)+1]fori=[0...qs.length-1]] v=join(d,[1...8]0)[8u-7...8u] f(s,c)=[total(2^{[7...0]}v)foru=[1...ceil(d.length/8)]]

Заполните левую часть всех двоичных строк до ширины двоичного числа символов кодера.

map

Замените двоичное число символов кодера семью пробелами.

zip/iter

Соедините двоичные строки вместе.

lambda s,e,j=''.join:map(lambda*a:int(j(a),2),*[iter(j(f"{e.find(c)+1:0{len(bin(len(e)))-2}b}"for c in s)+7*'0')]*8)

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

¤g # Same as above to get the length j # Pad each with leading spaces up to this length ð0: # Replace all spaces with 0s

Преобразование из пользовательского двоичного формата в десятичный.

 

EletteHog61


Рег
13 Apr, 2009

Тем
79

Постов
176

Баллов
591
  • 26, Oct 2024
  • #4

Питон, 115 байт

¤gjð0:

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

Старый Python, 122 байта

¤g°+€¦

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

 

Stefanhannum1223


Рег
25 Oct, 2024

Тем
54

Постов
179

Баллов
489
  • 26, Oct 2024
  • #5

Фактор, 123 байта

ā # Push a list in the range [1, (implicit) first input-length] b # Convert each to a binary string ¤g°+€¦ # Right-pad with 0s to make them all the same length: ¤ # Push the last/longest binary-string g # Pop and push its length ° # Pop and push 10 to the power this length + # Add it to each binary €¦ # Remove the leading 1 from each ‡ # Transliterate all characters in the first input to these # binary-strings in the second (implicit) input ¾8× # Push a string of 8 0s: "00000000" « # Append the strings together 8ô # Split it into parts of size 8 ¨ # Remove the trailing part C # Convert all binary-strings to integers # (after which it is output implicitly as result)

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

Объяснение

Принимает строку как массив кодовых точек, а символы кодера — как строку.

āb¤g°+€¦‡¾8׫8ô¨C ||answer||

Питон 3, 133 132 131 байт

θ Input string ? Map over characters and join η Encoder characters ⌕ Find 0-based index of ι Current character ⊕ Incremented ⍘ Custom base conversion using ! Literal string ` !` ◧ Left-padded to length η Encoder characters L Length ↨ Converted to base ² Literal integer `2` L Length ⪪ Split into substrings of length ⁸ Literal integer `8` E Map over substrings ι Current substring ◨ Right-padded to length ⁸ Literal integer `8` ⍘ Custom base conversion using ! Literal string ` !` I Cast to string Implicitly print

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

Сэкономил байт благодаря Стеффан!!!

 

Mazriel


Рег
28 Oct, 2006

Тем
66

Постов
195

Баллов
535
  • 26, Oct 2024
  • #6

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

IE⪪эθ◧⍘⊕⌕ηι !L↨L粦⁸⍘◨ι⁸ !

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

def f(s,e):w=len(f"{len(e):b}");return[int((''.join(f'{e.find(c)+1:0{w}b}'for c in s)+8*'0')[i:i+8],2)for i in range(0,len(s)*w,8)] ||answer||

05AB1E, 17 байты

! { 57 55 49 52 50 56 53 54 51 } "123456789" dup ! { 57 55 49 52 50 56 53 54 51 } "123456789" "123456789" length ! { 57 55 49 52 50 56 53 54 51 } "123456789" 9 [1,b] ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } dup ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } { 1 2 3 4 5 6 7 8 9 } last ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } 9 log2 ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } 3 1 + ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } 4 '[ >bin _ 48 pad-head ] ! { 57 55 49 52 50 56 53 54 51 } "123456789" { 1 2 3 4 5 6 7 8 9 } [ >bin 4 48 pad-head ] map ! { 57 55 49 52 50 56 53 54 51 } "123456789" { "0001" "0010" "0011" "0100" "0101" "0110" "0111" "1000" "1001" } zip ! { 57 55 49 52 50 56 53 54 51 } { { 49 "0001" } { 50 "0010" } { 51 "0011" } { 52 "0100" } { 53 "0101" } { 54 "0110" } { 55 "0111" } { 56 "1000" } { 57 "1001" } substitute ! { "1001" "0111" "0001" "0100" "0010" "1000" "0101" "0110" "0011" } concat ! "100101110001010000101000010101100011" 8 group ! { "10010111" "00010100" "00101000" "01010110" "0011" } [ 8 48 pad-tail bin> ] ! { "10010111" "00010100" "00101000" "01010110" "0011" } [ 8 48 pad-tail bin> ] map ! { 151 20 40 86 48 }

Вводы в обратном порядке, со строкой кодировки в качестве первого ввода.

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

Объяснение:

[ dup length [1,b] dup last log2 1 + '[ >bin _ 48 pad-head ] map zip substitute concat 8 group [ 8 48 pad-tail bin> ] map ]

_ _ +`_ __ %`_ could alternatively be L`.{8} для того же количества байтов:

||answer||

Питон 3, 116 байт

.+$ 7*

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

С использованием xnor's P^`.+ trick для фрагментации (но с _ instead).

 

Dargeamma44


Рег
25 Oct, 2024

Тем
57

Постов
209

Баллов
524
  • 26, Oct 2024
  • #7

Десмос, 304 265 байт

+`(_+)\1 $1 _ _

Оба входа представляют собой список кодовых точек, как и выходные данные. Это заняло у меня длинный время.

Попробуйте это на Десмосе!

-39 байт благодаря Эйдену Чоу

 

Ice777666


Рег
08 Jul, 2014

Тем
76

Постов
196

Баллов
596
  • 26, Oct 2024
  • #8

МАТЛ, 17 байт

L$`(.?)(?=.*(¶.*)(?!$)\1) $.2*

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

Следует отметить, L$`(.?)(?=.*(¶.*)(?!$)\1) $.2* +`(_+)\1 $1 _ _ P^`.+ .+$ 7* ¶ L`.{8} _ _ +`_ __ %`_ returns a matrix with the binary strings as rows, so they are automatically padded to the same length.

 

BADMAN


Рег
30 Jan, 2004

Тем
72

Постов
218

Баллов
628
  • 26, Oct 2024
  • #9

APL+WIN, 45 байт

Запрашивает строку, за которой следуют символы кодера:

JBUz0ZU⁸,yFŻ8¡s8z0ZḊḄ Main Link J Generate [1, 2, ...] as long as the encoding list B Convert to binary Uz0ZU Reverse, transpose padding with 0, transpose, reverse (*) ⁸, Pair the encoding list with the padded binary list y Use this to translate the message into binary strings F Flatten Ż8¡ Prepend 0 8 times (in case the list is shorter than 8) s8 Slice into blocks of 8 z0Z Transpose padding with 0, transpose (**) Ḋ Remove the block of 8 zeroes at the start Ḅ Convert from binary into numbers (*) this is a common pattern used to left-pad everything to the same length (**) this is a common pattern used to right-pad everything to the same length - because we prepended a block of 8 zeroes, there is at least one sublist of length 8, so everything will be padded to length 8

Попробуйте онлайн! Спасибо Диалог Классик

 

BrequeLipmepe67


Рег
24 Jun, 2009

Тем
66

Постов
191

Баллов
541
  • 26, Oct 2024
  • #10

Джулия 1.7, 125 байт

JBUz0ZU⁸,yFŻ8¡s8z0ZḊḄ

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

ожидает (b,o=k=[],i=32)=>g=a=>(i+=~Math.log2(b.length),k|=b.indexOf(a.shift())+1<<i)?g(a,i<25&&(o.push(k>>>24),k<<=8,i+=8)):o as a list of characters and string строка. Нужна Юлия 1.7 для (encoder_characters)(string)

 

Sereda_V_V


Рег
20 Mar, 2011

Тем
48

Постов
215

Баллов
455
  • 26, Oct 2024
  • #11

Рубин, 128 120 118 байт

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

Ŀ # Replace each element of <the key> in <the input> # with the corresponding value of... ¹ż # 1...len(key) b # Convert each to binary ∆Z # left-pad each with zeroes to length :∩L # The maximum length - the length when transposed f8ẇ # Reshape into chunks of 8 R R # With each reversed... 8∆Z # Left-pad to length 8 (so right-pad) vB # Convert each back from binary

s должны быть кодами символов входной строки, а x должны быть кодами символов кодера. Возвращает массив кодов символов.

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

 

Lissa Frolova


Рег
18 Nov, 2011

Тем
70

Постов
204

Баллов
564
  • 26, Oct 2024
  • #12

ПАРИ/ГП, 90 байт

¹żb:∩L∆ZĿf8ẇR8∆ZRvB

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

Вводит списки символов.

 

Telitehib51


Рег
07 May, 2020

Тем
82

Постов
216

Баллов
646
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно