小包を解析する


24

マークマイメールチャレンジでの支援のおかげで、PPCG-Postは生成されたバーコードですべての小包に正常にスタンプしました!

次に、それらをデコードします。

このチャレンジでは、Mark My Mailチャレンジから生成されたバーコードを指定して、プログラムがそれをデコードし、エンコードされた整数を返します。

しかし、気をつけて!バーコードが上下逆になっている可能性があります...


4ステートバーコード

エンコードの課題を逃した場合は、どのようなバーコードについて話しているのかを知る必要があります。4状態バーコードは、4つの可能な状態を持つバーの行で、それぞれが4を超える整数を表します。

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

ASCIIでレンダリングされたバーコードは3行のテキストを取り、パイプ(|)文字を使用してバーの一部を表し、スペース()を使用して空のセクションを表します。各バーの間に1つのスペースがあります。バーコードの例は次のようになります。

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

バーコードをエンコードした整数に戻すには、各バーを対応する4進数にマッピングし、それらを連結して、10進数に変換します。

各バーコードは上下を逆にすると異なるバーコードを表すため、オリエンテーションを計算できるように開始/停止シーケンスを実装します。この課題のために、Australia Postが指定する開始/停止シーケンスを使用します。各バーコードは1 0シーケンスで始まり、シーケンスで終わります。


チャレンジ

あなたの仕事は、ASCII 4状態バーコードを与えられ、それを解析し、それがエンコードする整数を返すことです-基本的にはMark My Mailの逆です。

しかし、物事を刺激するために、キャッチがあります - バーコードは逆さまに与えられるかもしれません。現実世界と同様に、バーコードリーダー(プログラム)に任せて、開始/停止シーケンスを使用して正しい方向決定します

例:

次のバーコードがある場合:

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

数字の最初と最後のペアがあるか0, 2ないかをはっきりと見ることができ1, 0ます。これは、バーコードが上下逆になっていることを意味します。したがって、正しい向きを実現するには、バーコードを180度回転する必要があります(各バーを反転するだけではありません)。

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

これで、デコードを開始できます。データをエンコードしないため、開始/停止シーケンスを無視して、各バーを対応するベース4桁にマッピングします。

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

--2 1 0 3 0 2 3--

これを基数4の整数2103023に連結9419し、最終結果のために10進表現に変換します。


ルール

  • 入力は常に、前述の開始/停止シーケンスを使用して、上記のようにASCIIでレンダリングされた有効な4ステートバーコードになります。
    • ゴルフに適した形式であれば、末尾のスペース、またはストリップされた行、および末尾の改行を要求できます。
    • 正しい向きである場合とそうでない場合があります-プログラムは、開始/停止シーケンスを使用して、逆さまに読み取るかどうかを判断する必要があります。
    • 基数4整数の先行ゼロ桁はエンコードしません。
  • 入力は、行のリスト、または改行を含む文字列として取得できます。
  • 出力は、バーコードによってエンコードされたデータを表す、言語の標準整数ベースの整数でなければなりません。
  • 郵便切手は小さく、それらに非常に小さなコードを収めることができるため、コードはできるだけ短くする必要があります。これは -最短のプログラム(バイト単位)が勝ちます!

テストケース

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

= 4096(反転)

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

= 7313145(反転)

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

= 9419(反転)

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

= 990(反転しない)

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

= 12345(反転しない)


-1 2つの投稿のタイトルは同じ形式ではありません。(「P the P」対「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から単項に変換します。

.*¶$
$&$&

最後の行を二重にします。

\|

10進数に変換します。


2

Java(OpenJDK 8)181 160バイト

Javaの解決策としては粗末ではありませんが、最適化ができると確信していますが、すでにこれを見つめすぎています。

部分文字列を使用するのではなく、ループを短くして、数バイトを削減します。

ゴルフ

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を与え、[OK]を私はこれをフォーマットしますが、例の1しかし、あなたが持っているexmpleを試みるが、それを反転させずに、多分私は悪い入力:)やっカント
JavaのGonzar

@JavaGonzalezArribas最初の例を試してみました(裏返していない)。うまくいくようです。入力の最初の行にスペースが少なすぎますか?
ルークスティーブンス

それはおそらく問題です、素晴らしい答え:)
Java Gonzar

提案l+~iの代わりにl-1-i
ceilingcat

2

Javaの8208 166 157 151バイト

それを試してみると、おそらくより良いことがあり、不要なチェックのために42を減らし、-9変数を削除し、-6をLuke Stevensに感謝します

入力は 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バイトのラムダを宣言するときに、aを囲む括弧を削除することもできます。
ルークスティーブンス


1

ピップ46 43 42バイト

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

バーコードの行を3つのコマンドライン引数として受け取ります。1行目と3行目は、2行目の長さまでスペースで埋める必要があります。オンラインでお試しください!

説明

最初にいくつかの準備作業:

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ビットの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があり、これを作成しているときに頭痛の種になります...配列にインデックスを付ける前に反転させる最適な方法が必要だと思いますが、それを行うには非常に多くの方法があります(最初のインデックスで、またはいずれかとflipudfliplrrot90'(トランスポーズ)、最終インデックス...)。スペースと|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

JavaScript(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.