Штрихкод-гольф: Створення UPC числа


12

Практично кожен магазин сьогодні використовує штрих-коди універсального коду товару (UPC) для спрощення процесу перевірки. Якщо ім’я для вас нічого не означає, ви обов'язково впізнаєте, як вони виглядають:

Зразок штрих-коду UPC-A

Формат

Найпоширеніша система - UPC-A, яка використовує 12 цифр для представлення кожного конкретного продукту. Кожна цифра кодується в ряд чорно-білих смуг, щоб машини могли читати код довжиною в сім біт. Всього існує 11 біт шаблонів, які вказують на початок, середину та кінець штрих-коду. Це доходить до загальної довжини штрих-коду 12 × 7 + 11 = 95 біт. (Відтепер, коли двійковий використовується для позначення кольору кожного біта, він 0є білим і 1чорним.)

Початок і кінець обох мають закономірність 101. Потім цифри діляться на 2 групи з 6 і кодуються, як показано нижче, з малюнком 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 пікселів, причому кожен "біт" повинен бути шириною один піксель і висотою 30 пікселів. Чорні смуги є в, rgb(0, 0, 0)а білі смуги - постійно прозорі або rgb(255, 255, 255).

Примітки

  • Візьміть вхід з stdin або командного рядка або напишіть функцію, яка приймає рядок або ціле число (зауважте, що вхід може мати провідні нулі, а більшість мов видаляють їх або перетворюють число в восьмикутник).
  • Виведіть зображення одним із наступних способів:
    • Збережіть його у вибраному вами файлі (PNG, PBM тощо).
    • Відобразити його на екрані.
    • Виведіть свої файлові дані в stdout.
  • Ви не можете використовувати бібліотеки або вбудовані модулі, які генерують штрих-коди ( я дивлюся на вас, Mathematica ), хоча ви можете використовувати бібліотеки зображень або графіки.
  • Остання цифра UPC, як правило, є контрольною цифрою , але для цих цілей вам не доведеться турбуватися про це.

Приклади

Ось ще кілька прикладів тестування вашого коду. Бінарний вихід також надається для зручності.

Вхід: 012345678910

Вихід:

10100011010011001001001101111010100011011000101010101000010001001001000111010011001101110010101

Вхід: 777777222222

Вихід:

10101110110111011011101101110110111011011101101010110110011011001101100110110011011001101100101

Оцінка балів

Це код гольфу , тому найкоротше подання (у байтах виграє). Tierereaker йде на найбільш ранню посаду.


Ммм ... соковиті фрукти.
Денніс

Чи можна ввести дані як масив? наприклад["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 символів, токенізований розмір файлів 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, додаткові 47 довелося додати до 90.

Це переміщує штрих-код далі від походження, як показано, якщо це прийнятно:

введіть тут опис зображення

Rev 0 BBC BASIC, 157 символів, токенізований розмір файлів 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і повинен бути виконаний в одному рядку. У безгольовій версії це робиться в три етапи. У версії для гольфу останні два кроки об'єднані в одне величезне вираження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

потім введіть номер штрих-коду.

Пояснення:

Бітові структури для штрих-кодів цифр зберігаються в рядку і замінюються вхідними цифрами за допомогою y///оператора транслітерації Perl . Кожне значення рядка підстановки містить 48 (ASCII '0') доданих від нього, щоб уникнути недрукувальних символів. Цифри у другій половині штрих-коду є оберненими цифрами у першій половині.

Центральний малюнок встановлюється на 0000000 (візерунок, який інакше ніколи не може з'являтися, кодується як "A", а потім "0"), а потім замінюється на 01010, а не обробляє його різну довжину як особливий випадок, коли sprinting.


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 кодів правої цифри (їх було легше вводити, ніж лівого боку, оскільки всі вони були символами, що відображаються). Після цього пряме перетворення від десяткової до двійкової з деяким дратівливим типом змінюється від знака до числового. vбудує заключний двійковий рядок, а потім повторюємо його 30 разів і виводимо на консоль.

Вибірка з лише 2 з 30 рядків, показаних для стислості:

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, це 2 байти на символ, я думаю.
mbomb007

Ба, так, я гадаю, моя ненавчена кодова відповідь тоді коротша
Dendrobium

0

Пітон 2, 174 байти

Я знаю, що це може бути гольф.

Рядок s- це двійкова таблиця у питанні з лівою половиною таблиці як лівою половиною рядка. Значення спочатку ANDed на 63, якщо вони знаходяться у правій половині (видаліть першу 1), потім зміщуються на 63 для друку ASCII.

БУГ: Наразі намагаються виправити помилку. Вихід першого прикладу відключається однією цифрою штрих-коду. Якщо ви це зрозумієте, повідомте, будь ласка.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.