Помогите разобраться с ответом от сервера codewars.com!

Решаю вот такую ката с сайта

https://www.codewars.com/kata/5ef9ca8b76be6d001d5e1c3e/train/python

Она называется Error correction #1 - Hamming Code === Исправление ошибок # 1 - Код Хэмминга Код Хэмминга используется для исправления ошибок, так называемых переворотов битов, при передаче данных. Далее в описании следует подробное объяснение того, как это работает. В этом Кате мы реализуем код Хэмминга с длиной в 3 бита;

Задача 1: функция кодирования

Реализуйте функцию кодирования, выполнив следующие шаги:

преобразовать каждую букву текста в ее значение ASCII; преобразовать

значения ASCII в 8-битные двоичные файлы; утроить каждый бит;

объединить результат

input: "hey" --> 104, 101, 121 // ASCII values --> 01101000, 01100101, 01111001 // binary --> 000111111000111000000000 000111111000000111000111 000111111111111000000111 // tripled --> "000111111000111000000000000111111000000111000111000111111111111000000111" // concatenated

Задача 2: функция декодирования:

Проверьте, не возникли ли ошибки, и исправьте их. Ошибками будут только перевороты битов, а не потеря битов:

111 -> 101: это может и случится 111 -> 11: этого не может быть

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

Шаги:

Разделите ввод на группы по три символа;

Проверьте, не произошла ли ошибка: замените каждую группу символом, который встречается чаще всего, например 010 -> 0, 110 -> 1 и т. Д .;

Возьмите каждую группу из 8 символов и преобразуйте это двоичное число;

Преобразуйте двоичные значения в десятичные (ASCII);

Преобразуйте значения ASCII в символы и объедините результат

input: "100111111000111001000010000111111000000111001111000111110110111000010111" --> 100, 111, 111, 000, 111, 001, ... // triples --> 0, 1, 1, 0, 1, 0, ... // corrected bits --> 01101000, 01100101, 01111001 // bytes --> 104, 101, 121 // ASCII values --> "hey"

Вот мои две функции:

import re
from string import digits
from string import punctuation
from string import whitespace

def encode(string):
    lst = []
    for el in string:
        if el in punctuation or el in digits or el in whitespace: # add 1 bit
            lst.append(bin(ord(el)).replace('b', '0'))
        else:
            lst.append(bin(ord(el)).replace('b', ''))
    K = []    
    for st in lst:
        
        for chars in st:
            K.append(chars*3) # triple the beats
    bits = ''.join(K)
        
    return bits # get a concatenated string of triple bits


def decode(bits):
    binary = re.sub(r'(\d{3})', r'\1 ', bits)
    binary = binary.replace('000', '0').replace('111', '1').replace(' ', '')
    binary = re.sub(r'(\d{8})', r'\1 ', binary)
    binary = binary.split()
    lst = []
    for bi in binary:
        lst.append(int(bi, 2))
        
    string = ''
    for el in lst:
        string += chr(el)
    
    return string

Вот ответ от проверочного сервера:

Passed: 204 Failed: 104 Exit Code: 1

Test encode function ======================> я прохожу

Test decode function ==================> у меня не проходит
Should work with short word
'\x9aI\x93v%' should equal 'hey'
Completed in 0.37ms
Should work with long word
'U\x1a&U!\x14Ù[\x9cÚV\x92\x07FöÆD\x82me thb]\x12\x06\x92\x066\x16â\t\x91½ this kata' should equal 'The Sensei told me that i can do this kata'

У меня установлена ОС на базе ядра Linux Ubuntu 20.04.1 Программирую в Thonny(мне кажется тут самый лучший и понятный отладчик) Самое главное в том что у меня в редакторе все получается и кодирование(получение битовой сконкатенированной строки) и декодирование(вставляю сконкатенированную битовую строку) === получаю строку ASCII

вот эта строка у меня в редакторе и кодируется и декодируется кодом Хемминга:

The Sensei told me that i can do this kata

а вот такую "байду" присылает сервер:

U\x1a&U!\x14Ù[\x9cÚV\x92\x07FöÆD\x82me thb]\x12\x06\x92\x066\x16â\t\x91½ this kata

Кто может, ПОЖАЛУЙСТА! объясните почему так происходит!


Ответы (3 шт):

Автор решения: vp_arth

Я решил её так:

hamm = {'000': '0','001': '0','010': '0','011': '1','100': '0','101': '1','110': '1','111': '1'}

def chunked_str(s, sz):
    return (s[i:i+sz] for i in range(0, len(s), sz))

def encode(string):
    return ''.join(3*bit for char in string for bit in format(ord(char), '08b'))

def decode(bits):
    repaired = ''.join(hamm[triplet] for triplet in chunked_str(bits, 3))
    return ''.join(chr(int(byte, 2)) for byte in chunked_str(repaired, 8))
→ Ссылка
Автор решения: gil9red

У вас не было исправления ошибок в тройках битов, это когда выбирается тот бит, который встречается чаще.

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

Пример выбора бита из троек (тут не имеет значение какой порядок битов):

  • 110 или 111 -> 1 (сумма битов 2 или 3)
  • 001 или 000 -> 0 (сумма битов 0 или 1)

Я исправил вашу функцию, попробуйте:

def decode(bits):
    binary = ''
    for tripled_bits in re.findall(r'\d{3}', bits):
        sums = sum(map(int, tripled_bits))
        binary += '1' if sums == 2 or sums == 3 else '0'

    text = ''
    for byte in re.findall(r'\d{8}', binary):
        text += chr(int(byte, 2))

    return text

PS.

Интересное задание :)

А у меня получилось так:

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i: i + n]


def encode(text: str) -> str:
    return ''.join(
        ''.join(b * 3 for b in f"{ord(c):08b}")  # Tripled bits
        for c in text
    )


def decode(bits: str) -> str:
    bit_items = []
    for tripled_bits in chunks(bits, 3):
        sums = sum(map(int, tripled_bits))

        # Example: 110 or 111 -> 1 and 000 -> 0 or 001 -> 0
        bit_items.append('1' if sums == 2 or sums == 3 else '0')

    binary = ''.join(bit_items)

    items = []
    for byte in chunks(binary, 8):
        items.append(chr(int(byte, 2)))

    return ''.join(items)
→ Ссылка
Автор решения: vp_arth

Проблема не в ответе от сервера.
Просто вы не до конца поняли задачу.

С пониманием encode проблем у вас вроде нет (хотя код переусложнили)

А вот с decode проблемы.

Проверьте, не возникли ли ошибки, и исправьте их.

Этот этап полностью пропущен.

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

Проще и производительнее всего завести словарь замен с восемью вхождениями.

{'000': '0','001': '0','010': '0','011': '1','100': '0','101': '1','110': '1','111': '1'}
→ Ссылка