Transisi String ke Bit


10

Tugas

Diberikan string input dari satu atau lebih karakter ASCII dengan titik codep antara 0 dan 128 (eksklusif), lakukan hal berikut:

  1. Konversi setiap karakter menjadi kode ASCII 7-bitnya (jika kode ASCII kurang dari 7 bit, masukkan nol bit di depan)
  2. Menggabungkan semua bit (ini menghasilkan 7*nbit di mana njumlah karakter)
  3. Untuk setiap bit dalam bitstream ini, cetak 1 jika berbeda dari bit sebelumnya, dan cetak 0 sebaliknya. Bit keluaran pertama selalu 1.

Contoh

Memasukkan:

Hi

Keluaran:

11011001011101

Penjelasan:

String "Hai" memiliki kode ASCII

72 105

yang dalam bit adalah:

1001000 1101001

Dan indikator bit transisi:

11011001011101

Ini golf kode. Hitungan byte terendah menang.

Uji Kasus

Uji kasus 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Uji kasus 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Test case 3 (dikreditkan ke Luis Mendo):

##
11100101110010

Selamat kepada Luis Mendo untuk solusi terpendek dengan 9 byte di MATL!


2
Test case yang disarankan ##( 0sedikit terkemuka ; beberapa jawaban saat ini gagal karena itu)
Luis Mendo

4
Bagaimana ini duplikat dari tantangan pengkodean Manchester? Apakah saya melewatkan sesuatu?
gastropner

2
Tantangan lainnya mengatakan mengubah aliran input bit menjadi aliran output laju ganda, dengan masing-masing input '1' diterjemahkan menjadi '01' dan setiap input '0' diterjemahkan menjadi '10' . Jadi tidak menipu menurut saya. Jika sejumlah besar orang mendukung komentar @ gastropner di atas, saya dapat membatalkan (atau pengguna lain dengan kemampuan itu)
Luis Mendo

1
@Shaggy: Kedua test case menyertakan spasi, yang hanya memiliki set bit tunggal, dan bukan yang ke-7. Jadi saya tidak berpikir pernyataan masalah menjamin bahwa setiap kode ascii akan persis 7 bit panjangnya.
rekursif

1
@SmileAndNod Setelah dipikir-pikir, saya pikir Anda tidak perlu menangani string kosong.
justhalf

Jawaban:


4

MATL , 9 byte

Hj7&B!hdg

Cobalah online!

Penjelasan

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

1
Ini adalah yang terpendek sejauh ini. +1. Sangat menyenangkan memiliki bawaan untuk perbedaan berurutan.
justhalf


4

Japt -P , 11 byte

Mengambil keuntungan dari fakta bahwa spasi dapat dipaksa 0dalam JavaScript ketika mencoba melakukan matematika atau, dalam hal ini, operasi bitwise di atasnya.

c_¤ù7Ãä^ i1

Cobalah atau jalankan semua test case

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

7-bit berarti bahwa jika 32 (untuk karakter spasi), itu akan menjadi 0100000. Juga% karakter (37) adalah0100101
justhalf

Ini bekerja sekarang. +1
justhalf

2

CJam , 21 byte

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

Cobalah online!

Penjelasan

Menampilkan tumpukan dengan input sampel 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

Untuk melihat apakah bit berbeda dari bit sebelumnya, kita melakukan vektor (elemen-bijaksana) antara bit array dan bit array tanpa elemen pertama. Kami juga menghapus bit terakhir dari hasil, karena selalu bit terakhir dari array yang lebih panjang tidak berubah.


2

APL (Dyalog Unicode) , 16 byte SBCS

Program lengkap. Meminta string dari stdin.

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

Cobalah online!

 meminta input ("kutipan di konsol")

11⎕DR¨ ubah setiap karakter menjadi bit-Boolean D ata R representasi

1↓¨ lepaskan bit pertama dari masing-masing

ϵ daftar (ratakan)

2≠/ perbedaan berpasangan

1, tambahkan satu



2

Arang , 25 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

⭆θ◧⍘℅鲦⁷←

Konversikan semua karakter menjadi biner dan pad dengan panjang 7 dan kemudian cetak, tetapi biarkan kursor di atas digit terakhir.

Wⅈ

Ulangi sampai kursor melebihi digit pertama.

←I﹪⍘KD²←01 ²

Hitung apakah digitnya berbeda dan timpa setiap digit dengan selisihnya.

1

Timpa digit pertama dengan a 1.





1

Python 2 , 104 byte

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]

Cobalah online!

Menusuknya dengan cepat.


Trik cerdas dengan a*128+ord(c)! Tapi bukankah reducedan lambdajenisnya mahal?
justhalf

1

Dart , 213 168 byte

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();}

Satu kalimat sebelumnya

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);

Cobalah online!

Verbositas ini dan kurangnya in built mudah benar-benar membunuh yang ini. Masih berhasil menarik satu liner sekalipun.

  • -45 byte dengan tidak menggunakan liner satu dan menggunakan untuk loop


1

Kotlin , 182 byte

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)

Cobalah online!

Semoga saya bisa meningkatkan ini segera, saya merasa harus ada beberapa tempat untuk perbaikan tetapi saya tidak bisa berpikir sekarang



1

C (gcc (MinGW)), 90 byte

Membutuhkan penyediaan kompiler 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;}


1

Ruby -p , 50 byte

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

Cobalah online!

Penjelasan

Baris pertama, sama dengan jawaban Value Ink :

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

Baris kedua:

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.

Di Ruby Anda dapat menggunakan interpolasi di Regexp literal, misalnya /Hello #{name}/, dan untuk variabel yang dimulai dengan $atau @Anda dapat menghilangkan kurung kurawal, jadi jika misalnya $&adalah "0"kemudian grawlixy yang /#$&$/menjadi /0$/.


1

K (ngn / k) , 9 13 byte

Larutan:

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

Cobalah online!

Penjelasan:

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

Catatan:

  • +4 byte untuk mendukung string yang hanya terdiri dari karakter 6-bit

Ini tampaknya gagal untuk input #misalnya (output hanya memiliki 6 bit)
Luis Mendo

@streetster, apakah Anda ingin mengirim versi yang sudah diperbaiki?
justhalf

1

Emojicode , 263 byte

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

Cobalah online di sini.

Tidak Disatukan:

🏁 🍇  💭 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.
    🍉
🍉


1

Python3.8 , 72 byte

Larutan:

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

Penjelasan:

Sejak Python 3.8 memperkenalkan ekspresi penugasan (daripada pernyataan penugasan standar), saya ingin menggunakannya dalam pemahaman daftar yang perlu mengingat item terakhir. Ini bukan cara terbaik untuk melakukan ini tetapi menunjukkan metode yang menarik dalam menggunakan ekspresi penugasan.

Kode menciptakan fungsi lambda yang mengambil argumen yang diperlukan yang merupakan string untuk dikonversi. Saat dipanggil, fungsi melanjutkan sebagai berikut. Setiap karakter dalam a dikonversi ke kode karakternya yang ditambahkan ke 128 untuk berurusan dengan karakter 6-bit (representasi biner akan selalu menjadi 8 bit dan kita dapat memotong bit pertama). Nomor ini dikonversi ke biner dan header (0x) dan 1 awal dari menambahkan 128 dipotong. String baru ini kemudian bergabung menjadi satu string yang lebih besar.

Untuk setiap karakter dalam string baru ini (yang berisi representasi 7-bit teks yang disatukan), diperiksa jika karakternya sama dengan karakter sebelumnya. Apa yang terjadi dengan karakter pertama? Karakter hasil pertama harus selalu "1" jadi kita hanya perlu memastikan bahwa apa pun yang ada di variabel karakter terakhir bukanlah "1" atau "0". Kami melakukan ini dengan menggunakan kembali parameter asli sekarang karena kami tidak menggunakannya lagi. Ini mungkin menjadi masalah jika string asli adalah satu "0" (satu "1" kebetulan bekerja) tetapi kita akan mengabaikannya.

Selama perbandingan, karakter sebelumnya dievaluasi terlebih dahulu sehingga ketika kami menggunakan ekspresi penugasan untuk mengatur variabel karakter sebelumnya ke karakter saat ini, itu tidak mempengaruhi evaluasi ekspresi perbandingan.

Perbandingan menghasilkan Benar atau Salah yang juga dapat digunakan sebagai 1 atau 0 masing-masing dalam Python, sehingga mereka digunakan untuk mencari "1" atau "0" dalam sebuah string


Anda dapat menyimpan beberapa byte dengan menggunakan string format literal: bin(ord(i)+128)[3:]->f"{ord(i):07b}"
movatica

1

Tcl , 215 167 140 byte

{{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}] ""}}

Cobalah online!

Menggunakan shift-by-one dan eksklusif-atau untuk mendeteksi transisi. Membawa lsb dari karakter saat ini ke msb dari karakter selanjutnya. Menggabungkan output untuk setiap karakter dengan menggabungkan daftar yang dikembalikan oleh lmap.

Menggunakan lambdas dengan argumen default untuk menyimpan byte pada inisialisasi dan perintah berulang.

Sangat bergantung pada urutan operasi. Bekerja untuk string kosong.


1

05AB1E (warisan) , 12 byte

Çb7jð0:¥ÄJ1ì

Menggunakan versi lawas 05AB1E, karena jsecara implisit menggabungkan string, yang membutuhkan eksplisit Jsetelah jdalam versi baru 05AB1E.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

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

1

Haskell , 137 byte

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)

Cobalah online!

Masalah terbesar di sini adalah mengubah boolean (hasil dari XOR) menjadi '0' / '1'.





Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.