Przejście z ciągu na bit

10

Zadanie

Biorąc pod uwagę ciąg wejściowy jednego lub więcej znaków ASCII, których punkty kodowe mają wartość od 0 do 128 (wyłączne), wykonaj następujące czynności:

  1. Konwertuj każdy znak na 7-bitowy kod ASCII (jeśli kod ASCII jest mniejszy niż 7 bitów, wstaw początkowe bity zerowe)
  2. Połącz wszystkie bity (powoduje to, że 7*nbit njest liczbą znaków)
  3. Dla każdego bitu w tym strumieniu bitów wydrukuj 1, jeśli różni się od poprzedniego bitu, i wydrukuj 0 w przeciwnym razie. Pierwszy bit wyjściowy to zawsze 1.

Przykład

Wejście:

Hi

Wynik:

11011001011101

Wyjaśnienie:

Ciąg „Hi” ma kody ASCII

72 105

które w bitach to:

1001000 1101001

I wskaźniki bitów przejścia:

11011001011101

To jest kod golfowy. Wygrywa najniższa liczba bajtów.

Przypadki testowe

Przypadek testowy 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Przypadek testowy 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Przypadek testowy 3 (kredyt dla Luisa Mendo):

##
11100101110010

Gratulacje dla Luisa Mendo za najkrótsze rozwiązanie z 9 bajtami w MATL!

justhalf
źródło
2
Sugerowany przypadek testowy ##(wiodący 0bit; niektóre odpowiedzi obecnie nie udają się z tego powodu)
Luis Mendo
4
Jak to jest duplikat wyzwania kodowania z Manchesteru? Czy coś brakuje?
gastropner
2
Drugie wyzwanie polega na przekształceniu strumienia wejściowego bitów w strumień wyjściowy o podwójnej szybkości, z każdym wejściowym „1” przetłumaczonym na „01” i każdym wejściowym „0” przetłumaczonym na „10” . Więc moim zdaniem nie oszukuj. Jeśli duża liczba osób poprze powyższy komentarz @ gastropner, mogę cofnąć duplikat (lub dowolnego innego użytkownika z tą umiejętnością)
Luis Mendo
1
@Shaggy: Oba przypadki testowe zawierają spację, która ma tylko jeden zestaw bitów, a nie 7.. Więc nie sądzę, aby opis problemu gwarantował, że każdy kod ascii będzie miał dokładnie 7 bitów długości.
rekurencyjny
1
@SmileAndNod Po namyśle myślę, że nie musisz obsługiwać pustego łańcucha.
justhalf

Odpowiedzi:

4

MATL , 9 bajtów

Hj7&B!hdg

Wypróbuj online!

Wyjaśnienie

H     % Push 2
j     % Read line of input, unevaluated
7&B   % Convert to binary with 7 bits. Gives a 7-column matrix
!     % Transpose
h     % Concatenate horiontally. The matrix is read in column-major order
d     % Consecutive differences
g     % Convert to logical. Implicitly display
Luis Mendo
źródło
1
To najkrótszy jak dotąd. +1. Fajnie jest mieć wbudowaną funkcję obsługi kolejnych różnic.
justhalf
4

Japt -P , 11 bajtów

Korzysta z faktu, że spacje można wymusić 0w JavaScript podczas próby wykonania na nim operacji matematycznej lub, w tym przypadku, bitowej.

c_¤ù7Ãä^ i1

Wypróbuj lub uruchom wszystkie przypadki testowe

c_¤ù7Ãä^ i1     :Implicit input of string
c_              :Map codepoints
  ¤             :  Convert to binary string
   ù7           :  Left pad with spaces to length 7
     Ã          :End map
      ä^        :XOR consecutive pairs
         i1     :Prepend 1
                :Implicitly join and output
Kudłaty
źródło
7-bit oznacza, że ​​jeśli jest to 32 (dla znaku spacji), to byłoby 0100000. Również znak% (37) byłby0100101
pół
Już działa. +1
justhalf
2

CJam , 21 bajtów

1q{i2b7Te[}%e__(;.^);

Wypróbuj online!

Wyjaśnienie

Pokazuje stos z przykładowym wejściem 5:

1 q      e# Push 1 and then the whole input: 1 "5"
{
  i      e# Convert to its char code: 1 [53]
  2 b    e# Convert to binary: 1 [[1 1 0 1 0 1]]
  7 T e[ e# Left-pad with 0 to length 7: 1 [[0 1 1 0 1 0 1]]
} %      e# Map this block over every character in the string
e_       e# Flatten array: 1 [0 1 1 0 1 0 1]
_ ( ;    e# Duplicate array and remove its first element: 1 [0 1 1 0 1 0 1] [1 1 0 1 0 1]
. ^      e# Element-wise xor: 1 [1 0 1 1 1 1 1]
) ;      e# Remove and pop the last element of the array: 1 [1 0 1 1 1 1]
         e# Stack implicitly printed: 1101111

Aby zobaczyć, czy bit różni się od poprzedniego, wykonujemy wektor (pod względem elementu) xor między tablicą bitów a tablicą bitów bez pierwszego elementu. Usuwamy również ostatni bit wyniku, ponieważ zawsze jest to ostatni bit dłuższej tablicy bez zmian.

NinjaBearMonkey
źródło
2

APL (Dyalog Unicode) , 16 bajtów SBCS

Pełny program Monituje o ciąg znaków ze standardowego wejścia.

1,2≠/∊1↓¨11DR¨⍞

Wypróbuj online!

 monit o wprowadzenie („cytat w konsoli”)

11⎕DR¨ zmień każdy znak na bit-Boolean D ata R reprezentacja

1↓¨ upuść pierwszy bit z każdego

ε nlist (spłaszczyć)

2≠/ różnica par

1, przygotuj jeden

Adám
źródło
2

Węgiel , 25 bajtów

⭆θ◧⍘℅鲦⁷←Wⅈ←I﹪⍘KD²←01 ²1

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

⭆θ◧⍘℅鲦⁷←

Konwertuj wszystkie znaki na binarne i wstaw je na długość 7, a następnie wydrukuj, ale pozostaw kursor nad ostatnią cyfrą.

Wⅈ

Powtarzaj, aż kursor znajdzie się nad pierwszą cyfrą.

←I﹪⍘KD²←01 ²

Oblicz, czy cyfry są różne, i zastąp każdą cyfrę różnicą.

1

Zastąp pierwszą cyfrę znakiem 1.

Neil
źródło
2

PowerShell , 73 56 49 bajtów

$args|%{$b=+$_
6..0}|%{+($c-ne($c=($b-shr$_)%2))}

Wypróbuj online!

-17 bajtów dzięki mazzy :)

Andrei Odegov
źródło
1
-17 bajtów : D
mazzy
Wspaniale, musisz sam to opublikować.
Andrei Odegov,
ta odpowiedź dla ciebie. moja księżniczka jest w innym zamku :))))
mazzy
1
@mazzy, trochę więcej -7 bajtów :)
Andrei Odegov
niesamowite i genialne! 【ツ】
mazzy
2

Oktawa , 36 30 bajtów

Napraw dzięki Luis Mendo

-2 bajty dzięki Sanchises

@(a)[1;~~diff(de2bi(a,7)'(:))]

Wypróbuj online!

Wygasły dane
źródło
Prawdopodobnie możesz zgolić kilka bajtów za pomocą de2bi.
Sanchises
Nie działał dla mnie przed @sanchises, ale przyjrzę się, kiedy będę mógł
Data
1

Python 2 , 104 bajty

lambda w:reduce(lambda(A,P),C:(A+'10'[P==C],C),bin(reduce(lambda a,c:a*128+ord(c),w,1))[3:],('','x'))[0]

Wypróbuj online!

Szybkie dźgnięcie w to.

Chas Brown
źródło
Sprytna sztuczka z a*128+ord(c)! Ale nie jest reducei lambdaniby kosztowne?
justhalf
1

Dart , 213 168 bajtów

f(s,{t,i}){t=s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList();for(i=t.length-1;i>0;i--)t[i]=t[i]==t[i-1]?'0':'1';t[0]='1';return t.join();}

Poprzedni jednowarstwowy

f(String s)=>'1'+s.runes.map((r)=>r.toRadixString(2).padLeft(7,'0')).join().split('').toList().reversed.reduce((p,e)=>p.substring(0,p.length-1)+(p[p.length-1]==e?'0':'1')+e).split('').reversed.join().substring(1);

Wypróbuj online!

Ta gadatliwość i brak łatwych do wbudowania naprawdę zabija to. Nadal jednak udało mi się wyciągnąć jedną wkładkę.

  • -45 bajtów, nie używając jednej wkładki i używając pętli for
Elcan
źródło
1

Kotlin , 182 bajty

var l='6'
fun f(b:String)=b.fold(""){t,i->t+"".a(i.toInt())}.map{if(l==it){l=it;0} else {l=it;1}}
fun String.a(v:Int):String=if(v<=0)"${this}0".reversed() else "${this}${v%2}".a(v/2)

Wypróbuj online!

Mam nadzieję, że uda mi się to wkrótce poprawić, wydaje mi się, że musi być kilka miejsc do poprawy, ale nie mogę teraz myśleć

Quinn
źródło
1

C (gcc (MinGW)), 90 bajtów

Wymaga zapewnienia kompilatora itoa().

n[9],b,c;f(char*s){for(b=*s<64;c=*s++;printf("%07s",itoa((c^c/2)&127,n,2)))c|=b<<7,b=c&1;}
gastropner
źródło
88 bajtów
ceilingcat
1

Rubinowy -p , 50 bajtów

gsub(/./){"%07b"%$&.ord}
gsub(/./){$`=~/#$&$/?0:1}

Wypróbuj online!

Wyjaśnienie

Pierwszy wiersz, taki sam jak odpowiedź Value Ink :

gsub(/./){       $&    }   # Replace each character $&…
                   .ord    # …with its ASCII code…
                %          # …formatted as…
          "%07b"           # …binary digits padded to 7 places.

Druga linia:

gsub(/./){      $&      }  # Replace each character $&…
          $`               # …if the text to its left…
            =~             # …matches…
              /#  $/       # …the Regexp /c$/ where "c" is the character…
                    ?0:1   # …with 0, or 1 otherwise.

W Ruby można użyć interpolacji w literały wyrażenia regularnego, np /Hello #{name}/, a dla zmiennych, które rozpoczynają się $lub @można pominąć nawiasy klamrowe, więc jeśli na przykład $&jest "0"to grawlixy /#$&$/staje /0$/.

Jordania
źródło
1

K (ngn / k) , 9 13 bajtów

Rozwiązanie:

~=':,/(7#2)\'

Wypróbuj online!

Wyjaśnienie:

~=':,/(7#2)\' / the solution
           \' / convert each
      (   )   / do this together
       7#2    / 2 2 2 2 2 2 2
    ,/        / flatten
 =':          / equal to each-previous?
~             / not

Uwagi:

  • +4 bajty do obsługi ciągów znaków składających się tylko z 6-bitowych znaków
streetster
źródło
Wydaje się, że #na przykład to się nie udaje (dane wyjściowe mają tylko 6 bitów)
Luis Mendo,
@streetster, czy chcesz opublikować poprawioną wersję?
justhalf
1

Emojicode , 263 bajty

🏁🍇🔤🔤➡️🖍🆕s🔂b📇🆕🔡👂🏼❗️❗️🍇🍪s🔪🔡🔢b❗️➕128 2❗️1 7❗️🍪➡️🖍s🍉🔤?🔤➡️🖍🆕p🔂b s🍇↪️b🙌p🍇👄🔤0🔤❗️🍉🙅🍇👄🔤1🔤❗️🍉b➡️🖍p🍉🍉

Wypróbuj online tutaj.

Nie golfowany:

🏁 🍇  💭 Main code block
    🔤🔤 ➡️ 🖍 🆕 s  💭 Start with s as the empty string
    🔂 b 📇 🆕 🔡 👂🏼  💭 For each byte b in the input ...
    ❗️ ❗️ 🍇
        🍪 s  💭 ... append ...
           🔪 🔡 🔢 b ❗️ ➕ 128  💭 ... b + 128 (this gives the leading zero(s) in case the binary representation of b is shorter than 7 digits) ...

                 2  💭 ... in binary ...
              ❗️
              1 7  💭 ... without the leading one ...
           ❗️
        🍪
        ➡️ 🖍 s  💭 ... to s
    🍉
    🔤?🔤 ➡️ 🖍 🆕 p  💭 This will be used as the previous character, by assigning it neither 0 nor 1 we assure the first bit output is always a one
    🔂 b s 🍇  💭 For each character in s:
        ↪️ b 🙌 p 🍇  💭 If it is the same as the previous character ...
            👄 🔤0🔤 ❗️  💭 ... output a zero ...
        🍉 🙅 🍇  💭  ... else ...
            👄 🔤1🔤 ❗️ 💭 ... output a one
        🍉
        b ➡️ 🖍 p  💭 And the current character becomes the new previous character.
    🍉
🍉
OOBalance
źródło
1

JavaScript (V8) , 150 95 bajtów

-55 dzięki @dana

x=>[...[...x].reduce((a,c)=>a+c.charCodeAt(0).toString(2).padStart(7,0),"")].map(c=>x!=(x=c)|0)

Wypróbuj online!

Geza Kerecsenyi
źródło
1

Python3.8 , 72 bajty

Rozwiązanie:

lambda a:["10"[a==(a:=x)]for x in"".join(bin(ord(i)+128)[3:]for i in a)]

Wyjaśnienie:

Odkąd Python 3.8 wprowadził wyrażenia przypisania (zamiast standardowych instrukcji przypisania), chciałem używać ich w zrozumieniu listy, która musi zapamiętać ostatni element. To nie jest najlepszy sposób, aby to zrobić, ale pokazuje ciekawą metodę użycia wyrażenia przypisania.

Kod tworzy funkcję lambda, która pobiera wymagany argument, którym jest ciąg znaków do konwersji. Po wywołaniu funkcja działa w następujący sposób. Każdy znak w a jest konwertowany na kod znakowy, do którego dodano 128, aby radzić sobie ze znakami 6-bitowymi (reprezentacja binarna zawsze będzie miała 8 bitów i możemy odciąć pierwszy bit). Liczba ta jest konwertowana na binarną, a nagłówek (0x) i początkowa 1 z dodania 128 są odcinane. Te nowe ciągi są następnie łączone w jeden większy ciąg.

Dla każdego znaku w tym nowym ciągu (który zawiera skonkatenowaną 7-bitową reprezentację tekstu) sprawdza się, czy znak jest taki sam jak poprzedni znak. Co dzieje się z pierwszą postacią? Pierwszym znakiem wynikowym zawsze powinna być „1”, więc musimy tylko upewnić się, że cokolwiek w zmiennej ostatniego znaku nie jest ani „1”, ani „0”. Robimy to poprzez ponowne użycie oryginalnego parametru, gdy już go nie używamy. Może to stanowić problem, jeśli oryginalny ciąg był pojedynczym „0” (pojedyncze „1” po prostu działa), ale to zignorujemy.

Podczas porównania poprzedni znak był oceniany jako pierwszy, więc kiedy używamy wyrażenia przypisania, aby ustawić zmienną poprzedniego znaku na bieżący znak, nie wpływa to na ocenę wyrażeń porównania.

Porównanie daje albo Prawdę, albo Fałsz, które mogą być również użyte jako 1 lub 0 odpowiednio w Pythonie, więc są one używane do wyszukiwania „1” lub „0” w ciągu

infinityCoding
źródło
Możesz zapisać niektóre bajty, używając literałów w formacie łańcuchowym: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica
1

Tcl , 215 167 140 bajtów

{{s {B binary} {X ~$w/64}} {join [lmap c [split $s {}] {$B scan $c c w;$B scan [$B format i [expr 2*$w^$w^$X<<7]] B7 r;set X $w;set r}] ""}}

Wypróbuj online!

Używa przełączania jeden po drugim i wyłączności lub do wykrywania przejść. Przenosi lsb bieżącego znaku do msb następnego znaku. Łączy dane wyjściowe dla każdego znaku, dołączając do listy zwróconej przez lmap.

Wykorzystuje lambdas z domyślnymi argumentami do zapisywania bajtów podczas inicjalizacji i powtarzanych poleceń.

W dużym stopniu zależy od kolejności działania. Działa na pusty ciąg.

SmileAndNod
źródło
1

05AB1E (starsza wersja) , 12 bajtów

Çb7jð0:¥ÄJ1ì

Używa starszej wersji 05AB1E, ponieważ jniejawnie łączy ze sobą ciągi znaków, co wymaga jawnego umieszczenia Jpo jnowej wersji 05AB1E.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Ç             # Convert the (implicit) input-string to a list of ASCII code-points
              #  i.e. "Hi#" → [72,105,35]
 b            # Convert each integer to a binary string
              #  → ["1001000","1101001","100011"]
  7j          # Prepend each with spaces to make them length 7,
              # and join everything together to a single string implicitly
              #  → "10010001101001 100011"
    ð0:       # Replace all those spaces with 0s
              #  → "100100011010010100011"
       ¥      # Get the deltas of each pair of 1s/0s
              #  → [-1,0,1,-1,0,0,1,0,-1,1,-1,0,1,-1,1,-1,0,0,1,0]
        Ä     # Get the absolute value of this
              #  → [1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,1,0,0,1,0]
         J    # Join them all together
              #  → "10110010111011110010"
          1ì  # And prepend a 1
              #  → "110110010111011110010"
              # (after which the result is output implicitly)
Kevin Cruijssen
źródło
1

Haskell , 137 bajtów

import Data.Char
b 0=[]
b n=odd n:b(n`div`2)
d x|x='1'|1<2='0'
c=('1':).map d.(zipWith(/=)<*>tail).concatMap(reverse.take 7.b.(+128).ord)

Wypróbuj online!

Największym problemem tutaj jest konwersja wartości logicznych (wynik XOR) na „0” / „1”.

Lamdba
źródło
1

Python 3 , 88 84 bajtów

l=2;s=''
for c in''.join(f'{ord(c):07b}'for c in input()):s+='01'[l!=c];l=c
print(s)

Wypróbuj online!

Uważam, że zadań należy unikać, ale nie mogłem wymyślić żadnego sposobu, aby to zrobić.

Aktualizacja:

justhalf
źródło
1
84 bajtów
movatica
1

PHP , 90 bajtów

for(;$c=ord($argn[$j++]);$o.=sprintf('%07b',$c));for(;($q=$o[$i++])>'';$p=$q)echo$p!=$q|0;

Wypróbuj online!

640 KB
źródło