计算一个单词的二进制拆分和


22

取一个s包含可打印ASCII字符的字符串作为输入,并输出其“二进制分割和”。需要解释吗?

如何获得二进制分割和?

A4在下面的说明中,我们将以字符串为例。

  • 将字符转换为二进制,将每个字母视为7位ASCII字符

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • 将二进制数连接成新的二进制数

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • 将新的二进制数字拆分为多个块,在其左边1不能有a 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,您可能是对的,它会更干净。我在Octave中解决了这个问题,但我也很开心,我希望其他人也能解决这个问题:)
Stewie Griffin

Answers:


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.

我以前错过了基本转换的技巧。
乔纳森·艾伦

啊,的确不错!
阿德南

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编码。在线尝试!



3

JavaScript(ES6),97 92字节

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

编辑:在@ ConorO'Brien的帮助下保存了5个字节。


我自己的解决方案也是97个字节:s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))我认为您可以使用我的replace方法保存一个字节
Conor O'Brien

1
@ ConorO'Brien我想不止一个字节!
尼尔

Oo,néc:e
Conor O'Brien

3

Japt18 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填充的时间较短。

多亏ETHproductionsOliver 削减了整个6个字节。

在这里尝试。


您可以在此处使用更多自动功能:òÈ<YÃ可以ò<(带有尾随空格),Ën2Ãx可以是xn2。您也可以使用T代替0来保存逗号。(另外,随时加入我们的Japt聊天室,如果你有问题或想与高尔夫:-)帮助)
ETHproductions

@ETHproductions再次感谢您,尤其是T技巧,不知道您可以为此使用变量,这非常方便。自动功能xn2在编译时看起来有些怪异x("n", 2),所以我认为在完全理解它们背后的逻辑之前还需要一些时间。在您的帮助下,Japt解决方案现在与Jelly答案并列第一。
Nit

ETHproductions最近为n2:提供了一个捷径Í。它尚未达到TIO,但您可以在这里使用它:ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver

@Oliver Wow,这是一个非常令人毛骨悚然的优势,解释器快捷方式参考中甚至都没有涉及。非常感谢!
Nit

2

果冻16 15 字节

感谢丹尼斯(Dennis)-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#],249245字节

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”,我已将其计数添加到上面的代码中。我不确定进口的规则是什么。

不打高尔夫球

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 '17

@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;的开始,然后用替代的这两个函数的所有实例fl
numbermaniac '17

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累积总结果。如果前一位p0,而当前位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!所有答案都必须是完整程序或可调用函数(与片段存储在硬编码变量中的片段相反)。但是,该函数可以是未命名的,因此包含a lambda w:就足以使您的答案有效。
马丁·恩德

抱歉,我说的可能不太好。您的编辑仍然无效,因为a)输入是硬编码的,b)如果这是一个完整的程序,它实际上不会打印结果。对于完整的程序,您必须从标准输入或命令行参数读取输入,并将结果打印到标准输出。这就是为什么我说,如果您通过添加将它作为函数提交,那可能是最简单的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=,因为我们允许使用未命名的函数(除非您为递归调用引用函数名)。
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位二进制,展平,查找不同之处,然后针对原始列表查找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

奖金

K4中也管理了一个31字节的版本,但是由于没有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⊥¨ -从二进制解码每个

+/ -总和

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.