Рассчитать вес Хэмминга с низким весом Хэмминга


19

Создайте программу, которая вычисляет вес Хемминга строки. Победителем является программа с наименьшим весом Хэмминга.

Правила:

  • Вес Хэмминга для символа ASCII определяется как общее количество бит, установленных 1в его двоичном представлении.
  • Предположим, что кодировка ввода 7-битная ASCII, переданная через любой механизм ввода, нормальный для вашего языка (например, stdin, args и т. Д.)
  • Выведите результат в виде числа в стандартный вывод или любой другой механизм вывода по умолчанию / обычный, используемый вашим языком.
  • Само собой разумеется, но вы должны иметь возможность реально запустить программу в реальной жизни, чтобы она была правильным решением.
  • Победителем является решение, код которого имеет наименьший вес Хэмминга.
  • Извините, в этом пробеле нет решений ! Хорошо, теперь вы можете кодировать в пробелах, я разобрался с правилами :)

Персональные примеры:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7

если мы возьмем 0x20/ ASCII 32 в качестве эталона, не будет ли гудение hello world10, а не 11?
Кристиан Лупаску

Почему вес hello world11? Только 10 символов отличаются от пробела. Кроме того, вес программы Хэмминга, кажется, только его длина, исключая пробелы. Не сильно отличается от нормального кода гольфа.
Угорен

Извините, я полностью облажался. Статья Википедии о весе Хэма довольно обманчива, и я полностью нарушил правила. Переписываю сейчас. Обновление: Хорошо, переписано, чтобы определить его как число битов, равное 1 в строке ASCII, извините за ошибку.
Полином

@ugoren Решение с более низкими значениями символов ASCII имеет меньший вес Хэмминга.
Полином

1
Теперь все это имеет смысл. ИСПОЛЬЗОВАНИЕ ВЕРХНИЙ, БЕРЕГИТЕСЬ ~AND o.
Угорен

Ответы:



8

J, вес 34

+/,#:a.i.

Использование - поместите строку для измерения в кавычки в конце:

   +/,#:a.i.'+/,#:a.i.'
34

В качестве альтернативы, принимая ввод с клавиатуры (вес 54):

   +/,#:a.i.1!:1[1
hello
21

Есть только один способ написать это :)
ephemient

Нет ... Я нашел решение, у которого вес Хэмминга на единицу меньше.
Junıʇǝɥʇuʎs

Не пытаясь быть шумом, но правила требуют программы, а не фрагмента.
FUZxxl

5

J , 39

+/,#:a.i:]

Эта функция принимает один аргумент. (Или замените ]строку напрямую; как отмечает Гарет, это снизит стоимость до 34.)

   + /, #: ai:] 'Привет, мир'
45
   + /, #: ai:] '+ /, #: ai:]'
39

Великие умы думают одинаково. :-)
Гарет

5

Питон, 189

print sum(bin(ord(A)).count("1")for A in raw_input())

2
Эквивалент Python 3 print(sum(bin(ord(A)).count('1')for A in input())), имеет оценку 180.
Dan04

4
@ dan04: используйте двойные кавычки вместо одиночных для 176.
Кит Рэндалл

5

QBasic, 322 311 286 264

H$=COMMAND$
FOR A=1 TO LEN(H$)
B=ASC(MID$(H$,A,1))
WHILE B>0
D=D+B MOD 2
B=B\2
WEND
NEXT
?D

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


1
+1 за использование одного из моих любимых языков всех времен. Это первый язык, на котором я научился кодировать на ПК.
Полином

5

Унарный 0

Вы все знали, что это будет. Сначала программа BrainFuck:

,[[>++[>>+>+<<<-]>>>
[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-]
[-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>
[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<
[>>+<[>>+>+<<<-]>>>[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]> 
[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<]>>>
[>+>+<<-]>>[<<+>>-][-]+<[>[-]<<[<<->>-]<<[>>+<<-]>>>[-]]>[<<<+<[-]>>>>
[-]]<<[->>>>+<<<<]<[-<<+>>]<<],]>>>>>>>.

Я добавил новые строки, чтобы сделать его «читабельным», но его вес Хэмминга составляет 4066. Он работает путем многократного получения отношения / остатков входной строки и суммирования всех остатков. Конечно, если вы запустите его самостоятельно, вы получите: 226 (4066% 256) (технически \ xe2), так что ясно, что он определяет себя победителем.

Теперь мы конвертируем его в унарный и получаем

000 ... 9*google^5.9 0's ... 000

Мы используем унарную реализацию с символами NULL \ x00 для '0' и boom, вес Хэмминга равен 0.

Дополнительный вопрос : для каких символов ASCII cвы можете запустить эту программу в строке, состоящей из Nповторений, и заставить ее вывести этот символ. (Например, строка из 32 пробелов дает пробел). Какие ценности Nработы (либо бесконечное количество из них будет работать, либо ни один не будет).


1
Я не уверен, что понимаю это решение. Программа BrainFuck имеет огромный вес Хэмминга. Принимает ли Unary нулевые байты в качестве программы, или вам нужно будет повторно реализовать Unary? Если это последнее, то это не совсем правильное решение - кто-нибудь может просто сказать: «Я определяю язык программирования, где любой отдельный входной байт дает {результат}», и побеждаю в каждом соревновании по коду на сайте.
Полином

1
Нулевой символ Unary будет в порядке. Все, что вам нужно, это EOF, чтобы сказать перестать считать. На самом деле, вот некоторые псевдо-C для чтения этого файла: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }не имеет значения, что вы выбрали в качестве своего унарного символа (если это не EOF).
Walpen

1
Ну вот унарный компилятор C, который отлично работает с нулевыми символами: ideone.com/MIvAg . Конечно, файл, необходимый для создания этой программы, не подходит для юниверса, но у нас есть возможность его запустить.
Walpen

3
Если вы не можете на самом деле запустить его, это на самом деле не является решением.
Полином

4
Как однажды сказал Карл Саган : «Если вы хотите рассчитать вес Хэмминга струны, вы должны сначала изобрести 10 ^ 500 вселенных». (миллиарды и даже миллиарды)
Walpen

4

С, вес 322 263 256

Учитывается ли вес Хэмминга для веса Хэмминга?

main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))D+=*A%2;printf("%d",D-2);}

Используются в основном стандартные техники игры в гольф.
Один цикл вычисляет вес (сдвиг вправо и добавление до нуля) и сканирует строку (продвигает указатель при достижении нуля).
Предполагается, Dчто инициализируется до 2 (один параметр).

Оптимизация по весу Хэмминга:
1. ABDH, с весом 2 каждый, используется для имен.
2. *++Hпредпочтительнее H[1].


Ха, я совершенно не понял твоего первого предложения до сих пор.
хлебница

Вы можете уменьшить счет до 230, выведите результат в виде одинарного числа:main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader

@schnaader, я никогда не знал, @была ли цифра в унарной системе. Я думал , что он использует только 0.. 0. Но если вы хотите пойти этим, кстати, printf("@"+*a%2)короче.
Угорен

@ugoren: Зависит от соглашения / определения унарных. Например, en.wikipedia.org/wiki/Unary_numeral_system использует метки и говорит: «В унарном языке нет явного символа, представляющего ноль, как в других традиционных базах».
Schnaader

@schnaader, хорошо, но я думаю, что это слишком сильно растягивает требование «как число».
Угорен

4

Golfscript 84 72 58

{2base~}%{+}*

(спасибо Говарду и Питеру Тейлору за помощь)

Входные данные: входная строка должна находиться в стеке (передаваться в качестве аргумента командной строки или просто помещаться в стек).

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

Вывод: выводит значение веса Хэмминга на консоль

Программу можно протестировать здесь .


1
Golfscript чувствителен к регистру? Если нет, вы можете сохранить несколько битов, используя BASEвместо base. Обновление: только что проверил, BASEне работает. Хорошее решение :)
Полином

@Polynomial Я попробовал это после просмотра вашего TEST/ testкомментария :) Но это не работает.
Кристиан Лупаску

От этого можно избавиться {...}2*, обратившись 2base~в первую очередь. Получает счет до 72.
Говард

@ Говард, спасибо за этот замечательный совет! Я применил это в своем ответе.
Кристиан Лупаску

Ваш тестовый механизм неверен, потому что вы забыли важное ограничение вашей страницы Web GolfScript. Вы должны иметь ;перед строкой, которую вы заменяете на stdin, так что в (;этом нет необходимости. Затем наблюдение Говарда сводит его к 65.
Питер Тейлор

2

Perl, 80 (22 символа)

Сделано и сделано:

perl -0777nE 'say unpack"%32B*"'

Или вот альтернативный вариант с весом 77 (21 символ):

perl -0777pE '$_=unpack"%32B*"'

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

Чтобы рассчитать вес, я предполагаю, что я считаю символы обычным способом (исключая perl -e/ -E, но включая другие символы опции). Если по какой-то причине люди жалуются на это, то лучшее, что я могу сделать без вариантов, это 90 (26 символов):

$/=$,,say unpack"%32B*",<>

Пример использования:

$ perl -0777nE 'say unpack"%32b*"' rickroll.txt
7071

Boom.


2

Пиф - 15

Отказ от ответственности: Этот ответ не имеет права на победу, так как Пайт моложе, чем этот вызов.

Используется .Bдля двоичного представления и подсчитывает количество "1"символов.

/.BQ\1

Принимает ввод в строке для сохранения по zсравнению с Q.

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


1

Скала 231

readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

Самотестируемый код:

"""readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum""".map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

с самотестирующейся модификацией.


Это вес 495, а не 231. Вы не можете получить вес 231 с 126 символами - это в среднем меньше 2, и все печатные символы (кроме @пробела, который вы не используете) имеют вес как минимум 2.
Угорен

1
@ugoren: Но это всего лишь 65 символов. Программа печатается почти дважды: один раз код для расчета веса Хэмминга и второй раз как статический ввод для вычисления его для программы. Но в вычисляющей части отсутствует «readLine ()» впереди, потому что он принимает буквенный ввод. Я попытался уточнить сам ответ.
пользователь неизвестен

1

Ява, вес 931 774 499 454

Я думаю, что это единственный ответ на данный момент с весом более 300.

class H{public static void main(String[]A){System.out.print(new java.math.BigInteger(A[0].getBytes()).bitCount());}}

Ожидается ввод в качестве аргумента командной строки.


1

GNU sed -r, 467 + 1

(+1 для использования -r- или это должно быть +4?)

Выходы в виде одинарного значения на строку источника; для преобразования в десятичную сумму, перенаправить вывод в | tr -d "\n" | wc -c. Считает все печатные символы ASCII (32-126), а также перевод строки (10).

s@[a-z]@\U& @g
s@[?{}~]@      @g
s@[][/7;=>OW|^]@     @g
s@[-'+.3569:<GKMNSUVYZ\\]@    @g
s@[#%&)*,CEFIJL1248ORTX]@   @g
s@$|[!"$(ABDH0P`]@  @g
y! @!11!

Трудно избежать перечисления всех символов, но мы можем уменьшить это, наблюдая, что строчные буквы имеют вес Хэмминга на единицу больше, чем соответствующие заглавные буквы. Мы предпочитаем новую строку (оценка 2) над точкой с запятой (оценка 5) в качестве разделителя операторов; мы предпочитаем @(оценка 1) или !(оценка 2) над /(оценка 5) в качестве разделителя шаблонов.

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

   2 4   3 5 6   7 
   ---  ------   - 
0:   @   0 P `   p |0

1: ! A   1 Q a   q | 
2: " B   2 R b   r |1
4: $ D   4 T d   t | 
8: ( H   8 X h   x | 

3: # C   3 S c   s | 
5: % E   5 U e   u | 
6: & F   6 V f   v |2
9: ) I   9 Y i   y | 
A: * J   : Z j   z | 
C: , L   < \ l   | | 

7: ´ G   7 W g   w | 
B: + K   ; [ k   { |3
D: - M   = ] m   } | 
E: . N   > ^ n   ~ | 

F: / O   ? _ o     |4
   ---  ------   -  
    1      2     3

Это может оказаться полезным для других.


0

Юлия 262 268

Модифицированная версия использует удобную функцию count_ones для сохранения 6 (262)

show(mapreduce(x->count_ones(x),+,map(x->int(x),collect(ARGS[1]))))

Старая версия без встроенной функции однократного подсчета (268)

show(mapreduce(x->int(x)-48,+,mapreduce(x->bits(x),*,collect(ARGS[1]))))

Использует аргумент командной строки для ввода.


0

CJam 52 или 48

Если вход еще не в стеке (52)

q:i2fbs:s:i:+

Если вход находится в стеке (48)

:i2fbs:s:i:+

Например

"Hello World":i2fbs:s:i:+

0

Юлия, HW 199

H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))

С

A="H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))"

или непосредственно вставив строку:

julia> H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect("H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))")))
199

Версия без присмотра (HW 411) выглядит следующим образом:

bitstring=mapreduce(x->bits(x),*,collect(teststring[:]))
mapreduce(checkbit->checkbit=='1',+,bitstring)

И для удовольствия вот оптимизированная версия (вес Хэмминга 231 ) о том, как Бакерг решает эту проблему:

A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))

с

H="A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))"

0

HPPPL (HP Prime Programming Language), 74

sum(hamdist(ASC(a),0))

Графический калькулятор HP Prime имеет встроенную функцию hamdist (). Вес Хэмминга каждого персонажа равен расстоянию Хэмминга от 0.

ASC (строка) создает массив значений ASCII каждого символа в строке.

Hamdist (значение, 0) вычисляет расстояние Хемминга от 0 для каждого значения ASCII

sum () суммирует все значения.

Вычисление веса Хэмминга из собственного исходного кода:

Вес Хэмминга HPPPL


0

05AB1E , вес 17 (4 байта )

ÇbSO

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

Объяснение:

Ç       # Convert the characters in the (implicit) input to their ASCII decimal values
        #  i.e. "Test" → [84,101,115,116]
 b      # Convert those values to binary
        #  i.e. [84,101,115,116] → ["1010100","1100101","1110011","1110100"]
  S     # Split it into a list of 0s and 1s (implicitly flattens)
        #  i.e. ["1010100","1100101","1110011","1110100"]
        #   → [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0]
   O    # Sum those (and output implicitly)
        #  i.e. [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0] → 16

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.