소포 파싱


24

Mark My Mail 챌린지 에 대한 도움 덕분에 PPCG-Post는 생성 된 바코드로 모든 소포를 성공적으로 스탬프 처리했습니다!

이제 해독 할 차례입니다.

이 챌린지에서 프로그램은 Mark My Mail 챌린지 에서 생성 된 바코드가 주어지면이를 해독하고 인코딩 된 정수를 반환합니다.

그러나 조심하십시오! 바코드가 거꾸로되어있을 수 있습니다.


4 상태 바코드

인코딩 문제를 놓친 경우 어떤 종류의 바코드를 사용해야하는지 알아야합니다. 4 상태 바코드는 4 개의 가능한 상태를 가진 일련의 막대로, 각각 4 자리 정수를 나타냅니다.

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

ASCII로 렌더링 된 바코드는 파이프 ( |) 문자를 사용하여 막대의 일부를 나타내고 공백 ( )을 사용하여 빈 섹션을 나타내는 세 줄의 텍스트를 사용합니다 . 각 막대 사이에 하나의 공백이 있습니다. 바코드 예는 다음과 같습니다.

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

바코드를 인코딩 된 정수로 다시 변환하려면 각 막대를 해당하는 기본 4 자리 숫자로 매핑하고이를 연결 한 다음 10 진수로 변환하십시오.

각 바코드는 거꾸로 되어도 다른 바코드를 나타내므로 시작 / 중지 시퀀스를 구현하여 오리엔테이션을 계산할 수 있습니다. 이 과제를 위해 Australia Post에서 지정한 시작 / 중지 시퀀스를 사용합니다. 각 바코드는 1 0시퀀스로 시작하고 끝납니다 .


도전

당신의 임무는 ASCII 4- 상태 바코드가 주어지면, 그것을 분석하고 인코딩 한 정수를 반환하는 것입니다. 본질적으로 Mark My Mail 의 반대입니다 .

그러나 물건을 꾸미기 위해 잡기 가 있습니다. 바코드가 거꾸로 나올 수 있습니다. 실제와 마찬가지로 시작 / 중지 순서를 사용하여 올바른 방향결정 하기 위해 바코드 리더 (프로그램)에 남아 있습니다 .

예:

다음과 같은 바코드가 있습니다 :

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

우리는 숫자의 첫 번째와 마지막 쌍이 0, 2아닌 것을 분명히 볼 수 있습니다 1, 0. 즉, 바코드가 거꾸로되어 있으므로 올바른 방향을 얻으려면 각 막대를 뒤집는 것이 아니라 180도 회전 해야합니다 .

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

이제 디코딩을 시작할 수 있습니다. 데이터를 인코딩하지 않기 때문에 시작 / 중지 시퀀스를 무시하고 각 막대를 해당하는 기본 4 자리 숫자에 매핑합니다.

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

--2010 3 3--

이것을 base-4 integer 2103023에 연결 한 다음 9419최종 결과 를 위해 10 진수로 변환합니다 .


규칙

  • 입력은 항상 설명 된 시작 / 중지 시퀀스와 함께 위에서 설명한대로 ASCII로 렌더링 된 유효한 4 상태 바코드입니다.
    • 후행 공백이나 줄 바꿈 및 후행 줄 바꿈 (골프에 적합한 형식)을 요청할 수 있습니다.
    • 올바른 방향 일 수도 있고 아닐 수도 있습니다. 프로그램은 시작 / 중지 순서를 사용하여 거꾸로 읽을 지 여부를 결정해야합니다.
    • base-4 정수에서 선행 0 자리를 인코딩하지 않습니다.
  • 입력을 줄 목록 또는 줄 바꿈 문자열로 사용할 수 있습니다.
  • 출력은 언어 표준 정수 기반의 정수 여야하며 바코드로 인코딩 된 데이터를 나타냅니다.
  • 우표가 작고 코드에 아주 작은 코드를 넣을 수 있으므로 코드는 가능한 짧아야합니다. 이것은 . 따라서 가장 짧은 프로그램 (바이트)이 이깁니다!

테스트 사례

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

= 4096 (플 리핑)

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

= 7313145 ( 플 리핑 )

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

= 9419 ( 플 리핑 )

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

= 990 ( 뒤집지 않음)

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

= 12345 ( 뒤집지 않음)


-1 두 게시물의 제목이 같은 형식이 아닙니다. ( "P the P"vs "M my M", 'the'또는 'my': p 선택)
Rɪᴋᴇʀ

1
"라인의 목록"중 하나가 될 것입니다 [String], [{#Char}], [{Char}], [[Char]]?, 주어진 String것과 같습니다{#Char}
Οurous

3
@Ouros 그게 무슨 표기법입니까? 데이터 유형이 언어마다 매우 다르기 때문에 대답이 "예"라고 강력하게 생각합니다. 따라서 코딩 문제는 일반적으로 "해당 언어에 해당하는 것이 무엇이든"을 받아들입니다.
IMSoP

1
무엇 향후 계획? 이메일을 보내시겠습니까? 전보를 전송 하시겠습니까? 게시물을 처리 하시겠습니까?
Sanchises

1
@Ourous 예, IMSoP가 설명했듯이 데이터 유형은 유연합니다.
FlipTack

답변:



5

껍질 , 16 바이트

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

온라인으로 사용해보십시오!

입력은 행 목록입니다 (TIO 링크는 명확성을 위해 여러 줄 문자열을 사용합니다). 줄의 길이는 같아야하며 추가 공백이 없어야합니다.

설명

ḋṁẊ=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

망막 , 71 바이트

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

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

온라인으로 사용해보십시오! 링크에는 작은 테스트 사례가 포함됩니다. 첫 번째와 마지막 줄은 중간 줄 길이만큼 공백으로 채워야합니다. 설명:

(.).
$1

불필요한 공간을 삭제하십시오.

sO$^`^\|.*|.

코드의 문자를 반대로 바꾸십시오. 그러나 바코드가로 시작 |하면 전체 코드를 선택하고 그렇지 않으면 문자로 분할하십시오. 그런 다음 뒤집으십시오. 코드가로 시작하면 코드가 반전됩니다 0.

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

시작 / 중지 시퀀스와 가운데 행을 삭제하십시오 (우리에게는 쓸모가 없습니다).

\|
 |
+`\| 
 ||||

공백과 |s를 밑 4에서 단항으로 변환하십시오 .

.*¶$
$&$&

마지막 줄을 두 배로 늘리십시오.

\|

십진수로 변환합니다.


2

자바 (오픈 JDK 8) , 181 (160) 바이트

자바 솔루션에 너무 초라하지는 않지만, 내가 만들 수있는 최적화가 있다고 확신하지만 이미 너무 오랫동안 쳐다 보았습니다.

부분 문자열을 사용하는 대신 루프를 줄여 몇 바이트를 줄이십시오.

골프

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

온라인으로 사용해보십시오!

언 골프

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

코드를 시도했지만 예제 "| | |"의 역 바코드로 "| | | | | | | | | | |" 그리고 나에게 1024를 주라. 좋아, 나는 이것을 포맷 할 수 없지만, 예제에서 하나는 있지만, 당신이 가지고있는 exmple을 시도하지만 그것을
뒤집지

@JavaGonzalezArribas 첫 번째 예제를 시도했지만 뒤집지 않았습니다. 입력의 첫 줄에 공백을 너무 적게 넣을 수 있습니까?
Luke Stevens

아마 문제, 좋은 대답은 :)하는지
자바 Gonzar

l+~i대신 추천l-1-i
ceilingcat

2

자바 (8) , 208 (166) 157 151 바이트

루크 스티븐스 (Luke Stevens) 덕분에 불필요한 검사로 인해 42 개 감소, -9 개 변수 제거, -6 개 시도

입력은 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;}

언 골프 :

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
문자열 대신 문자 배열을 사용하는 경우 | == "|"대신> 32를 사용하여 각 사용에 대해 2 바이트를 절약합니다 (전체 6 개). 다른 2 바이트에 대한 람다를 선언 할 때 괄호를 제거 할 수도 있습니다.
Luke Stevens


1

, 46 43 42 바이트

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

바코드 줄을 세 개의 명령 줄 인수로 사용합니다. 첫 번째와 세 번째 줄은 두 번째 줄의 길이에 공백을 채워야합니다. 온라인으로 사용해보십시오!

설명

먼저 몇 가지 준비 작업 :

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

중간 행을 무시하고 |1과 0으로 취급 하면 각 막대는 2 비트 이진수 일뿐입니다.

(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

껍질 , 39 38 바이트

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

문자열 목록으로 입력합니다 : 온라인으로 시도 하거나 시험 복을 사용해보십시오 !

설명

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

옥타브 , 80 75 68 바이트

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

온라인으로 사용해보십시오!

흥미롭게도, bi2de왼쪽이 아닌 오른쪽에 기본 MSB가 있어서이 작업을 수행하는 동안 두통이 생길 수 있습니다 ... 인덱싱하기 전에 배열을 뒤집는 최적의 방법이 있어야한다고 생각하지만 그렇게하는 방법 은 매우 많습니다 ( 중 첫번째 인덱스에 또는 함께 flipud, fliplr, rot90, '(트랜스), 최종 인덱싱 ...). 공백과 |s를 가진 직사각형 배열을 취합니다 (따라서 후행 공백이 필요합니다)

@(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

자바 스크립트 (ES6) 184 181 바이트

나는 경험 많은 골퍼가 아닙니다-이것이 향상 될 수 있다고 확신하지만이 도전을 좋아했습니다! 나는 항상 그 마크에 대해 궁금했습니다.

함수 f는 후행 공백이 필요한 문자열 목록을 가져옵니다. 명확성을 위해 아래 코드에 줄 바꿈이 추가되었습니다 (바이트 수에는 포함되지 않음).

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)

용법

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

설명이 포함 된 언 골프 버전

// 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.