Barcodegolf: สร้าง 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

ตัวอย่าง

สมมติว่าคุณมี 022000 125033UPC (นั่นไม่ใช่ตัวเลขสุ่มทิ้งความคิดเห็นถ้าคุณเข้าใจความสำคัญของมัน) คุณเริ่มต้นด้วยแผ่นสำเร็จรูปที่เหมือนกันในบาร์โค้ดทุกอัน:

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

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟดังนั้นการส่งที่สั้นที่สุด (เป็นไบต์ชนะ) Tiebreaker ไปที่โพสต์แรกสุด


อืม ... ผลไม้ฉ่ำ
เดนนิส

อินพุตสามารถใช้เป็นอาร์เรย์ได้หรือไม่? เช่น["777777","222222"]
Downgoat

@ วิหารหืมมฉันคิดว่ามันค่อนข้างยืด ฉันจะบอกว่าไม่
NinjaBearMonkey

2
สแกนบาร์โค้ด UPC ครั้งแรก!
เดนนิส

1
อันนี้ยอดเยี่ยม บาร์โค้ดติดใจฉันอยู่เสมอ
Beta Decay

คำตอบ:


3

CJam, 58 57 ไบต์

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

พิมพ์ Portable 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 chars, ไฟล์ขนาดโทเค็น 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ลูป เพื่อหลีกเลี่ยงการทำลายMOD247 เพิ่มเติมจะต้องมีการเพิ่มรวม 90

สิ่งนี้จะย้ายบาร์โค้ดเพิ่มเติมจากจุดเริ่มต้นดังที่แสดงถ้ายอมรับ:

ป้อนคำอธิบายรูปภาพที่นี่

Rev 0 BBC พื้นฐาน, 157 ascii chars, ไฟล์ขนาดโทเค็น 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และจะต้องทำทั้งหมดในหนึ่งบรรทัด ในรุ่นที่ไม่ได้รับการตีลังกาจะทำในสามขั้นตอน ในรุ่น golfed สองขั้นตอนสุดท้ายจะรวมกันเป็นนิพจน์ขนาดใหญ่เดียว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

เอาท์พุททั่วไปรุ่น ungolfed พร้อมกับเอาต์พุตทดสอบ

ป้อนคำอธิบายรูปภาพที่นี่


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

คัดลอกไปที่ไฟล์บาร์โค้ดต่อจากนั้นเรียกใช้ดังนี้:

perl barcode.perl > output.pbm

จากนั้นใส่หมายเลขบาร์โค้ด

คำอธิบาย:

รูปแบบบิตสำหรับตัวเลขบาร์โค้ดจะถูกเก็บไว้ในสตริงและแทนที่สำหรับตัวเลขอินพุตโดยใช้ตัวy///ดำเนินการทับศัพท์ภาษาPerl แต่ละค่าในสตริงการแทนที่มีการเพิ่ม 48 (ASCII '0') เพื่อหลีกเลี่ยงอักขระที่ไม่สามารถพิมพ์ได้ ตัวเลขในครึ่งหลังของบาร์โค้ดเป็นค่าผกผันของครึ่งปีแรก

รูปแบบกลางถูกตั้งค่าเป็น 0000000 (รูปแบบที่ไม่สามารถปรากฏขึ้นมาเข้ารหัสเป็น 'A' และ '0') แล้วแทนที่ด้วย 01010 แทนที่จะจัดการความยาวที่แตกต่างกันเป็นกรณีพิเศษเมื่อsprintไอเอ็นจี


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

Bah, แท้จริงแล้ว, ฉันเดาว่าคำตอบที่ไม่มีการเข้ารหัสของฉันจะสั้นลงแล้ว
Dendrobium

0

Python 2, 174 ไบต์

ฉันรู้ว่ามันสามารถเล่นกอล์ฟได้

สตริงsเป็นตารางไบนารีในคำถามที่มีครึ่งซ้ายของตารางเป็นครึ่งซ้ายของสตริง ค่าจะถูก ANDed 63 ก่อนหากอยู่ในครึ่งขวา (ลบ 1 ก่อน) จากนั้นเลื่อนด้วย 63 เพื่อให้สามารถพิมพ์ ASCII ได้

BUG: ขณะนี้พยายามแก้ไขข้อบกพร่อง เอาต์พุตของตัวอย่างแรกถูกปิดโดยหนึ่งหลักของบาร์โค้ด หากคุณคิดออกโปรดแจ้งให้เราทราบ

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.