Mã hóa nhị phân


11

Điều này dựa trên xkcd # 153 .

Tạo một chương trình hoặc hàm được đặt tên có 2 tham số, mỗi tham số là một chuỗi hoặc một danh sách hoặc mảng byte hoặc ký tự. Tham số thứ hai sẽ chỉ chứa các ký tự được rút ra từ lrfu(hoặc các byte ASCII tương đương). Nó nên được hiểu là một loạt các hướng dẫn được thực hiện trên một chuỗi bit được biểu thị bằng tham số đầu tiên.

Việc xử lý được thực hiện phải tương đương như sau:

  1. Chuyển đổi tham số đầu tiên thành một chuỗi bit đơn được hình thành bằng cách ghép các bit của mỗi ký tự (được hiểu là một trong ASCII 7 bit, ASCII mở rộng 8 bit hoặc mã hóa Unicode tiêu chuẩn). Ví dụ: nếu tham số đầu tiên là "AB"thì đây sẽ là một trong 10000011000010(7 bit), 0100000101000010(8 bit hoặc UTF-8) 00000000010000010000000001000010hoặc 01000001000000000100001000000000(UTF-16 trong hai endianness), v.v.
  2. Đối với mỗi ký tự trong tham số thứ hai, theo thứ tự, thực hiện lệnh tương ứng:
    • lxoay chuỗi bit trái một. Ví dụ 10000011000010trở thành 00000110000101.
    • rxoay chuỗi bit phải. Ví dụ 10000011000010trở thành 01000001100001.
    • flật (hoặc đảo ngược) từng bit trong chuỗi bit. Ví dụ 10000011000010trở thành 01111100111101.
    • uđảo ngược chuỗi bit. Ví dụ 10000011000010trở thành 01000011000001.
  3. Chuyển đổi chuỗi bit thành chuỗi ASCII sử dụng một ký tự cho mỗi bit. Ví dụ 10000011000010trở thành "10000011000010". Điều này là do không phải tất cả các bộ 7/8 bit có một ký tự được gán cho chúng.

Ví dụ (bằng Python):

>>> f("b", "rfu")
01110011

Nó biến "b"thành biểu diễn nhị phân ASCII 8 bit của nó 01100010, xoay nó phải ( 00110001), lật từng bit ( 11001110) và đảo ngược nó ( 01110011).

Uyển chuyển

Nhân vật khác có thể được sử dụng thay cho các nhân vật l, r, f, và u, nhưng họ phải được ghi rõ ràng.

Bảng điểm

Cảm ơn @Optimizer đã tạo đoạn mã sau. Để sử dụng, nhấp vào "Hiển thị đoạn mã", cuộn xuống dưới cùng và nhấp vào "► Chạy đoạn mã".


3
Tham số thứ hai có thể là gì? Có thể được "rrfrburb"không? Ngoài ra, khi một người dịch chuyển hoặc đảo ngược các bit, liệu người ta có làm điều đó cho từng chữ cái riêng lẻ hay toàn bộ chuỗi không? Nhiều trường hợp thử nghiệm sẽ làm cho nó rõ ràng hơn.
xnor

1
Bạn có nghĩa là thay đổi hoặc xoay? một leftshift trong C sẽ dẫn đến bit ngoài cùng bên trái bị mất và bit ngoài cùng bên phải trở thành số không. Đối với một bản quyền trên một số không dấu, điều ngược lại xảy ra. Đối với một số đã ký Tôi không chắc chắn liệu có một hành vi được xác định chung cho những gì được thay đổi cho các số âm hay không (là 0 hay 1?) Dù sao đi nữa, thông tin luôn bị mất khi thực hiện thay đổi, không phải là trường hợp cho một vòng quay.
Cấp sông St


2
@flawr, tôi không nghĩ nó sẽ có lợi thế hơn khả năng tìm kiếm 'xkcd'
Peter Taylor

1
@KSFT Tôi nghĩ rằng tôi sẽ phải nói không với điều đó. Làm cho nó một chuỗi bằng cách tham gia nó.

Câu trả lời:


1

CJam, 34 32 byte

1l+256b2b1>l{~"11W:mm%!<>">4%~}/

Nó sử dụng các ký tự sau để được hướng dẫn:

0: left rotation
1: right rotation
2: reverse
3: flip

Đầu vào đang lấy từ STDIN với từ trên dòng đầu tiên và chuỗi lệnh trên dòng thứ hai.

Kiểm tra nó ở đây.

Giải trình

Lấy chuỗi bit thực sự chỉ là vấn đề diễn giải mã ký tự dưới dạng các chữ số của số cơ sở 256 (và nhận đại diện cơ sở 2 của nó). Điều khó khăn là chuyển đổi cơ sở sau sẽ không tạo ra kết quả với 0 ở bên trái. Do đó, tôi thêm 1 đầu vào đầu vào ban đầu, sau đó tách lại 1 đầu đó trong biểu diễn nhị phân. Ví dụ, nếu đầu vào là ab, tôi biến nó thành một mảng [1 'a 'b], diễn giải là cơ sở-256 (các ký tự được tự động chuyển đổi thành mã ký tự), và là 90466cơ sở-2 [1 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0]. Bây giờ nếu tôi loại bỏ dẫn đầu, 1tôi đã có dòng bit tôi đang tìm kiếm.

Đó là những gì phần này của mã làm:

1l+256b2b1>

Bây giờ tôi đọc danh sách các hướng dẫn và thực hiện một khối cho mỗi ký tự trong chuỗi lệnh:

l{...}/

Điều đầu tiên cần làm là để đánh giá nhân vật và số nguyên thực tế 0, 1, 2hoặc 3. Bây giờ phép thuật đánh gôn thực sự ... tùy thuộc vào hướng dẫn mà tôi muốn chạy một đoạn mã ngắn thực hiện thao tác:

Integer:  Code  Operation
0         1m<   "Left rotation";
1         1m>   "Right rotation";
2         W%    "Reverse";
3         :!    "Flip each bit";

Tôi có thể lưu trữ chúng trong một loạt các khối và chọn đúng khối để chạy, nhưng mã hóa chúng trong một chuỗi thực sự ngắn hơn:

"11W:mm%!<>">4%~

Đầu tiên, tôi sử dụng liên kết số nguyên với hướng dẫn để cắt đầu chuỗi. Vì vậy, đối với xoay trái, chuỗi không thay đổi, đối với xoay phải, ký tự đầu tiên bị loại bỏ và cứ thế. Sau đó, tôi chọn mỗi ký tự thứ tư từ chuỗi, bắt đầu từ ký tự đầu tiên, với 4%. Lưu ý cách bốn đoạn mã được phân phối trong toàn chuỗi. Cuối cùng tôi chỉ đánh giá chuỗi là mã với ~.

Chuỗi bit được in tự động vào cuối chương trình.


Tại sao 1m<chứ không phải (+? Bạn đang làm việc trên một mảng chứ không phải là một số, phải không?
Peter Taylor

@Peter ồ đúng rồi, cảm ơn. Tôi sẽ sửa nó sau.
Martin Ender

2

CJam, 34 byte

Một cách tiếp cận khác trong CJam.

1l+256b2b1>l_S/,1&@f=_,,@f{W%~}\f=

Văn bản đầu vào nằm trên dòng đầu tiên và các hướng dẫn nằm trên dòng thứ hai.

Hướng dẫn:

)        Rotate left.
(        Rotate right.
 (space) Flip.
~        Reverse.

1
Điều này là khá thông minh. Một sự xấu hổ f~không được thực hiện mặc dù, phải không? ;)
Martin Ender

2

Số 33

jku@[+eGPG+tGhG_Gms!dG)sHwsmjCk2z

Sử dụng:

0    : rotate right
1    : rotate left
2    : reverse order
3    : flip values

Github Pyth

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

Đây là một chương trình lấy chuỗi làm đối số thứ nhất và chuỗi lệnh làm đối số thứ hai. Trong phiên bản trực tuyến, bạn nên cung cấp các chuỗi được phân tách bằng một dòng mới, như vậy:

AbC
0321

Giải trình:

                                    : z=input() (implicit)
jk                                  : join("", ...)
  u@[                 )sHw          : reduce(select from [...] the value at int(H), input(), ...)
     +eGPG                          : [ G[-1] + G[:1],
          +tGhG                     : G[1:] + G[1],
               _G                   : G[::-1],
                 ms!dG              : map(lambda d: int(not(d)), G) ]
                          smjCk2z   : first arg = sum(map(lambda k:convert_to_base(ord(k),2),z)

Một cái gì đó tôi không thể hiểu được: Pyth reducetự động sử dụng Gcho giá trị trước và Hcho giá trị tiếp theo.


Mất liên lạc của bạn? Chỉ ngắn hơn 1 byte so với CJam?
Tối ưu hóa

@Optimizer Trên thực tế, tôi có thể đánh bại điều đó bằng cách sử dụng các hướng dẫn tương tự. Nhưng tôi không nghĩ rằng điều này sẽ hợp lệ bởi vì thách thức nói rằng "Các chữ cái khác có thể được sử dụng thay thế lrfu, nhưng chúng phải được ghi lại rõ ràng." (nhấn mạnh của tôi)
Martin Ender

1

Scala - 192

def f(i:String,l:String)=(i.flatMap(_.toBinaryString).map(_.toInt-48)/:l){
case(b,'l')⇒b.tail:+b.head
case(b,'r')⇒b.last+:b.init
case(b,'f')⇒b.map(1-_)
case(b,'u')⇒b.reverse}.mkString

1

Matlab (166 byte)

Điều này sử dụng các chữ cái abcdthay vì lrfutương ứng.

function D=f(B,C)
D=dec2bin(B,8)';
D=D(:);
g=@circshift;
for c=C
switch c-97
case 0
D=g(D,-1);
case 1
D=g(D,1);
case 2
D=char(97-D);
case 3
D=flipud(D);
end
end
D=D';

Một số thủ thuật được sử dụng ở đây để tiết kiệm không gian:

  • Sử dụng abcdchữ cho phép tôi trừ đi 97một lần, và sau đó các chữ cái trở 0, 1, 2, 3. Điều này tiết kiệm không gian trong switch- casemệnh đề.
  • Xác định circshiftlà một hàm ẩn danh một chữ cái cũng tiết kiệm không gian, vì nó được sử dụng hai lần.
  • Dbao gồm '0'và các '1'ký tự (mã ASCII 4849), câu lệnh D=char(97-D)tương ứng với đảo ngược giữa '0''1'các giá trị. Lưu ý rằng điều 97này không có gì để làm với điều đó được đề cập ở trên.
  • Chuyển vị liên hợp phức 'được sử dụng thay vì chuyển vị .'.

0

Con trăn 2 - 179

b="".join([bin(ord(i))[2:]for i in input()])
for i in input():b=b[-1]+b[:-1]if i=="r"else b[1:]+b[0]if i=="l"else[str("10".find(j))for j in b]if i=="f"else b[::-1]
print"".join(b)

0

C #, 418 byte

using System;using System.Collections.Generic;using System.Linq;class P{string F(string a,string o){var f=new Dictionary<char,Func<string,IEnumerable<char>>>{{'l',s=>s.Substring(1)+s[0]},{'r',s=>s[s.Length-1]+s.Substring(0,s.Length-1)},{'u',s=>s.Reverse()},{'f',s=>s.Select(c=>(char)(97-c))}};return o.Aggregate(string.Join("",a.Select(c=>Convert.ToString(c,2).PadLeft(8,'0'))),(r,c)=>new string(f[c](r).ToArray()));}}

Định dạng:

using System;
using System.Collections.Generic;
using System.Linq;

class P
{
    string F(string a, string o)
    {
        // define string operations
        var f = new Dictionary<char, Func<string, IEnumerable<char>>>
        {
            {'l', s => s.Substring(1) + s[0]},
            {'r', s => s[s.Length - 1] + s.Substring(0, s.Length - 1)},
            {'u', s => s.Reverse()},
            {'f', s => s.Select(c => (char) (97 - c))}
        };
        // for each operation invoke f[?]; start from converted a
        return o.Aggregate(
            // convert each char to binary string, pad left to 8 bytes and join them
            string.Join("", a.Select(c => Convert.ToString(c, 2).PadLeft(8, '0'))),
            // invoke f[c] on result of prev operation
            (r, c) => new string(f[c](r).ToArray())
        );
    }
}

0

J, 164

([: >@:}. (([: }. >&{.) ; >@:{.@:>@:{. 128!:2 >@:}.)^:({.@:$@:>@:{.))@:(>@:((<;._1 ' 1&|."1 _1&|."1 -. |."1') {~ 'lrfu' i. 0&({::)@:]) ; ;@:([: (8$2)&#: a. i. 1&({::)))

Định dạng:

nextop=:([: }. >&{.)
exec=: (>@:{.@:>@:{.) apply"1 >@:}.
times=: ({.@:$@:>@:{.)
gapply=: [: >@:}. (nextop ; exec)^:(times) f.

tobin=: ;@:([: (8#2)&#:(a.i.1&{::))
g=:'1&|.';'_1&|.';'-.';'|.'
tog =:  g {~ ('lrfu' i. 0&{::@:])
golf=: gapply @: (>@:tog;tobin)  f.

Thí dụ

golf ('rfu';'b')
0 1 1 1 0 0 1 1


golf ('lruuff';'b')
0 1 1 0 0 0 1 0

(8#2)#: 98
0 1 1 0 0 0 1 0

golf ('lruuff';'AB')
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0

tobin '';'AB'
0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0

0

JavaScript (E6), 163 167

Sử dụng đầy đủ tính linh hoạt đầu vào, một chức năng được đặt tên với 2 tham số mảng.

  • Tham số đầu tiên, mảng byte tương ứng với mã ký tự 7 bit
  • Tham số thứ hai, mảng byte tương ứng với các ký tự ascii 'F', 'L', 'R', 'U' -> 70, 76, 82, 85

Hàm trả về một chuỗi ký tự gồm '1' và '0'

F=(a,s,r='')=>
  a.map(c=>r+=(128|c).toString(2).slice(-7))-
  s.map(c=>a=c<71?a.map(c=>1-c):c<77?a.concat(a.shift):c<83?[a.pop(),...a]:a.reverse(),a=[...r])
  ||a.join('')

Ví dụ f("b", "rfu") dịch sang F([98],[82,70,85]), kết quả là0111001

Lưu ý sử dụng chuỗi ký tự dài hơn rất nhiều trong javascript! Byte đếm 186

F=(a,s,r='')=>
  [for(c of a)r+=(128|c.charCodeAt()).toString(2).slice(-7)]-
  [for(c of(a=[...r],s))a=c<'G'?a.map(c=>1-c):c<'M'?a.concat(a.shift):c<'S'?[a.pop(),...a]:a.reverse()]
  ||a.join('')

Ví dụ F("b", "RFU") , kết quả là 0111001một lần nữa


0

Ruby, 151

f=->i,s{s.chars.inject(i.unpack("B*")[0]){|a,c|
a.reverse! if c==?u
a.tr!"01","10" if c==?f
a<<a.slice!(1..-1) if c==?l
a<<a.slice!(0..-2) if c==?r
a}}

Khá đơn giản. Vòng lặp máng các nhân vật trong svà thực hiện một hành động cho bất kỳ trong số họ.


0

Con trăn 2, 142

j="".join
f=lambda S,I:reduce(lambda s,i:[s[1:]+s[0],s[-1]+s[:-1],s[::-1],j([`1^int(c)`for c in s])][int(i)],I,j([bin(ord(c))[2:]for c in S]))

Tương tự như câu trả lời thứ ba của tôi trong cách tiếp cận: Tôi xây dựng một danh sách tất cả các chuỗi và chỉ mục vào nó dựa trên giá trị của chuỗi lệnh mà tôi lặp lại bằng cách sử dụng giảm.

Sử dụng:

0  ->  Rotate left
1  ->  Rotate right
2  ->  Reverse order
3  ->  Invert bits
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.