Transition chaîne à bit


10

Tâche

Étant donné une chaîne d'entrée d'un ou plusieurs caractères ASCII dont les points de code sont compris entre 0 et 128 (exclusif), procédez comme suit:

  1. Convertissez chaque caractère en son code ASCII 7 bits (si le code ASCII est inférieur à 7 bits, mettez les premiers bits zéro)
  2. Concatène tous les bits (il en résulte des 7*nbits où nest le nombre de caractères)
  3. Pour chaque bit de ce flux binaire, imprimez 1 s'il est différent du bit précédent et imprimez 0 sinon. Le premier bit de sortie est toujours 1.

Exemple

Contribution:

Hi

Production:

11011001011101

Explication:

La chaîne "Hi" a les codes ASCII

72 105

qui en bits sont:

1001000 1101001

Et les indicateurs de bits de transition:

11011001011101

C'est le golf de code. Le nombre d'octets le plus bas gagne.

Cas de test

Cas de test 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Cas de test 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Test case 3 (crédit à Luis Mendo):

##
11100101110010

Félicitations à Luis Mendo pour la solution la plus courte avec 9 octets en MATL!


2
Cas de test suggéré ##( 0bit principal ; certaines réponses échouent actuellement à cause de cela)
Luis Mendo

4
Comment est-ce un double du défi d'encodage de Manchester? Suis-je en train de manquer quelque chose?
gastropner

2
L'autre défi consiste à convertir un flux d'entrée de bits en un flux de sortie à double débit, chaque entrée «1» étant convertie en «01» et chaque entrée «0» traduite en «10» . Donc pas dupe à mon avis. Si un grand nombre de personnes votent le commentaire de @ gastropner ci-dessus, je peux dé-duper (ou tout autre utilisateur avec cette capacité)
Luis Mendo

1
@Shaggy: Les deux cas de test incluent un espace, qui n'a qu'un seul ensemble de bits, et non le 7e. Je ne pense donc pas que l'énoncé du problème garantit que chaque code ascii aura exactement 7 bits de longueur.
récursif

1
@SmileAndNod Après réflexion, je pense que vous n'avez pas besoin de gérer une chaîne vide.
moitié du

Réponses:


4

MATL , 9 octets

Hj7&B!hdg

Essayez-le en ligne!

Explication

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display

1
C'est le plus court jusqu'à présent. +1. C'est amusant d'avoir un intégré pour les différences consécutives.
Justhalf


4

Japt -P , 11 octets

Profite du fait que les espaces peuvent être contraints 0en JavaScript lorsque vous essayez d'effectuer une opération mathématique ou, dans ce cas, au niveau du bit.

c_¤ù7Ãä^ i1

Essayez-le ou exécutez tous les cas de test

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
  ¤             :  Convert to binary string
   ù7           :  Left pad with spaces to length 7
     Ã          :End map
      ä^        :XOR consecutive pairs
         i1     :Prepend 1
                :Implicitly join and output

Le 7 bits signifie que s'il est 32 (pour le caractère espace), il le serait 0100000. De plus, le caractère% (37) serait0100101
juste le

Ça marche maintenant. +1
juste la moitié du

2

CJam , 21 octets

1q{i2b7Te[}%e__(;.^);

Essayez-le en ligne!

Explication

Affichage de la pile avec un exemple d'entrée 5:

1 q      e# Push 1 and then the whole input: 1 "5"
{
  i      e# Convert to its char code: 1 [53]
  2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
  7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
         e# Stack implicitly printed: 1101111

Pour voir si un bit est différent du bit précédent, nous faisons un vecteur (élément par élément) entre le tableau de bits et le tableau de bits sans le premier élément. Nous supprimons également le dernier bit du résultat, car il s'agit toujours du dernier bit du tableau le plus long inchangé.


2

APL (Dyalog Unicode) , 16 octets SBCS

Programme complet. Demande la chaîne de stdin.

1,2≠/∊1↓¨11DR¨⍞

Essayez-le en ligne!

 demande de saisie ("un devis dans une console")

11⎕DR¨ modifier chaque caractère de bit booléenne D ata R ePresentation

1↓¨ déposez le premier bit de chaque

ϵ nlist (aplatir)

2≠/ différence par paire

1, ajouter un



2

Fusain , 25 octets

⭆θ◧⍘℅鲦⁷←Wⅈ←I﹪⍘KD²←01 ²1

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

⭆θ◧⍘℅鲦⁷←

Convertissez tous les caractères en binaire et remplissez-les à une longueur de 7, puis imprimez-les, mais laissez le curseur sur le dernier chiffre.

Wⅈ

Répétez jusqu'à ce que le curseur se trouve sur le premier chiffre.

←I﹪⍘KD²←01 ²

Calculez si les chiffres sont différents et remplacez chaque chiffre par la différence.

1

Remplacez le premier chiffre par un 1.





1

Python 2 , 104 octets

lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]

Essayez-le en ligne!

Un coup de couteau rapide.


Astuce astucieuse avec a*128+ord(c)! Mais n'est-ce pas reduceet lambdaplutôt coûteux?
juste le

1

Dart , 213 168 octets

f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}

Précédent one-liner

f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);

Essayez-le en ligne!

Cette verbosité et ce manque d'inserts faciles à construire tuent vraiment celui-ci. Pourtant, j'ai quand même réussi à tirer une ligne.

  • -45 octets en n'utilisant pas une ligne et en utilisant une boucle for


1

Kotlin , 182 octets

var l='6'
fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}}
fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)

Essayez-le en ligne!

J'espère que je pourrai améliorer cela bientôt, j'ai l'impression qu'il doit y avoir des points à améliorer mais je ne peux pas penser en ce moment



1

C (gcc (MinGW)), 90 octets

Nécessite un compilateur fournissant itoa().

n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}


1

Rubis -p , 50 octets

gsub(/./){"%07b"%$&.ord}
gsub(/./){$`=~/#$&$/?0:1}

Essayez-le en ligne!

Explication

Première ligne, identique à la réponse de Value Ink :

gsub(/./){       $&    }   # Replace each character $&…
                   .ord    # …with its ASCII code…
                %          # …formatted as…
          "%07b"           # …binary digits padded to 7 places.

Deuxième ligne:

gsub(/./){      $&      }  # Replace each character $&…
          $`               # …if the text to its left…
            =~             # …matches…
              /#  $/       # …the Regexp /c$/ where "c" is the character…
                    ?0:1   # …with 0, or 1 otherwise.

Dans Ruby, vous pouvez utiliser l'interpolation dans les littéraux Regexp, par exemple /Hello #{name}/, et pour les variables qui commencent par $ou @vous pouvez omettre les accolades, donc si par exemple $&est "0"alors le grawlixy /#$&$/devient /0$/.


1

K (ngn / k) , 9 13 octets

Solution:

~=':,/(7#2)\'

Essayez-le en ligne!

Explication:

~=':,/(7#2)\' / the solution
           \' / convert each
      (   )   / do this together
       7#2    / 2 2 2 2 2 2 2
    ,/        / flatten
 =':          / equal to each-previous?
~             / not

Remarques:

  • +4 octets pour prendre en charge les chaînes composées uniquement de caractères 6 bits

Cela semble échouer pour l'entrée #par exemple (la sortie n'a que 6 bits)
Luis Mendo

@streetster, voulez-vous publier la version fixe?
moitié du

1

Emojicode , 263 octets

🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉

Essayez-le en ligne ici.

Non golfé:

🏁 🍇  💭 Main code block
    🔤🔤 ➡️ 🖍 🆕 s  💭 Start with s as the empty string
    🔂 b 📇 🆕 🔡 👂🏼  💭 For each byte b in the input ...
    ❗️ ❗️ 🍇
        🍪 s  💭 ... append ...
           🔪 🔡 🔢 b ❗️ ➕ 128  💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ...

                 2  💭 ... in binary ...
              ❗️
              1 7  💭 ... without the leading one ...
           ❗️
        🍪
        ➡️ 🖍 s  💭 ... to s
    🍉
    🔤?🔤 ➡️ 🖍 🆕 p  💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one
    🔂 b s 🍇  💭 For each character in s:
        ↪️ b 🙌 p 🍇  💭 If it is the same as the previous character ...
            👄 🔤0🔤 ❗️  💭 ... output a zero ...
        🍉 🙅 🍇  💭  ... else ...
            👄 🔤1🔤 ❗️ 💭 ... output a one
        🍉
        b ➡️ 🖍 p  💭 And the current character becomes the new previous character.
    🍉
🍉


1

Python3.8 , 72 octets

Solution:

lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]

Explication:

Depuis que Python 3.8 a introduit les expressions d'affectation (plutôt que les instructions d'affectation standard), j'ai voulu les utiliser dans une liste de compréhension qui doit se souvenir du dernier élément. Ce n'est pas la meilleure façon de procéder, mais illustre une méthode intéressante d'utilisation de l'expression d'affectation.

Le code crée une fonction lambda qui prend l'argument requis qui est la chaîne à convertir. Lorsqu'elle est appelée, la fonction se déroule comme suit. Chaque caractère dans a est converti en son code de caractère auquel 128 est ajouté pour traiter les caractères 6 bits (la représentation binaire sera toujours de 8 bits et nous pouvons couper le premier bit). Ce nombre est converti en binaire et l'en-tête (0x) et le 1 initial de l'ajout de 128 sont coupés. Ces nouvelles chaînes sont ensuite jointes en une chaîne plus grande.

Pour chaque caractère de cette nouvelle chaîne (qui contient la représentation concaténée à 7 bits du texte), il est vérifié si le caractère est le même que le caractère précédent. Que se passe-t-il avec le premier personnage? Le premier caractère de résultat doit toujours être "1", nous devons donc nous assurer que tout ce qui se trouve dans la dernière variable de caractère n'est ni "1" ni "0". Nous le faisons en réutilisant le paramètre d'origine maintenant que nous ne l'utilisons plus. Cela peut être un problème si la chaîne d'origine était un simple "0" (un seul "1" fonctionne simplement) mais nous l'ignorerons.

Pendant la comparaison, le caractère précédent a été évalué en premier, donc lorsque nous utilisons l'expression d'affectation pour définir la variable de caractère précédente sur le caractère actuel, cela n'affecte pas l'évaluation des expressions de comparaison.

La comparaison produit soit Vrai soit Faux qui peut également être utilisé comme 1 ou 0 respectivement en Python, donc ils sont utilisés pour rechercher un "1" ou "0" dans une chaîne


Vous pouvez enregistrer quelques octets en utilisant des littéraux au format chaîne: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica

1

Tcl , 215 167 140 octets

{{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}

Essayez-le en ligne!

Utilise shift-by-one et exclusif-ou pour détecter les transitions. Porte lsb du caractère actuel au msb du caractère suivant. Combine la sortie de chaque caractère en rejoignant la liste renvoyée par lmap.

Utilise des lambdas avec des arguments par défaut pour économiser des octets lors de l'initialisation et des commandes répétées.

Dépend fortement de l'ordre de fonctionnement. Fonctionne pour une chaîne vide.


1

05AB1E (hérité) , 12 octets

Çb7jð0:¥ÄJ1ì

Utilise la version héritée de 05AB1E, car jjoint implicitement les chaînes ensemble, ce qui nécessite une explicite Japrès la jdans la nouvelle version de 05AB1E.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Ç             # Convert the (implicit) input-string to a list of ASCII code-points
              #  i.e. "Hi#" → [72,105,35]
 b            # Convert each integer to a binary string
              #  → ["1001000","1101001","100011"]
  7j          # Prepend each with spaces to make them length 7,
              # and join everything together to a single string implicitly
              #  → "10010001101001 100011"
    ð0:       # Replace all those spaces with 0s
              #  → "100100011010010100011"
       ¥      # Get the deltas of each pair of 1s/0s
              #  → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0]
        Ä     # Get the absolute value of this
              #  → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0]
         J    # Join them all together
              #  → "10110010111011110010"
          1ì  # And prepend a 1
              #  → "110110010111011110010"
              # (after which the result is output implicitly)

1

Haskell , 137 octets

import Data.Char
b 0=[]
b n=odd n:b(n`div`2)
d x|x='1'|1<2='0'
c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)

Essayez-le en ligne!

Le plus gros problème ici est de convertir les booléens (résultat du XOR) en '0' / '1'.





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.