Chuyển đổi chuỗi sang bit


10

Bài tập

Đưa ra một chuỗi đầu vào gồm một hoặc nhiều ký tự ASCII mà các điểm mã nằm trong khoảng từ 0 đến 128 (loại trừ), hãy làm như sau:

  1. Chuyển đổi từng ký tự thành mã ASCII 7 bit của nó (nếu mã ASCII nhỏ hơn 7 bit, đặt các bit 0 hàng đầu)
  2. Nối tất cả các bit (điều này dẫn đến 7*ncác bit có nsố lượng ký tự)
  3. Đối với mỗi bit trong dòng bit này, hãy in 1 nếu nó khác với bit trước đó và in 0 nếu không. Bit đầu ra đầu tiên luôn là 1.

Thí dụ

Đầu vào:

Hi

Đầu ra:

11011001011101

Giải trình:

Chuỗi "Hi" có mã ASCII

72 105

mà trong bit là:

1001000 1101001

Và các chỉ số bit chuyển tiếp:

11011001011101

Đây là mã golf. Số byte thấp nhất sẽ thắng.

Các trường hợp thử nghiệm

Trường hợp thử nghiệm 1:

Hello World!
110110010101110011010101101010110001110000111110000110000001011101101010101100110001

Trường hợp thử nghiệm 2:

%% COMMENT %%
1110111111011111100001100010010100001010110101011010011101010011111110011000001101111110111

Trường hợp thử nghiệm 3 (tín dụng cho Luis Mendo):

##
11100101110010

Xin chúc mừng Luis Mendo cho giải pháp ngắn nhất với 9 byte trong MATL!


2
Trường hợp thử nghiệm được đề xuất ##(dẫn đầu 0; một số câu trả lời hiện không thành công vì điều đó)
Luis Mendo

4
Làm thế nào đây là một bản sao của thách thức mã hóa Manchester? Tui bỏ lỡ điều gì vậy?
dạ dày

2
Thách thức khác cho biết việc chuyển đổi một luồng bit đầu vào thành luồng đầu ra có tốc độ gấp đôi, với mỗi đầu vào '1' được dịch thành '01' và mỗi đầu vào '0' được dịch thành '10' . Vì vậy, không lừa dối theo ý kiến ​​của tôi. Nếu một số lượng lớn người ủng hộ nhận xét của @ gastropner ở trên, tôi có thể hủy lừa đảo (hoặc bất kỳ người dùng nào khác có khả năng đó)
Luis Mendo

1
@Shaggy: Cả hai trường hợp thử nghiệm đều bao gồm một khoảng trắng, chỉ có một bit duy nhất và không phải là thứ 7. Vì vậy, tôi không nghĩ rằng báo cáo vấn đề đang đảm bảo rằng mỗi mã ascii sẽ có độ dài chính xác 7 bit.
đệ quy

1
@SmileAndNod Về suy nghĩ thứ hai, tôi nghĩ bạn không cần phải xử lý chuỗi rỗng.
justhalf

Câu trả lời:


4

MATL , 9 byte

Hj7&B!hdg

Hãy thử trực tuyến!

Giải trình

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
Đây là ngắn nhất cho đến nay. +1. Thật thú vị khi có một tích hợp cho sự khác biệt liên tiếp.
cần


4

Japt -P , 11 byte

Lợi dụng thực tế là các không gian có thể bị ép buộc 0trong JavaScript khi cố gắng thực hiện một phép toán hoặc, trong trường hợp này, hoạt động theo bit trên nó.

c_¤ù7Ãä^ i1

Hãy thử nó hoặc chạy tất cả các trường hợp thử nghiệm

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 có nghĩa là nếu nó là 32 (đối với ký tự khoảng trắng), thì nó sẽ như vậy 0100000. Ngoài ra,% ký tự (37) sẽ là0100101
ngay

Nó đang làm việc bây giờ. +1
ngay

2

CJam , 21 byte

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

Hãy thử trực tuyến!

Giải trình

Hiển thị ngăn xếp với đầu vào mẫu là 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

Để xem một bit có khác với bit trước hay không, chúng ta thực hiện một vectơ (phần tử khôn ngoan) giữa mảng bit và mảng bit mà không có phần tử đầu tiên. Chúng tôi cũng loại bỏ bit cuối cùng của kết quả, bởi vì nó luôn là bit cuối cùng của mảng dài hơn không thay đổi.


2

APL (Dyalog Unicode) , 16 byte SBCS

Chương trình đầy đủ. Lời nhắc cho chuỗi từ stdin.

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

Hãy thử trực tuyến!

 lời nhắc cho đầu vào ("trích dẫn trong bảng điều khiển")

11⎕DR¨ thay đổi từng ký tự thành bit-Boolean D ata R epresentation

1↓¨ thả từng bit đầu tiên từ mỗi

ε nlist (flatten)

2≠/ sự khác biệt cặp

1, trả trước một



2

Than , 25 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

⭆θ◧⍘℅鲦⁷←

Chuyển đổi tất cả các ký tự thành nhị phân và đệm chúng thành một chiều dài 7 và sau đó in chúng, nhưng để con trỏ qua chữ số cuối cùng.

Wⅈ

Lặp lại cho đến khi con trỏ qua chữ số đầu tiên.

←I﹪⍘KD²←01 ²

Tính xem các chữ số có khác nhau không và ghi đè lên mỗi chữ số với sự khác biệt.

1

Ghi đè chữ số đầu tiên bằng 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]

Hãy thử trực tuyến!

Một cú đâm nhanh vào nó.


Khéo léo với a*128+ord(c)! Nhưng không phải là reducelambdaloại tốn kém?
cần

1

Phi tiêu , 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();}

Lớp lót trước

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

Hãy thử trực tuyến!

Sự dài dòng và thiếu xây dựng dễ dàng này thực sự đang giết chết cái này. Vẫn quản lý để kéo một lớp lót mặc dù.

  • -45 byte bằng cách không sử dụng một lớp lót và sử dụng vòng lặp for


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)

Hãy thử trực tuyến!

Hy vọng rằng tôi có thể cải thiện điều này sớm, tôi cảm thấy như phải có một số điểm cần cải thiện nhưng tôi không thể nghĩ ngay bây giờ



1

C (gcc (MinGW)), 90 byte

Yêu cầu một trình biên dịch cung cấp 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}

Hãy thử trực tuyến!

Giải trình

Dòng đầu tiên, giống như câu trả lời của Value Ink :

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

Dòng thứ hai:

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.

Trong Ruby bạn có thể sử dụng nội suy trong literals biểu thức chính quy, ví dụ /Hello #{name}/, và cho các biến bắt đầu bằng $hoặc @bạn có thể bỏ qua các dấu ngoặc nhọn, vì vậy nếu ví dụ như $&"0"thì grawlixy /#$&$/trở thành /0$/.


1

K (ngn / k) , 9 13 byte

Giải pháp:

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

Hãy thử trực tuyến!

Giải trình:

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

Ghi chú:

  • +4 byte để hỗ trợ các chuỗi chỉ bao gồm các ký tự 6 bit

Điều này dường như không thành công cho đầu vào #chẳng hạn (đầu ra chỉ có 6 bit)
Luis Mendo

@streetster, bạn có muốn đăng phiên bản cố định không?
vừa qua

1

Biểu tượng cảm xúc , 263 byte

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

Hãy thử trực tuyến tại đây.

Ung dung:

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

Giải pháp:

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

Giải trình:

Kể từ khi Python 3.8 giới thiệu các biểu thức gán (chứ không phải là các câu lệnh gán tiêu chuẩn), tôi đã muốn sử dụng chúng trong phần hiểu danh sách cần ghi nhớ mục cuối cùng. Đây không phải là cách tốt nhất để làm điều này nhưng thể hiện một phương pháp thú vị khi sử dụng biểu thức gán.

Mã này tạo ra một hàm lambda, lấy tham số cần thiết là chuỗi cần chuyển đổi. Khi được gọi, hàm tiến hành như sau. Mỗi ký tự trong a được chuyển đổi thành mã ký tự của nó, được thêm vào 128 để xử lý các ký tự 6 bit (biểu diễn nhị phân sẽ luôn là 8 bit và chúng ta có thể cắt bit đầu tiên). Số này được chuyển đổi thành nhị phân và tiêu đề (0x) và số 1 ban đầu từ việc thêm 128 được cắt nhỏ. Các chuỗi mới này sau đó được nối thành một chuỗi lớn hơn.

Đối với mỗi ký tự trong chuỗi mới này (chứa biểu diễn 7 bit được nối của văn bản), nó được kiểm tra nếu ký tự đó giống với ký tự trước đó. Điều gì xảy ra với nhân vật đầu tiên? Ký tự kết quả đầu tiên phải luôn là "1" vì vậy chúng ta chỉ cần đảm bảo rằng bất cứ thứ gì trong biến ký tự cuối cùng không phải là "1" hay "0". Chúng tôi làm điều này bằng cách sử dụng lại tham số ban đầu mà chúng tôi không sử dụng nó nữa. Đây có thể là một vấn đề nếu chuỗi ban đầu là một "0" (một "1" duy nhất chỉ xảy ra để làm việc) nhưng chúng tôi sẽ bỏ qua điều đó.

Trong quá trình so sánh, ký tự trước được đánh giá trước vì vậy khi chúng ta sử dụng biểu thức gán để đặt biến ký tự trước thành ký tự hiện tại, nó không ảnh hưởng đến đánh giá của biểu thức so sánh.

Việc so sánh tạo ra True hoặc false cũng có thể được sử dụng tương ứng là 1 hoặc 0 trong Python, vì vậy chúng được sử dụng để tra cứu "1" hoặc "0" trong chuỗi


Bạn có thể lưu một số byte bằng cách sử dụng định dạng chuỗi ký tự: 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}] ""}}

Hãy thử trực tuyến!

Sử dụng shift-by-one và độc quyền-hoặc để phát hiện chuyển đổi. Mang lsb của nhân vật hiện tại đến msb của nhân vật tiếp theo. Kết hợp đầu ra cho mỗi ký tự bằng cách tham gia danh sách được trả về bởi lmap.

Sử dụng lambdas với các đối số mặc định để lưu byte khi khởi tạo và lặp lại các lệnh.

Dựa nhiều vào thứ tự hoạt động. Hoạt động cho chuỗi rỗng.


1

05AB1E (di sản) , 12 byte

Çb7jð0:¥ÄJ1ì

Sử dụng phiên bản kế thừa của 05AB1E, do jngầm kết hợp các chuỗi lại với nhau, đòi hỏi một sự rõ ràng Jsau jphiên bản mới của 05AB1E.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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

Hãy thử trực tuyến!

Vấn đề lớn nhất ở đây là chuyển đổi booleans (kết quả của XOR) thành '0' / '1'.





Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.