Générer un bit de parité


18

Un bit de parité est l'une des formes les plus simples d'une somme de contrôle. Tout d'abord, vous devez choisir la parité, paire ou impaire. Disons que nous choisissons même. Maintenant, nous avons besoin d'un message à transmettre. Disons que notre message est "Foo". Ceci est écrit en binaire comme:

01000110 01101111 01101111

Maintenant, nous comptons le nombre total de 1's là-dedans, qui est 15. Puisque 15 est un nombre impair, nous devons ajouter un bit supplémentaire à la fin de notre message, et nous aurons maintenant un nombre pair de bits' on ' . Ce dernier bit ajouté est appelé "bit de parité". Si nous avions choisi une parité impaire pour notre somme de contrôle, nous aurions dû ajouter un «0» supplémentaire afin que le nombre de bits reste impair.

Le défi:

Vous devez écrire un programme ou une fonction qui détermine le bit de parité correct pour une chaîne. Votre programme doit prendre deux entrées:

  • Une chaîne, s. C'est le message sur lequel la somme de contrôle sera calculée. Cela sera limité aux 95 caractères ASCII imprimables.

  • Un caractère ou une chaîne de caractères unique p, qui sera soit epour la parité paire, soit opour la parité impaire.

et produire une valeur true-falsey représentant le bit de parité correct. Vérité si c'est un 1, et falsey si c'est un 0.

Les commandes internes qui comptent le nombre de bits "on" dans une chaîne ou un caractère ne sont pas autorisées. Par exemple, une fonction fqui fait cela: f('a') == 3ou f('foo') == 16est interdite. Tout le reste, comme la conversion de base, est un jeu équitable.

Test 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

Il s'agit de codegolf, donc les failles standard s'appliquent et la réponse la plus courte en octets l'emporte.

Classement


10
Plutôt ennuyeux, oa même la parité.
Neil

Pouvez-vous clarifier que les "Builtins qui comptent le nombre de bits" on "dans une chaîne ou un caractère ne sont pas autorisés." un peu mieux? Qu'en est-il de la conversion de base intégrée? Etc ..
orlp

@DrGreenEggsandHamDJ Les commentaires sur les sites Stack sont volatils et peuvent disparaître sans avertissement sans raison, au gré de tout utilisateur capable. En conséquence, il est fortement encouragé que les spécifications faisant partie intégrante du défi soient dans le post lui-même, pas dans la section des commentaires.
chat

1
@cat Par exemple, en python: str(int(s, 2)).count('1')? Non, je ne considérerais pas cela comme une fonction intégrée unique qui viole cette règle. Ma modification le rend-elle plus claire?
DJMcMayhem

1
@cat En ce qui me concerne char == single_char_string. J'ai également modifié cela dans le post.
DJMcMayhem

Réponses:


9

MATL , 8 7 octets

8\hBz2\

Essayez-le en ligne! Ou vérifiez tous les cas de test à la fois .

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 octets

Parce que, tu sais, 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;}

Ceci est un lambda pour un BiFunction<String, Character, Boolean>.

eet osemblent être inversés dans la déclaration de retour, car apparemment ma logique était à l'envers.


5

Python 2, 51 octets

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

Ceci est basé sur une idée de Sp3000 pour compter 1 dans la représentation sous forme de chaîne de la liste des codes de caractères en binaire plutôt que de sommer pour chaque caractère.

La nouvelle astuce consiste à gérer eet odans ce domaine aussi. Si eétait impair et opair, nous pourrions simplement ajouter le bit de parité à la chaîne avant de faire le compte (en les retournant parce que «1» est vrai). Malheureusement, ils ne le sont pas. Mais, si nous supprimons tout sauf leurs deux derniers bits, c'est maintenant vrai.

e 0b11001|01
o 0b11011|11 

Cela se fait en supprimant le premier 9caractère de la représentation sous forme de chaîne.

['0b11001|01', 

Wow, c'est une façon très soignée de gérer eo!
Sp3000

4

Gelée, 9 8 octets

OBFSḂ⁼V}

Essayez-le en ligne!

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

Merci à Dennis pour un octet!


1
J'essayais moi-même de trouver une réponse Jelly, mais ces règles de chaînage m'ont fait oublier :-)
Luis Mendo

2
@LuisMendo Je suis dans le même bateau; c'est ma première réponse Jelly après avoir essayé de l'apprendre depuis trop longtemps: P
Poignée de porte

Ce V}... celui-là était vraiment cool !!! (Dennis est un vrai golfeur) +1 Il a battu toutes mes tentatives.
Erik the Outgolfer

4

C, 62 octets

  • 12 octets enregistrés grâce à @LevelRiverSt et @TonHospel.

XOR a la belle propriété qu'il peut être utilisé pour réduire les chaînes à un seul caractère, tout en préservant la parité.

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 devrait calculer la parité de p et est même 1 octet plus court
Ton Hospel

1
L'espace char *sest inégalé
Ton Hospel

2
62 octets: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}le %3retourne toujours 0 pour un 0, mais peut renvoyer 1 ou 2 pour un 1. Ceci est acceptable selon les règles:truthy if it's a 1
Level River St

1
27030>>((p^p>>4)&15)&1. Eh bien, euh, évidemment. ;-)
Digital Trauma

@LevelRiverSt Brilliant! Merci!
Digital Trauma

4

Python, 58 57 octets

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

1
53 (Python 2 uniquement):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000

Vous pouvez enregistrer un octet avec !=p>'e'.
xnor

Attendez, mon octet-save ne fonctionne pas vraiment parce que Python le traite comme une inégalité chaînée.
xnor

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

@xnor Publiez simplement votre propre réponse.
orlp

3

Pyth, 12 octets

q@"oe"sjCz2w

Suite de tests.

         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 octets

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

Le twiddling de bits s'est avéré plus court que la conversion en base 2 et en comptant 1s.


2

Perl, 29 octets

Comprend +2 pour -p

Exécuter avec l'entrée sur STDIN comme chaîne d'espace de caractères de parité, par exemple

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

parity.pl

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

2

J, 27 octets

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

Usage

   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

JavaScript (ES6), 69 octets

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

1

PowerShell v2 +, 91 octets

/ moi pleure dans un coin

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

Ouais ... donc, la conversion de base n'est pas un fort avantage pour PowerShell. La conversion de la chaîne d'entrée en représentation binaire $a|%{[convert]::toString(+$_,2)}est de 32 octets en soi ...

Prend des entrées $aet $btranstype explicitement en $atant que tableau de caractères dans le processus. Nous vérifions ensuite si $best -equel à o, et -xorque l'autre moitié du programme. Pour cette partie, nous prenons la chaîne d'entrée $a, la canalisons à travers une boucle pour convertir chaque lettre en binaire, -jointoutes celles-ci ensemble pour former une chaîne solide et -replacetous les 0s sans rien. Nous comptons ensuite le .lengthde cette chaîne et le prenons mod-2 pour déterminer s'il est pair ou impair, qui sera commodément soit 0ou 1, parfait pour le-xor .

Reviendra Trueou en Falseconséquence. Voir les cas de test ci-dessous:

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

Facteur, 85 octets

Pour une raison quelconque, je n'ai pas pu envelopper ma tête autour de celui-ci jusqu'à il y a quelques minutes, quand j'ai simplifié (et peut-être raccourci?) Le code.

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

?est comme un opérateur ternaire: il teste la véracité du troisième élément de pile et sélectionne la truevaleur ou la falsevaleur.

Il est à peu près équivalent au pséduocode de type C suivant:

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

Le reste du code est assez simple:

[                       ! 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

Code machine IA-32, 15 octets

Hexdump:

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

Code d'assemblage:

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

Il s'agit d'une fonction qui reçoit son premier argument (chaîne) dans ecxet son deuxième argument (char) dans dl. Il renvoie le résultat dans eax, il est donc compatible avec la fastcallconvention d'appel.

Ce code contourne les règles lorsqu'il utilise l' setpoinstruction:

Les commandes internes qui comptent le nombre de bits "on" dans une chaîne ou un caractère ne sont pas autorisées

Cette instruction définit alle bit de parité calculé par l'instruction précédente - j'ai donc ces deux astuces sur les règles:

  • Il ne compte pas le nombre de bits "on" - il calcule directement le bit de parité!
  • Techniquement, c'est l'instruction précédente ( xor) qui calcule le bit de parité. L' setpoinstruction la déplace uniquement vers le alregistre.

Ces détails sémantiques à l'écart, voici l'explication de ce que fait le code.

Les représentations des personnages sont:

'e' = 01100101
'o' = 01101111

Si on leur ajoute 1, ils se trouvent avoir juste la bonne parité:

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

Nous avons donc XORtous les caractères de la chaîne, l'initialisation alà ces valeurs, ce qui donne la réponse.


La première instruction est movzx eax, dlau lieu de la plus évidente (et plus courte) mov al, dl, car je veux avoir le numéro 0 dans un registre ( ahdans ce cas) afin de pouvoir le comparer dans le bon ordre ( 0, [ecx]plutôt que [ecx], 0).


1

Julia, 58 47 45 40 octets

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

Il s'agit d'une fonction qui accepte une chaîne et un caractère et renvoie un entier.

Pour obtenir le nombre de uns dans la représentation binaire, nous appliquons d'abord la binfonction à chaque caractère de la chaîne, ce qui nous donne un tableau de chaînes binaires. Ensuite, réduisez-les en un en utilisant prod(car *c'est la concaténation de chaînes dans Julia) et prenez l'intersection définie de cette chaîne et le code de caractère pour 1, ce qui nous donne une chaîne de uns. Le dernier index de cette chaîne est le nombre de ceux. Nous XOR ceci avec 1 si le caractère fourni est o et 0 sinon, puis obtenir la parité en utilisant AND au niveau du bit 1.

Essayez-le en ligne! (inclut tous les cas de test)

Enregistré 18 octets grâce à Dennis!


1

05AB1E , 15 , 13 octets

Code:

€ÇbSOÈ„oe²k<^

Exemple d'entrée:

Programming Puzzles and Code-Golf
o

Exemple de sortie:

1

Explication:

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

Merci à Adnan d'avoir économisé 2 octets.


Wow très agréable! Vous pouvez jouer au golf sur deux octets à l'aide de la ²commande. Cela pousse automatiquement la deuxième entrée en haut de la pile. En outre, l'utilisation de chaînes de deux caractères peut être raccourcie . "oe"Est donc équivalent à . Pour 13 octets: €ÇbSOÈ„oe²k<^:)
Adnan

05AB1E utilise également l' encodage CP-1252 , donc chaque caractère ici est de 1 octet :).
Adnan

@Adnan: Merci! Notepad ++ utilisé pour le bytecount et supposait juste qu'il comptait les caractères: P
Emigna

0

Rubis, 57 octets

Si 0était falsey à Ruby, le ==pourrait probablement être basculé sur juste -, ou il pourrait y avoir d'autres optimisations, mais ce n'est pas le cas.

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

0

Rétine , 102 octets

Prend la chaîne sur la première ligne et la lettre sur la deuxième ligne. Utilise le codage ISO 8859-1.

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

Essayez-le en ligne

La classe de caractères sur la première ligne correspond à n'importe quel caractère avec un nombre impair de caractères dans la représentation binaire.

Description du fonctionnement de la détection paire / impaire avec l'expression régulière ici .


0

Octave, 56 octets

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

La bitunpackfonction, pour les caractères ASCII, les renvoie dans l'ordre petit-boutien. Donc, en mettant le drapeau de parité à la fin de notre chaîne, en déballant le tout et en supprimant les 5 derniers bits, nous pouvons ensuite résumer le tout mod 2 pour notre réponse ultime.

Usage:

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

0

 Lisp commun, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Additionnez le nombre de log-codes de s.
  • Le reste de ceci, lorsqu'il est divisé par 2, est comparé à la position de l'argument de parité pdans la chaîne "oe"(0 ou 1). Par exemple, s'il y en a 4, le reste est nul. Si p est o, alors aucun bit supplémentaire ne doit être ajouté et le test retourne faux.

Assez imprimé

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

0

Java, 91 octets

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

J'ai fait la même chose que @ CAT97, mais j'ai supprimé certains caractères en utilisant le modulo 8 et la concaténation de @Luis Mendo et l'utilisation de int au lieu de booléen.

Ceci est un lambda pour un BiFunction<String, Character, Boolean>.


0

Matlab, 49 octets

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

où:

  • x est la chaîne d'entrée;
  • p est «e» pour une parité paire et «o» pour une parité impaire.

Par exemple:

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

ans =

     0

0

Outils Bash et Unix (72 octets)

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

Excepte scomme premier et pcomme deuxième argument. Heureusement, les 3 derniers bits de oet eont respectivement une parité paire et impaire.

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

La fourniture de l'entrée via <<<ajoute un caractère de saut de ligne, mais la parité de \nest égale, donc ce n'est pas un problème.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.