Barcodegolf: Bir sayının UPC'sini oluşturma


12

Günümüzde hemen hemen her mağaza , teslim sürecini basitleştirmek için Evrensel Ürün Kodu (UPC) barkodlarını kullanıyor. İsim sizin için bir şey ifade etmiyorsa, kesinlikle neye benzediklerini anlayacaksınız:

Örnek UPC-A barkodu

Biçim

En yaygın sistem, her bir ürünü temsil etmek için 12 basamak kullanan UPC-A'dır. Her basamak, makinelerin kodu 7 bit uzunluğunda okumasına izin vermek için bir dizi siyah ve beyaz çizgili olarak kodlanır. Barkodun başlangıcını, ortasını ve sonunu gösteren toplam 11 bitlik desen vardır. Bu toplam 12 × 7 + 11 = 95 bit barkod uzunluğuna gelir. (Bundan sonra, her bitin rengini belirtmek için ikili kullanıldığında 0, beyaz ve 1siyahtır.)

Başlangıç ​​ve bitiş her ikisinin de bir deseni vardır 101. Basamaklar daha sonra 2 grup 6'ya bölünür ve aşağıda gösterildiği gibi 01010sol ve sağ gruplar arasında bir desenle kodlanır . Bu tablo her bir sayının desenini listeler. Rakamın sağ veya sol tarafta olmasına bağlı olarak desenin farklı olduğuna dikkat edin (Bu, barkodun baş aşağı taranmasına izin verir). Bununla birlikte, sağdaki desen, solun tersi (beyaz için siyah takas ve tersi).

UPC dönüşüm tablosu

Yukarıdaki görüntüyü göremiyorsanız, bu her sayının ikili eşdeğeridir.

#   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

Misal

Diyelim ki UPC'niz var 022000 125033. (Bunlar rastgele sayılar değildir. Eğer önemlerini anlarsanız bir yorum bırakın.) Her barkodda aynı olan bu kazan plakasıyla başlıyorsunuz:

101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx101

Rakamlar için, her birini, bulunduğu tarafın (sol veya sağ) karşılık gelen kodlamasıyla değiştirirsiniz. Hala kafanız karıştıysa, aşağıdaki resme bakın.

UPC kodlamasının dökümü

Burada |parçaları ayıran borular ile ikili çıktı .

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

Meydan okuma

Kullanıcı girişi için UPC-A barkodunu veren bir program yazın. Görüntünün boyutları 95 × 30 piksel olmalı ve her "bit" bir piksel genişliğinde ve 30 piksel yüksekliğinde olmalıdır. Siyah şeritler içeride rgb(0, 0, 0)ve beyaz şeritler sürekli saydam veya rgb(255, 255, 255).

notlar

  • Stdin veya komut satırından girdi alın veya bir dize veya tamsayı alan bir işlev yazın (girişin başında sıfır olabilir ve çoğu dil bunları kaldırır veya sayıyı sekizlik biçime dönüştürür).
  • Görüntünün çıktısını aşağıdaki yollardan biriyle alın:
    • İstediğiniz ad ve biçime (PNG, PBM, vb.) Sahip bir dosyaya kaydedin.
    • Ekranda görüntüleyin.
    • Dosya verilerini stdout'a çıktılar.
  • Resim veya grafik kitaplıkları kullanabilmenize rağmen , barkod üreten kitaplıkları veya yerleşik yapıları ( size bakıyorum Mathematica ) kullanamazsınız.
  • Bir UPC'nin son basamağı genellikle bir kontrol basamağıdır , ancak bu amaçlar için endişelenmenize gerek yoktur.

Örnekler

Kodunuzu test etmek için bazı örnekler. İkili çıktı da kolaylık sağlamak için verilmiştir.

Giriş: 012345678910

Çıktı:

10100011010011001001001101111010100011011000101010101000010001001001000111010011001101110010101

Giriş: 777777222222

Çıktı:

10101110110111011011101101110110111011011101101010110110011011001101100110110011011001101100101

puanlama

Bu kod golf , yani kısa teslim (bayt kazanır). Tiebreaker en erken mesaja gider.


Mmm ... sulu meyve.
Dennis

Girdi bir dizi olarak alınabilir mi? ör.["777777","222222"]
Downgoat

@vihan Hmm, sanırım bu biraz gergin. Hayır diyeceğim.
NinjaBearMonkey

2
İlk taranmış UPC barkodu!
Dennis

1
Bu harika. Barkodlar beni her zaman büyüledi
Beta Çürümesi

Yanıtlar:


3

CJam, 58 57 bayt

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

STDOUT'a Taşınabilir BitMap (ASCII) yazdırır. Çevrimiçi deneyin.

Nasıl çalışır

'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 karakter, tokenize dosya boyutu 132 bayt

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 ofsetini idöngüye dahil ederek birkaç bayt kurtardı . Kırılmayı önlemek MOD2için, toplam 90'a 47 eklenmesi gerekiyordu.

Bu, kabul edilebilirse barkodu gösterildiği gibi başlangıç ​​noktasından daha ileriye taşır:

resim açıklamasını buraya girin

Rev 0 BBC BASIC, 157 ascii karakter, tokenize dosya boyutu 137 bayt

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

Yorumlayıcıyı http://www.bbcbasic.co.uk/bbcwin/bbcwin.html adresinden indirin

Varsayılan ekran modu beyaz zemin üzerine siyah metindir. Bu orijinal BBC BASC'den farklıdır.

Test baskısı ile hareketsiz versiyon

Bir veri çubuğunun hesaplanması bağlıdır IF j<42ve hepsi bir satırda yapılmalıdır. Kurtulmamış versiyonda üç adımda yapılır. Golf edilmiş versiyonda son iki adım tek bir büyük ifadede birleştirilirp=...

Bitmap'lerin sırasını tersine çevirmek zorunda kaldım, çünkü >>(j MOD 7)bitlere erişmek için kullanıyorum , yani önce en az önemli bite erişiyorum. Bu yapıldıktan sonra, tüm sol bitmapler ASCII aralığındadır.

  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

Tipik çıktı, test edilmemiş versiyon, test edilmemiş versiyon

resim açıklamasını buraya girin


2

JavaScript ES6, 225 bayt

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 özellikleri ile daha kısa olabilirdi ama desteklerinden emin değilim, bu yüzden ES6'ya bağlı kalıyorum. Ben de bir dizi olarak bir giriş varsayıyorum. Çıktı bir PBN dosyasıdır . Ayrıca golf yapmak için bir sürü vardır.

Eğer yanlış bir şey yaptıysam yorum bırak ve düzelttiğinden emin olacağım


Sanırım PBM dosyasını kastediyorsun ...
sergiol

2

Perl, 153 bayt

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

Bir barkod.perl dosyasına kopyalayın ve şu şekilde çalıştırın:

perl barcode.perl > output.pbm

ardından barkod numarasını girin.

Açıklama:

Barkod basamakları için bit desenleri bir dizede saklanır ve Perl y///harf çevirisi operatörü kullanılarak giriş basamakları ile değiştirilir . Değiştirilemeyen karakterlerden kaçınmak için, ikame dizesindeki her değere 48 (ASCII '0') eklenir. Barkodun ikinci yarısındaki rakamlar, ilk yarıdakilerin tersidir.

Merkezi desen 0000000 olarak ayarlanır (aksi takdirde asla görünmeyen, 'A' ve sonra '0' olarak kodlanan bir desendir) ve daha sonra özel uzunluğunda özel bir durum olarak kullanmak yerine 01010 ile sprintdeğiştirilir.


1

Oktav, 115 bayt

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),:)

Çok satırlı sürüm:

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),:)

nsağ taraftaki rakam kodlarının ASCII eşdeğeri (girilebilir karakterler olduğu için girilmesi sol tarafa göre daha kolaydı). Bundan sonra, bazı can sıkıcı türlerle düz ondalıktan ikiye dönüşüm char'tan nümana değişir. vSon ikili dizgiyi oluşturur ve 30 kez tekrarlar ve konsola çıkarırız.

Kısa olması için gösterilen 30 satırdan yalnızca 2 tanesiyle örnek çıktı:

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

Sıkıştırılmış çıktı:

1010111011011101101110110111011011101101110110101110110011011001101100110110011011001101100101

Başlangıçta görüntüyü göstermeyi amaçlamıştım, ancak konsola çıktı göndermek beni 9 bayt kurtardı. Sonuçları kullanarak imshowgörüntüleyebilirsiniz, ancak 1beyaz ve 0siyah olarak görüntülenir , bu nedenle önce verileri ters çevirmeniz gerekir.

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

1

Kobra - 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 bayt

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)

msgstr "en kısa gönderim (bayt olarak kazanır)". Kodunuzu bayt cinsinden saymanız gerekir, bu yüzden Unicode kullanıyorsanız, karakter başına 2 bayt olduğunu düşünüyorum.
mbomb007

Bah, evet, sanırım unicoless cevabım daha kısa
Dendrobium

0

Python 2, 174 bayt

Golf yapılabileceğini biliyorum.

Dize s, sorudaki ikili tablodur ve tablonun sol yarısı dizenin sol yarısıdır. Sağ yarıysa (ilk 1'i kaldırın) önce değerler 63'tür ve sonra ASCII yazdırılabilir olmak için 63'e kaydırılır.

Hata: Şu anda bir hatayı düzeltmeye çalışıyor. İlk örneğin çıktısı, barkodun bir rakamı ile kapalıdır. Eğer çözerseniz, lütfen bana bildirin.

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:])

Ya da, meydan okumayı tamamen yanlış yaptım. Bu durumda da bana haber ver.
mbomb007
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.