Hitung jumlah biner dari sebuah kata

22

Ambil string, sberisi karakter ASCII yang dapat dicetak sebagai input, dan output "jumlah binernya". Perlu penjelasan?

Bagaimana Anda mendapatkan jumlah biner?

Kami akan menggunakan string A4sebagai contoh dalam penjelasan berikut.

  • Ubah karakter menjadi biner, perlakukan setiap huruf sebagai karakter ASCII 7-bit

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Menggabungkan nomor biner menjadi angka biner baru

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Membagi nomor biner baru menjadi potongan-potongan, di mana tidak ada yang 1bisa 0ke kiri Anda tidak boleh membagi secara berurutan 1.

    10000010110100 -> 100000, 10, 110, 100
    
  • Ubah angka biner ini menjadi desimal

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Ambil jumlah dari angka-angka ini:

    32 + 2 + 6 + 4 = 44
    

Jadi, output untuk string A4seharusnya 44.


Kasus uji:

a
49

A4
44

codegolf
570

Hello, World!
795
Stewie Griffin
sumber
2
Saya pikir ini akan menjadi tantangan yang lebih baik tanpa langkah konversi ASCII, hanya mengambil nomor (desimal) setelah langkah 2 sebagai masukan.
xnor
Yah, 8372sebenarnya.
xnor
1
@ xnor, Anda mungkin benar, dan itu akan lebih bersih. Saya senang menyelesaikan ini dalam Oktaf, dan saya berharap orang lain akan menikmati pemecahannya juga :)
Stewie Griffin

Jawaban:

12

Python 2 , 86 81 76 byte

-5 byte terima kasih Adnan
-5 byte terima kasih xnor

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

Cobalah online!

for c in input():s=s*128+ord(c)untuk melakukan konversi ASCII secara numerik, di mana *128digunakan untuk meninggalkan shift s7 kali (langkah 1 dan 2)
eval(('0'+new_bin).replace('01','0+0b1'))untuk membagi dan menjumlahkan (langkah 3, 4 dan 5)

tongkat
sumber
Trik yang bagus dengan eval! Melakukan konversi ASCII secara numerik menghemat beberapa byte.
xnor
7

Jelly , 13 byte

Oḅ128BŒg;2/ḄS

Cobalah online!

Bagaimana itu bekerja

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
sumber
Saya telah melewatkan trik konversi basis sebelumnya.
Jonathan Allan
Ah, trik yang bagus!
Adnan
6

MATL , 14 byte

YB!'1+0*'XXZBs

Cobalah online!

Penjelasan

Pertimbangkan input 'A4'sebagai contoh.

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
sumber
5

05AB1E , 18 byte

Kode:

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

Penjelasan:

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

Menggunakan penyandian 05AB1E . Cobalah online!

Adnan
sumber
5

05AB1E , 14 byte

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

Port jawaban Jelly saya , menggunakan offset 128 dari jawaban Adabab's 05ab1e (bukan 256 dalam jawaban Jelly yang saya tulis).

Cobalah online!

Bagaimana?

Çž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
sumber
3

JavaScript (ES6), 97 92 byte

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

Sunting: Disimpan 5 byte dengan bantuan dari @ ConorO'Brien.

Neil
sumber
Solusi saya sendiri adalah 97 byte, juga: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))Anda dapat menggunakan metode ganti saya untuk menghemat satu byte, saya kira
Conor O'Brien
1
@ ConorO'Brien Lebih dari satu byte, saya pikir!
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.

Mengambil input sebagai string tunggal.
Saya juga mencoba penambahan 128 atau 256 yang digunakan oleh jawaban lain, tetapi 0-padding lebih pendek untuk digunakan.

Mencukur 6 byte total berkat produk ETH dan Oliver .

Cobalah di sini.

Nit
sumber
Anda dapat menggunakan lebih banyak fungsi-otomatis di sini: òÈ<YÃbisa ò<(dengan spasi tambahan), dan Ën2Ãxbisa xn2. Anda juga dapat menggunakan Tdi tempat 0untuk menghemat koma. (Juga, silakan bergabung dengan kami di chatroom Japt jika Anda memiliki pertanyaan atau ingin membantu bermain golf :-))
ETHproductions
@ ETHproductions Terima kasih lagi, terutama untuk Ttriknya, tidak tahu Anda bisa (ab) menggunakan variabel untuk itu, itu sangat berguna. Fungsi-otomatisnya xn2terlihat agak aneh ketika dikompilasi, x("n", 2)jadi saya pikir ini masih akan memakan waktu sebelum saya sepenuhnya memahami logika di belakangnya. Dengan bantuan Anda, solusi Japt sekarang diikat untuk tempat pertama dengan jawaban Jelly .
Nit
ETHproductions baru ini membuat jalan pintas untuk n2: Í. Itu belum mengenai TIO, tetapi Anda dapat menggunakannya di sini: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver
@ Oliver Wow, itu tepi yang sangat berdarah, yang bahkan belum tercakup dalam referensi pintasan juru bahasa. Terima kasih banyak!
Nit
2

Jelly , 16 15 byte

-1 byte berkat Dennis (tidak perlu diratakan oleh 1 ketika rata penuh baik-baik saja - ganti ;/dengan F)

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

Cobalah online!

Bagaimana?

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
sumber
1
;/dapat diganti dengan 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 Online

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

Cobalah online!

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;

Cobalah online!

atau

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
sumber
1

Pyth , 21 byte

Itu terlalu panjang ...

siR2:.BiCMQ128"1+0+"1

Suite uji.

Biarawati Bocor
sumber
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

Cobalah online!

Catatan: versi pada tio.run memiliki "Sistem terbuka" di header, saya telah menambahkan hitungannya ke kode di atas. Saya tidak yakin apa aturan impornya.

Tidak disatukan

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
sumber
jika open Systemsama dengan C # s using System;maka ya Anda harus memasukkannya dalam hitungan. Jika Anda dapat melakukannya di F #, Anda sepenuhnya dapat memenuhi syarat untuk apa pun System. Misalnya, dalam C # System.Console...alih-alihusing System;Console...
TheLethalCoder
@TheLethalCoder Sama saja, ya. Juga, terima kasih telah menjelaskan ini :) Saya memilih versi "terbuka .." karena bukan hanya String, tetapi juga Konversi yang langsung ada di namespace itu.
Brunner
0

Perl 6 , 62 byte

{sum map {:2(~$_)},.comb».ord».fmt('%07b').join~~m:g/11*0*/}
Sean
sumber
gunakan .ordssebagai ganti .comb».ord. awalan [~]sering dapat digunakan sebagai gantinya .join. combada yang melakukan m:g/…hal itu. /11*0*/dapat disingkat menjadi /1+0*/. Saya datang dengan{sum map {:2($_)},comb /1+0*/,[~] .ords».fmt('%07b')}
Brad Gilbert b2gills
0

J , 34 byte

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

Cobalah online!

Penjelasan

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

Mathematica 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)&
J42161217
sumber
Anda dapat menyimpan 7 byte dengan melakukan f=FromDigits;l=Flatten;di awal, dan kemudian mengganti semua instance dari kedua fungsi tersebut dengan fdan l.
numbermaniac
0

J , 40 byte

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

pemakaian:

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

pengembalian 44

protista
sumber
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)))

Yah saya berharap konversi dari ASCII ke byte lebih pendek dari ini. Badan loop aktual cukup pendek, digunakan runtuk mengakumulasi hasil saat ini dan Runtuk mengakumulasi hasil total. Jika bit sebelumnya padalah 0dan bit saat cini 1maka kami membagi sepotong baru dan menumpuk R, jika tidak, kami memperbarui rdan tetap Rseperti itu.

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

Diperbarui, terima kasih kepada Martin Ender.

Kucing bayangan
sumber
1
Selamat datang di PPCG! Semua jawaban harus berupa program lengkap atau fungsi yang dapat dipanggil (sebagai lawan dari snippet di mana input disimpan dalam variabel hardcoded). Fungsi ini dapat dinamai, jadi termasuk a lambda w:akan cukup untuk membuat jawaban Anda valid.
Martin Ender
Maaf, saya mungkin tidak bisa mengucapkannya dengan baik. Hasil edit Anda masih tidak valid karena a) input hardcoded, b) Jika ini adalah program lengkap, itu sebenarnya tidak mencetak hasilnya. Untuk program lengkap Anda harus membaca input dari input standar atau argumen baris perintah, dan mencetak hasilnya ke output standar. Itu sebabnya saya mengatakan itu mungkin paling mudah jika Anda mengirimkannya sebagai fungsi dengan menambahkan lambda w:.
Martin Ender
Ohhh, Ok, saya mengerti, itu akan cukup seperti ini: f = lambda w: sum (peta (lambda x: int (x, 2), "". Join (peta (lambda x: bin (ord (x)) ) [2:]. Zfill (7), daftar (w))) ganti ("01", "0: 1"). Split (":")))
ShadowCat
ya, itu benar. Anda bahkan tidak memerlukannya f=, karena kami mengizinkan fungsi yang tidak disebutkan namanya (kecuali jika Anda merujuk nama fungsi untuk panggilan rekursif).
Martin Ender
0

K (oK) , 31 byte

Larutan:

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

Cobalah online!

Contoh:

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

Penjelasan:

Konversikan ke nilai ASCII, konversikan ke biner 7-bit, ratakan, temukan tempat berbeda, dan terhadap daftar asli untuk menemukan di mana 1s berbeda. Potong pada indeks ini, konversikan kembali ke desimal dan jumlahkan:

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

Bonus

Mengelola versi 31 byte di K4 juga, tetapi karena tidak ada TIO untuk itu saya memposting solusi OK saya.

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

APL (Dyalog) , 30 byte

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

Cobalah online!

Bagaimana?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - menyandikan masing-masing dalam biner

¯7↑¨ - dan pad ke kiri dengan nol ke 7 tempat

- Ratakan

1∘+⊆⊢ - Partisi sendiri meningkat satu

2⊥¨ - decode masing-masing dari biner

+/ - jumlah

Uriel
sumber