คำนวณผลรวมการแยกไบนารีของคำ


22

ใช้สตริงsที่มีอักขระ ASCII ที่พิมพ์ได้เป็นอินพุตและเอาต์พุต "ผลรวมการแยกไบนารี" ต้องการคำอธิบาย?

คุณจะได้รับผลรวมการแยกไบนารีได้อย่างไร

เราจะใช้สตริงA4เป็นตัวอย่างในคำอธิบายต่อไปนี้

  • แปลงอักขระเป็นไบนารีโดยใช้ตัวอักษรแต่ละตัวเป็นอักขระ ASCII 7 บิต

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • ต่อเลขฐานสองเข้ากับเลขฐานสองใหม่

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • แยกเลขฐานสองใหม่ออกเป็นส่วน ๆ โดยที่ไม่มี1ทาง0ไปทางซ้าย คุณไม่ควรแยก1s

    10000010110100 -> 100000, 10, 110, 100
    
  • แปลงเลขฐานสองเหล่านี้เป็นทศนิยม

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • หาผลรวมของตัวเลขเหล่านี้:

    32 + 2 + 6 + 4 = 44
    

ดังนั้นผลลัพธ์สำหรับสตริงควรจะเป็นA444


กรณีทดสอบ:

a
49

A4
44

codegolf
570

Hello, World!
795

2
ฉันคิดว่านี่น่าจะเป็นความท้าทายที่ดีกว่าหากไม่มีขั้นตอนการแปลง ASCII เพียงป้อนหมายเลข (ทศนิยม) หลังจากขั้นตอนที่ 2 เป็นอินพุต
XNOR

ที่8372จริงแล้ว
xnor

1
@ xnor คุณอาจพูดถูกและจะสะอาดกว่า แม้ว่าฉันจะสนุกกับการแก้ปัญหานี้ใน Octave และฉันหวังว่าคนอื่นจะสนุกกับการแก้มันด้วย :)
Stewie Griffin

คำตอบ:


12

Python 2 , 86 81 76 ไบต์

-5 ไบต์ขอบคุณ Adnan
-5 ไบต์ขอบคุณ xnor

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

ลองออนไลน์!

for c in input():s=s*128+ord(c)เพื่อทำการแปลง ASCII เป็นตัวเลขโดยที่*128จะใช้การเลื่อนซ้ายs7 ครั้ง (ขั้นตอนที่ 1 และ 2)
eval(('0'+new_bin).replace('01','0+0b1'))เพื่อแยกและรวม (ขั้นตอนที่ 3, 4 และ 5)


เคล็ดลับที่ดีกับeval! การทำการแปลง ASCIIจะบันทึกตัวเลขบางไบต์
xnor

7

เยลลี่ขนาด 13 ไบต์

Oḅ128BŒg;2/ḄS

ลองออนไลน์!

มันทำงานอย่างไร

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.

ฉันพลาดกลอุบายของการแปลงฐานมาก่อน
Jonathan Allan

Ah, เคล็ดลับที่ดีแน่นอน!
Adnan

6

MATL , 14 ไบต์

YB!'1+0*'XXZBs

ลองออนไลน์!

คำอธิบาย

พิจารณาการป้อนข้อมูล'A4'เป็นตัวอย่าง

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 ไบต์

รหัส:

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

คำอธิบาย:

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

ใช้การเข้ารหัส05AB1E ลองออนไลน์!


5

05AB1E , 14 ไบต์

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

พอร์ตคำตอบ Jelly ของฉันโดยใช้ 128 ออฟเซ็ตจากคำตอบ 05ab1e ของ Adnan (แทนที่จะเป็น 256 ในคำตอบ Jelly ที่ฉันเขียน)

ลองออนไลน์!

อย่างไร?

Çž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 ไบต์

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

แก้ไข: บันทึก 5 ไบต์ด้วยความช่วยเหลือจาก @ ConorO'Brien


วิธีการแก้ปัญหาของฉันคือ 97 ไบต์เช่นกัน: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))คุณสามารถใช้วิธีการเปลี่ยนของฉันเพื่อบันทึกไบต์ฉันคิดว่า
Conor O'Brien

1
@ ConorO'Brien มากกว่าหนึ่งไบต์ฉันคิดว่า!
Neil

Oo, n ฉัน c e: D
Conor O'Brien

3

Japt , 18 12 ไบต์

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.

รับอินพุตเป็นสตริงเดี่ยว
ฉันยังลองใช้คำตอบอื่น ๆ เพิ่ม 128 หรือ 256 ที่ใช้ แต่การ 0-padding นั้นสั้นกว่าที่จะใช้

โกนมหันต์ 6 ทั้งไบต์ขอบคุณที่ETHproductionsและโอลิเวอร์

ลองที่นี่


คุณสามารถใช้ฟังก์ชั่นอัตโนมัติที่นี่: òÈ<YÃสามารถò<(มีต่อท้ายพื้นที่) และสามารถËn2Ãx xn2นอกจากนี้คุณยังสามารถใช้Tแทน0เครื่องหมายจุลภาคได้ (และอย่าลังเลที่จะเข้าร่วมกับเราในห้องแชท Japtถ้าคุณมีคำถามหรือต้องการความช่วยเหลือเกี่ยวกับการเล่นกอล์ฟ :-))
ETHproductions

@ETHproductions ขอขอบคุณอีกครั้งโดยเฉพาะอย่างยิ่งสำหรับTเคล็ดลับไม่ทราบว่าคุณสามารถ (ab) ใช้ตัวแปรสำหรับสิ่งนั้นมันมีประโยชน์มาก ฟังก์ชั่นอัตโนมัตินั้นxn2ดูแปลก ๆ เมื่อทำการคอมไพล์x("n", 2)ดังนั้นฉันคิดว่ามันคงต้องใช้เวลาซักหน่อยก่อนที่ฉันจะเข้าใจตรรกะที่อยู่ข้างหลังพวกเขาอย่างเต็มที่ ด้วยความช่วยเหลือของคุณโซลูชัน Japt จะเชื่อมโยงกับคำตอบของเยลลี่เป็นที่แรก
นิด

ETHproductions เพิ่งทำทางลัดสำหรับ:n2 Íยังไม่ได้กด TIO แต่คุณสามารถใช้งานได้ที่นี่: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/ …
โอลิเวอร์

@Oliver ว้าวมันขอบเลือดออกมากซึ่งยังไม่ครอบคลุมในการอ้างอิงทางลัดสำหรับล่ามเลย ขอบคุณมาก!
นิตย์

2

เยลลี่ , 16 15 ไบต์

-1 ไบต์ขอบคุณเดนนิส (ไม่จำเป็นต้องแบน 1 เมื่อแบนเต็มปรับ - แทนที่;/ด้วยF)

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

ลองออนไลน์!

อย่างไร?

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
;/Fสามารถถูกแทนที่ด้วย
Dennis

2

PHP, 116 ไบต์

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

เวอร์ชั่นออนไลน์

PHP, 117 ไบต์

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

ลองออนไลน์!

PHP, 120 ไบต์

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;

ลองออนไลน์!

หรือ

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 ไบต์

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

ลองออนไลน์!

หมายเหตุ: เวอร์ชันของ tio.run มี "open System" ในส่วนหัวฉันได้เพิ่มการนับลงในรหัสด้านบน ฉันไม่แน่ใจว่ากฎนั้นเกี่ยวกับการนำเข้า

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

หากopen Systemเป็นเช่นเดียวกับ C # s using System;ใช่คุณต้องรวมไว้ในการนับ หากคุณสามารถทำได้ใน F # คุณสามารถมีคุณสมบัติได้อย่างเต็มที่สิ่งที่Systemมีไว้สำหรับ ตัวอย่างเช่นใน C # System.Console...แทนusing System;Console...
TheLethalCoder

@TheLethalCoder เหมือนกันใช่ นอกจากนี้ขอขอบคุณที่ชี้แจงเรื่องนี้ :) ฉันเลือกใช้รุ่น "open .. " เพราะไม่เพียง แต่เป็น String แต่ยังแปลงที่อยู่ในเนมสเปซนั้นด้วย
Brunner

0

Perl 6 , 62 ไบต์

{sum map {:2(~$_)},.comb».ord».fmt('%07b').join~~m:g/11*0*/}

ใช้แทน.ords .comb».ordคำนำหน้ามักจะสามารถนำมาใช้แทน[~] มีอยู่ซึ่งทำสิ่งนี้ สามารถลงไป ฉันมาด้วย.joincombm:g/…/11*0*//1+0*/{sum map {:2($_)},comb /1+0*/,[~] .ords».fmt('%07b')}
แบรดกิลเบิร์ต b2gills

0

J , 34 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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

mathematica 193 ไบต์

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

คุณสามารถบันทึก 7 ไบต์โดยทำf=FromDigits;l=Flatten;ในช่วงเริ่มต้นและจากนั้นเปลี่ยนทุกกรณีของทั้งสองฟังก์ชั่นด้วยและf l
numbermaniac


0

Clojure 150 ไบต์

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

ฉันหวังว่าการแปลงจาก ASCII เป็นไบต์จะสั้นกว่านี้ ร่างกายลูปที่เกิดขึ้นจริงค่อนข้างสั้นใช้rเพื่อสะสมผลลัพธ์ปัจจุบันและRเพื่อสะสมผลรวม ถ้าบิตก่อนหน้าpนี้0และบิตปัจจุบันcคือ1เราแบ่งแบ่งอันใหม่และสะสมเป็นRมิฉะนั้นเราจะอัปเดตrและเก็บRตามเดิม


0

Python 123 ไบต์

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

อัปเดตต้องขอบคุณ Martin Ender


1
ยินดีต้อนรับสู่ PPCG! คำตอบทั้งหมดจะต้องเป็นโปรแกรมเต็มรูปแบบหรือฟังก์ชั่นที่เรียกได้ (ตรงข้ามกับตัวอย่างที่เก็บข้อมูลไว้ในตัวแปร hardcoded) แม้ว่าจะไม่มีชื่อฟังก์ชั่นก็ตามดังนั้นการรวมถึง a lambda w:ก็เพียงพอที่จะทำให้คำตอบของคุณถูกต้อง
Martin Ender

ขออภัยฉันอาจไม่ได้วลีที่ดี การแก้ไขของคุณยังไม่ถูกต้องเนื่องจากก) อินพุตถูกฮาร์ดโค้ด b) หากนี่เป็นโปรแกรมเต็มรูปแบบจะไม่ได้พิมพ์ผลลัพธ์จริง สำหรับโปรแกรมแบบเต็มคุณจะต้องอ่านอินพุตจากอินพุตมาตรฐานหรืออาร์กิวเมนต์บรรทัดคำสั่งแล้วพิมพ์ผลลัพธ์ไปยังเอาต์พุตมาตรฐาน lambda w:นั่นเป็นเหตุผลที่ผมบอกว่ามันอาจจะง่ายที่สุดถ้าคุณส่งเป็นฟังก์ชั่นโดยการเพิ่ม
Martin Ender

โอ้เข้าใจแล้วฉันเข้าใจแล้วมันจะเพียงพอเช่นนี้: f = lambda w: sum (แผนที่ (lambda x: int (x, 2), "". เข้าร่วม (แผนที่ (lambda x: bin (ord (x)) ) [2:]. zfill (7), รายการ (w))). แทนที่ ("01", "0: 1"). split (":")))
ShadowCat

ใช่มันถูกต้อง คุณไม่จำเป็นต้องมีf=เพราะเราอนุญาตให้ใช้งานฟังก์ชั่นที่ไม่มีชื่อ (เว้นแต่คุณจะอ้างอิงชื่อฟังก์ชั่นสำหรับการโทรซ้ำ)
Martin Ender

0

K (oK) , 31 ไบต์

วิธีการแก้:

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

ลองออนไลน์!

ตัวอย่าง:

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

คำอธิบาย:

แปลงเป็นค่า ASCII, แปลงเป็นเลขฐานสอง 7 บิต, แผ่, ค้นหาตำแหน่งที่แตกต่าง, และเทียบกับรายการต้นฉบับเพื่อหาจุดที่1แตกต่าง ตัดที่ดัชนีเหล่านี้แปลงกลับเป็นทศนิยมและสรุป:

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

โบนัส

จัดการรุ่น31 ไบต์ในK4ด้วย แต่เนื่องจากไม่มี TIO สำหรับฉันฉันโพสต์โซลูชั่นของฉัน oK

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

0

APL (Dyalog) 30 ไบต์

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

ลองออนไลน์!

อย่างไร?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - เข้ารหัสแต่ละรายการในไบนารี

¯7↑¨ - และปัดไปทางซ้ายด้วยเลขศูนย์ถึง 7 ตำแหน่ง

- แบน

1∘+⊆⊢ - แบ่งพาร์ติชันด้วยตนเองเพิ่มขึ้นทีละหนึ่ง

2⊥¨ - ถอดรหัสแต่ละตัวจากไบนารี

+/ - ผลรวม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.