Tính tổng số nhị phân của một từ


22

Lấy một chuỗi, schứa các ký tự ASCII có thể in làm đầu vào và xuất "tổng tách nhị phân" của nó. Cần một lời giải thích?

Làm thế nào để bạn có được tổng số nhị phân?

Chúng tôi sẽ sử dụng chuỗi A4làm ví dụ trong phần giải thích sau.

  • Chuyển đổi các ký tự thành nhị phân, coi mỗi chữ cái là ký tự ASCII 7 bit

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Ghép các số nhị phân thành một số nhị phân mới

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Chia số nhị phân mới thành các khối, trong đó không 1thể có một 0bên trái của nó. Bạn không nên chia 1s liên tiếp .

    10000010110100 -> 100000, 10, 110, 100
    
  • Chuyển đổi các số nhị phân này thành số thập phân

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Lấy tổng của các số này:

    32 + 2 + 6 + 4 = 44
    

Vì vậy, đầu ra cho chuỗi A4nên được 44.


Các trường hợp thử nghiệm:

a
49

A4
44

codegolf
570

Hello, World!
795

2
Tôi nghĩ rằng đây sẽ là một thử thách đẹp hơn nếu không có bước chuyển đổi ASCII, chỉ lấy số (thập phân) sau bước 2 làm đầu vào.
xnor

Vâng, 8372thực sự.
xnor

1
@xnor, bạn có thể đúng, và nó sẽ sạch hơn. Mặc dù vậy, tôi rất vui khi giải quyết vấn đề này trong Octave và tôi hy vọng những người khác cũng sẽ thích giải quyết nó :)
Stewie Griffin

Câu trả lời:


12

Python 2 , 86 81 76 byte

-5 byte cảm ơn Adnan
-5 byte cảm ơn xnor

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

Hãy thử trực tuyến!

for c in input():s=s*128+ord(c)để thực hiện chuyển đổi ASCII bằng số, trong đó *128được sử dụng để dịch chuyển trái s7 lần (bước 1 và 2)
eval(('0'+new_bin).replace('01','0+0b1'))để phân chia và tính tổng (bước 3, 4 và 5)


Thủ thuật hay với eval! Thực hiện chuyển đổi ASCII bằng số giúp tiết kiệm một số byte.
xnor

7

Thạch , 13 byte

Oḅ128BŒg;2/ḄS

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

Tôi đã bỏ lỡ thủ thuật chuyển đổi cơ sở trước đây.
Jonathan Allan

Ah, lừa thật đấy!
Ad Nam

6

MATL , 14 byte

YB!'1+0*'XXZBs

Hãy thử trực tuyến!

Giải trình

Hãy xem xét đầu vào 'A4'là một ví dụ.

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

Mã số:

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

Giải trình:

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

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!


5

05AB1E , 14 byte

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

Một cổng của câu trả lời Jelly của tôi , sử dụng offset 128 từ câu trả lời 05ab1e của Adnan (chứ không phải là 256 trong câu trả lời Jelly tôi đã viết).

Hãy thử trực tuyến!

Làm sao?

Çž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$&'))

Chỉnh sửa: Đã lưu 5 byte với một số trợ giúp từ @ ConorO'Brien.


Giải pháp của riêng tôi cũng là 97 byte: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))Bạn có thể sử dụng phương pháp thay thế của tôi để lưu một byte, tôi nghĩ
Conor O'Brien

1
@ ConorO'Brien Hơn một byte, tôi nghĩ vậy!
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.

Đưa đầu vào dưới dạng một chuỗi.
Tôi cũng đã thử bổ sung 128 hoặc 256 được sử dụng bởi các câu trả lời khác, nhưng phần đệm 0 được sử dụng ngắn hơn.

Cạo sạch toàn bộ 6 byte nhờ ETHproductionsOliver .

Hãy thử nó ở đây.


Bạn có thể sử dụng nhiều chức năng tự động hơn ở đây: òÈ<YÃcó thể ò<(có dấu cách) và Ën2Ãxcó thể xn2. Bạn cũng có thể sử dụng Tthay 0cho dấu phẩy. (Ngoài ra, cảm thấy tự do để tham gia với chúng tôi trong các chatroom Japt nếu bạn đã từng có thắc mắc hoặc muốn giúp đỡ với chơi golf :-))
ETHproductions

@ETHproductions Cảm ơn một lần nữa, đặc biệt là về Tmánh khóe, không biết bạn có thể (ab) sử dụng các biến cho điều đó, điều đó rất tiện dụng. Chức năng tự động xn2trông hơi kỳ lạ khi được biên dịch, x("n", 2)vì vậy tôi nghĩ rằng nó vẫn sẽ mất một chút trước khi tôi hoàn toàn hiểu logic đằng sau chúng. Với sự giúp đỡ của bạn, giải pháp Japt hiện đang được gắn với vị trí đầu tiên với câu trả lời Jelly .
Nit

ETHproductions gần đây đã thực hiện một lối tắt cho n2: Í. Nó chưa đạt TIO, nhưng bạn có thể sử dụng nó ở đây: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/ Khăn
Oliver

@Oliver Wow, điều đó rất khó hiểu, thậm chí còn không có trong tài liệu tham khảo các phím tắt thông dịch viên. Cảm ơn rất nhiều!
Nit

2

Thạch , 16 15 byte

-1 byte nhờ Dennis (không cần phải làm phẳng 1 khi hoàn toàn ổn định - thay thế ;/bằng F)

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

Hãy thử trực tuyến!

Làm sao?

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
;/có thể được thay thế bằng 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));

Phiên bản trực tuyến

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

Hãy thử trực tuyến!

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;

Hãy thử trực tuyến!

hoặc là

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

Hãy thử trực tuyến!

Lưu ý: phiên bản trên tio.run có "Hệ thống mở" trong tiêu đề, tôi đã thêm số lượng của nó vào mã ở trên. Tôi không chắc chắn các quy tắc về nhập khẩu.

Bị đánh cắp

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

if open Systemgiống như C # s using System;thì có, bạn cần đưa nó vào số đếm. Nếu bạn có thể làm điều đó trong F #, bạn hoàn toàn có thể đủ điều kiện cho dù đó Systemlà gì. Ví dụ: trong C # System.Console...thay vìusing System;Console...
TheLethalCoder

@TheLethalCoder Cũng vậy, đúng vậy. Ngoài ra, cảm ơn vì đã làm rõ điều này :) Tôi đã chọn phiên bản "mở .." vì đó không chỉ là Chuỗi mà còn Chuyển đổi trực tiếp trong không gian tên đó.
Brunner


0

J , 34 byte

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

Hãy thử trực tuyến!

Giải trình

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

toán học 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)&

Bạn có thể lưu 7 byte bằng cách thực hiện f=FromDigits;l=Flatten;khi bắt đầu và sau đó thay thế tất cả các phiên bản của hai hàm đó bằng fl.
numbermaniac

0

J , 40 byte

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

sử dụng:

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

trả lại 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)))

Vâng, tôi đã hy vọng việc chuyển đổi từ ASCII sang byte ngắn hơn thế này. Phần thân vòng lặp thực tế khá ngắn, sử dụng rđể tích lũy kết quả hiện tại và Rtích lũy tổng kết quả. Nếu các bit trước p0và các bit hiện tại c1sau đó chúng tôi chia một đoạn mới và tích lũy để R, nếu không chúng tôi cập nhật rvà duy trì Rnhư nó đã được.


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

Cập nhật, nhờ Martin Ender.


1
Chào mừng đến với PPCG! Tất cả các câu trả lời cần phải là chương trình đầy đủ hoặc các hàm có thể gọi được (trái ngược với đoạn trích trong đó đầu vào được lưu trữ trong một biến mã hóa cứng). Tuy nhiên, chức năng có thể không được đặt tên, vì vậy bao gồm một lambda w:sẽ đủ để làm cho câu trả lời của bạn hợp lệ.
Martin Ender

Xin lỗi, tôi có lẽ đã không cụm từ đó tốt. Chỉnh sửa của bạn vẫn không hợp lệ vì a) đầu vào bị mã hóa cứng, b) Nếu đây là một chương trình đầy đủ, nó không thực sự in kết quả. Đối với một chương trình đầy đủ, bạn phải đọc đầu vào từ đầu vào tiêu chuẩn hoặc đối số dòng lệnh và in kết quả sang đầu ra tiêu chuẩn. Đó là lý do tại sao tôi nói nó có thể dễ nhất nếu bạn gửi nó dưới dạng hàm bằng cách thêm lambda w:.
Martin Ender

Ohhh, Ok, tôi hiểu rồi, nó sẽ là như thế này: f = lambda w: sum (map (lambda x: int (x, 2), "". Tham gia (map (lambda x: bin (ord (x) ) [2:]. Zfill (7), list (w))). Thay thế ("01", "0: 1"). Split (":")))
ShadowCat

vâng, điều đó hợp lệ. Bạn thậm chí không cần f=, bởi vì chúng tôi cho phép các hàm không tên (trừ khi bạn tham chiếu tên hàm cho các cuộc gọi đệ quy).
Martin Ender

0

K (oK) , 31 byte

Dung dịch:

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

Hãy thử trực tuyến!

Ví dụ:

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

Giải trình:

Chuyển đổi sang giá trị ASCII, chuyển đổi thành nhị phân 7 bit, làm phẳng, tìm nơi khác biệt và so với danh sách ban đầu để tìm nơi 1khác biệt. Cắt tại các chỉ số này, chuyển đổi lại thành số thập phân và tổng hợp:

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

Tiền thưởng

Quản lý một phiên bản 31 byte trong K4 , nhưng vì không có TIO cho nó nên tôi đang đăng giải pháp oK của mình.

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

0

APL (Dyalog) , 30 byte

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

Hãy thử trực tuyến!

Làm sao?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - mã hóa từng cái trong nhị phân

¯7↑¨ - và đệm sang trái với số không đến 7 vị trí

- làm phẳng

1∘+⊆⊢ - phân vùng tự tăng thêm một

2⊥¨ - giải mã từng từ nhị phân

+/ - tổng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.