Вычислить двоичную сумму деления слова


22

Возьмите строку, sсодержащую печатные символы ASCII в качестве входных данных, и выведите ее «двоичную сумму деления». Нужно объяснение?

Как вы получаете двоичную сумму?

Мы будем использовать строку A4в качестве примера в следующем объяснении.

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

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Объединить двоичные числа в новое двоичное число

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Разбейте новое двоичное число на куски, где ни один не 1может иметь 0слева от себя. Вы не должны разделять последовательные 1строки.

    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

Python 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 от ответа Adnan 05ab1e (а не 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$&'))я думаю, вы можете использовать мой метод замены для сохранения байта
Конор О'Брайен,

1
@ ConorO'Brien Больше, чем байт, я думаю!
Нил

Oo, n i c e: D
Конор О'Брайен

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, используемое в других ответах, но заполнение нулями было короче.

Благодаря ETHproductions и Оливеру удалось избавиться от целых 6 байт .

Попробуйте это здесь.


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

@ETHproductions Еще раз спасибо, особенно за Tтрюк, не знал, что вы можете (ab) использовать переменные для этого, это очень удобно. Авто-функция xn2выглядит немного странно при компиляции, x("n", 2)поэтому я думаю, что пройдет еще немного времени, прежде чем я полностью пойму логику, стоящую за ними. С вашей помощью решение Japt теперь связано с ответом Jelly на первое место .
Нит

ETHproductions недавно сделал ярлык n2: Í. Он еще не попал в TIO, но вы можете использовать его здесь: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Оливер

@ Оливер Вау, это очень круто, это еще даже не упомянуто в справочнике по ярлыкам переводчика. Большое спасибо!
Нить

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 имеет «открытую систему» ​​в заголовке, я добавил ее количество в код выше. Я не уверен, каковы правила импорта.

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 #, using System;то да, вам нужно включить его в счетчик. Если вы можете сделать это в F #, вы можете полностью квалифицироваться, для чего Systemон предназначен. Например, в C # System.Console...вместоusing System;Console...
TheLethalCoder

@TheLethalCoder То же самое, да. Кроме того, спасибо за разъяснение этого :) Я выбрал версию "open ..", потому что это не только String, но и Convert, которые живут в этом пространстве имен.
Бруннер


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

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), list (w))). Replace ("01", "0: 1"). Split (":")))
ShadowCat

да, это верно. Вам даже не нужно f=, потому что мы разрешаем безымянные функции (если вы не ссылаетесь на имя функции для рекурсивных вызовов).
Мартин Эндер

0

K (ок) , 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различий и сравнение с исходным списком для поиска различий s. Вырежьте по этим показателям, переведите обратно в десятичную и суммируйте:

+/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 для нее нет, я публикую свое решение ОК.

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