Calculer la somme fractionnée binaire d'un mot


22

Prenez une chaîne, scontenant des caractères ASCII imprimables en entrée, et sortez sa "somme divisée binaire". Besoin d'une explication?

Comment obtenez-vous la somme fractionnée binaire?

Nous utiliserons la chaîne A4comme exemple dans l'explication suivante.

  • Convertissez les caractères en binaire, en traitant chaque lettre comme un caractère ASCII 7 bits

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Concaténer les nombres binaires en un nouveau nombre binaire

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Divisez le nouveau nombre binaire en morceaux, où aucun ne 1peut avoir un 0à sa gauche. Vous ne devez pas fractionner l' 1art.

    10000010110100 -> 100000, 10, 110, 100
    
  • Convertissez ces nombres binaires en décimal

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Prenez la somme de ces nombres:

    32 + 2 + 6 + 4 = 44
    

Ainsi, la sortie de la chaîne A4devrait être 44.


Cas de test:

a
49

A4
44

codegolf
570

Hello, World!
795

2
Je pense que cela aurait été un plus beau défi sans l'étape de conversion ASCII, en prenant simplement le nombre (décimal) après l'étape 2 en entrée.
xnor

Eh bien, en 8372fait.
xnor

1
@xnor, vous avez peut-être raison et ce serait plus propre. Cependant, je me suis amusé à résoudre ce problème dans Octave, et j'espère que d'autres apprécieront également de le résoudre :)
Stewie Griffin

Réponses:


12

Python 2 , 86 81 76 octets

-5 octets merci Adnan
-5 octets merci xnor

s=0
for c in input():s=s*128+ord(c)
print eval(bin(s).replace('01','0+0b1'))

Essayez-le en ligne!

for c in input():s=s*128+ord(c)pour effectuer la conversion ASCII numériquement, où *128est utilisé pour déplacer à gauche s7 fois (étapes 1 et 2)
eval(('0'+new_bin).replace('01','0+0b1'))pour diviser et additionner (étapes 3, 4 et 5)


Belle astuce avec le eval! Faire la conversion ASCII économise numériquement quelques octets.
xnor

7

Gelée , 13 octets

Oḅ128BŒg;2/ḄS

Essayez-le en ligne!

Comment ça marche

Oḅ128BŒg;2/ḄS  Main link. Argument: s (string)

O              Ordinal; map characters to their code points.
 ḅ128          Unbase 128; convert the resulting list from base 128 to integer.
     B         Binary; Convert the resulting integer to base 2.
      Œg       Group consecutive, equal bits.
        ;2/    Concatenate all non-overlapping pairs.
           Ḅ   Unbinary; convert from base 2 to integer.
            S  Take the sum.

J'ai déjà manqué cette astuce de conversion de base.
Jonathan Allan

Ah, belle astuce en effet!
Adnan

6

MATL , 14 octets

YB!'1+0*'XXZBs

Essayez-le en ligne!

Explication

Considérez la saisie 'A4'comme exemple.

YB        % Implicit input. Convert to binary using characters '0' and '1'. 
          % Gives a char matrix, where each row corresponds to a number
          % STACK: ['1000001'; '0110100']
!         % Transpose. This is necessary because MATL uses column-major 
          % order when linearizing a matrix into a vector
          % STACK: ['10'; '01'; '01'; '00'; '01'; '00'; '10']
'1+0*'    % Push this string: regexp pattern
          % STACK: ['10'; '01'; '01'; '00'; '01'; '00'; '10'], '1+0*'
XX        % Regexp. Linearizes the first input into a row (in column-major
          % order), and pushes a cell array of substrings that match the
          % pattern given by the second input
          % STACK: {'100000'; '10'; 110'; '100'}
ZB        % Convert each string into a decimal number. Gives numeric vector
          % STACK: [32; 2; 6; 4]
s         % Sum. Implicitly display
          % STACK: 44

5

05AB1E , 18 octets

Code:

Çžy+b€¦JTR021:2¡CO

Explication:

Ç                   # Take the ASCII value of each character
 žy+                # Add 128 to each value (to pad each with enough zeros)
    b               # Convert to binary
     €¦             # Remove the first character
       J            # Join the array
        TR021:      # Replace 01 by 021
              2¡    # Split on the number 2
                C   # Convert from binary to decimal
                 O  # Sum them all up

Utilise l' encodage 05AB1E . Essayez-le en ligne!


5

05AB1E , 14 octets

Çžy+b€¦Jγ2ôJCO

Un portage de ma réponse Jelly , en utilisant le décalage 128 de la réponse 05ab1e d' Adnan (plutôt que le 256 dans la réponse Jelly que j'ai écrite).

Essayez-le en ligne!

Comment?

Çžy+b€¦Jγ2ôJCO
Ç              - to ordinals
   +           - add
 žy            - literal 128
    b          - to binary
     €         - for each
      ¦        -   dequeue
       J       - join
        γ      - group into chunks of equal elements
          ô    - split into chunks of
         2     - literal 2
           J   - join
            C  - from binary
             O - sum

3

JavaScript (ES6), 97 92 octets

s=>eval(s.replace(/./g,c=>(128+c.charCodeAt()).toString(2).slice(1)).replace(/1+/g,'+0b$&'))

Edit: enregistré 5 octets avec l'aide de @ ConorO'Brien.


Ma propre solution était également de 97 octets: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))vous pouvez utiliser ma méthode de remplacement pour enregistrer un octet, je pense
Conor O'Brien

1
@ ConorO'Brien Plus qu'un octet, je pense!
Neil

Oo, n i c e: D
Conor O'Brien

3

Japt , 18 12 octets

c_¤ùT7Ãò< xÍ
c_           // Firstly, take the input and map over it as charcodes.
  ¤          // Take the binary representation of each item
   ùT7       // and left-pad it with zeroes to standardize the items.
      Ã      // After all of the above,
       ò<    // partition the result where ever a 0 precedes a 1.
          xÍ // Then sum the numbers from base 2.

Prend l'entrée en une seule chaîne.
J'ai également essayé l'ajout de 128 ou 256 utilisé par d'autres réponses, mais le remplissage 0 était plus court à utiliser.

Rasé un énorme 6 octets grâce à ETHproductions et Oliver .

Essayez-le ici.


Vous pouvez utiliser plus de fonctions automatiques ici: òÈ<YÃpeut être ò<(avec un espace de fin) et Ën2Ãxpeut l'être xn2. Vous pouvez également utiliser Tà la place de 0pour économiser sur la virgule. (Aussi, n'hésitez pas à nous rejoindre dans le salon de discussion Japt si vous avez des questions ou souhaitez de l'aide avec le golf :-))
ETHproductions

@ETHproductions Merci encore, surtout pour l' Tastuce, je ne savais pas que vous pouviez (ab) utiliser des variables pour cela, c'est très pratique. La fonction automatique xn2semble un peu bizarre lors de sa compilation, x("n", 2)donc je pense que cela prendra encore un peu avant de comprendre pleinement la logique derrière eux. Avec votre aide, la solution Japt est maintenant liée à la première place avec la réponse Jelly .
Nit

ETHproductions a récemment fait un raccourci pour n2: Í. Il n'a pas encore atteint TIO, mais vous pouvez l'utiliser ici: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver

@Oliver Wow, c'est un bord très saillant, qui n'est même pas encore couvert dans la référence des raccourcis interprètes. Merci beaucoup!
Nit

2

Gelée , 16 15 octets

-1 octet grâce à Dennis (pas besoin d'aplatir de 1 lorsqu'un aplatissement complet est correct - remplacer ;/par F)

O+⁹Bṫ€3FŒg;2/ḄS

Essayez-le en ligne!

Comment?

O+⁹Bṫ€3FŒg;2/ḄS - Main link: list of characters, s    e.g. "A4"
O               - cast to ordinal (vectorises)        [65,52]
  ⁹             - literal 256
 +              - add (vectorises)                    [321, 308]
   B            - convert to binary (vectorises)      [[1,0,1,0,0,0,0,0,1],[1,0,0,1,1,0,1,0,0]]
    ṫ€3         - tail €ach from index 3              [[1,0,0,0,0,0,1],[0,1,1,0,1,0,0]]
       F        - reduce with concatenation           [1,0,0,0,0,0,1,0,1,1,0,1,0,0]
        Œg      - group runs of equal elements        [[1],[0,0,0,0,0],[1],[0],[1,1],[0],[1],[0,0]]
          ;2/   - pairwise reduce with concatenation  [[1,0,0,0,0,0],[1,0],[1,1,0],[1,0,0]]
             Ḅ  - convert from binary (vectorises)    [32,2,6,4]
              S - sum                                 44

1
;/peut être remplacé par F.
Dennis

2

PHP, 116 octets

for(;$c=ord($argn[$i++]);)$r.=sprintf("%07b",$c);$t=mb_split("(?<=0)(?=1)",$r);echo array_sum(array_map(bindec,$t));

Version en ligne

PHP, 117 octets

for(;$c=ord($argn[$i++]);)$r.=sprintf("%07b",$c);$t=preg_split("#0\K(?=1)#",$r);echo array_sum(array_map(bindec,$t));

Essayez-le en ligne!

PHP, 120 octets

for(;$c=ord($argn[$i++]);)$r.=sprintf("%07b",$c);preg_match_all("#1+0+#",$r,$t);foreach($t[0]as$b)$s+=bindec($b);echo$s;

Essayez-le en ligne!

ou

for(;$c=ord($argn[$i++]);)$r.=sprintf("%07b",$c);preg_match_all("#1+0+#",$r,$t);echo array_sum(array_map(bindec,$t[0]));


1

[F #], 249 245 octets

open System
let rec c a=function|[]->[a]|'0'::'1'::y->(a+"0")::(c""('1'::y))|x::y->c(a+string x)y
let x i=c""(String.Join("",(Seq.map(fun c->Convert.ToString(int c,2).PadLeft(7,'0'))i))|>Seq.toList)|>Seq.map(fun c->Convert.ToInt32(c,2))|>Seq.sum

Essayez-le en ligne!

Remarque: la version sur tio.run a "système ouvert" dans l'en-tête, j'ai ajouté son nombre au code ci-dessus. Je ne sais pas quelles sont les règles sur les importations.

Non golfé

let rec convert acc = function
    | [] -> [acc]
    | '0'::'1'::xs -> (acc + "0") :: (convert "" ('1'::xs))
    | x::xs -> convert (acc + string x) xs

let calculateSum input =
    let binary = Seq.map (fun x -> Convert.ToString(int x, 2).PadLeft(7, '0')) input

    String.Join("", binary)
    |> Seq.toList
    |> convert ""
    |>Seq.map (fun x -> Convert.ToInt32(x, 2))
    |>Seq.sum

si open Systemc'est la même chose que C #, using System;alors oui, vous devez l'inclure dans le décompte. Si vous pouvez le faire en F #, vous pourrez pleinement vous qualifier pour quoi que ce Systemsoit. Par exemple, en C # System.Console...au lieu deusing System;Console...
TheLethalCoder

@TheLethalCoder C'est la même chose, oui. Aussi, merci d'avoir clarifié cela :) J'ai opté pour la version "open .." car ce n'est pas seulement String, mais aussi Convert qui vit dans cet espace de noms.
Brunner


0

J , 34 octets

[:+/@(,#.;.1~1,1=2#.\,)(7#2)#:3&u:

Essayez-le en ligne!

Explication

[:+/@(,#.;.1~1,1=2#.\,)(7#2)#:3&u:  Input: array of characters S
                              3&u:  Get ASCII values of each character
                       (7#2)        Array with 7 copies of the value 2
                            #:      Convert each value to a base 2 array with length 7
[:  (                 )             Operate on those binary values
                     ,                Flatten it
                 2  \                 For each infix of size 2
                  #.                    Convert it to decimal from binary
               1=                     Test each value for equality to 1
             1,                       Prepend a 1
      ,                               The flattened binary values
         ;.1~                         Chop that at each occurrence of a 1
       #.                               Convert each chop from binary to decimal
 +/@                                Reduce by addition

0

mathématique 193 octets

f=FromDigits;l=Flatten;(S=Split@l@Table[PadLeft[IntegerDigits[ToCharacterCode@#,2][[k]],7],{k,StringLength@#}];Plus@@Table[f[RealDigits@f@Join[S[[i]],S[[i+1]]],2],{i,1,Length@S-1,2}]+Last@l@S)&

Vous pouvez enregistrer 7 octets en effectuant f=FromDigits;l=Flatten;au début, puis en remplaçant toutes les instances de ces deux fonctions par fet l.
numbermaniac

0

J , 40 octets

+/>#.&.>(1,}.|.1 0 E.|.b)<;.1 b=.,#:a.i.

usage:

+/>#.&.>(1,}.|.1 0 E.|.b)<;.1 b=.,#:a.i.'A4'

renvoie 44


0

Clojure, 150 octets

#(loop[[c & C](for[i % j[64 32 16 8 4 2 1]](mod(quot(int i)j)2))p 0 r 0 R 0](if c(if(=(dec c)p 0)(recur C c 1(+ R r))(recur C c(+(* 2 r)c)R))(+ R r)))

Eh bien, j'espérais que la conversion de l'ASCII en octets était plus courte que cela. Le corps de boucle réel est assez court, rpermettant d'accumuler le résultat actuel et Rd'accumuler le résultat total. Si le bit précédent pest 0et le bit actuel cest 1alors nous divisons un nouveau morceau et nous accumulons R, sinon nous mettons à jour le ret le conservons Rtel qu'il était.


0

Python 123 octets

lambda w:sum(map(lambda x:int(x,2),"".join(map(lambda x:bin(ord(x))[2:].zfill(7),list(w))).replace("01","0:1").split(":")))

Mis à jour, merci à Martin Ender.


1
Bienvenue chez PPCG! Toutes les réponses doivent être des programmes complets ou des fonctions appelables (par opposition aux extraits de code où l'entrée est stockée dans une variable codée en dur). La fonction peut cependant ne pas être nommée, donc inclure un lambda w:suffirait pour rendre votre réponse valide.
Martin Ender

Désolé, je n'ai probablement pas bien formulé cela. Votre modification n'est toujours pas valide car a) l'entrée est codée en dur, b) S'il s'agit d'un programme complet, il n'imprime pas réellement le résultat. Pour un programme complet, vous devez lire l'entrée depuis l'entrée standard ou un argument de ligne de commande et imprimer le résultat sur la sortie standard. C'est pourquoi j'ai dit que c'est probablement plus facile si vous le soumettez en tant que fonction en ajoutant lambda w:.
Martin Ender

Ohhh, ok, je comprends, ce serait suffisant comme ceci: f = lambda w: sum (map (lambda x: int (x, 2), "". Join (map (lambda x: bin (ord (x)) ) [2:]. Zfill (7), list (w))). Replace ("01", "0: 1"). Split (":")))
ShadowCat

oui, c'est valable. Vous n'avez même pas besoin de la f=, car nous autorisons les fonctions sans nom (sauf si vous faites référence au nom de la fonction pour les appels récursifs).
Martin Ender

0

K (oK) , 31 octets

Solution:

+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$

Essayez-le en ligne!

Exemples:

+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$,"a"
49
+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$"A4"
44
+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$"codegolf"
570
+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$"Hello, World!"
795

Explication:

Convertissez en valeurs ASCII, convertissez en binaire 7 bits, aplatissez, trouvez où diffère et contre la liste d'origine pour trouver où 1diffèrent. Coupez à ces indices, reconvertissez en décimal et résumez:

+/2/'_[;x]&x&~~':x:,/(7#2)\'`i$ / the solution
                            `i$ / convert to integer
                     (7#2)      / draw from 2, 7 times => 2 2 2 2 2 2 2
                          \'    / decode each (convert to binary)
                   ,/           / flatten
                 x:             / save as x
             ~~':               / not-not-each previous (differ)
            &                   / and with
           x                    / x
          &                     / indices where true
     _[;x]                      / projection, cut x at ...
  2/'                           / encode each (convert from binary)
+/                              / sum up

Prime

Géré une version 31 octets dans K4 aussi, mais comme il n'y a pas de TIO pour cela, je poste ma solution ok.

+/2/:'_[;x]@&x&~~':x:,/1_'0b\:'

0

APL (Dyalog) , 30 octets

{+/2⊥¨(1∘+⊆⊢)∊¯7↑¨2⊥⍣¯1¨⎕UCS⍵}

Essayez-le en ligne!

Comment?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - encoder chacun en binaire

¯7↑¨ - et pad vers la gauche avec des zéros à 7 places

- aplatir

1∘+⊆⊢ - partition par soi augmentée d'un

2⊥¨ - décode chacun du binaire

+/ - somme

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.