Calcola la somma binaria divisa di una parola


22

Prendi una stringa, scontenente caratteri ASCII stampabili come input, e genera la sua "somma divisa binaria". Hai bisogno di una spiegazione?

Come si ottiene la somma divisa binaria?

Useremo la stringa A4come esempio nella seguente spiegazione.

  • Converti i caratteri in binario, trattando ogni lettera come un carattere ASCII a 7 bit

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Concatena i numeri binari in un nuovo numero binario

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Dividi il nuovo numero binario in blocchi, dove no 1può avere a 0alla sua sinistra. Non dovresti dividere 1s consecutivi .

    10000010110100 -> 100000, 10, 110, 100
    
  • Converti questi numeri binari in decimali

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Prendi la somma di questi numeri:

    32 + 2 + 6 + 4 = 44
    

Quindi, l'output per la stringa A4dovrebbe essere 44.


Casi test:

a
49

A4
44

codegolf
570

Hello, World!
795

2
Penso che questa sarebbe stata una sfida più bella senza il passaggio di conversione ASCII, prendendo solo il numero (decimale) dopo il passaggio 2 come input.
xnor

Bene, in 8372realtà.
xnor

1
@xnor, potresti avere ragione, e sarebbe più pulito. Mi sono divertito a risolverlo in Octave, e spero che anche gli altri si divertiranno a risolverlo :)
Stewie Griffin

Risposte:


12

Python 2 , 86 81 76 byte

-5 byte grazie Adnan
-5 byte grazie xnor

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

Provalo online!

for c in input():s=s*128+ord(c)per eseguire la conversione ASCII numericamente, dove *128viene utilizzato per spostare a sinistra s7 volte (passaggi 1 e 2)
eval(('0'+new_bin).replace('01','0+0b1'))per dividere e sommare (passaggi 3, 4 e 5)


Bel trucco con il eval! La conversione ASCII numericamente salva alcuni byte.
xnor

7

Gelatina , 13 byte

Oḅ128BŒg;2/ḄS

Provalo online!

Come funziona

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.

Ho perso quel trucco di conversione di base prima.
Jonathan Allan,

Ah, davvero un bel trucco!
Adnan,

6

MATL , 14 byte

YB!'1+0*'XXZBs

Provalo online!

Spiegazione

Considera l'input 'A4'come esempio.

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 byte

Codice:

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

Spiegazione:

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

Utilizza la codifica 05AB1E . Provalo online!


5

05AB1E , 14 byte

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

Una porta della mia risposta Jelly , usando l'offset 128 dalla risposta 05ab1e di Adnan (piuttosto che il 256 nella risposta Jelly che ho scritto).

Provalo online!

Come?

Çž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 byte

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

Modifica: salvato 5 byte con l'aiuto di @ ConorO'Brien.


La mia soluzione era anche di 97 byte: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))puoi usare il mio metodo di sostituzione per salvare un byte, credo
Conor O'Brien

1
@ ConorO'Brien Più di un byte, penso!
Neil,

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

3

Japt , 18 12 byte

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.

Accetta l'input come singola stringa.
Ho anche provato l'aggiunta 128 o 256 utilizzata da altre risposte, ma il padding 0 era più breve da usare.

Rasato un intero enorme 6 byte grazie a ETHproductions e Oliver .

Provalo qui.


Puoi usare più funzioni automatiche qui: òÈ<YÃpuò essere ò<(con spazio finale) e Ën2Ãxpuò essere xn2. Puoi anche usare Tal posto di 0per salvare sulla virgola. (Inoltre, sentiti libero di unirti a noi nella chat room di Japt se hai domande o desideri aiuto con il golf :-))
ETHproductions

@ETHproductions Grazie ancora, specialmente per il Ttrucco, non sapevo che potresti (ab) usare le variabili per questo, è molto utile. La funzione automatica xn2sembra un po 'strana una volta compilata, x("n", 2)quindi penso che ci vorrà ancora un po' prima di comprendere appieno la logica dietro di loro. Con il tuo aiuto, la soluzione Japt è ora legata per prima cosa con la risposta Jelly .
Nit

ETHproductions ha recentemente fatto una scorciatoia per n2: Í. Non ha ancora colpito TIO, ma puoi usarlo qui: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver

@Oliver Wow, questo è un margine molto sanguinante, che non è nemmeno ancora coperto nel riferimento alle scorciatoie dell'interprete. Molte grazie!
Nit

2

Gelatina , 16 15 byte

-1 byte grazie a Dennis (non è necessario appiattire di 1 quando un appiattimento completo va bene - sostituire ;/con F)

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

Provalo online!

Come?

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
;/può essere sostituito con F.
Dennis,

2

PHP, 116 byte

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

Versione online

PHP, 117 byte

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

Provalo online!

PHP, 120 byte

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;

Provalo online!

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]));


1

[F #], 249 245 byte

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

Provalo online!

Nota: la versione su tio.run ha "sistema aperto" nell'intestazione, ho aggiunto il suo conteggio al codice sopra. Non sono sicuro di quali siano le regole sulle importazioni.

Ungolfed

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

se open Systemè uguale a C # s using System;allora sì, è necessario includerlo nel conteggio. Se riesci a farlo in F #, potresti qualificarti a tutto ciò che Systemserve. Ad esempio, in C # System.Console...anzichéusing System;Console...
TheLethalCoder

@TheLethalCoder È lo stesso, sì. Inoltre, grazie per aver chiarito questo :) Ho optato per la versione "open .." perché non è solo String, ma anche Converti che vive in quello spazio dei nomi.
Brunner,


0

J , 34 byte

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

Provalo online!

Spiegazione

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

matematica 193 byte

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)&

È possibile salvare 7 byte eseguendo f=FromDigits;l=Flatten;all'inizio, quindi sostituendo tutte le istanze di queste due funzioni con fe l.
numbermaniac,

0

J , 40 byte

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

utilizzo:

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

restituisce 44


0

Clojure, 150 byte

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

Beh, speravo che la conversione da ASCII a byte fosse più breve di così. Il corpo del loop effettivo è piuttosto breve, usando rper accumulare il risultato corrente e Rper accumulare il risultato totale. Se il bit precedente pè 0e il bit corrente cè 1quindi suddividiamo un nuovo pezzo e ci accumuliamo R, altrimenti aggiorniamo re manteniamo Rcom'era.


0

Python 123 byte

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

Aggiornato, grazie a Martin Ender.


1
Benvenuti in PPCG! Tutte le risposte devono essere programmi completi o funzioni richiamabili (al contrario dei frammenti in cui l'input è memorizzato in una variabile codificata). La funzione può essere senza nome, tuttavia, quindi includere un lambda w:sarebbe sufficiente per rendere valida la tua risposta.
Martin Ender,

Mi dispiace, probabilmente non ho detto bene. La modifica non è ancora valida perché a) l'input è codificato, b) Se si tratta di un programma completo, in realtà non stampa il risultato. Per un programma completo dovresti leggere l'input dall'input standard o un argomento della riga di comando e stampare il risultato sull'output standard. Ecco perché ho detto che probabilmente è più semplice se lo invii come funzione aggiungendo lambda w:.
Martin Ender,

Ohhh, ok, ho capito, sarebbe abbastanza così: 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ì, è valido. Non è nemmeno necessario il f=, perché consentiamo funzioni senza nome (a meno che non si faccia riferimento al nome della funzione per le chiamate ricorsive).
Martin Ender,

0

K (oK) , 31 byte

Soluzione:

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

Provalo online!

Esempi:

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

Spiegazione:

Converti in valori ASCII, converti in binario a 7 bit, appiattisci, trova dove differisce e rispetto all'elenco originale per trovare dove 1differiscono. Taglia a questi indici, converti nuovamente in decimale e riassumi:

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

indennità

Gestita una versione a 31 byte anche in K4 , ma poiché non esiste un TIO per questo sto pubblicando la mia soluzione oK.

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

0

APL (Dyalog) , 30 byte

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

Provalo online!

Come?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - codifica ciascuno in binario

¯7↑¨ - e pad a sinistra con zeri a 7 posti

- appiattire

1∘+⊆⊢ - partizione auto-aumentata di uno

2⊥¨ - decodifica ciascuno dal binario

+/ - somma

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.