UPC: Difference between revisions

From Rosetta Code
Content added Content deleted
(Created page with "{{draft task}} Task: Convert upc barcodes to decimal. Specifically: The UPC standard is actually a collection of standards -- physical standard...")
 
m (J implementation)
Line 47: Line 47:


Finally, the last digit is a checksum digit which may be used to help detect errors. Multiply each digit in the represented 12 digit sequence by the corresponding number in (3,1,3,1,3,1,3,1,3,1,3,1) and add products, and the sum (mod 10) must be 0 (must have a zero as its last digit) if the number has been read correctly.
Finally, the last digit is a checksum digit which may be used to help detect errors. Multiply each digit in the represented 12 digit sequence by the corresponding number in (3,1,3,1,3,1,3,1,3,1,3,1) and add products, and the sum (mod 10) must be 0 (must have a zero as its last digit) if the number has been read correctly.

=={{header|J}}==

Implementation:

<lang J>upcdigit=:".;._2]0 :0
0 0 0 1 1 0 1 NB. 0
0 0 1 1 0 0 1 NB. 1
0 0 1 0 0 1 1 NB. 2
0 1 1 1 1 0 1 NB. 3
0 1 0 0 0 1 1 NB. 4
0 1 1 0 0 0 1 NB. 5
0 1 0 1 1 1 1 NB. 6
0 1 1 1 0 1 1 NB. 7
0 1 1 0 1 1 1 NB. 8
0 0 0 1 0 1 1 NB. 9
)

upc2dec=:3 :0
if. 95~: #code=. '#'=dtb dlb y do._ return.end.
if. (11$1 0) ~: 0 1 2 45 46 47 48 49 92 93 94{ code do._ return. end.
digits=. <./([:,upcdigit i.0 1~:(3 50+/i.6 7) { ])"1 code,:|.code
if. 10 e.digits do._ return.end.
if.0 ~:10|digits+/ .* 12$3 1 do._ return.end.
)</lang>

Here, we perform some basic integrity checks and use a table lookup to identify the decimal digits.

Task example:

<lang J>barcodes=:0 :0
# # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # #
# # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # #
# # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # #
# # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # #
# # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # #
# # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # #
# # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # #
# # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # #
# # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # #
# # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # #
)

upc2dec;._2 barcodes
9 2 4 7 7 3 2 7 1 0 1 9
4 0 3 9 4 4 4 4 1 0 5 0
8 3 4 9 9 9 6 7 6 7 0 6
9 3 9 8 2 5 1 5 8 8 1 1
_ 0 0 0 0 0 0 0 0 0 0 0
3 1 6 3 1 3 7 1 8 7 1 7
2 1 4 5 7 5 8 7 5 6 0 8
8 1 8 7 7 8 8 4 1 8 1 3
7 0 6 4 6 6 7 4 3 0 3 0
6 5 3 4 8 3 5 4 0 4 3 5
</lang>

The row which begins with _ is the damaged row. (If rescanning did not fix that problem, the operator would have to enter the code manually.)

It may be desirable to format the result differently, but that's currently not a part of the task definition.

Revision as of 19:22, 25 November 2019

UPC is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Task: Convert upc barcodes to decimal.

Specifically:

The UPC standard is actually a collection of standards -- physical standards, data format standards, product reference standards... Here, we focus on some of the data format standards, with an imaginary physical+electrical implementation which converts physical UPC barcodes to ascii, with spaces and # characters representing the presence or absence of ink.

Here, we have a representation of 10 different UPC-A bar codes read by our imaginary bar code reader:

         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       
        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         
         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         
       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        
         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          
          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         
         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        
        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         
         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       
        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         

Some of these were input upside down, and one has a timing error.

The task is to implement code to find the corresponding decimal representation of each, rejecting the error. Extra credit for handling the rows entered upside down (the other option is to reject them).

Notes:

Each digit is represented by 7 bits:

  0: 0 0 0 1 1 0 1
  1: 0 0 1 1 0 0 1
  2: 0 0 1 0 0 1 1
  3: 0 1 1 1 1 0 1
  4: 0 1 0 0 0 1 1
  5: 0 1 1 0 0 0 1
  6: 0 1 0 1 1 1 1
  7: 0 1 1 1 0 1 1
  8: 0 1 1 0 1 1 1
  9: 0 0 0 1 0 1 1

On the left hand side of the bar code a space represents a 0 and a # represents a 1. On the right hand side of the bar code, a # represents a 0 and a space represents a 1 (alternatively: spaces always represent zeros and # characters always represent ones, but the representation is logically negated -- 1s and 0s are flipped -- on the right hand side of the bar code).

The UPC-A barcode structure begins with at least 9 spaces (which our imaginary bar code reader unfortunately doesn't always reproduce properly), then has a '# #' sequence marking the start of the sequence, then has the six "left hand" digits, then has a ' # # ' sequence in the middle, then has the six "right hand digits" and finally ends with another '# #' end sequence and nine trailing spaces (which might be eaten by wiki edits and in any event were not quite captured correctly by our imaginary bar code reader).

Finally, the last digit is a checksum digit which may be used to help detect errors. Multiply each digit in the represented 12 digit sequence by the corresponding number in (3,1,3,1,3,1,3,1,3,1,3,1) and add products, and the sum (mod 10) must be 0 (must have a zero as its last digit) if the number has been read correctly.

J

Implementation:

<lang J>upcdigit=:".;._2]0 :0

 0 0 0 1 1 0 1 NB. 0
 0 0 1 1 0 0 1 NB. 1
 0 0 1 0 0 1 1 NB. 2
 0 1 1 1 1 0 1 NB. 3
 0 1 0 0 0 1 1 NB. 4
 0 1 1 0 0 0 1 NB. 5
 0 1 0 1 1 1 1 NB. 6
 0 1 1 1 0 1 1 NB. 7
 0 1 1 0 1 1 1 NB. 8
 0 0 0 1 0 1 1 NB. 9

)

upc2dec=:3 :0

 if. 95~: #code=. '#'=dtb dlb y do._ return.end.
 if. (11$1 0) ~: 0 1 2 45 46 47 48 49 92 93 94{ code do._ return. end.
 digits=. <./([:,upcdigit i.0 1~:(3 50+/i.6 7) {  ])"1 code,:|.code
 if. 10 e.digits do._ return.end.
 if.0 ~:10|digits+/ .* 12$3 1 do._ return.end.

)</lang>

Here, we perform some basic integrity checks and use a table lookup to identify the decimal digits.

Task example:

<lang J>barcodes=:0 :0

        # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       
       # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         
        # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         
      # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        
        # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          
         # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         
        # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        
       # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         
        # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       
       # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         

)

  upc2dec;._2 barcodes

9 2 4 7 7 3 2 7 1 0 1 9 4 0 3 9 4 4 4 4 1 0 5 0 8 3 4 9 9 9 6 7 6 7 0 6 9 3 9 8 2 5 1 5 8 8 1 1 _ 0 0 0 0 0 0 0 0 0 0 0 3 1 6 3 1 3 7 1 8 7 1 7 2 1 4 5 7 5 8 7 5 6 0 8 8 1 8 7 7 8 8 4 1 8 1 3 7 0 6 4 6 6 7 4 3 0 3 0 6 5 3 4 8 3 5 4 0 4 3 5 </lang>

The row which begins with _ is the damaged row. (If rescanning did not fix that problem, the operator would have to enter the code manually.)

It may be desirable to format the result differently, but that's currently not a part of the task definition.