UPC: Difference between revisions
Content added Content deleted
(Added Wren) |
|||
Line 884: | Line 884: | ||
} |
} |
||
return 0; |
return 0; |
||
}</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|D}}== |
|||
{{trans|C++}} |
|||
<lang d>import std.algorithm : countUntil, each, map; |
|||
import std.array : array; |
|||
import std.conv : to; |
|||
import std.range : empty, retro; |
|||
import std.stdio : writeln; |
|||
import std.string : strip; |
|||
import std.typecons : tuple; |
|||
immutable LEFT_DIGITS = [ |
|||
" ## #", |
|||
" ## #", |
|||
" # ##", |
|||
" #### #", |
|||
" # ##", |
|||
" ## #", |
|||
" # ####", |
|||
" ### ##", |
|||
" ## ###", |
|||
" # ##" |
|||
]; |
|||
immutable RIGHT_DIGITS = LEFT_DIGITS.map!`a.map!"a == '#' ? ' ' : '#'".array`.array; |
|||
immutable END_SENTINEL = "# #"; |
|||
immutable MID_SENTINEL = " # # "; |
|||
void decodeUPC(string input) { |
|||
auto decode(string candidate) { |
|||
int[] output; |
|||
size_t pos = 0; |
|||
auto next = pos + END_SENTINEL.length; |
|||
auto part = candidate[pos .. next]; |
|||
if (part == END_SENTINEL) { |
|||
pos = next; |
|||
} else { |
|||
return tuple(false, cast(int[])[]); |
|||
} |
|||
foreach (_; 0..6) { |
|||
next = pos + 7; |
|||
part = candidate[pos .. next]; |
|||
auto i = countUntil(LEFT_DIGITS, part); |
|||
if (i >= 0) { |
|||
output ~= i; |
|||
pos = next; |
|||
} else { |
|||
return tuple(false, cast(int[])[]); |
|||
} |
|||
} |
|||
next = pos + MID_SENTINEL.length; |
|||
part = candidate[pos .. next]; |
|||
if (part == MID_SENTINEL) { |
|||
pos = next; |
|||
} else { |
|||
return tuple(false, cast(int[])[]); |
|||
} |
|||
foreach (_; 0..6) { |
|||
next = pos + 7; |
|||
part = candidate[pos .. next]; |
|||
auto i = countUntil(RIGHT_DIGITS, part); |
|||
if (i >= 0) { |
|||
output ~= i; |
|||
pos = next; |
|||
} else { |
|||
return tuple(false, cast(int[])[]); |
|||
} |
|||
} |
|||
next = pos + END_SENTINEL.length; |
|||
part = candidate[pos .. next]; |
|||
if (part == END_SENTINEL) { |
|||
pos = next; |
|||
} else { |
|||
return tuple(false, cast(int[])[]); |
|||
} |
|||
int sum = 0; |
|||
foreach (i,v; output) { |
|||
if (i % 2 == 0) { |
|||
sum += 3 * v; |
|||
} else { |
|||
sum += v; |
|||
} |
|||
} |
|||
return tuple(sum % 10 == 0, output); |
|||
} |
|||
auto candidate = input.strip; |
|||
auto output = decode(candidate); |
|||
if (output[0]) { |
|||
writeln(output[1]); |
|||
} else { |
|||
output = decode(candidate.retro.array.to!string); |
|||
if (output[0]) { |
|||
writeln(output[1], " Upside down"); |
|||
} else if (output[1].empty) { |
|||
writeln("Invalid digit(s)"); |
|||
} else { |
|||
writeln("Invalid checksum", output); |
|||
} |
|||
} |
|||
} |
|||
void main() { |
|||
auto barcodes = [ |
|||
" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # ", |
|||
" # # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # # ", |
|||
" # # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # # ", |
|||
" # # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # # ", |
|||
" # # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # # ", |
|||
" # # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # # ", |
|||
" # # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # # ", |
|||
" # # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # # ", |
|||
" # # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # # ", |
|||
" # # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # # ", |
|||
]; |
|||
barcodes.each!decodeUPC; |
|||
}</lang> |
}</lang> |
||
{{out}} |
{{out}} |