Phân tích bưu kiện


24

Nhờ sự giúp đỡ của bạn trong thử thách Mark My Mail , PPCG-Post đã đóng dấu thành công tất cả các bưu kiện của mình bằng mã vạch được tạo!

Bây giờ, đã đến lúc giải mã chúng.

Trong thử thách này, chương trình của bạn sẽ, đưa ra một mã vạch được tạo từ thử thách Mark My Mail , giải mã nó và trả về số nguyên được mã hóa.

Nhưng xem ra! Mã vạch có thể bị lộn ngược ...


Mã vạch 4 trạng thái

Trong trường hợp bạn bỏ lỡ thử thách mã hóa, bạn sẽ cần biết loại mã vạch nào chúng ta đang nói đến. Mã vạch 4 trạng thái là một hàng thanh có bốn trạng thái có thể, mỗi trạng thái đại diện cho một số nguyên cơ sở 4:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

Được hiển thị trong ASCII, mã vạch sẽ chiếm ba dòng văn bản, sử dụng |ký tự pipe ( ) để thể hiện một phần của thanh và dấu cách ( ) để thể hiện một phần trống. Sẽ có một khoảng trống ở giữa mỗi thanh. Một mã vạch ví dụ có thể trông như thế này:

| | | | | | | | | |
| | | | | | | | | | | | | | | | |
    | | | | | | | |

Để chuyển đổi mã vạch trở lại số nguyên mà nó mã hóa, ánh xạ mỗi thanh thành chữ số cơ sở tương ứng của nó, nối các mã này và chuyển đổi nó thành số thập phân.

Vì mỗi mã vạch cũng sẽ đại diện cho một mã vạch khác nhau khi lộn ngược, chúng tôi thực hiện một chuỗi bắt đầu / dừng để có thể tính toán nguồn gốc. Với mục đích của thử thách này, chúng tôi sẽ sử dụng chuỗi bắt đầu / dừng được chỉ định bởi Australia Post: mỗi mã vạch bắt đầu và kết thúc bằng một 1 0chuỗi.


Các thách thức

Nhiệm vụ của bạn là, được cung cấp mã vạch 4 trạng thái ASCII, phân tích cú pháp và trả về số nguyên mà nó mã hóa - về cơ bản là đảo ngược của Mark My Mail .

Nhưng để cải thiện mọi thứ, có một nhược điểm - mã vạch có thể bị đảo lộn. Như trong thế giới thực, nó sẽ được để lại cho đầu đọc mã vạch (chương trình của bạn) để xác định hướng chính xác bằng cách sử dụng chuỗi bắt đầu / dừng.

Thí dụ:

Cho mã vạch sau:

    | | | |
| | | | | | | | | | |
  | | | | |

Chúng ta có thể thấy rõ rằng các cặp chữ số đầu tiên và cuối cùng có 0, 2và không 1, 0. Điều này có nghĩa là mã vạch bị lộn ngược - vì vậy chúng ta phải xoay 180 độ (không chỉ lật từng thanh) để đạt được hướng chính xác:

| | | | |  
| | | | | | | | | | |
    | | | |    

Bây giờ, chúng ta có thể bắt đầu giải mã. Chúng tôi ánh xạ mỗi thanh đến chữ số cơ sở 4 tương ứng của nó, bỏ qua các chuỗi bắt đầu / dừng vì chúng không mã hóa dữ liệu.

| | | | |  
| | | | | | | | | | |
    | | | |    

- - 2 1 0 3 0 2 3 - -

Chúng tôi ghép nó thành số nguyên cơ số 4 2103023, sau đó chuyển đổi nó thành biểu diễn thập phân của nó 9419cho kết quả cuối cùng.


Quy tắc

  • Đầu vào sẽ luôn là mã vạch 4 trạng thái hợp lệ, được hiển thị trong ASCII như được nêu ở trên, với trình tự bắt đầu / dừng được mô tả.
    • Bạn có thể yêu cầu các dấu cách, hoặc các vạch bị tước, cũng như một dòng mới ở cuối - bất kỳ định dạng nào phù hợp với việc chơi gôn của bạn.
    • Nó có thể hoặc không thể theo đúng hướng - chương trình của bạn phải xác định xem có nên đọc ngược nó hay không, bằng cách sử dụng trình tự bắt đầu / dừng.
    • Nó sẽ không mã hóa các chữ số 0 hàng đầu trong số nguyên cơ sở 4.
  • Bạn có thể lấy đầu vào làm danh sách các dòng hoặc một chuỗi có dòng mới.
  • Đầu ra phải là một số nguyên trong cơ sở số nguyên tiêu chuẩn của ngôn ngữ của bạn, đại diện cho dữ liệu được mã hóa bằng mã vạch.
  • Vì tem bưu chính nhỏ và có thể chứa rất ít mã trên chúng, mã của bạn sẽ cần phải ngắn nhất có thể: đây là một - vì vậy chương trình ngắn nhất (tính bằng byte) sẽ thắng!

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

| | | | | | | | | | |
  | | |

= 4096 (lật)

      | | | | | | | |
| | | | | | | | | | | | | | | |
  | | | | | | | | | |

= 7313145 (lật)

    | | | |
| | | | | | | | | | |
  | | | | |

= 9419 (lật)

| | | | | |   
| | | | | | | | |
    | | | |     

= 990 (không lật)

| | | | |   
| | | | | | | | | | |
    | | |       

= 12345 (không lật)


-1 tiêu đề trên hai bài viết không cùng định dạng. ("P the P" so với "M my M", chọn 'the' hoặc 'my': p)
Rɪᴋᴇʀ

1
Sẽ "danh sách các dòng" là bất kỳ [String], [{#Char}], [{Char}], [[Char]]?, Cho rằng Stringtương đương với{#Char}
Οurous

3
@Ouros Ký hiệu đó là gì? Tôi hoàn toàn nghi ngờ câu trả lời là "có", bởi vì các loại dữ liệu rất khác nhau giữa các ngôn ngữ, do đó, các thách thức về mã hóa thường chấp nhận "bất cứ thứ gì tương đương trong ngôn ngữ của bạn", nhưng tôi không biết bạn đại diện cho những biểu hiện nào khác nhau.
IMSoP

1
Cái gì tiếp theo? Phát ra email? Truyền Telegram? Xử lý bài?
Sanchise

1
@Ourous có, kiểu dữ liệu rất linh hoạt, như IMSoP đã mô tả.
FlipTack

Câu trả lời:



5

Husk , 16 byte

ḋṁẊ=hhttĊ2T§▼↔m↔

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

Đầu vào là danh sách các dòng (liên kết TIO sử dụng chuỗi nhiều dòng cho rõ ràng). Các dòng phải có độ dài bằng nhau và không được có thêm dấu cách.

Giải trình

ḋṁẊ=hhttĊ2T§▼↔m↔  Input is a list of strings x.
           §▼     Lexicographic minimum of
             ↔    x reversed and
              m↔  x with each line reversed.
          T       Transpose. Now we have a list of columns.
        Ċ2        Get every second column, removing the blank ones.
    hhtt          Remove first 2 and last 2 (the orientation markers).
 ṁ                Map and concatenate
  Ẋ=              equality of adjacent pairs.
                  This turns a column like "|| " into [1,0], and these pairs are concatenated.
ḋ                 Convert from binary to integer.




2

Võng mạc , 71 byte

(.).
$1
sO$^`^\|.*|.

^..|..¶.*¶..|..$
¶
\|
 |
+`\| 
 ||||
.*¶$
$&$&
\|

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm nhỏ hơn. Yêu cầu các dòng đầu tiên và cuối cùng được đệm không gian theo chiều dài của dòng giữa. Giải trình:

(.).
$1

Xóa các khoảng trống không cần thiết.

sO$^`^\|.*|.

Đảo ngược các ký tự trong mã, nhưng nếu mã vạch bắt đầu bằng a |, sau đó chọn toàn bộ mã, nếu không thì chia nó thành các ký tự. Sau đó, đảo ngược chúng. Điều này lật mã nếu nó bắt đầu bằng a 0.

^..|..¶.*¶..|..$
¶

Xóa trình tự bắt đầu / dừng và hàng giữa (không có ích cho chúng tôi).

\|
 |
+`\| 
 ||||

Chuyển đổi không gian và |s từ cơ sở 4 sang unary.

.*¶$
$&$&

Nhân đôi dòng cuối cùng.

\|

Chuyển đổi thành số thập phân.


2

Java (OpenJDK 8) , 181 160 byte

Không quá tồi tệ cho một giải pháp java, tôi chắc chắn có những tối ưu hóa tôi có thể thực hiện, nhưng tôi đã nhìn chằm chằm vào điều này quá lâu.

Cắt giảm một vài byte bằng cách rút ngắn vòng lặp thay vì sử dụng chuỗi con.

Chơi gôn

c->{String r="";Integer i,j,l=c[0].length;for(i=4;i<l-4;i+=2){j=c[0][0]>32?i:l-1-i;r+=c[0][j]%8/4*(j==i?1:2)+c[2][j]%8/4*(j==i?2:1)+"";}return l.parseInt(r,4);}

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

Bị đánh cắp

String r = "";
Integer i, j, l = c[0].length;
for(i=4; i<l-4; i+=2){
    j = c[0][0]>32 ? i : l-1-i;
    r += c[0][j]%8/4 * (j==i?1:2) + c[2][j]%8/4 * (j==i?2:1) + "";
}
return l.parseInt(r, 4);

Chỉ cần thử mã của bạn nhưng với mã vạch đảo ngược của ví dụ "| | |" "| | | | | | | | | | | |" và đưa cho tôi 1024, Ok tôi không thể định dạng cái này, nhưng ví dụ về ví dụ, nhưng hãy thử exmple bạn có nhưng không đảo ngược nó, có thể tôi đã làm một đầu vào tồi :)
Java Gonzar 19/12/17

@JavaGonzalezArribas Tôi đã thử ví dụ đầu tiên (không lật) và nó có vẻ hoạt động tốt. Có thể là bạn đặt quá ít khoảng trắng trong dòng đầu tiên của đầu vào?
Luke Stevens

Đó có lẽ là vấn đề, câu trả lời tuyệt vời :)
Java Gonzar

Đề xuất l+~ithay vìl-1-i
trần

2

Java 8 , 208 166 157 151 byte

Dùng thử, có thể tốt hơn, giảm 42 do kiểm tra không cần thiết, -9 loại bỏ biến, -6 nhờ Luke Stevens

Đầu vào là một char[][3]

(a)->{int i=2,c,s=0;c=(a[0][0]>32)?1:-1;for(;i<a.length-2;i++){s+=((a[i][1-c]>32?1:0)+(a[i][1+c]>32?2:0))*Math.pow(4,c==1?a.length-i-3:i-2);}return s;}

vô dụng:

int b(char[][] a) {
    int i=2,c,s=0;                      //i for looping, c to check if it's reversed, s is the sum, n the number
    c=(a[0][0]>32)?1:-1; //Check if must be reversed

    for(;i<a.length-2;i++){         //Looping elements

            //(Checking value for 1 + Checking value for 2) * Power, if reversed increasing, else decreasing
        s+=((a[i][1-c]>32?1:0)+(a[i][1+c]>32?2:0))*Math.pow(4,c==1?a.length-i-3:i-2);   
    }
    return s;
}

1
Nếu bạn sử dụng một mảng ký tự thay vì Chuỗi, bạn có thể kiểm tra | bằng cách sử dụng> 32 thay vì == "|" giúp tiết kiệm 2 byte cho mỗi lần sử dụng (6 tổng thể). Bạn cũng có thể xóa dấu ngoặc quanh a khi khai báo lambda cho hai byte khác.
Luke Stevens


1

Pip , 46 43 42 byte

IsQ@@gg:RV*RVgY^gR'|1(J@UW2*y@2+@y)TM2FB:4

Lấy các dòng của mã vạch là ba đối số dòng lệnh. Các dòng đầu tiên và thứ ba phải được đệm theo chiều dài của dòng thứ hai với khoảng trắng. Hãy thử trực tuyến!

Giải trình

Đầu tiên một số chuẩn bị:

IsQ@@gg:RV*RVg Y^gR'|1

                        g is cmdline args; s is space (implicit)
IsQ                     If space equals
   @@g                  the first character of the first line, then:
           RVg           Reverse the order of the rows in g
        RV*              then reverse the characters in each row
      g:                 and assign the result back to g
                 gR'|1  In g, replace pipe character with 1
                ^       Split each row into a list of characters
               Y        Yank the result into y

Bây giờ hãy quan sát rằng nếu chúng ta bỏ qua hàng giữa và coi |là 1 và 0, thì mỗi thanh chỉ là một số nhị phân 2 bit:

(J@UW2*y@2+@y)TM2FB:4

       y@2             Third row
     2*                Multiply by 2, turning 1 into 2 and space into 0
           @y          First row
          +            Add
   UW                  Unweave: creates a list of two lists, the first containing all
                       even-indexed elements (in our case, the actual data), the second
                       containing all odd-indexed elements (the space separators)
  @                    First item of that list
 J                     Join the list of digits into a string
(            )TM2      Trim 2 characters from the beginning and end
                 FB:4  Convert from base 4 (: makes the precedence lower than TM)
                       Autoprint

1

Husk , 39 38 byte

B4ththmȯ%4+3%5f≠192Ḟz+zṀ·*cN?↔m↔(='|←←

Lấy đầu vào dưới dạng danh sách các chuỗi: Dùng thử trực tuyến hoặc thử bộ phần mềm thử nghiệm!

Giải trình

B4ththm(%4+3%5)f≠192Ḟz+zṀ·*cN?↔m↔(='|←←)
                             ?   (='|←←)  -- if the very first character == '|'
                              ↔           --   reverse the lines
                                          -- else
                               m↔         --   reverse each line
                       zṀ·*cN             -- zip the lines with [1,2,3..] under..
                        Ṁ·*c              --   convert each character to its codepoint and multiply by one of [1,2,3]
                    Ḟz+                   -- reduce the lines under zipWith(+) (this sums the columns)

               f≠192                      -- only keep elements ≠ 192 (gets rid of the separating lines)

-- for the example from the challenge we would now have:
--   [652,376,468,652,376,744,376,468,744,652,376]

      m(      )                           -- map the following function
        %4+3%5                            --   λx . ((x % 5) + 3) % 4
-- this gives us: [1,0,2,1,0,3,0,2,3,1,0]
    th                                    -- remove first & last element
  th                                      -- remove first & last element
B4                                        -- interpret as base4 number


0

Octave , 80 75 68 byte

@(b)bi2de({rot90(t=~~(b-32)([3,1],[1:2:end]),2),t}{2-t(2)}(5:end-4))

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

Thật kỳ lạ, bi2deMSB mặc định ở bên phải chứ không phải bên trái, dẫn đến một số vấn đề đau đầu trong khi tôi thực hiện điều này ... Tôi nghĩ rằng tôi nên có cách tối ưu để lật mảng trước khi lập chỉ mục, nhưng có rất nhiều cách để làm điều đó ( hoặc trong việc lập chỉ mục đầu tiên, hoặc với flipud, fliplr, rot90, '(transpose), việc lập chỉ mục cuối cùng ...). Tạo một mảng hình chữ nhật có dấu cách và |s (vì vậy, dấu cách cần có)

@(b)                    % Define anonymous function taking input b

t=                      % Inline-define t,
~~(b-32)                % which is the input, converted to 1's and 0's,
([3 1],[1:2:end])       % but only keep the relevant rows (1 and 3 flipped vertically) and columns (only odd) 

{rot90(t,2),t}          % Flip 180 degrees
{2-t(2)                 % depending on whether the second element of t is 1 or 0.}

(5:end-4)               % Flatten array, discarding control bits
bi2de( ... )            % and convert from binary to decimal,

0

JavaScript (ES6), 184 181 byte

Tôi không phải là một tay golf có kinh nghiệm - Tôi chắc chắn điều này có thể được cải thiện, nhưng tôi yêu thích thử thách này! Tôi đã luôn tự hỏi về những dấu hiệu đó.

Hàm flấy một danh sách các chuỗi có khoảng trắng theo yêu cầu. Các dòng mới được thêm vào mã bên dưới cho rõ ràng (không bao gồm trong số byte).

f=t=>((o=[[...t[0]],[...t[2]]])[0][0]=='|'?o:(z=a=>a.reverse())(o.map(z)))
.map((a,r)=>a.filter((_,i)=>~i%2).map(e=>(1+r)*(e=='|')).slice(2,-2))
.reduce((a,b)=>a+parseInt(b.join``,4),0)

Sử dụng

t=['                     ','| | | | | | | | | | |','  |             |   |']
console.log(f(t)) // 4096

Phiên bản Ungolfed với lời giải thích

// take list of strings, t, as input:
f = t => ( 

  // create output variable o, discard middle row, turn other rows into lists:
  ( o = [ [...t[0]], [...t[2]] ] )

  // if top-left position isn't a pipe, rotate 180 degrees.
  // Alias [].reverse to save 3 bytes :D
  [0][0] == '|' ? o : ( z = a=> a.reverse() )( o.map(z) )

).map( (a,r) => 

  // remove even-numbered positions (non-encoding spaces):
  a.filter( (_,i) => ~i%2 )

  // convert non-pipes into zeros, and pipes into 1 or 2;
  // top row becomes the base4 1-component, bottom row is 2:
  .map( e => (1+r) * (e=='|') ).slice(2,-2)

// convert rows to base4 component strings, then decimal, then sum them:
).reduce( (a,b) => a + parseInt(b.join``,4),0)
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.