Создать бит четности


18

Бит четности , является одним из простейших форм контрольной суммы. Во-первых, вы должны выбрать паритет, четный или нечетный. Допустим, мы выбираем даже. Теперь нам нужно сообщение для передачи. Допустим, наше сообщение "Foo". Это записано в двоичном виде как:

01000110 01101111 01101111

Теперь мы посчитаем общее число 1's там, которое составляет 15. Поскольку 15 - нечетное число, мы должны добавить один дополнительный бит в конец нашего сообщения, и теперь у нас будет четное число битов' on ' , Этот последний добавленный бит известен как «бит четности». Если бы мы выбрали нечетную четность для нашей контрольной суммы, нам пришлось бы добавить дополнительный «0», чтобы число битов оставалось нечетным.

Соревнование:

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

  • Строка, s. Это сообщение, на которое будет рассчитана контрольная сумма. Это будет ограничено 95 печатными символами ASCII.

  • Символьная или односимвольная строка p, которая будет либо eдля четной четности, либо oдля нечетной четности.

и получить значение truey-falsey, представляющее правильный бит четности. Правда, если это 1, и ложь, если это 0.

Встроенные функции, которые считают количество включенных битов в строке или символе, не допускаются. Например, функция, fкоторая делает это: f('a') == 3или f('foo') == 16запрещена. Все остальное, например базовое преобразование, является честной игрой.

Тест IO:

(without the quotes)
s: "0"
p: 'e'
output: 0

s: "Foo"
p: 'e'
output: 1

s: "Hello World!"
p: 'o'
output: 0

s: "Alex is right"
p: 'e'
output: 1

s: "Programming Puzzles and Code-Golf" 
p: 'e'
output: 0

s: "Programming Puzzles and Code-Golf" 
p: 'o'
output: 1

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

Leaderboard


10
Скорее досадно, oимеет даже паритет.
Нил

Можете ли вы уточнить, что «встроенные функции, которые считают количество включенных битов в строке или символе, не допускаются». чуть лучше? Как насчет встроенного преобразования базы? Etc ..
orlp

@DrGreenEggsandHamDJ Комментарии на сайтах стеков изменчивы и могут исчезать без предупреждения без всякой причины по прихоти любого способного пользователя. В результате настоятельно рекомендуется, чтобы спецификации, являющиеся неотъемлемой частью задачи, содержались в самой публикации, а не в разделе комментариев.
кот

1
@cat Например, в Python: str(int(s, 2)).count('1')? Нет, я бы не подумал, что это единственная встроенная функция, которая нарушает это правило. Мое редактирование делает это более ясным?
DJMcMayhem

1
@cat Насколько я понимаю char == single_char_string. Я также отредактировал это в посте.
DJMcMayhem

Ответы:


9

MATL , 8 7 байт

8\hBz2\

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

8\    % Implicitly take first input ('e' or 'o'), and compute modulo 8. Inputs 'e' and 'o' 
      % give 5 or 7 respectively, which have an even or odd number of `1` bits resp.
h     % Implicitly take second input, and concatenate
B     % Convert to binary. Gives 2D array, with one row for each original entry 
z     % Number of nonzero values in that 2D array
2\    % Modulo 2, i.e. compute parity

9

Java, 97 байт

Потому что, вы знаете, Java.

(s,c)->{boolean e=1>0;for(int i:s.getBytes())while(i>0){if(i%2==1)e=!e;i/=2;}return c=='o'?e:!e;}

Это лямбда для BiFunction<String, Character, Boolean>.

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


5

Python 2, 51 байт

lambda s,p:`map(bin,map(ord,p+s))`[9:].count('1')%2

Это основано на идее Sp3000 подсчитывать 1 в строковом представлении списка кодов символов в двоичном формате, а не суммировать для каждого символа.

Новый трюк - справиться eи oс этим тоже. Если бы это eбыло нечетно и oчетно, мы могли бы просто добавить бит четности в строку перед выполнением подсчета (переключая их, потому что «1» - это Истина). К сожалению, это не так. Но если мы удалим все, кроме последних двух битов, то это правда.

e 0b11001|01
o 0b11011|11 

Это делается путем удаления первого 9символа строкового представления.

['0b11001|01', 

Вау, это действительно аккуратный способ обработки eo!
Sp3000

4

Желе, 9 8 байт

OBFSḂ⁼V}

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

O         convert each character in argument 1 (left arg) to its codepoint (ord)
 B        convert to binary (list of 0s and 1s)
  F       flatten
   S      sum the entire list, giving the number of 1s in the entire string
    Ḃ     mod 2 (take the last bit)
       }  now, with the second (right) argument...
      V   eval with no arguments. This returns...
            1 for e because it expands to 0e0 (i.e., does 0 exist in [0])
            0 for o because it expands to 0o0 (0 OR 0, false OR false, false)
     ⁼    test equality between the two results

Спасибо Денису за байт!


1
Я сам пытался придумать ответ Jelly, но эти правила цепочки окутывают меня :-)
Luis Mendo

2
@ LuisMendo Я в одной лодке; это мой первый ответ желе после того, как я пытался выучить его слишком долго: P
дверная ручка

Это V}... это было действительно круто !!! (Деннис настоящий игрок в гольф) +1 Это превзошло все мои попытки.
Эрик Outgolfer

4

C, 62 байта

  • 12 байтов сохранено благодаря @LevelRiverSt и @TonHospel.

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

f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}

Ideone.


1
27030>>((p^p>>4)&15)&1 должен вычислить соотношение p и даже на 1 байт короче
Тон Хоспел

1
Пространство в char *sэто не нужно
Тон Хоспел

2
62 байт: всегда будет возвращать 0 для 0, но может возвращать 1 или 2 для 1. Это допустимо в соответствии с правилами:f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}%3truthy if it's a 1
Уровень реки Сент

1
27030>>((p^p>>4)&15)&1, Ну, очевидно. ;-)
Цифровая травма

@LevelRiverSt Блестящий! Благодарность!
Цифровая травма

4

Python, 58 57 байт

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'

1
53 (только Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000

Вы можете сохранить байт с помощью !=p>'e'.
xnor

Подождите, мое сохранение байтов на самом деле не работает, потому что Python рассматривает это как цепное неравенство.
xnor

lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
xnor

@xnor Просто оставь свой ответ.
Orlp


3

JavaScript (ES6), 84 72 байта

(s,p)=>(t=p>'e',[...s].map(c=>t^=c.charCodeAt()),t^=t/16,t^=t/4,t^t/2)&1

Битовое чередование оказалось короче, чем преобразование в базу 2 и подсчет 1s.


2

Perl, 29 байт

Включает +2 для -p

Выполнить с вводом в STDIN в качестве строки пространства символов четности, например

parity.pl <<< "p Programming Puzzles and Code-Golf"

parity.pl

#!/usr/bin/perl -p
$_=unpack"B*",$_|b;$_=1&y;1;

2

J, 27 байт

'oe'&i.@[=[:~:/^:2@#:3&u:@]

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

   f =: 'oe'&i.@[=[:~:/^:2@#:3&u:@]
   'e' f '0'
0
   'e' f 'Foo'
1
   'o' f 'Hello World!'
0
   'e' f 'Alex is right'
1
   'e' f 'Programming Puzzles and Code-Golf'
0
   'o' f 'Programming Puzzles and Code-Golf'
1


1

PowerShell v2 +, 91 байт

/ я плачу в углу

param([char[]]$a,$b)$b-eq'o'-xor(-join($a|%{[convert]::toString(+$_,2)})-replace0).length%2

Да ... итак, базовая конверсия не подходит для PowerShell. Преобразование из входной строки в двоичное представление $a|%{[convert]::toString(+$_,2)}само по себе составляет 32 байта ...

Принимает ввод $aи $b, явно приводя $aкак char-массив в процессе. Затем мы проверяем, $bявляется ли это -eqUAL oи -xorдругой половиной программы. Для этой части мы берем входную строку $a, пропускаем ее через цикл, чтобы преобразовать каждую букву в двоичную, -joinвсе вместе, чтобы сформировать одну сплошную строку, и -replaceвсе 0без нуля. Затем мы посчитаем .lengthэту строку и возьмем ее mod-2, чтобы определить, является ли она четной или нечетной, что будет удобно либо, 0либо 1, идеально подходит для -xor.

Вернется Trueили Falseсоответственно. Смотрите тестовые случаи ниже:

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "0" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Foo" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Hello World!" o
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Alex is right" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" o
True

1

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

По какой-то причине я не мог обернуть голову вокруг этого до тех пор, пока несколько минут назад я не упростил (и, возможно, сократил?) Код.

[ "e" = [ even? ] [ odd? ] ? [ [ >bin ] { } map-as concat [ 49 = ] count ] dip call ]

?похож на троичный оператор: он проверяет достоверность третьего элемента стека и выбирает либо trueзначение, либо falseзначение.

Это примерно эквивалентно следующему C-подобному псевдокоду:

void* parity_tester_function = strcmp(p, "e") ? (void *) even?  // it's a function pointer (I think)
                                              : (void *) odd? ;

Остальная часть кода довольно проста:

[                       ! to count a string's set bits:
    [ >bin ] { } map-as ! get the binary of each character, and map as an array, because you can't have stringy data nested in another string (that's called a type error)
    concat              ! { "a" "B" } concat -> "aB"
    [ 49 = ] count      ! count items in the resulting string which match this condition (in this case, the condition we're testing is whether the character has the same code point as "1")
] dip                   ! take the above function pointer off the stack, apply this anonymous function to the now-top of the stack, then restore the value after the quotation finishes.
                        ! in other words, apply this quotation to the second-to-top item on the stack
call                    ! remember that conditionally chosen function pointer? it's on the top of the stack, and the number of sets bits is second.
                        ! we're gonna call either odd? or even? on the number of set bits, and return the same thing it does.

1

Машинный код IA-32, 15 байтов

HexDump:

0f b6 c2 40 32 01 0f 9b c0 3a 21 41 72 f6 c3

Код сборки:

    movzx eax, dl;
    inc eax;
repeat:
    xor al, [ecx];
    setpo al;
    cmp ah, [ecx];
    inc ecx;
    jb repeat;
    ret;

Это функция, которая получает свой первый аргумент (строку) в ecxи второй аргумент (символ) в dl. Он возвращает результат eax, поэтому он совместим с fastcallсоглашением о вызовах.

Этот код изменяет правила, когда он использует setpoинструкцию:

Встроенные функции, которые считают количество включенных битов в строке или символе, не допускаются.

Эта инструкция устанавливает alбит четности, вычисленный предыдущей инструкцией, поэтому в правилах у меня есть два куска:

  • Он не считает количество включенных бит - он вычисляет бит четности напрямую!
  • Технически, это предыдущая инструкция ( xor), которая вычисляет бит четности. setpoИнструкция только перемещает его в alрегистр.

Этим семантическим деталям нет пути, вот объяснение того, что делает код.

Представления персонажей:

'e' = 01100101
'o' = 01101111

Если мы добавим 1 к ним, они получат правильное соотношение:

'e' + 1 = 01100110 (odd parity)
'o' + 1 = 01110000 (even parity)

Таким образом, мы XORвсе символы строки, инициализирующие alэти значения, что дает ответ.


Первая инструкция movzx eax, dlвместо более очевидной (и более короткой) mov al, dl, потому что я хочу иметь номер 0 в регистре ( ahв данном случае), чтобы иметь возможность сравнивать его в правильном порядке ( 0, [ecx]а не [ecx], 0).


1

Юлия, 58 47 45 40 байт

f(s,p)=(p>'e')$endof(prod(bin,s)∩49)&1

Это функция, которая принимает строку и символ и возвращает целое число.

Чтобы получить число единиц в двоичном представлении, мы сначала применяем binфункцию к каждому символу в строке, которая дает нам массив двоичных строк. Затем сведите их к одному использованию prod(поскольку *в Julia используется конкатенация строк) и возьмите пересечение множества этой строки и код символа для 1, что дает нам строку единиц. Последний индекс этой строки - это число единиц. Мы XOR это с 1, если предоставленный символ o и 0 в противном случае, затем получить четность, используя побитовое И 1.

Попробуйте онлайн! (включает все тестовые случаи)

Благодаря Деннису сэкономлено 18 байт!


1

05AB1E , 15 , 13 байтов

Код:

€ÇbSOÈ„oe²k<^

Пример ввода:

Programming Puzzles and Code-Golf
o

Пример вывода:

1

Объяснение:

€                 # for each char in string
 Ç                # get ascii value
  b               # convert to binary
   S              # split to single chars (ex: '1101' to '1','1','0','1')
    O             # sum
     È            # check if even
      „oe         # push string "oe"
         ²        # push 2nd input (p)
          k       # get 1-based index of p in "oe"
           <      # decrease (to get either 0-based index)
            ^     # xor with result of È

Спасибо Аднану за сохранение 2 байта.


Вау очень приятно! Вы можете отыграть два байта с помощью ²команды. Это автоматически выдвигает второй вход поверх стека. Кроме того, строки из двух символов могут быть сокращены с помощью . Так "oe"эквивалентно . Для 13 байтов: €ÇbSOÈ„oe²k<^:)
Аднан

05AB1E также использует кодировку CP-1252 , поэтому каждый символ здесь составляет 1 байт :).
Аднан

@Adnan: Спасибо! Использовал notepad ++ для bytecount и просто предполагал, что он подсчитал символы: P
Emigna

0

Рубин, 57 байт

Если 0бы в Ruby была ложь, то, ==вероятно, можно было бы переключиться на просто -, или могли бы быть другие оптимизации, но это не так.

->s,b{s.gsub(/./){$&.ord.to_s 2}.count(?1)%2==(b>?i?0:1)}

0

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

Принимает строку в первой строке и букву во второй строке. Использует кодировку ISO 8859-1.

[12478abdghkmnpsuvyzCEFIJLOQRTWX#%&)*,/;=>@[\]^| ](?=.*¶)
1
[^1](?=.*¶)
0
^(0|10*1)*¶o|^0*1(0|10*1)*¶e

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

Класс символов в первой строке соответствует любому символу с нечетным числом единиц в двоичном представлении.

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


0

Октава, 56 байт

f=@(s,p) mod(sum((i=bitunpack([s p]))(1:length(i)-5)),2)

bitunpackФункция, для ASCII символов, возвращает их в прямом порядке байт порядка. Таким образом, поместив флаг четности в конец нашей строки, распаковав все это и отбросив последние 5 битов, мы можем затем суммировать все значение mod 2 для нашего окончательного ответа.

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

octave:137> f('Hello World!', 'o')
ans = 0
octave:138> f('Hello World!', 'e')
ans =  1

0

 Обыкновенный Лисп, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Сумма логарифма char-кодов s.
  • Остальная часть этого при делении на 2 сравнивается с положением аргумента четности pв строке "oe"(0 или 1). Например, если их 4, остаток равен нулю. Если p есть o, то дополнительный бит не должен быть добавлен, и тест возвращает false.

Довольно отпечатанных

(lambda (s p)
  (= (mod (reduce '+ (mapcar 'logcount (map 'list 'char-code s))) 2)
     (position p "oe")))

0

Java, 91 байт

(s,c)->{s+=c%8;int e=1;for(int i:s.getBytes())while(i>0){if(i%2==1)e^=1;i/=2;}return e==0;}

Я сделал то же самое, что и @ CAT97, но удалил некоторые символы, используя модуль 8 и конкатенацию @Luis Mendo и используя int вместо логического.

Это лямбда для BiFunction<String, Character, Boolean>.


0

Matlab, 49 байт

f=@(x,p)mod(sum(sum(dec2bin(x)-'0'))+(p-'e'>0),2)

где:

  • х - входная строка;
  • р - «е» для четной четности и «о» для нечетной.

Например:

>> f('Programming Puzzles and Code-Golf','e')

ans =

     0

0

Инструменты Bash и Unix (72 байта)

f(){ bc<<<"$(xxd -b<<<"$2$1"|cut -b9-64|tail -c +7|tr -dc 1|wc -c)%2" }

Исключает sкак первый и pкак второй аргумент. К счастью, последние 3 бита oи eимеет нечетную и четность соответственно.

xxd -b        print the concatenation of `p` and `s` in binary
cut -b9-64    parse xxd output
tail -c +7    keep only the last 3 bits of `p`
tr -dc 1      keep only the `1`s
wc -c         count them
bc ...%2      modulo two

Предоставление ввода через <<<добавляет символ перевода строки, но четность \nчетна, так что это не проблема.

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