Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
162
Task/UPC/Ada/upc.adb
Normal file
162
Task/UPC/Ada/upc.adb
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
-- Parse scanned UPC-A codes
|
||||
-- J. Carter 2024 May
|
||||
|
||||
with Ada.Containers.Hashed_Maps;
|
||||
with Ada.Strings.Fixed;
|
||||
with Ada.Strings.Hash;
|
||||
with Ada.Text_IO;
|
||||
|
||||
procedure UPC is
|
||||
subtype Digit_Pattern is String (1 .. 7);
|
||||
subtype Digit_Character is Character range '0' .. '9';
|
||||
type Pattern_Map is array (Digit_Character) of Digit_Pattern;
|
||||
|
||||
package Digit_Maps is new Ada.Containers.Hashed_Maps (Key_Type => Digit_Pattern,
|
||||
Element_Type => Digit_Character,
|
||||
Hash => Ada.Strings.Hash,
|
||||
Equivalent_Keys => "=");
|
||||
|
||||
Start_Stop_Marker : constant String := "# #";
|
||||
Middle_Marker : constant String := " # # ";
|
||||
|
||||
Scan_Length : constant := 2 * Start_Stop_Marker'Length + Middle_Marker'Length + 12 * Digit_Pattern'Length;
|
||||
|
||||
procedure Parse (Count : in Positive; Scan : in String; Reversed : in Boolean := False) with
|
||||
Pre => Scan'First = 1 and Scan'Length = Scan_Length;
|
||||
-- Parses Scan and prints the result
|
||||
-- Count is the line #
|
||||
-- If Scan is invalid and not Reversed, tries to parse a reversed version of Scan before printing that Scan is invalid
|
||||
|
||||
Left_Pattern_Map : constant Pattern_Map :=
|
||||
('0' => " ## #",
|
||||
'1' => " ## #",
|
||||
'2' => " # ##",
|
||||
'3' => " #### #",
|
||||
'4' => " # ##",
|
||||
'5' => " ## #",
|
||||
'6' => " # ####",
|
||||
'7' => " ### ##",
|
||||
'8' => " ## ###",
|
||||
'9' => " # ##");
|
||||
Right_Pattern_Map : constant Pattern_Map :=
|
||||
('0' => "### # ",
|
||||
'1' => "## ## ",
|
||||
'2' => "## ## ",
|
||||
'3' => "# # ",
|
||||
'4' => "# ### ",
|
||||
'5' => "# ### ",
|
||||
'6' => "# # ",
|
||||
'7' => "# # ",
|
||||
'8' => "# # ",
|
||||
'9' => "### # ");
|
||||
|
||||
Left_Map : Digit_Maps.Map;
|
||||
Right_Map : Digit_Maps.Map;
|
||||
|
||||
function Image (Count : in Positive) return String is
|
||||
(if Count < 10 then Count'Image else Count'Image (2 .. 3) );
|
||||
|
||||
procedure Parse (Count : in Positive; Scan : in String; Reversed : in Boolean := False) is
|
||||
function Backwards return String with
|
||||
Post => Backwards'Result'First = Scan'First and
|
||||
Backwards'Result'Last = Scan'Last and
|
||||
(for all I in Scan'Range => Backwards'Result (I) = Scan (Scan'Last - I + 1) );
|
||||
|
||||
function Backwards return String is
|
||||
Right : Positive := Scan'Last;
|
||||
Result : String := Scan;
|
||||
begin -- Backwards
|
||||
Swap : for Left in 1 .. Scan'Last / 2 loop
|
||||
Result (Left) := Scan (Right);
|
||||
Result (Right) := Scan (Left);
|
||||
Right := Right - 1;
|
||||
end loop Swap;
|
||||
|
||||
return Result;
|
||||
end Backwards;
|
||||
|
||||
Result : String (1 .. 12);
|
||||
Start : Positive := 1 + Start_Stop_Marker'Length;
|
||||
Stop : Positive;
|
||||
begin -- Parse
|
||||
if Scan (1 .. Start_Stop_Marker'Length) /= Start_Stop_Marker or
|
||||
Scan (Scan'Last - Start_Stop_Marker'Length + 1 .. Scan'Last) /= Start_Stop_Marker
|
||||
then
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & ' ' & Scan & ": invalid, missing start or stop marker");
|
||||
|
||||
return;
|
||||
end if;
|
||||
|
||||
if Scan (1 + Start_Stop_Marker'Length + 6 * Digit_Pattern'Length ..
|
||||
1 + Start_Stop_Marker'Length + 6 * Digit_Pattern'Length + Middle_Marker'Length - 1) /= Middle_Marker
|
||||
then
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & ' ' & Scan & ": invalid, missing middle marker");
|
||||
|
||||
return;
|
||||
end if;
|
||||
|
||||
Left_Side : for I in 1 .. 6 loop
|
||||
Stop := Start + Digit_Pattern'Length - 1;
|
||||
|
||||
if not Left_Map.Contains (Scan (Start .. Stop) ) then
|
||||
if not Reversed then
|
||||
Parse (Count => Count, Scan => Backwards, Reversed => True);
|
||||
else
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & ": invalid");
|
||||
end if;
|
||||
|
||||
return;
|
||||
end if;
|
||||
|
||||
Result (I) := Left_Map.Element (Scan (Start .. Stop) );
|
||||
Start := Stop + 1;
|
||||
end loop Left_Side;
|
||||
|
||||
Start := Start + Middle_Marker'Length;
|
||||
|
||||
Right_Side : for I in 7 .. 12 loop
|
||||
Stop := Start + Digit_Pattern'Length - 1;
|
||||
|
||||
if not Right_Map.Contains (Scan (Start .. Stop) ) then
|
||||
if not Reversed then
|
||||
Parse (Count => Count, Scan => Backwards, Reversed => True);
|
||||
else
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & ": invalid");
|
||||
end if;
|
||||
|
||||
return;
|
||||
end if;
|
||||
|
||||
Result (I) := Right_Map.Element (Scan (Start .. Stop) );
|
||||
Start := Stop + 1;
|
||||
end loop Right_Side;
|
||||
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & ": " & Result & (if Reversed then " reversed" else "") );
|
||||
end Parse;
|
||||
|
||||
Count : Natural := 0;
|
||||
begin -- UPC
|
||||
Fill_Left : for D in Left_Pattern_Map'Range loop
|
||||
Left_Map.Insert (Key => Left_Pattern_Map (D), New_Item => D);
|
||||
end loop Fill_Left;
|
||||
|
||||
Fill_Right : for D in Right_Pattern_Map'Range loop
|
||||
Right_Map.Insert (Key => Right_Pattern_Map (D), New_Item => D);
|
||||
end loop Fill_Right;
|
||||
|
||||
All_Lines : loop
|
||||
exit All_Lines when Ada.Text_IO.End_Of_File;
|
||||
|
||||
One_Line : declare
|
||||
Line : constant String := Ada.Strings.Fixed.Trim (Ada.Text_IO.Get_Line, Ada.Strings.Both);
|
||||
begin -- One_Line
|
||||
Count := Count + 1;
|
||||
|
||||
if Line'Length /= Scan_Length then
|
||||
Ada.Text_IO.Put_Line (Item => Image (Count) & " invalid scan;" & Line'Length'Image & "/=" & Scan_Length'Image);
|
||||
else
|
||||
Parse (Count => Count, Scan => Line);
|
||||
end if;
|
||||
end One_Line;
|
||||
end loop All_Lines;
|
||||
end UPC;
|
||||
30
Task/UPC/Crystal/upc.cr
Normal file
30
Task/UPC/Crystal/upc.cr
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
UPC_RE = %r{^\s*# #((?:[ #]{7}){6}) # # ((?:[ #]{7}){6})# #\s*$}
|
||||
UPC_DIGITS = [" ## #", " ## #", " # ##", " #### #", " # ##",
|
||||
" ## #", " # ####", " ### ##", " ## ###", " # ##"]
|
||||
|
||||
def decode_upc (line)
|
||||
return nil unless line =~ UPC_RE
|
||||
digits = ($1 + $2.tr("# ", " #")).chars.in_slices_of(7).map(&.join)
|
||||
.map {|d| UPC_DIGITS.index! d }
|
||||
if [3,1,3,1,3,1,3,1,3,1,3,1].zip(digits).map {|m, d| m * d}.sum % 10 != 0
|
||||
return nil
|
||||
end
|
||||
digits
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
|
||||
[" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # ",
|
||||
" # # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # # ",
|
||||
" # # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # # ",
|
||||
" # # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # # ",
|
||||
" # # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # # ",
|
||||
" # # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # # ",
|
||||
" # # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # # ",
|
||||
" # # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # # ",
|
||||
" # # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # # ",
|
||||
" # # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # # "]
|
||||
.each do |line|
|
||||
code = decode_upc(line) || decode_upc(line.reverse)
|
||||
puts code || "(bad barcode)"
|
||||
end
|
||||
|
|
@ -41,7 +41,7 @@ void decodeUPC(string input) {
|
|||
part = candidate[pos .. next];
|
||||
auto i = countUntil(LEFT_DIGITS, part);
|
||||
if (i >= 0) {
|
||||
output ~= i;
|
||||
output ~= cast(int) i;
|
||||
pos = next;
|
||||
} else {
|
||||
return tuple(false, cast(int[])[]);
|
||||
|
|
@ -61,7 +61,7 @@ void decodeUPC(string input) {
|
|||
part = candidate[pos .. next];
|
||||
auto i = countUntil(RIGHT_DIGITS, part);
|
||||
if (i >= 0) {
|
||||
output ~= i;
|
||||
output ~= cast(int) i;
|
||||
pos = next;
|
||||
} else {
|
||||
return tuple(false, cast(int[])[]);
|
||||
|
|
|
|||
|
|
@ -1,57 +1,66 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">numbers</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">" ## #"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 0</span>
|
||||
<span style="color: #008000;">" ## #"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 1</span>
|
||||
<span style="color: #008000;">" # ##"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 2</span>
|
||||
<span style="color: #008000;">" #### #"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 3</span>
|
||||
<span style="color: #008000;">" # ##"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 4</span>
|
||||
<span style="color: #008000;">" ## #"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 5</span>
|
||||
<span style="color: #008000;">" # ####"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 6</span>
|
||||
<span style="color: #008000;">" ### ##"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 7</span>
|
||||
<span style="color: #008000;">" ## ###"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 8</span>
|
||||
<span style="color: #008000;">" # ##"</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- 9</span>
|
||||
with javascript_semantics
|
||||
constant numbers = {" ## #", -- 0
|
||||
" ## #", -- 1
|
||||
" # ##", -- 2
|
||||
" #### #", -- 3
|
||||
" # ##", -- 4
|
||||
" ## #", -- 5
|
||||
" # ####", -- 6
|
||||
" ### ##", -- 7
|
||||
" ## ###", -- 8
|
||||
" # ##"} -- 9
|
||||
function flip(string s)
|
||||
for i,ch in s do
|
||||
s[i] = iff(ch='#'?' ':'#')
|
||||
end for
|
||||
return s
|
||||
end function
|
||||
constant numberf = apply(numbers,flip)
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">bar_code</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">bar_code</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bar_code</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bar_code</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">95</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #000000;">bar_code</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"# #"</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #000000;">bar_code</span><span style="color: #0000FF;">[</span><span style="color: #000000;">46</span><span style="color: #0000FF;">..</span><span style="color: #000000;">50</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">" # # "</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #000000;">bar_code</span><span style="color: #0000FF;">[</span><span style="color: #000000;">93</span><span style="color: #0000FF;">..</span><span style="color: #000000;">95</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">"# #"</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">reversed</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span> <span style="color: #008080;">to</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">st</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">6</span><span style="color: #0000FF;">?</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">7</span><span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">:</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">7</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">number</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bar_code</span><span style="color: #0000FF;">[</span><span style="color: #000000;">st</span><span style="color: #0000FF;">..</span><span style="color: #000000;">st</span><span style="color: #0000FF;">+</span><span style="color: #000000;">6</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">6</span> <span style="color: #008080;">then</span> <span style="color: #000000;">number</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">number</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" #X"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"X #"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">number</span><span style="color: #0000FF;">,</span><span style="color: #000000;">numbers</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"invalid checksum\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">reversed</span><span style="color: #0000FF;">?</span><span style="color: #008000;">" (upside down)"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">bar_code</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bar_code</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"invalid\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
procedure decode(string bar_code)
|
||||
bar_code = trim(bar_code)
|
||||
if length(bar_code)=95
|
||||
and bar_code[1..3]="# #"
|
||||
and bar_code[46..50]=" # # "
|
||||
and bar_code[93..95]="# #" then
|
||||
for reversed=false to true do
|
||||
sequence r = {}, nums = numbers
|
||||
integer st = 4, checksum = 0, k
|
||||
for i=1 to 12 do
|
||||
k = find(bar_code[st..st+6],nums)-1
|
||||
if k=-1 then exit end if
|
||||
r &= k
|
||||
checksum += iff(odd(i)?k*3:k)
|
||||
st += 7
|
||||
if i=6 then
|
||||
st += 5
|
||||
nums = numberf
|
||||
end if
|
||||
end for
|
||||
if k!=-1 then
|
||||
if remainder(checksum,10) then
|
||||
printf(1,"invalid checksum\n")
|
||||
else
|
||||
printf(1,"%v%s\n",{r,iff(reversed?" (upside down)","")})
|
||||
end if
|
||||
return
|
||||
end if
|
||||
bar_code = reverse(bar_code)
|
||||
end for
|
||||
end if
|
||||
printf(1,"invalid\n")
|
||||
end procedure
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">bar_codes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"""
|
||||
# # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # #
|
||||
# # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # #
|
||||
# # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # #
|
||||
# # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # #
|
||||
# # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # #
|
||||
# # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # #
|
||||
# # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # #
|
||||
# # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # #
|
||||
# # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # #
|
||||
# # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # #
|
||||
"""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bar_codes</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bar_codes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
constant bar_codes = split("""
|
||||
# # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # #
|
||||
# # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # #
|
||||
# # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # #
|
||||
# # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # #
|
||||
# # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # #
|
||||
# # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # #
|
||||
# # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # #
|
||||
# # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # #
|
||||
# # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # #
|
||||
# # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # #
|
||||
""","\n",true)
|
||||
for t in bar_codes do decode(t) end for
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ fn decode_upc(input: &str) {
|
|||
return (false, output);
|
||||
}
|
||||
let part = &candidate[pos..pos + END_SENTINEL.len()];
|
||||
if part == END_SENTINEL {
|
||||
pos += END_SENTINEL.len();
|
||||
} else {
|
||||
if part != END_SENTINEL {
|
||||
return (false, output);
|
||||
}
|
||||
|
||||
|
|
|
|||
105
Task/UPC/V-(Vlang)/upc.v
Normal file
105
Task/UPC/V-(Vlang)/upc.v
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
const left_digits = {
|
||||
" ## #": 0,
|
||||
" ## #": 1,
|
||||
" # ##": 2,
|
||||
" #### #": 3,
|
||||
" # ##": 4,
|
||||
" ## #": 5,
|
||||
" # ####": 6,
|
||||
" ### ##": 7,
|
||||
" ## ###": 8,
|
||||
" # ##": 9,
|
||||
}
|
||||
const end_sentinel = "# #"
|
||||
const mid_sentinel = " # # "
|
||||
const barcodes = [
|
||||
" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # ",
|
||||
" # # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # # ",
|
||||
" # # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # # ",
|
||||
" # # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # # ",
|
||||
" # # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # # ",
|
||||
" # # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # # ",
|
||||
" # # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # # ",
|
||||
" # # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # # ",
|
||||
" # # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # # ",
|
||||
" # # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # # ",
|
||||
]
|
||||
|
||||
// right_digits by swapping "#" and " "
|
||||
fn make_right_digits() map[string]int {
|
||||
mut right := map[string]int{}
|
||||
mut swapped := []rune{}
|
||||
for k, v in left_digits {
|
||||
swapped.clear() // clear array
|
||||
for ch in k.runes() {
|
||||
if ch == `#` { swapped << ` ` }
|
||||
else if ch == ` ` { swapped << `#` }
|
||||
else { swapped << ch }
|
||||
}
|
||||
right[swapped.string()] = v
|
||||
}
|
||||
return right
|
||||
}
|
||||
|
||||
fn decode(candidate string, right_digits map[string]int) ?[]int {
|
||||
mut pos, mut sum := 0, 0
|
||||
mut output := []int{}
|
||||
mut part := candidate[pos..pos + end_sentinel.len]
|
||||
if candidate.len < end_sentinel.len { return none }
|
||||
if part != end_sentinel { return none }
|
||||
pos += end_sentinel.len
|
||||
for _ in 0 .. 6 {
|
||||
if pos + 7 > candidate.len { return none }
|
||||
part = candidate[pos..pos + 7]
|
||||
pos += 7
|
||||
val := left_digits[part] or { return none }
|
||||
output << val
|
||||
}
|
||||
if pos + mid_sentinel.len > candidate.len { return none }
|
||||
part = candidate[pos..pos + mid_sentinel.len]
|
||||
if part != mid_sentinel { return none }
|
||||
pos += mid_sentinel.len
|
||||
for _ in 0 .. 6 {
|
||||
if pos + 7 > candidate.len { return none }
|
||||
part = candidate[pos..pos + 7]
|
||||
pos += 7
|
||||
val := right_digits[part] or { return none }
|
||||
output << val
|
||||
}
|
||||
if pos + end_sentinel.len > candidate.len { return none }
|
||||
part = candidate[pos..pos + end_sentinel.len]
|
||||
if part != end_sentinel { return none }
|
||||
pos += end_sentinel.len
|
||||
// validation
|
||||
for i, d in output {
|
||||
if i % 2 == 0 { sum += d * 3 }
|
||||
else { sum += d }
|
||||
}
|
||||
if sum % 10 != 0 { return none }
|
||||
return output
|
||||
}
|
||||
|
||||
fn decode_upc(input string) {
|
||||
right_digits := make_right_digits()
|
||||
candidate := input.trim_space()
|
||||
mut out := decode(candidate, right_digits)
|
||||
mut rev := candidate.runes().reverse().string()
|
||||
if out != none {
|
||||
println(out)
|
||||
return
|
||||
}
|
||||
// try reversed input
|
||||
out = decode(rev, right_digits)
|
||||
if out != none {
|
||||
println("${out} Upside down")
|
||||
return
|
||||
}
|
||||
// if decoding failed
|
||||
println("(bad barcode)")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for barcode in barcodes {
|
||||
decode_upc(barcode)
|
||||
}
|
||||
}
|
||||
102
Task/UPC/VBScript/upc.vbs
Normal file
102
Task/UPC/VBScript/upc.vbs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
'read UPC barcode Antoni Gual 10/2022 https://rosettacode.org/wiki/UPC
|
||||
|
||||
Option Explicit
|
||||
Const m_limit ="# #"
|
||||
Const m_middle=" # # "
|
||||
Dim a,bnum,i,check,odic
|
||||
a=array(" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # ",_
|
||||
" # # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # # ",_
|
||||
" # # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # # ",_
|
||||
" # # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # # ",_
|
||||
" # # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # # ",_
|
||||
" # # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # # ",_
|
||||
" # # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # # ",_
|
||||
" # # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # # ",_
|
||||
" # # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # # ",_
|
||||
" # # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # # ")
|
||||
|
||||
' 0 1 2 3 4 5 6 7 8 9
|
||||
bnum=Array("0001101","0011001","0010011","0111101","0100011"," 0110001","0101111","0111011","0110111","0001011")
|
||||
|
||||
Set oDic = WScript.CreateObject("scripting.dictionary")
|
||||
For i=0 To 9:
|
||||
odic.Add bin2dec(bnum(i),Asc("1")),i+1
|
||||
odic.Add bin2dec(bnum(i),Asc("0")),-i-1
|
||||
Next
|
||||
|
||||
For i=0 To UBound(a) : print pad(i+1,-2) & ": "& upc(a(i)) :Next
|
||||
WScript.Quit(1)
|
||||
|
||||
Function bin2dec(ByVal B,a) 'binary,ascii of bit 1
|
||||
Dim n
|
||||
While len(b)
|
||||
n =n *2 - (asc(b)=a) 'true is -1 in vbs
|
||||
b=mid(b,2)
|
||||
Wend
|
||||
bin2dec= n And 127
|
||||
End Function
|
||||
|
||||
Sub print(s):
|
||||
On Error Resume Next
|
||||
WScript.stdout.WriteLine (s)
|
||||
If err= &h80070006& Then WScript.Echo " Please run this script with CScript": WScript.quit
|
||||
End Sub
|
||||
function pad(s,n) if n<0 then pad= right(space(-n) & s ,-n) else pad= left(s& space(n),n) end if :end function
|
||||
|
||||
Function iif(t,a,b) If t Then iif=a Else iif=b End If :End Function
|
||||
|
||||
Function getnum(s,r) 'get a number from code, check if its's reversed and trim the code
|
||||
Dim n,s1,r1
|
||||
'returns number or 0 if not found
|
||||
s1=Left(s,7)
|
||||
s=Mid(s,8)
|
||||
r1=r
|
||||
Do
|
||||
If r Then s1=StrReverse(s1)
|
||||
n=bin2dec(s1,asc("#"))
|
||||
If odic.exists(n) Then
|
||||
getnum=odic(n)
|
||||
Exit Function
|
||||
Else
|
||||
If r1<>r Then getnum=0:Exit Function
|
||||
r=Not r
|
||||
End If
|
||||
Loop
|
||||
End Function
|
||||
|
||||
Function getmarker(s,m) 'get a marker and trim the code
|
||||
getmarker= (InStr(s,m)= 1)
|
||||
s=Mid(s,Len(m)+1)
|
||||
End Function
|
||||
|
||||
Function checksum(ByVal s)
|
||||
Dim n,i : n=0
|
||||
do
|
||||
n=n+(Asc(s)-48)*3
|
||||
s=Mid(s,2)
|
||||
n=n+(Asc(s)-48)*1
|
||||
s=Mid(s,2)
|
||||
Loop until Len(s)=0
|
||||
checksum= ((n mod 10)=0)
|
||||
End function
|
||||
|
||||
Function upc(ByVal s1)
|
||||
Dim i,n,s,out,rev,j
|
||||
|
||||
'forget about the leading adn trailing spaces, the task says they may be wrong
|
||||
s=Trim(s1)
|
||||
If getmarker(s,m_limit)=False Then upc= "bad start marker ":Exit function
|
||||
rev=False
|
||||
out=""
|
||||
For j= 0 To 1
|
||||
For i=0 To 5
|
||||
n=getnum(s,rev)
|
||||
If n=0 Then upc= pad(out,16) & pad ("bad code",-10) & pad("pos "& i+j*6+1,-11): Exit Function
|
||||
out=out & Abs(n)-1
|
||||
Next
|
||||
If j=0 Then If getmarker(s,m_middle)=False Then upc= "bad middle marker " & out :Exit Function
|
||||
Next
|
||||
If getmarker(s,m_limit)=False Then upc= "bad end marker " :Exit function
|
||||
If rev Then out=strreverse(out)
|
||||
upc= pad(out,16) & pad(iif (checksum(out),"valid","not valid"),-10)& pad(iif(rev,"reversed",""),-11)
|
||||
End Function
|
||||
Loading…
Add table
Add a link
Reference in a new issue