Gere um bit de paridade

18

Um bit de paridade , é uma das formas mais simples de uma soma de verificação. Primeiro, você deve escolher a paridade, par ou ímpar. Digamos que escolhemos par. Agora, precisamos de uma mensagem para transmitir. Digamos que nossa mensagem seja "Foo". Isso está escrito em binário como:

01000110 01101111 01101111

Agora, contamos o número total de 1's' lá, que é 15. Como 15 é um número ímpar, devemos adicionar um bit extra ao final de nossa mensagem e agora teremos um número par de bits 'on' . Este último bit adicionado é conhecido como "bit de paridade". Se tivéssemos escolhido uma paridade ímpar para nossa soma de verificação, teríamos que adicionar um '0' extra para que o número de bits permanecesse ímpar.

O desafio:

Você deve escrever um programa ou função que determine qual é o bit de paridade correto para uma string. Seu programa deve receber duas entradas:

  • Uma corda s. Essa é a mensagem na qual a soma de verificação será calculada. Isso será restrito aos 95 caracteres imprimíveis ASCII.

  • Um caractere ou sequência de caracteres única p, que será eparidade par ou oparidade ímpar.

e produza um valor truthy-falsey representando o bit de paridade correto. Verdadeiramente se for um 1, e falsey se for um 0.

Construções internas que contam o número de bits "ativados" em uma sequência ou caractere não são permitidas. Por exemplo, uma função fque faz isso: f('a') == 3ou f('foo') == 16é banida. Qualquer outra coisa, como a conversão de base, é um jogo justo.

Teste de E / S:

(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

Este é um codegolf, então as brechas padrão se aplicam e a resposta mais curta em bytes vence.

Entre os melhores

DJMcMayhem
fonte
10
De maneira irritante, otem até paridade.
Neil
Você pode esclarecer que "Builtins que contam o número de bits" ativados "em uma sequência ou caractere não são permitidos". um pouco melhor? E a conversão de base incorporada? Etc ..
orlp 25/04
@DrGreenEggsandHamDJ Os comentários nos sites da Stack são voláteis e estão sujeitos a desaparecer sem aviso prévio, sem motivo, por capricho de qualquer usuário capaz. Como resultado, é altamente recomendável que as especificações integrantes do desafio estejam no próprio post, não na seção de comentários.
gato
1
@cat Por exemplo, em python str(int(s, 2)).count('1'):? Não, eu não consideraria essa uma única função interna que viola essa regra. Minha edição deixa mais claro?
DJMcMayhem
1
@cat Tanto quanto eu estou preocupado char == single_char_string. Eu também editei isso no post.
DJMcMayhem

Respostas:

9

MATL , 8 7 bytes

8\hBz2\

Experimente online! Ou verifique todos os casos de teste de uma só vez .

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
Luis Mendo
fonte
9

Java, 97 bytes

Porque, você sabe, 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;}

Este é um lambda para a BiFunction<String, Character, Boolean>.

ee oparece estar invertida na declaração de retorno porque, aparentemente, minha lógica estava ao contrário.

CAD97
fonte
5

Python 2, 51 bytes

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

Isso se baseia na idéia do Sp3000 de contar 1 na representação de seqüência de caracteres da lista de códigos de caracteres em binário, em vez de somar para cada caractere.

O novo truque é pega ee oneste também. Se efosse ímpar e opar, poderíamos simplesmente acrescentar o bit de paridade à string antes de fazer a contagem (invertê-los porque '1' é Truthy). Infelizmente, eles não são. Mas, se removermos todos, exceto os dois últimos bits, agora é verdade.

e 0b11001|01
o 0b11011|11 

Isso é feito removendo o primeiro 9caractere da representação em cadeia.

['0b11001|01', 
xnor
fonte
Uau, essa é uma maneira muito legal de lidar eo!
SP3000
4

Geléia, 9 8 bytes

OBFSḂ⁼V}

Experimente online!

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

Obrigado ao Dennis por um byte!

Maçaneta
fonte
1
Eu estava-me a tentar chegar a uma resposta Jelly, mas essas regras encadeamento me ellude :-)
Luis Mendo
2
@LuisMendo Estou no mesmo barco; esta é a minha primeira resposta Jelly depois de ter tentado aprender por ... um caminho muito longo: P
Doorknob
Isso V}... aquele foi muito legal !!! (Dennis é um verdadeiro jogador de golfe) +1 Ele venceu todas as minhas tentativas.
Erik the Outgolfer
4

C, 62 bytes

  • 12 bytes salvos graças a @LevelRiverSt e @TonHospel.

O XOR tem a propriedade legal de que ele pode ser usado para reduzir cadeias de caracteres para um caractere, preservando a paridade.

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

Ideone.

Trauma Digital
fonte
1
27030>>((p^p>>4)&15)&1 deve calcular a paridade de p e é ainda 1 byte mais curto
Ton Hospel 26/16/16
1
O espaço não char *sé necessário
Ton Hospel
2
62 bytes: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}O %3sempre retornará 0 para um 0, mas pode retornar 1 ou 2 para a 1. Isto é aceitável sob as regras:truthy if it's a 1
Nível River St
1
27030>>((p^p>>4)&15)&1. Bem, erre, obviamente. ;-)
Digital Trauma
@LevelRiverSt Brilliant! obrigado!
Digital Trauma
4

Python, 58 57 bytes

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'
orlp
fonte
1
53 (somente Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000 26/04
Você pode salvar um byte com !=p>'e'.
Xnor
Espere, meu byte-save não funciona porque o Python o trata como uma desigualdade encadeada.
Xnor
lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
Xnor
@xnor Basta postar sua própria resposta.
orlp
3

Pitão, 12 bytes

q@"oe"sjCz2w

Suíte de teste.

         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
Maçaneta da porta
fonte
3

JavaScript (ES6), 84 72 bytes

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

O ajuste de bits acabou sendo mais curto do que converter para a base 2 e contar 1s.

Neil
fonte
2

Perl, 29 bytes

Inclui +2 para -p

Execute com a entrada STDIN como sequência de espaço de caracteres de paridade, por exemplo

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

parity.pl

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

J, 27 bytes

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

Uso

   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
milhas
fonte
1

JavaScript (ES6), 69 bytes

(s,p)=>[...s].map(c=>{for(n=c.charCodeAt();n;n>>=1)r^=n&1},r=p>"e")|r
user81655
fonte
1

PowerShell v2 +, 91 bytes

/ eu chora no canto

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

Sim ... então, a conversão de base não é um ponto forte para o PowerShell. A conversão da sequência de entrada para representação binária$a|%{[convert]::toString(+$_,2)} é de 32 bytes por si só ...

Recebe entrada $ae $b, explicitamente, lança $acomo um char-array no processo. Em seguida, verificamos se $bé -eqnecessário oe -xorcom a outra metade do programa. Para essa parte, pegamos a string de entrada, passamos $apor um loop para converter cada letra em binário, -jointodos juntos para formar uma string sólida e -replacetodos os 0s sem nada. Contamos então a .lengthsequência e a usamos mod-2 para determinar se é par ou ímpar, o que será convenientemente um 0ou outro 1, perfeito para o -xor.

Voltará Trueou em Falseconformidade. Veja os casos de teste abaixo:

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
AdmBorkBork
fonte
1

Fator, 85 bytes

Por alguma razão, eu não conseguia entender isso até alguns minutos atrás, quando simplifiquei (e talvez abreviei?) O código.

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

?é como um operador ternário: ele testa a veracidade do terceiro item da pilha e seleciona o truevalor ou o falsevalor.

É aproximadamente equivalente ao seguinte pseduocode do tipo C:

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

O restante do código é bem simples:

[                       ! 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.
gato
fonte
1

Código de máquina IA-32, 15 bytes

Hexdump:

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

Código de montagem:

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

Esta é uma função que recebe seu primeiro argumento (string) ecxe o segundo argumento (char) em dl. Ele retorna o resultado em eax, portanto, é compatível com ofastcall convenção de chamada.

Este código dobra as regras quando usa a setpoinstrução:

Construções internas que contam o número de bits "ativados" em uma sequência ou caractere não são permitidas

Esta instrução define alo bit de paridade calculado pela instrução anterior - então eu tenho esses dois detalhes sobre as regras:

  • Não conta o número de bits "on" - calcula o bit de paridade diretamente!
  • Tecnicamente, é a instrução anterior ( xor) que calcula o bit de paridade. A setpoinstrução apenas a move para o alregistrador.

Esses detalhes semânticos estão fora do caminho, aqui está a explicação sobre o que o código faz.

As representações dos personagens são:

'e' = 01100101
'o' = 01101111

Se adicionarmos 1 a eles, eles terão a paridade certa:

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

Então, XORtodos os caracteres da string são inicializados alcom esses valores, o que fornece a resposta.


A primeira instrução é, em movzx eax, dlvez da mais óbvia (e mais curta) mov al, dl, porque eu quero ter o número 0 em um registro ( ahneste caso) para poder compará-lo na ordem correta ( 0, [ecx]e não [ecx], 0).

anatolyg
fonte
1

Julia, 58 47 45 40 bytes

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

Esta é uma função que aceita uma string e um caractere e retorna um número inteiro.

Para obter o número de unidades na representação binária, primeiro aplicamos a binfunção a cada caractere na cadeia, o que nos fornece uma matriz de cadeias binárias. Em seguida, reduza-os para um único uso prod(já que *é concatenação de string em Julia) e faça a interseção definida dessa string e o código de caractere para 1, o que nos fornece uma string de uns. O último índice dessa sequência é o número de unidades. Nós o XORamos com 1 se o caractere fornecido é o e 0, caso contrário, obtemos a paridade usando AND 1 bit a bit.

Experimente online! (inclui todos os casos de teste)

Economizou 18 bytes graças a Dennis!

Alex A.
fonte
1

05AB1E , 15 , 13 bytes

Código:

€ÇbSOÈ„oe²k<^

Exemplo de entrada:

Programming Puzzles and Code-Golf
o

Saída de exemplo:

1

Explicação:

€                 # 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 È

Agradecimentos a Adnan por salvar 2 bytes.

Emigna
fonte
Wow muito legal! Você pode obter dois bytes de golfe usando o ²comando Isso empurra automaticamente a segunda entrada no topo da pilha. Além disso, seqüências de caracteres de dois caracteres podem ser reduzidas usando . Então "oe"é equivalente a . Para 13 bytes: €ÇbSOÈ„oe²k<^:)
Adnan
05AB1E também usa a codificação CP-1252 , portanto, cada caractere aqui tem 1 byte :).
Adnan
@ Adnan: Obrigado! Bloco de notas usado ++ para o bytecount e apenas assumiu que contou caracteres: P
Emigna
0

Ruby, 57 bytes

Se 0foi falsey em Ruby, ==provavelmente poderia ser alterado para apenas -, ou pode haver outras otimizações, mas não é.

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

Retina , 102 bytes

Pega a corda na primeira linha e a letra na segunda linha. Usa codificação ISO 8859-1.

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

Experimente online

A classe de caracteres na primeira linha corresponde a qualquer caractere com um número ímpar de um na representação binária.

Descrição de como a detecção par / ímpar com regex funciona aqui .

mbomb007
fonte
0

Oitava, 56 bytes

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

A bitunpackfunção, para caracteres ASCII, os retorna em ordem little-endian. Então, colocando a bandeira de paridade no final de nossa string, descompactando a coisa toda e soltando os últimos 5 bits, podemos então resumir a coisa toda mod 2 para a nossa resposta final.

Uso:

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

 Lisp comum, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Soma a contagem de log de códigos de char de s.
  • O restante disso, quando dividido por 2, é comparado à posição do argumento de paridade pna sequência "oe"(0 ou 1). Por exemplo, se houver 4, o restante será zero. Se p for o, nenhum bit adicional deverá ser adicionado e o teste retornará falso.

Pretty-impresso

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

Java, 91 bytes

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

Fiz o mesmo que o @ CAT97, mas retirei alguns caracteres usando o módulo 8 e a concatenação de @Luis Mendo e o uso de int em vez de booleano.

Este é um lambda para a BiFunction<String, Character, Boolean>.

miselico
fonte
0

Matlab, 49 bytes

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

Onde:

  • x é a string de entrada;
  • p é 'e' para paridade par e 'o' para par ímpar.

Por exemplo:

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

ans =

     0
PieCot
fonte
0

Ferramentas Bash e Unix (72 bytes)

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

Excepta scomo o primeiro e po segundo argumento. Felizmente, os últimos 3 bits oe etem paridade ímpar e par, respectivamente.

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

O fornecimento da entrada via <<<adiciona um caractere de avanço de linha, mas a paridade de \né par e, portanto, não é um problema.

pgy
fonte