Jump to content

UPC: Difference between revisions

4,521 bytes added ,  2 years ago
Line 1,800:
[7, 0, 6, 4, 6, 6, 7, 4, 3, 0, 3, 0]
[6, 5, 3, 4, 8, 3, 5, 4, 0, 4, 3, 5]</pre>
 
=={{header|Ksh}}==
<lang Ksh>#!/bin/ksh
 
# Find the corresponding UPC decimal representation of each, rejecting the error
 
# # Variables:
#
UPC_data_file="../upc.data"
END_SEQ='# #' # Start and End sequence
MID_SEQ=' # # ' # Middle sequence
typeset -a CHK_ARR=( 3 1 3 1 3 1 3 1 3 1 3 1 )
integer bpd=7 # Number of bits per digit
integer numdig=6 # Number of digits per "side"
typeset -a umess=( '' 'Upside down')
typeset -a udig=( 0001101 0011001 0010011 0111101 0100011 0110001 0101111 0111011 0110111 0001011 )
 
# # Functions:
#
 
# # Function _validate(array) - verify result with CHK_ARR
#
function _validate {
typeset _arr ; nameref _arr="$1"
typeset _ifs ; _ifs="$2"
typeset _dp _singlearr _oldIFS
 
_oldIFS=$IFS ; IFS=${_ifs}
typeset -ia _singlearr=( ${_arr[@]} )
integer _dp=$(_dotproduct _singlearr CHK_ARR)
IFS=${_oldIFS}
 
return $(( _dp % 10 ))
}
 
# # Function _dotproduct(arr1, arr2) - return dot product
#
function _dotproduct {
typeset _arr1 ; nameref _arr1="$1"
typeset _arr2 ; nameref _arr2="$2"
typeset _i _dp ; integer _i _dp
 
for (( _i=0; _i<${#_arr1[*]}; _i++ )); do
(( _dp += ( _arr1[_i] * _arr2[_i] ) ))
done
echo ${_dp}
}
 
# # Function _flipit(string) - return flipped string
#
function _flipit {
typeset _buf ; _buf="$1"
typeset _tmp ; unset _tmp
 
for (( _i=$(( ${#_buf}-1 )); _i>=0; _i-- )); do
_tmp="${_tmp}${_buf:${_i}:1}"
done
 
echo "${_tmp}"
}
 
# # Function _bitget(string, side) - return bitless string & bit
#
function _bitget {
typeset _buff ; _buff="$1"
typeset _side ; integer _side=$2
typeset _ubit _bit
 
_ubit=${_buff:0:1}
[[ ${_ubit} == \# ]] && _bit=1 || _bit=0
(( _side )) && (( _bit = ! _bit ))
 
echo ${_buff#*${_ubit}}
return ${_bit}
}
 
# # Function _decode(upc_arr, digit_arr)
#
function _decode {
typeset _uarr ; nameref _uarr="$1" # UPC code array
typeset _darr ; nameref _darr="$2" # Decimal array
 
typeset _s _d _b _bit _digit _uarrcopy ; integer _s _d _b _bit
typeset -a _uarrcopy=( ${_uarr[@]} )
 
for (( _s=0; _s<${#_uarr[*]}; _s++ )); do # each "side"
for (( _d=0; _d<numdig; _d++ )) ; do # each "digit"
for (( _b=0; _b<bpd; _b++ )) ; do # each "bit"
_uarr[_s]=$(_bitget ${_uarr[_s]} ${_s}) ; _bit=$?
_digit="${_digit}${_bit}"
done
 
_darr[_s]="${_darr[_s]} $(_todec ${_digit})"
if (( $? )); then # May be upside-down
typeset -a _uarr=( ${_uarrcopy[@]} ) # Replace
return 1
fi
unset _digit
done
done
}
 
# # Function _todec(digit) - Return numeric digit from upc code
#
function _todec {
typeset _bdig ; _bdig="$1"
typeset _i ; integer _i
 
for (( _i=0; _i<${#udig[*]}; _i++ )); do
[[ ${_bdig} == ${udig[_i]} ]] && echo ${_i} && return 0
done
return 1
}
 
# # Function _parseUPC(str, arr) - parse UPS string into 2 ele array
#
function _parseUPC {
typeset _buf ; typeset _buf="$1"
typeset _arr ; nameref _arr="$2"
typeset _pre _mid
 
_pre="${_buf%%${END_SEQ}*}"
_buf="${_buf#*${_pre}}" # Strip preamble
_buf="${_buf#*${END_SEQ}}" # Strip $SEQ
 
_arr[0]="${_buf:0:$((bpd * numdig))}" # Get the left hand digits
_buf="${_buf#*${_arr[0]}}" # Strip left side digits
 
_mid="${_buf:0:5}" # Check the middle SEQ
_buf="${_buf#*${MID_SEQ}}" # Strip $SEQ
 
_arr[1]="${_buf:0:$((bpd * numdig))}" # Get the right hand digits
_buf="${_buf#*${_arr[1]}}" # Strip right side digits
 
_end="${_buf:0:3}" # Check the end SEQ
_buf="${_buf#*${END_SEQ}}" # Strip $SEQ
}
 
######
# main #
######
 
oldIFS="$IFS" ; IFS=''
while read; do
[[ "$REPLY" == \;* ]] && continue
 
unset side_arr ; typeset -a side_arr # [0]=left [1]=right
_parseUPC "$REPLY" side_arr
 
unset digit_arr ; typeset -a digit_arr # [0]=left [1]=right
_decode side_arr digit_arr ; integer uflg=$?
if (( uflg )); then # Flip sides and reverse UPC_code
unset digit_arr ; typeset -a digit_arr # [0]=left [1]=right
buff="$(_flipit "${side_arr[0]}")"
side_arr[0]="$(_flipit "${side_arr[1]}")"
side_arr[1]="${buff}"
_decode side_arr digit_arr ; integer vflg=$?
fi
 
(( ! vflg )) && _validate digit_arr "${oldIFS}" ; integer vflg=$?
if (( vflg )); then
print "INVALID DIGIT(S)"
unset vflg
else
print "${digit_arr[*]} ${umess[uflg]}"
unset uflg
fi
 
done < ${UPC_data_file}</lang>
{{out}}
<pre> 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 Upside down
9 3 9 8 2 5 1 5 8 8 1 1 Upside down
INVALID DIGIT(S)
3 1 6 3 1 3 7 1 8 7 1 7 Upside down
2 1 4 5 7 5 8 7 5 6 0 8
8 1 8 7 7 8 8 4 1 8 1 3 Upside down
7 0 6 4 6 6 7 4 3 0 3 0
6 5 3 4 8 3 5 4 0 4 3 5</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
70

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.