Oblicz binarną podzieloną sumę słowa

22

Weź ciąg znaków szawierający drukowalne znaki ASCII jako dane wejściowe i wyślij jego „binarną podzieloną sumę”. Potrzebujesz wyjaśnienia?

Jak uzyskać binarną sumę podziału?

Wykorzystamy ciąg A4jako przykład w poniższym objaśnieniu.

  • Konwertuj znaki na binarne, traktując każdą literę jako 7-bitowy znak ASCII

    A -> ASCII 65 -> 1000001
    4 -> ASCII 52 -> 0110100
    
  • Połącz liczby binarne w nową liczbę binarną

    A4 -> 1000001 & 0110100 -> 10000010110100
    
  • Podziel nową liczbę dwójkową na części, gdzie nie 1ma 0po lewej stronie żadnego . Nie należy dzielić kolejnych 1s.

    10000010110100 -> 100000, 10, 110, 100
    
  • Konwertuj te liczby binarne na dziesiętne

    100000, 10, 110, 100 -> 32, 2, 6, 4
    
  • Weź sumę tych liczb:

    32 + 2 + 6 + 4 = 44
    

Tak więc wyjście A4powinno być takie 44.


Przypadki testowe:

a
49

A4
44

codegolf
570

Hello, World!
795
Stewie Griffin
źródło
2
Myślę, że byłoby to ładniejsze wyzwanie bez kroku konwersji ASCII, biorąc po prostu (dziesiętną) liczbę po kroku 2 jako dane wejściowe.
xnor
No, 8372rzeczywiście.
xnor
1
@ xnor, możesz mieć rację i byłoby czystsze. Świetnie się bawiłem, rozwiązując to w Octave, i mam nadzieję, że inni również z przyjemnością to rozwiązają :)
Stewie Griffin

Odpowiedzi:

12

Python 2 , 86 81 76 bajtów

-5 bajtów dzięki Adnan
-5 bajtów dzięki xnor

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

Wypróbuj online!

for c in input():s=s*128+ord(c)wykonać numerycznie konwersję ASCII, gdzie 7 razy w *128lewo przesuwa się s(kroki 1 i 2)
eval(('0'+new_bin).replace('01','0+0b1'))do podziału i sumowania (kroki 3, 4 i 5)

Pręt
źródło
Niezła sztuczka z eval! Wykonanie konwersji ASCII numerycznie oszczędza niektóre bajty.
xnor
7

Galaretka , 13 bajtów

Oḅ128BŒg;2/ḄS

Wypróbuj online!

Jak to działa

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.
Dennis
źródło
Wcześniej tęskniłem za konwersją bazy.
Jonathan Allan
Ach, niezła sztuczka!
Adnan
6

MATL , 14 bajtów

YB!'1+0*'XXZBs

Wypróbuj online!

Wyjaśnienie

Rozważ dane wejściowe 'A4'jako przykład.

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
Luis Mendo
źródło
5

05AB1E , 18 bajtów

Kod:

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

Wyjaśnienie:

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

Wykorzystuje kodowanie 05AB1E . Wypróbuj online!

Adnan
źródło
5

05AB1E , 14 bajtów

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

Port mojej odpowiedzi Jelly , przy użyciu przesunięcia 128 od odpowiedzi Adnana 05ab1e (zamiast 256 w odpowiedzi Jelly, którą napisałem).

Wypróbuj online!

W jaki sposób?

Çž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
Jonathan Allan
źródło
3

JavaScript (ES6), 97 92 bajtów

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

Edycja: Zapisano 5 bajtów przy pewnej pomocy @ ConorO'Brien.

Neil
źródło
Moje własne rozwiązanie również miało 97 bajtów: s=>eval([...s].map(e=>(e.charCodeAt()+128).toString(2).slice(1)).join``.replace(/1+0*/g,'+0b$&'))Myślę, że możesz użyć mojej metody zastępowania, aby zapisać bajt
Conor O'Brien
1
@ ConorO'Brien Myślę, że to więcej niż bajt!
Neil
O, n i c e: D
Conor O'Brien
3

Japt , 18 12 bajtów

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.

Pobiera dane wejściowe jako pojedynczy ciąg.
Wypróbowałem również dodatek 128 lub 256 używany przez inne odpowiedzi, ale wypełnienie 0 było krótsze.

Ogolono całe 6 bajtów dzięki ETHproductions i Oliverowi .

Wypróbuj tutaj.

Gnida
źródło
Możesz użyć więcej funkcji automatycznych tutaj: òÈ<YÃmoże być ò<(ze spacją) i Ën2Ãxmoże być xn2. Możesz także użyć Tzamiast 0oszczędzać na przecinku. (Prosimy również dołączyć do nas na czacie Japt, jeśli masz pytania lub chciałbyś pomóc w
grze
@ETHproductions Jeszcze raz dziękuję, szczególnie za Tpodstęp, nie wiedziałem, że możesz (ab) użyć do tego zmiennych, to bardzo przydatne. Automatyczna funkcja xn2wygląda nieco dziwnie po kompilacji, x("n", 2)więc myślę, że jeszcze trochę potrwa, zanim w pełni zrozumiem logikę, która się za nimi kryje. Z twoją pomocą rozwiązanie Japt jest teraz związane na pierwszym miejscu z odpowiedzią Jelly .
Nit
ETHproductions niedawno skrót dla n2: Í. To jeszcze nie uderzyło w TIO, ale możesz go użyć tutaj: ethproductions.github.io/japt/?v=1.4.5&code=Y1+k+VQ3w/…
Oliver
@Oliver Wow, to bardzo krwawa przewaga, która nie jest jeszcze uwzględniona w odnośniku do skrótów tłumacza. Wielkie dzięki!
Nit,
2

Galaretka , 16 15 bajtów

-1 bajt dzięki Dennis (bez potrzeby spłaszczenie o 1, gdy pełny Spłaszczenie miałko - wymienić ;/z F)

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

Wypróbuj online!

W jaki sposób?

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
Jonathan Allan
źródło
1
;/można zastąpić F.
Dennis
2

PHP, 116 bajtów

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

Wersja online

PHP, 117 bajtów

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

Wypróbuj online!

PHP, 120 bajtów

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;

Wypróbuj online!

lub

for(;$c=ord($argn[$i++]);)$r.=sprintf("%07b",$c);preg_match_all("#1+0+#",$r,$t);echo array_sum(array_map(bindec,$t[0]));
Jörg Hülsermann
źródło
1

Pyt , 21 bajtów

To za długo...

siR2:.BiCMQ128"1+0+"1

Zestaw testowy.

Leaky Nun
źródło
1

[F #], 249 245 bajtów

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

Wypróbuj online!

Uwaga: wersja na tio.run ma w nagłówku „otwarty System”, dodałem jego liczbę do powyższego kodu. Nie jestem pewien, jakie są reguły dotyczące importu.

Nie golfił

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
Brunner
źródło
jeśli open Systemjest taki sam jak C # s, using System;to tak, musisz dołączyć to do liczby. Jeśli możesz to zrobić w F #, możesz w pełni zakwalifikować się do tego, do czego Systemsłuży. Na przykład w C # System.Console...zamiastusing System;Console...
TheLethalCoder
@TheLethalCoder To jest to samo, tak. Ponadto, dziękuję za wyjaśnienie tego :) Wybrałem wersję „open ..”, ponieważ jest to nie tylko String, ale także Convert, które działają w tej przestrzeni nazw.
Brunner
0

Perl 6 , 62 bajtów

{sum map {:2(~$_)},.comb».ord».fmt('%07b').join~~m:g/11*0*/}
Sean
źródło
użyj .ordszamiast .comb».ord. [~]często można użyć przedrostka .join. combistnieje, co robi to m:g/…. /11*0*/można skrócić do /1+0*/. Wpadłem{sum map {:2($_)},comb /1+0*/,[~] .ords».fmt('%07b')}
b2gills Brad Gilbert
0

J , 34 bajty

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

Wypróbuj online!

Wyjaśnienie

[:+/@(,#.;.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
mile
źródło
0

mathematica 193 bajtów

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)&
J42161217
źródło
Możesz zapisać 7 bajtów, wykonując f=FromDigits;l=Flatten;na początku, a następnie zastępując wszystkie wystąpienia tych dwóch funkcji znakami fi l.
numbermaniac
0

J , 40 bajtów

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

stosowanie:

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

zwraca 44

protista
źródło
0

Clojure, 150 bajtów

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

Miałem nadzieję, że konwersja z ASCII na bajty była krótsza. Rzeczywista bryła pętli jest dość krótka, służy rdo kumulacji bieżącego wyniku i Rkumulacji wyniku całkowitego. Jeśli poprzedni bit pjest, 0a bieżący cjest 1, dzielimy nowy fragment i gromadzimy go R, w przeciwnym razie aktualizujemy ri zachowujemyR tak, jak było.

NikoNyrh
źródło
0

Pyton 123 bajty

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

Zaktualizowano, dzięki Martinowi Enderowi.

ShadowCat
źródło
1
Witamy w PPCG! Wszystkie odpowiedzi muszą być pełnymi programami lub funkcjami wywoływalnymi (w przeciwieństwie do urywków, w których dane wejściowe są przechowywane w zmiennej zakodowanej na stałe). Funkcja może być jednak bezimienna, więc dołączenie a lambda w:byłoby wystarczające, aby twoja odpowiedź była ważna.
Martin Ender
Przepraszam, prawdopodobnie nie powiedziałem zbyt dobrze. Twoja edycja jest nadal nieprawidłowa, ponieważ a) dane wejściowe są zakodowane na stałe, b) Jeśli jest to pełny program, tak naprawdę nie drukuje wyniku. W przypadku pełnego programu należy odczytać dane wejściowe ze standardowego wejścia lub argumentu wiersza poleceń i wydrukować wynik na standardowe wyjście. Dlatego powiedziałem, że jest to prawdopodobnie najłatwiejsze, jeśli prześlesz go jako funkcję poprzez dodanie lambda w:.
Martin Ender
Ohhh, Ok, rozumiem, wystarczyłoby to tak: 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
tak, to jest poprawne. Nie potrzebujesz nawet tego f=, ponieważ zezwalamy na funkcje bez nazw (chyba że odwołujesz się do nazwy funkcji dla wywołań rekurencyjnych).
Martin Ender
0

K (oK) , 31 bajtów

Rozwiązanie:

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

Wypróbuj online!

Przykłady:

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

Wyjaśnienie:

Konwertuj na wartości ASCII, konwertuj na 7-bitowe pliki binarne, spłaszcz, znajdź, gdzie się różni, i względem oryginalnej listy, aby znaleźć, gdzie się 1różnią. Wytnij te indeksy, przelicz z powrotem na dziesiętne i podsumuj:

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

Premia

Zarządzałem również 31-bajtową wersją w K4 , ale ponieważ nie ma dla niej TIO, zamieszczam moje rozwiązanie OK.

+/2/:'_[;x]@&x&~~':x:,/1_'0b\:'
streetster
źródło
0

APL (Dyalog) , 30 bajtów

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

Wypróbuj online!

W jaki sposób?

⎕UCS⍵ - Unicodify

2⊥⍣¯1¨ - koduje każdy w formacie binarnym

¯7↑¨ - i pad w lewo z zerami do 7 miejsc

- spłaszczyć

1∘+⊆⊢ - podział przez siebie powiększony o jeden

2⊥¨ - dekoduje każdy z pliku binarnego

+/ - suma

Uriel
źródło