Calcular la suma dividida binaria de una palabra

22

Tome una cadena que scontenga caracteres ASCII imprimibles como entrada y genere su "suma dividida binaria". ¿Necesitas una explicación?

¿Cómo se obtiene la suma dividida binaria?

Usaremos la cadena A4como ejemplo en la siguiente explicación.

  • Convierta los caracteres a binario, tratando cada letra como un carácter ASCII de 7 bits

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Concatenar los números binarios en un nuevo número binario

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Divida el nuevo número binario en fragmentos, donde no 1puede haber un 0a su izquierda. No debe dividir 1s consecutivos .

    10000010110100 -> 100000, 10, 110, 100
    
  • Convierta estos números binarios a decimales

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Toma la suma de estos números:

    32 + 2 + 6 + 4 = 44
    

Entonces, la salida para la cadena A4debería ser 44.


Casos de prueba:

a
49

A4
44

codegolf
570

Hello, World!
795
Stewie Griffin
fuente
2
Creo que esto habría sido un desafío mejor sin el paso de conversión ASCII, simplemente tomando el número (decimal) después del paso 2 como entrada.
xnor
Bueno, en 8372realidad
xnor
1
@xnor, puede que tengas razón, y sería más limpio. Sin embargo, me divertí resolviendo esto en Octave, y espero que otros disfruten resolviéndolo también :)
Stewie Griffin

Respuestas:

12

Python 2 , 86 81 76 bytes

-5 bytes gracias Adnan
-5 bytes gracias xnor

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

Pruébalo en línea!

for c in input():s=s*128+ord(c)para hacer la conversión ASCII numéricamente, donde *128se usa para desplazarse a la izquierda s7 veces (pasos 1 y 2)
eval(('0'+new_bin).replace('01','0+0b1')) para dividir y sumar (pasos 3, 4 y 5)

Barra
fuente
Buen truco con el eval! Hacer la conversión ASCII numéricamente ahorra algunos bytes.
xnor
7

Jalea , 13 bytes

Oḅ128BŒg;2/ḄS

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
He perdido ese truco de conversión de base antes.
Jonathan Allan
Ah, buen truco de verdad!
Adnan
6

MATL , 14 bytes

YB!'1+0*'XXZBs

Pruébalo en línea!

Explicación

Considere la entrada 'A4'como un ejemplo.

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
Luis Mendo
fuente
5

05AB1E , 18 bytes

Código:

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

Explicación:

Ç                   # 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

Utiliza la codificación 05AB1E . Pruébalo en línea!

Adnan
fuente
5

05AB1E , 14 bytes

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

Un puerto de mi respuesta Jelly , usando el desplazamiento 128 de la respuesta 05ab1e de Adnan (en lugar del 256 en la respuesta Jelly que escribí).

Pruébalo en línea!

¿Cómo?

Çž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
Jonathan Allan
fuente
3

JavaScript (ES6), 97 92 bytes

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

Editar: guardado 5 bytes con ayuda de @ ConorO'Brien

Neil
fuente
Mi propia solución también fue de 97 bytes: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))creo que puede usar mi método de reemplazo para guardar un byte
Conor O'Brien
1
@ ConorO'Brien ¡Más que un byte, creo!
Neil
Oo, n i c e: D
Conor O'Brien
3

Japt , 18 12 bytes

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.

Toma la entrada como una sola cadena.
También probé la adición 128 o 256 utilizada por otras respuestas, pero el relleno de 0 fue más corto de usar.

Se redujo la friolera de 6 bytes gracias a ETHproductions y Oliver .

Pruébalo aquí.

Liendre
fuente
Puede usar más funciones automáticas aquí: òÈ<YÃpuede ser ò<(con espacio final) y Ën2Ãxpuede ser xn2. También puede usar Ten lugar de 0guardar en la coma. (Además, siéntase libre de unirse a nosotros en la sala de chat de Japt si alguna vez tiene preguntas o desea ayuda con el golf :-))
ETHproductions
@ETHproductions Gracias de nuevo, especialmente por el Ttruco, no sabía que podía (ab) usar variables para eso, eso es muy útil. La función automática se xn2ve un poco extraña cuando se compila, x("n", 2)por lo que creo que todavía tomará un poco antes de comprender completamente la lógica detrás de ellos. Con su ayuda, la solución Japt ahora está vinculada al primer lugar con la respuesta Jelly .
Nit
ETHproductions recientemente hicieron un acceso directo para n2: Í. Todavía no ha llegado a TIO, pero puede usarlo aquí: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver
@Oliver Wow, eso es muy innovador, eso ni siquiera está cubierto en la referencia de atajos del intérprete todavía. ¡Muchas gracias!
Nit
2

Gelatina , 16 15 bytes

-1 byte gracias a Dennis (no es necesario aplanar en 1 cuando un aplanamiento completo está bien; reemplácelo ;/con F)

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

Pruébalo en línea!

¿Cómo?

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
Jonathan Allan
fuente
1
;/puede ser reemplazado con F.
Dennis
2

PHP, 116 bytes

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

Versión en línea

PHP, 117 bytes

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

Pruébalo en línea!

PHP, 120 bytes

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;

Pruébalo en línea!

o

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

[F #], 249 245 bytes

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

Pruébalo en línea!

Nota: la versión en tio.run tiene "Sistema abierto" en el encabezado, he agregado su cuenta al código anterior. No estoy seguro de cuáles son las normas sobre las importaciones.

Sin 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
Brunner
fuente
si open Systemes lo mismo que C # s, using System;entonces sí, debe incluirlo en el recuento. Si puede hacerlo en F #, podría calificar completamente para lo que Systemsea. Por ejemplo, en C # en System.Console...lugar deusing System;Console...
TheLethalCoder
@TheLethalCoder Es lo mismo, sí. Además, gracias por aclarar esto :) Opté por la versión "abierta ..." porque no es solo String, sino también Convert que se vive en ese espacio de nombres.
Brunner
0

Perl 6 , 62 bytes

{sum map {:2(~$_)},.comb».ord».fmt('%07b').join~~m:g/11*0*/}
Sean
fuente
usar en .ordslugar de .comb».ord. El prefijo a [~]menudo se puede usar en lugar de .join. combexiste lo que hace la m:g/…cosa. /11*0*/se puede acortar a /1+0*/. Se me ocurrió{sum map {:2($_)},comb /1+0*/,[~] .ords».fmt('%07b')}
Brad Gilbert b2gills
0

J , 34 bytes

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

Pruébalo en línea!

Explicación

[:+/@(,#.;.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
millas
fuente
0

Mathica 193 bytes

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)&
J42161217
fuente
Puede guardar 7 bytes haciendo f=FromDigits;l=Flatten;al principio, y luego reemplazando todas las instancias de esas dos funciones con fy l.
numbermaniac
0

J , 40 bytes

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

uso:

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

devuelve 44

protista
fuente
0

Clojure, 150 bytes

#(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)))

Bueno, esperaba que la conversión de ASCII a bytes fuera más corta que esto. El cuerpo del bucle real es bastante corto, y se usa rpara acumular el resultado actual y Rpara acumular el resultado total. Si el bit anterior pes 0y el bit actual ces 1entonces, dividimos un nuevo fragmento y lo acumulamos R, de lo contrario, actualizamos el ry mantenemos Rcomo estaba.

NikoNyrh
fuente
0

Python 123 bytes

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(":")))

Actualizado, gracias a Martin Ender.

ShadowCat
fuente
1
Bienvenido a PPCG! Todas las respuestas deben ser programas completos o funciones invocables (a diferencia de los fragmentos donde la entrada se almacena en una variable codificada). Sin embargo, la función puede no tener nombre, por lo que incluir una lambda w:sería suficiente para que su respuesta sea válida.
Martin Ender
Lo siento, probablemente no lo dije bien. Su edición aún no es válida porque a) la entrada está codificada, b) Si se trata de un programa completo, en realidad no imprime el resultado. Para un programa completo, tendría que leer la entrada desde la entrada estándar o un argumento de línea de comandos e imprimir el resultado en la salida estándar. Es por eso que dije que probablemente sea más fácil si lo envías como una función agregando lambda w:.
Martin Ender
Ohhh, Ok, lo entiendo, sería suficiente así: 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
Sí, eso es válido. Ni siquiera necesita el f=, porque permitimos funciones sin nombre (a menos que haga referencia al nombre de la función para llamadas recursivas).
Martin Ender
0

K (oK) , 31 bytes

Solución:

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

Pruébalo en línea!

Ejemplos:

+/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

Explicación:

Convierte a valores ASCII, convierte a binario de 7 bits, aplana, encuentra dónde difiere y compara con la lista original para encontrar dónde 1difieren. Corte en estos índices, convierta de nuevo a decimal y resuma:

+/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

Prima

También administré una versión de 31 bytes en K4 , pero como no tengo TIO, publico mi solución OK.

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

APL (Dyalog) , 30 bytes

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

Pruébalo en línea!

¿Cómo?

⎕UCS⍵ - Unicodificar

2⊥⍣¯1¨ - codificar cada uno en binario

¯7↑¨ - y pad a la izquierda con ceros a 7 lugares

- aplanar

1∘+⊆⊢ - partición por sí mismo aumentada en uno

2⊥¨ - decodificar cada uno desde binario

+/ suma

Uriel
fuente