Створіть біт паритету


18

Біт парності , є одним з найпростіших форм контрольної суми. По-перше, ви повинні вибрати паритет, парний чи непарний. Скажімо, ми вибираємо навіть. Тепер нам потрібне повідомлення для передачі. Скажімо, наше повідомлення "Foo". Це пишеться у двійковій формі як:

01000110 01101111 01101111

Тепер ми підраховуємо загальну кількість 1"s" там, яка дорівнює 15. Оскільки 15 - непарне число, ми повинні додати ще один додатковий біт до кінця повідомлення, і тепер у нас буде парне число "on" біт . Цей останній доданий біт відомий як "біт парності". Якби ми вибрали непарний паритет для нашої контрольної суми, нам доведеться додати додаткові «0», щоб число біт залишалося непарним.

Змагання:

Ви повинні написати програму або функцію, яка визначає, що є правильним бітом парності для рядка. Ваша програма повинна взяти два входи:

  • Рядок, s. Це повідомлення, на яке буде розрахована контрольна сума. Це буде обмежено 95 символами для друку ASCII.

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

і виробляють значення truthy-falsey, що представляє правильний біт парності. Truthy, якщо це a 1, і Falsey, якщо це a 0.

Вбудовані, які рахують кількість бітів "on" у рядку чи символу, не дозволяються. Наприклад, функція, 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

Це кодовий гольф, тому застосовуються стандартні лазівки, і найкоротша відповідь у байтах виграє.

Таблиця лідерів


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 байт

Тому що, знаєте, Ява.

(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" - Truthy). На жаль, їх немає. Але якщо ми видалимо всі, крім останніх двох біт, це тепер правда.

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
Я сам намагався придумати відповідь Джеллі, але ці правила, пов'язані з ланцюгом, вражають мене :-)
Луїс Мендо

2
@LuisMendo Я в тому ж човні; це моя перша відповідь на желе, після того, як я намагався її навчитись ... занадто довго: P
Doorknob

Що V}... той був справді крутий !!! (Денніс - справжній гольфіст) +1 Він бив кожну мою спробу.
Ерік Аутгольфер

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;}

Ідеон.


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

1
Простір у char *sне забуває
Тон Євангелія

2
62 байти: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}The %3завжди буде повертати 0 для 0, але може повернути 1 або 2 для 1. Це прийнятно за правилами:truthy if it's a 1
Level River St

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

@LevelRiverSt Блискуче! Спасибі!
Цифрова травма

4

Пітон, 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

Pyth, 12 байт

q@"oe"sjCz2w

Тестовий набір.

         z    take a line of input
        C     convert to int
       j  2   convert to base 2, array-wise (so, array of 0s and 1s)
      s       sum (count the number of ones)
 @"oe"        modular index into the string to get either "o" or "e"
q          w  test equality to second line of input

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не -eqвідповідає цьому 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і другий аргумент (char) в dl. Він повертає результат у eax, тому він сумісний із fastcallумовами виклику.

Цей код згинає правила, коли він використовує setpoінструкцію:

Вбудовані, які рахують кількість бітів "on" у рядку чи символу, не дозволяються

Ця інструкція встановлює alбіт паритету, обчислений попередньою інструкцією, - отже, у мене є ці два нитковиди щодо правил:

  • Він не враховує кількість бітів "on" - він обчислює біт парності безпосередньо!
  • Технічно саме 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(оскільки *це конкатенація рядків у Джулії) та перейдіть до встановленого перетину цієї рядка та коду символів 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: Дякую! Використовував блокнот ++ для рахунку і просто припускав, що він рахує символів: P
Емінья,

0

Рубін, 57 байт

Якщо 0в Рубі був фальси, то, ==ймовірно, можна було б перейти на просто -, або можуть бути інші оптимізації, але це не так.

->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, то жодного додаткового біта не слід додавати, а тест повернення помилковий.

Досить друковані

(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

Матлаб, 49 байт

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

де:

  • x - рядок введення;
  • p - це "e" для парного парності, а "o" для непарного.

Наприклад:

>> 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.