Обчисліть двійкову розділену суму слова


22

Візьміть рядок, sщо містить вхідні символи ASCII для друку, і виведіть його "двійкову розділену суму". Потрібно пояснення?

Як ви отримуєте двійкову суму розбиття?

Ми будемо використовувати рядок A4як приклад у наступному поясненні.

  • Перетворіть символи у двійкові, трактуючи кожну букву як 7-бітний символ ASCII

    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
    

Отже, вихід для рядка A4повинен бути 44.


Тестові приклади:

a
49

A4
44

codegolf
570

Hello, World!
795

2
Я думаю, що це було б приємніше завдання без кроку перетворення ASCII, просто взявши (десятковий) номер після кроку 2 як вхідний.
xnor

Ну, 8372власне.
xnor

1
@xnor, ти можеш мати рацію, і це було б чистіше. Мені було весело вирішувати це в Октаві, і я сподіваюся, що і іншим сподобається його вирішити :)
Стюі Гріффін

Відповіді:


12

Пітон 2 , 86 81 76 байт

-5 байт дякую Аднану
-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.

Я раніше пропустив цей трюк перетворення бази.
Джонатан Аллан

Ах, приємний трюк справді!
Аднан

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 (а не 256 у відповіді, яку я написав).

Спробуйте в Інтернеті!

Як?

Çž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 Я думаю, що більше байта!
Ніл

Oo, n i 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 та Oliver .

Спробуйте це тут.


Тут ви можете використовувати більше автоматичних функцій: òÈ<YÃможна ò<(з пробілом), а Ën2Ãxможна xn2. Ви також можете використовувати Tзамість, 0щоб зберегти на комі. (Також не соромтесь приєднатися до нас у чаті Japt, якщо у вас виникнуть запитання чи ви хочете допомогти у
гольфі

@ETHproductions Ще раз дякую, особливо за Tтрюк, не знав, що ти можеш (аб) використовувати для цього змінні, це дуже зручно. Автомобільна функція xn2виглядає дещо дивно, коли компілюється, x("n", 2)тому я думаю, що це все ще займе трохи, перш ніж я повністю зрозумію логіку, що їх лежить. З вашою допомогою рішення Japt тепер прив'язується до першого місця з відповіддю на Jelly .
Ніт

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.
Денніс

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 має "відкриту систему" у заголовку, я додав її кількість до коду вище. Я не впевнений, які правила щодо імпорту.

Безумовно

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, але й конвертувати, що живуть у цьому просторі імен.
Бруннер


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

математика 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

J , 40 байт

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

використання:

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

повертає 44


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

Оновлено, завдяки Мартіну Ендеру.


1
Ласкаво просимо до PPCG! Усі відповіді повинні бути або повноцінними програмами, або функціями, що викликаються (на відміну від фрагментів, де вхід зберігається у твердо кодованій змінній). Однак функцію можна не називати, тому включення а lambda w:буде достатньо, щоб відповідь була дійсною.
Мартін Ендер

Вибачте, я, мабуть, не так добре висловився. Ваша редакція все ще недійсна, оскільки: а) вхід жорстко закодований; б) Якщо це повноцінна програма, вона фактично не друкує результат. Для повної програми вам доведеться прочитати вхід зі стандартного вводу чи аргументу командного рядка та надрукувати результат на стандартний вихід. Тому я сказав, що це, мабуть, найпростіше, якщо ви подаєте його як функцію, додавши lambda w:.
Мартін Ендер

Ой, добре, я розумію, цього було б досить: f = lambda w: sum (map (lambda x: int (x, 2), "". Join (map (lambda x: bin (ord (x) ) [2:]. Zfill (7), список (w))) .замінити ("01", "0: 1"). Split (":")))
ShadowCat

так, це дійсно. Вам навіть не потрібні f=, тому що ми дозволяємо неназвані функції (якщо ви не посилаєтесь на ім’я функції для рекурсивних дзвінків).
Мартін Ендер

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-бітний двійковий, вирівняти, знайти, де відрізняється, та проти оригінального списку, щоб знайти, де 1s відрізняються. Виріжте ці показники, перетворіть їх у десятковий і підсумовуйте:

+/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⊥¨ - декодувати кожен з двійкових

+/ - сума

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.