単語のバイナリ分割合計を計算する


22

文字列を取り、 s入力可能な印刷可能なASCII含むを取得し、その「バイナリ分割合計」を出力します。説明が必要ですか?

バイナリ分割合計はどのように取得しますか?

A4次の説明では、文字列を例として使用します。

  • 文字をバイナリに変換し、各文字を7ビットASCII文字として扱います

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • 2進数を新しい2進数に連結します

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • 新しい2進数をチャンクに分割します。チャンクは左に配置1できません0。連続したを分割しないでください1

    10000010110100 -> 100000, 10, 110, 100
    
  • これらの2進数を10進数に変換します

    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の後の(10進数)番号を取得するだけで、より良い課題になったと思います。
xnor

まあ、8372実際に。
xnor

1
@xnor、あなたは正しいかもしれません、そしてそれはきれいです。しかし、Octaveでこれを解決するのは楽しかったし、他の人もそれを楽しんでくれることを願っています:)
Stewie Griffin

回答:


12

パイソン286 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変換を数値的に実行します。7 *128回左シフトs(ステップ1および2)
eval(('0'+new_bin).replace('01','0+0b1'))して分割および合計(ステップ3、4および5)するために使用されます。


と素敵なトリックevalASCII変換を行うと、数バイト節約できます。
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

Adnanの05ab1e回答から128オフセットを使用した、私のJelly回答のポート(私が書いたJelly回答の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$&'))

編集:@ ConorO'Brienの助けを借りて5バイトを保存しました。


私自身の解決策も97バイトでしs=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))た。バイトを保存するために私のreplaceメソッドを使用することができます
コナーオブライエン

1
@ ConorO'Brien 1バイト以上だと思う!
ニール

あぁ、N I C E:D
コナー・オブライエン

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トリックについては、変数を(ab)使用できるとは知りませんでした。自動関数xn2はコンパイル時に少し奇妙に見えるx("n", 2)ので、その背後にあるロジックを完全に理解するにはまだ少し時間がかかると思います。あなたの助けを借りて、JaptソリューションはJelly answerで最初に結び付けられました。
Nit

ETHproductionsは最近ショートカットを作成しましたn2Í。まだTIOにはヒットしていませんが、ここで使用できます:ethproductions.github.io/japt/?v
オリバー

@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#]、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 SystemC#sと同じ場合using System;、はい、カウントに含める必要があります。F#でそれを行うことができれば、Systemが何であれ完全に修飾できます。たとえば、C#のSystem.Console...代わりにusing System;Console...
-TheLethalCoder

@TheLethalCoderそれは同じです、はい。また、これを明確にしてくれてありがとう:)文字列だけでなく、その名前空間に存在するConvertでもあるため、「open ..」バージョンを選択しました。
ブルナー


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;開始時に、その後でこれら2つの関数のすべてのインスタンスを置き換えるfl
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を累積して合計結果を累積するために使用されます。前のビット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へようこそ!すべての答えは、完全なプログラムまたは呼び出し可能な関数である必要があります(入力がハードコードされた変数に格納されるスニペットとは対照的です)。ただし、関数には名前を付けなくてもかまいません。そのlambda w:ため、答えを有効にするにはa を含めるだけで十分です。
マーティンエンダー

申し訳ありませんが、私はおそらくそれをうまく言いませんでした。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=名前のない関数が許可されているため、再帰呼び出しの関数名を参照しない限り、さえ必要ありません。
マーティンエンダー

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の検索、元のリストに対するsの異なる場所の検索。これらのインデックスで切り取り、10進数に変換して戻します:

+/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∘+⊆⊢ -自己によるパーティションが1つ増加

2⊥¨ -バイナリからそれぞれをデコード

+/ -合計

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.