Barcodegolf:数値のUPCを生成する


12

最近では、ほぼすべての店舗でUniversal Product Code(UPC)バーコードを使用して、チェックアウトプロセスを簡素化しています。名前があなたにとって何の意味も持たない場合、あなたは彼らがどのように見えるかを確実に認識するでしょう:

サンプルUPC-Aバーコード

フォーマット

最も一般的なシステムはUPC-Aで、12桁を使用して特定の製品を表します。各桁は一連の黒と白のストライプにエンコードされ、マシンが7ビット長のコードを読み取れるようにします。バーコードの開始、中間、終了を示す合計11ビットのパターンがあります。これにより、バーコードの合計長は12×7 + 11 = 95ビットになります。(これから、各ビットの色を参照するためにバイナリが使用される場合、0白と1黒になります。)

開始と終了の両方のパターンがあり101ます。次に、数字は6つの2つのグループに分割され、以下に示すようにエンコードされます01010。左右のグループの間にパターンがあります。次の表に、各番号のパターンを示します。パターンは、数字が右側にあるか左側にあるかによって異なります(これにより、バーコードを上下逆さまにスキャンできます)。ただし、右のパターンは左のパターンの反対です(白を黒に、逆に白をスワップ)。

UPC変換表

上の画像が表示されない場合、これは各数値のバイナリに相当します。

#   Left    Right
0   0001101 1110010
1   0011001 1100110
2   0010011 1101100
3   0111101 1000010
4   0100011 1011100
5   0110001 1001110
6   0101111 1010000
7   0111011 1000100
8   0110111 1001000
9   0001011 1110100

UPCを持っているとしましょう022000 125033。(これらは乱数ではありません。それらの重要性を理解したら、コメントを残してください。)すべてのバーコードで同じこの定型文から始めます。

101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx101

数字については、各数字を、それが存在する側(左または右)に対応するエンコードに置き換えます。まだ混乱している場合は、下の画像を参照してください。

UPCエンコーディングの内訳

以下は、|パーツを分離するパイプを使用したバイナリ出力です。

101|0001101|0010011|0010011|0001101|0001101|0001101|01010|1100110|1101100|1001110|1110010|1000010|1000010|101

チャレンジ

ユーザー入力用のUPC-Aバーコードを出力するプログラムを作成します。画像のサイズは95×30ピクセルで、各「ビット」は幅1ピクセル、高さ30ピクセルでなければなりません。黒のストライプが入ってrgb(0, 0, 0)おり、白のストライプが常に透明またはになっていrgb(255, 255, 255)ます。

ノート

  • stdinまたはコマンドラインから入力を取得するか、文字列または整数を取得する関数を記述します(入力には先行ゼロが含まれることがあり、ほとんどの言語ではそれらを削除するか、数値を8進数に変換します)。
  • 次のいずれかの方法で画像を出力します。
    • 任意の名前と形式(PNG、PBMなど)でファイルに保存します。
    • 画面に表示します。
    • ファイルデータをstdoutに出力します。
  • 画像またはグラフィックスライブラリを使用しても、バーコードを生成するライブラリまたはビルトインを使用することはできません(Mathematicaを参照しています)。
  • UPCの最後の数字は通常チェックディジットですが、これらの目的のためにそれについて心配する必要はありません。

コードをテストするためのいくつかの例を次に示します。便宜上、バイナリ出力も提供されます。

入力: 012345678910

出力:

10100011010011001001001101111010100011011000101010101000010001001001000111010011001101110010101

入力: 777777222222

出力:

10101110110111011011101101110110111011011101101010110110011011001101100110110011011001101100101

得点

これはコードGolfですので、最短の提出(バイト単位)が勝ちです。Tiebreakerは最初の投稿に移動します。


うーん...ジューシーなフルーツ。
デニス

入力を配列として取り込むことはできますか?例["777777","222222"]
ダウンゴート

@vihanうーん、それは少しストレッチだと思う。私はノーと言うつもりです。
NinjaBearMonkey

2
初めてスキャンされたUPCバーコード!
デニス

1
これは素晴らしいです。バーコードはいつも私を魅了してきました
ベータ崩壊

回答:


3

CJam、58 57バイト

'P1N95S30N[A1r:~"rflB\NPDHt":i2fbf=:R6<::!0AAR6>A1]s30*S*

ポータブルBitMap(ASCII)をSTDOUTに出力します。オンラインでお試しください。

使い方

'P1N95S30N     e# Push 'P', 1, '\n', 95, ' ', 30 and '\n'.

[              e#
  A1           e#   Push 10 and 1.
  r            e#   Read a token from STDIN.
  :~           e#   Caluate each character ('0' -> 0).
  "rflB\NPDHt" e#   Push that string.
  :i           e#   Cast each character to integer.
               e#   This pushes [114 102 108 66 92 78 80 68 72 116].
  2fb          e#   Convert each integer to base 2.
               e#   This pushes the representations for the right side.
  f=           e#   Select the proper representation of each digit in the input.
  :R           e#   Save the result in R.
  6<           e#   Keep the representations of the first six digits.
  ::!          e#   Negate each binary digit to obtain the "left" representation.
  0AA          e#   Push 0, 10, 10.
  R6>          e#   Push the representations of the last six digits.
  A1           e#   Push 10, 1.
]s             e# Collect in an array and cast to string.

30*            e# Repeat the resulting string 30 times.
S*             e# Join it, using spaces as separators.

4

Rev 1 BBC BASIC、155 ASCII文字、トークン化ファイルサイズ132バイト

INPUTn$
FORi=91TO185p=i MOD2j=i MOD47IFj<42j+=i DIV141*42p=(j>41EORASC(MID$("XLd^bFznvh",VAL(MID$(n$,j/7+1,1))+1)))>>(j MOD7)AND1
IFp LINEi*2,60,i*2,0
NEXT

43のオフセットを iループに。破損を回避するためにMOD2、合計で90を追加するために47を追加する必要がありました。

これは、許容される場合、以下に示すように、バーコードを原点からさらに移動します。

ここに画像の説明を入力してください

Rev 0 BBC BASIC、157 ASCII文字、トークン化ファイルサイズ137バイト

INPUTn$
FORi=1TO95p=i MOD2j=(i+43)MOD47IFj<42j+=i DIV51*42p=(i>50EORASC(MID$("XLd^bFznvh",VAL(MID$(n$,j/7+1,1))+1)))>>(j MOD7)AND1
IFp LINEi*2,0,i*2,60
NEXT

インタプリタをhttp://www.bbcbasic.co.uk/bbcwin/bbcwin.htmlからダウンロードしてください

デフォルトの画面モードは、白の背景に黒のテキストです。これは、元のBBC BASCとは異なります。

テスト印刷のあるゴルフバージョン

データバーの計算は、IF j<42すべての行に依存しているため、すべてを1行で行う必要があります。改変されていないバージョンでは、3つのステップで行われます。ゴルフバージョンでは、最後の2つのステップが1つの巨大な表現に結合されますp=...

>>(j MOD 7)ビットにアクセスするために使用するため、ビットマップの順序を逆にする必要がありました。つまり、最下位ビットに最初にアクセスします。これが完了すると、左側のビットマップはすべてASCII範囲になります。

  INPUTn$
  FOR i=1TO95                            :REM iterate through 95 bars
    p=i MOD2                             :REM calculate colour of format bar 1=black
    j=(i+43)MOD47                        :REM repetition is 42 data bars + 5 format bars. offset and modulo. if j<42 it is a data bar and we must change p.

    REM if i DIV 51=1 we are in the second half, so add 42 to j. Find the bitmap for left hand value, from character j/7 of the input.
    REM i>50 evaluates to false=0 true=-1. XOR this with p to invert bitmap for right hand side. Shift and AND with 1.  
    IF j<42 j+=i DIV51*42:p=ASC(MID$("XLd^bFznvh",  VAL(MID$(n$,j/7+1,1))+1  )) :p=(i>50EORp)>>(j MOD7) AND 1

    IF j MOD 7 = 0 PRINT                  :REM format test output
    PRINT ;p;                             :REM print test output
    IF p LINEi*2-2,0,i*2-2,60             :REM if p=1 plot bar. there are 2 logical units for each pixel.
  NEXT

典型的な出力、テスト出力付きの非ゴルフバージョン

ここに画像の説明を入力してください


2

JavaScript ES6、225バイト

s=>`P1
30 90
`+([...`101${(f=(z,j)=>[...j].map(i=>`000${z[+i].toString(2)}`.slice(-7)).join``)([13,25,19,61,35,49,47,59,55,11],s[0])}01010${f([114,102,108,66,92,78,80,68,72,116],s[1])}101`].join` `+`
`).repeat(30).slice(0,-1)

ES7の機能ではもっと短かったかもしれませんが、それらのサポートについてはわかりませんので、ES6に固執しています。また、入力を配列として想定しています。出力はPBNファイルです。たくさんのゴルフもあります。

何か間違ったことをした場合はコメントを残してください。


私はあなたの平均PBMファイル...と思う
sergiol

2

Perl、153バイト

substr($_=<>,6,0)=A;y/0-9A/=ICmSa_kg;0/;$s.=sprintf("%07b",-48+ord$1^($k++>6?127:0))while/(.)/g;$s=~s/0{7}/01010/;print"P1
95 30
".('101'.$s.'101'.$/)x30

ファイルbarcode.perlにコピーして、次のように実行します:

perl barcode.perl > output.pbm

次にバーコード番号を入力します。

説明:

バーコード数字のビットパターンは文字列に格納され、Perl y///音訳演算子を使用して入力数字の代わりに使用されます。置換文字列の各値には、印刷できない文字を避けるために48(ASCII '0')が追加されています。バーコードの後半の数字は、前半の数字の逆です。

中央のパターンは0000000(それ以外の場合は表示されないパターンで、「A」、次に「0」としてエンコードされる)に設定され、sprintingの場合に異なる長さを処理するのではなく01010で置換されます。


1

オクターブ、115バイト

function b(s)
n='rflB\MPDHt'-0;r=dec2bin(n(s-47)',7)'(:)-48;v=[a=[1 0 1] ~r(1:42)' 0 a r(43:84)' a];v(ones(30,1),:)

複数行バージョン:

function b(s)
   n='rflB\MPDHt'-0;
   r=dec2bin(n(s-47)',7)'(:)-48;
   v=[a=[1 0 1] ~r(1:42)' 0 a r(43:84)' a];
   v(ones(30,1),:)

nは、右側の数字コードに相当するASCIIです(すべて表示可能な文字であるため、左側よりも入力が簡単でした)。その後、いくつかの迷惑なタイプの10進数から2進数への直接変換は、charからnumericに変わります。v最終的なバイナリ文字列を構築し、それを30回繰り返してコンソールに出力します。

簡潔にするために、30行のうち2行のみを表示したサンプル出力:

s = '777777222222';
ans =

 Columns 1 through 30:

   1   0   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1
   1   0   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1
...

 Columns 31 through 60:

   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   0   1   1   1   0   1   1   0   0   1   1   0   1
   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   0   1   1   1   0   1   1   0   0   1   1   0   1
...

 Columns 61 through 90:

   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0
   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0
...

 Columns 91 through 94:

   0   1   0   1
   0   1   0   1
...

圧縮された出力:

1010111011011101101110110111011011101101110110101110110011011001101100110110011011001101100101

元々は画像を表示するつもりでしたが、出力をコンソールに送信することで9バイト節約できました。を使用して結果を表示できますが、白と黒imshowで表示さ1れる0ため、最初にデータを反転する必要があります。

imshow(~v(ones(30,1),:));

1

コブラ-218

do(s='')
    print'P1\n95 30'+('\n'+('101'+(for n in 12get Convert.toString(if((t=139+[2,14,8,50,24,38,36,48,44,0][s[n]to int-48])and n<6,t,~t),2)[-7:]+if(n-5,'','01010')).join('')+'101').toCharArray.join(' ')).repeat(30)

1

Javascript ES6、199バイト

n=>`P1 95 30 `+(101+(g=(a,...s)=>(``+1e12+n).slice(...s,-6).split``.map(m=>(1e3+a[m].toString(2)).slice(-7)).join``)(a=[13,25,19,61,35,49,47,59,55,11],-12)+`01010`+g(a.map(i=>~i&127))+101).repeat(30)

「最短の提出(バイト単位で勝ちます)」。コードをバイト単位でカウントする必要があるため、Unicodeを使用する場合は1文字あたり2バイトになると思います。
mbomb007

フン、いや、私は私の非ユニコードに変換された答えが、その後短い推測
デンドロビウム

0

Python 2、174バイト

ゴルフできることは知っています。

文字列 sは、テーブルの左半分が文字列の左半分である質問のバイナリテーブルです。値は、右半分の場合は最初に63でANDされ(最初の1を削除)、次に63だけシフトされて印刷可能なASCIIになります。

バグ:現在、バグを修正しようとしています。最初の例の出力は、バーコードの1桁分ずれています。あなたがそれを理解した場合、私に知らせてください。

I=raw_input()
s="LXR|bpnzvJcekA[MOCGs"
x="".join(format(ord(s[int(I[i])+10*(i>5)])-63|1+63*(i>5),'07b')for i in range(len(I)))
L=len(x)/2
print"101%s01010%s101"%(x[:L],x[L:])

または、チャレンジを完全に間違ってしました。その場合もお知らせください。
mbomb007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.