Perl - GD::Graph - Gap between plot and y-axis - perl

I am using Perl's GD::Graph
module to plot a signal profile. I've managed to get almost everything to look just about right, except that for some reason there is an irritating and unwanted gap between the y-axis and the first plotted point. How can I eliminate this?
Here is the code for the test page I've written (it display on my localhost server, but I tried installing it on my live server so that others here could see the result, it errors - I think there must be some Perl modules missing from my live site):
#!perl
use POSIX;
use CGI ':standard';
use GD::Graph::area;
use GD::Graph::colour qw(:colours);
use strict;
# Graph constants
GD::Graph::colour::add_colour( axes => [ 0x00, 0x00, 0x00 ] );
GD::Graph::colour::add_colour( earth => [ 0x00, 0x00, 0x00 ] );
GD::Graph::colour::add_colour( beam => [ 0x00, 0x00, 0x00 ] );
GD::Graph::colour::add_colour( clutter => [ 0x66, 0x33, 0x00 ] );
GD::Graph::colour::add_colour( terrain => [ 0x00, 0x99, 0x00 ] );
GD::Graph::colour::add_colour( earth => [ 0x00, 0x00, 0x00 ] );
GD::Graph::colour::add_colour( fre1 => [ 0xFF, 0x33, 0x00 ] );
GD::Graph::colour::add_colour( fre2 => [ 0xFF, 0x66, 0x00 ] );
GD::Graph::colour::add_colour( sky1 => [ 0x33, 0x66, 0x99 ] );
GD::Graph::colour::add_colour( sky2 => [ 0x66, 0x99, 0xCC ] );
# All arrays should same number of entries.
my #data = (
[ 0, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 5, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 10, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 15, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 20, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 25, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, 30, undef, undef, undef, undef, undef, undef, undef, undef, undef ],
[ 450, 458, 459, 458, 457, 455, 453, 451, 449, 447, 444, 441, 438, 435, 432, 429, 426, 422, 420, 416, 413, 409, 406, 402, 399, 395, 391, 388, 384, 381, 376, 373, 369, 365, 361, 358, 353, 350, 345, 341, 337, 333, 329, 325, 321, 316, 313, 308, 304, 299, 296, 291, 286, 282, 277, 273, 268, 265, 259, 256, 250, 247, 241, 236, 232, 227, 223, 217, 213, 208, 204, 198, 194, 188, 184, 178, 173, 168, 163, 158, 152, 148, 142, 137, 131, 126, 120, 115, 109, 102, 97, 90, 85, 78, 72, 64, 58, 50, 43, 32 ],
[ 450, 453, 451, 449, 447, 444, 441, 438, 435, 432, 428, 426, 422, 418, 415, 411, 408, 404, 400, 396, 393, 389, 386, 381, 378, 374, 369, 366, 361, 358, 353, 350, 345, 342, 337, 334, 329, 326, 321, 316, 313, 308, 305, 300, 296, 291, 288, 283, 279, 274, 271, 266, 261, 257, 252, 249, 244, 240, 235, 231, 226, 222, 217, 212, 208, 203, 199, 194, 190, 185, 181, 176, 172, 166, 162, 157, 151, 147, 142, 138, 132, 128, 123, 118, 113, 108, 103, 98, 92, 87, 82, 76, 71, 65, 60, 54, 49, 42, 36, 27 ],
[ 450, 445, 440, 436, 432, 428, 423, 419, 414, 411, 406, 402, 397, 392, 389, 384, 380, 375, 372, 367, 363, 358, 354, 350, 346, 341, 336, 332, 328, 324, 319, 315, 310, 307, 302, 298, 293, 290, 285, 280, 276, 271, 268, 263, 259, 254, 250, 246, 242, 237, 233, 228, 224, 220, 215, 211, 206, 203, 198, 194, 189, 186, 181, 176, 172, 167, 164, 159, 155, 150, 147, 142, 138, 133, 129, 125, 120, 116, 111, 107, 102, 99, 94, 90, 85, 82, 77, 73, 68, 63, 60, 55, 51, 46, 43, 38, 34, 29, 25, 21 ],
[ 450, 437, 429, 423, 416, 411, 405, 400, 394, 389, 383, 379, 373, 367, 363, 357, 353, 347, 343, 337, 333, 328, 323, 318, 314, 309, 303, 299, 294, 290, 285, 281, 275, 272, 266, 262, 257, 253, 248, 243, 239, 234, 231, 226, 222, 217, 213, 208, 205, 200, 196, 191, 186, 183, 178, 174, 169, 166, 161, 157, 153, 149, 144, 140, 136, 132, 128, 124, 120, 116, 112, 108, 104, 100, 97, 92, 88, 84, 80, 77, 73, 69, 65, 62, 58, 55, 51, 48, 44, 40, 37, 34, 31, 27, 25, 22, 19, 17, 15, 14 ],
[ 450, 432, 422, 415, 406, 400, 393, 387, 380, 375, 368, 363, 357, 350, 345, 339, 334, 328, 324, 318, 313, 307, 303, 297, 293, 287, 281, 277, 271, 267, 262, 258, 252, 248, 243, 239, 233, 229, 224, 219, 215, 210, 206, 201, 197, 192, 188, 183, 180, 175, 171, 166, 161, 158, 153, 149, 145, 141, 136, 133, 128, 125, 120, 116, 112, 108, 105, 100, 97, 93, 89, 85, 82, 78, 75, 71, 67, 64, 60, 57, 53, 50, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 17, 15, 13, 11, 10, 8, 8, 9 ],
[ 387, 344, 266, 240, 222, 215, 190, 156, 120, 76, 99, 151, 167, 158, 167, 158, 157, 148, 114, 89, 87, 28, 11, 11, 12, 12, 12, 13, 13, 13, 13, 23, 15, 34, 39, 38, 72, 107, 122, 134, 128, 128, 121, 100, 82, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 20, 20, 15, 15, 15, 15, 14, 14, 14, 14, 60, 53, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 2, 1, 26 ],
[ 386, 343, 261, 235, 217, 210, 185, 151, 105, 61, 84, 136, 152, 143, 152, 153, 152, 143, 109, 84, 82, 23, 11, 11, 12, 12, 12, 13, 13, 13, 13, 23, 15, 34, 34, 33, 67, 102, 117, 129, 123, 128, 121, 100, 82, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 60, 53, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 2, 1, 26 ],
[ 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 2, 2, 1, 1 ]
);
my $dist = 32.745;
my $mygraph = GD::Graph::area->new( 800, 300 );
$mygraph->set(
transparent => 0,
l_margin => 3,
b_margin => 3,
t_margin => 5,
r_margin => 5,
text_space => 3,
axis_space => 7,
tick_length => -5,
accent_treshold => 100,
x_label_position => 0.5,
bgclr => 'white',
fgclr => 'black',
boxclr => 'sky1',
labelclr => 'black',
axislabelclr => 'black',
textclr => 'black',
x_label => 'Kilometres',
y_label => 'Metres',
x_label_skip => 15.27,
x_last_label_skip => 1,
x_min_value => 0,
x_max_value => $dist,
borderclrs => [qw(fre2 fre1 black fre2 sky1 clutter terrain axes)],
dclrs => [qw(fre2 fre1 fre1 fre2 sky1 clutter terrain axes)]
) or warn $mygraph->error;
my $myimage = $mygraph->plot( \#data ) or die $mygraph->error;
print "Content-type: image/png\n\n";
print $myimage->png;
Background Information
I currently have a very successful web page which enables UK citizens to align a terrestrial TV aerial towards a given transmitter.
Here's an example of it in action
Once loading has completed, and the relevant buttons enabled, there three available visual components to help align the aerial and predict the likely usefulness of the signal:
A Google map for finding a landmark to point the aerial towards
A UK Ordnance Survey map showing the signal path
A vertical signal profile showing potential obstructions
It is the last of these, which is obtained by pressing the Signal Profile button at the bottom of the form and is displayed at the bottom of the page beneath the two maps, that is of concern here. I'm looking to replace it because it currently uses the Google Chart Tools API which unfortunately has been deprecated by Google and was supposed to end in 2015, but fortunately so far they've kept it running.
I've been looking ever since for a replacement come the day that Google throw the switch, but have had very limited success. If anyone knows of a package I could install on my own server to replace Google's chart drawing functionality, I'd be most grateful to know about it.

This feels like an off-by-one error in the code, but I don't have time to investigate further now. I'll just note that a work-around seems to be to replace:
x_min_value => 0,
with
x_min_value => 1,

Related

Filter Scala Matrix with condition

I have the given matrix in Scala:
val matrix = Array([30, 0, 13, 21, 25, 15],
[55, 47, 26, 54, 44, 3],
[21, 19, 23, 47, 29, 13],
[52, 50, 44, 14, 21, 24],
[10, 37, 0, 22, 17, 58],
[36, 55, 48, 27, 13, 35])
I need to filter the matrix (values from 2nd column > 40 and values fom 4rd column <45)
Can i do this somehow with the matrix.filter method?
You can try this way:
scala> :paste
// Entering paste mode (ctrl-D to finish)
val matrix = Array(Array(30, 0, 13, 21, 25, 15),
Array(55, 47, 26, 54, 44, 3),
Array(21, 19, 23, 47, 29, 13),
Array(52, 50, 44, 14, 21, 24),
Array(10, 37, 0, 22, 17, 58),
Array(36, 55, 48, 27, 13, 35))
// Exiting paste mode, now interpreting.
matrix: Array[Array[Int]] = Array(Array(30, 0, 13, 21, 25, 15), Array(55, 47, 26, 54, 44, 3), Array(21, 19, 23, 47, 29, 13), Array(52, 50, 44, 14, 21, 24), Array(10, 37, 0, 22, 17, 58), Array(36, 55, 48, 27, 13, 35))
scala> matrix.filter(x => x(1) > 40 && x(3) < 45)
res0: Array[Array[Int]] = Array(Array(52, 50, 44, 14, 21, 24), Array(36, 55, 48, 27, 13, 35))

How to fastly access the variable in a function?

I have a function cal_power that called many times (3000times) in my main project. It uses the loop-up table way to perform computing the power of a scale number (follows some rule to make the table). The TABLE is a vector 1x510.
In my current solution, for each time the function cal_power is called, the TABLE is initialization again, thus it takes some waste time. We know that the value in TABLE is fixed, do we have anyway in MATLAB to initialize the value of TABLE just one time, and it can access anywhere? I tried to use a global variable but it spends more time than my current solution. Thanks
function p = cal_power( ii )
% Input: ii: Integer in {0,255} (forced to be, if not)
% Output:
% p = TABLE( mod( ii, 255) + 1 );
% TABLE : look-up table
TABLE = [1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76,...
152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157,...
39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35,...
70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222,...
161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60,...
120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163,...
91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52,...
104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59,...
118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218,...
169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85,...
170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198,...
145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171,...
75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25,...
50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81,...
162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9,...
18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11,...
22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71,...
142, 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38,...
76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192,...
157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159,...
35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111,...
222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30,...
60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223,...
163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26,...
52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147,...
59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218,...
169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85,...
170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198,...
145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171,...
75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25,...
50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81,...
162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9,...
18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11,...
22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71,...
142];
p = TABLE( mod( ii, 255) + 1 );
Just use Matlab Persistent Variable:
function p = cal_power( ii )
% Input: ii: Integer in {0,255} (forced to be, if not)
% Output:
% p = TABLE( mod( ii, 255) + 1 );
% TABLE : look-up table
persistent TABLE;
if isempty(TABLE)
TABLE = [1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76,...
152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157,...
39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35,...
70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222,...
end
UPDATE:
The following Code featuring the persistent variable took 0.034 seconds on my machine compared to 0.039 seconds without persistent:
tic
for i=1:3000
ii = round(rand*254)+1;
p=cal_power(ii);
end
toc
So I don't see that it is slower at all. Especially not by a factor 5.
If you still need a different solution, initialize the TABLE in the beginning of your main-function and just pass it to cal_power as additional parameter.
function p = cal_power( ii , TABLE)
% don't initialize TABLE here anymore
...
end
This way you make sure that TABLE only gets initialized once. Passing the variable as a reference should not consume much computation time too.

Convert UInt8 to character UTF8

My code for converting UInt8 to character is:
for item in array {
print(Character(UnicodeScalar(item)))
}
the data in array is:
[10, 0, 0, 0, 2, 0, 0, 0, 105, 100, 14, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 76, 111, 110, 103, 1, 0, 0, 0, 97, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 1, 0, 0, 0, 98, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 1, 0, 0, 0, 99, 2, 0, 0, 0, 91, 66, 1, 0, 0, 0, 100, 2, 0, 0, 0, 91, 66, 1, 0, 0, 0, 102, 2, 0, 0, 0, 91, 66, 1, 0, 0, 0, 101, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 66, 111, 111, 108, 101, 97, 110, 9, 0, 0, 0, 116, 121, 112, 101, 95, 99, 111, 100, 101, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 8, 0, 0, 0, 103, 114, 111, 117, 112, 95, 105, 100, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 10, 0, 0, 0, 103, 114, 111, 117, 112, 95, 99, 111, 100, 101, 17, 0, 0, 0, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, 1, 0, 0, 0, 1, 0, 0, 0, 49, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 3, 0, 0, 0, 21, 0, 0, 0, 216, 167, 216, 180, 216, 174, 216, 167, 216, 181, 32, 216, 170, 216, 172, 216, 167, 216, 177, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 49, 0, 9, 0, 0, 0, 1, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 49, 0, 1, 0, 0, 0, 1, 0, 0, 0, 50, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 50, 48, 0, 3, 0, 0, 0, 28, 0, 0, 0, 216, 167, 216, 180, 216, 174, 216, 167, 216, 181, 32, 216, 186, 217, 138, 216, 177, 32, 216, 170, 216, 172, 216, 167, 216, 177, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 49, 0, 9, 0, 0, 0, 1, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 49, 0, 1, 0, 0, 0, 1, 0, 0, 0, 51, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 51, 48, 0, 3, 0, 0, 0, 19, 0, 0, 0, 216, 172, 216, 167, 216, 177, 219, 140, 32, 216, 180, 216, 177, 217, 131, 216, 167, 216, 161, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 49, 0, 9, 0, 0, 0, 1, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 53, 57, 0, 1, 0, 0, 0, 1, 0, 0, 0, 52, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 54, 48, 0, 3, 0, 0, 0, 60, 0, 0, 0, 216, 179, 216, 167, 217, 138, 216, 177, 32, 216, 173, 216, 179, 216, 167, 216, 168, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 47, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 217, 134, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 54, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 49, 0, 9, 0, 0, 0, 1, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 53, 56, 0, 1, 0, 0, 0, 1, 0, 0, 0, 53, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 3, 0, 0, 0, 10, 0, 0, 0, 216, 181, 217, 134, 216, 175, 217, 136, 217, 130, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 54, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 48, 48, 0, 3, 0, 0, 0, 4, 0, 0, 0, 116, 101, 115, 116, 0, 4, 0, 0, 0, 4, 0, 0, 0, 116, 101, 115, 116, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 51, 50, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 3, 0, 0, 0, 28, 0, 0, 0, 216, 167, 216, 179, 217, 134, 216, 167, 216, 175, 32, 217, 134, 216, 178, 216, 175, 32, 216, 181, 217, 134, 216, 175, 217, 136, 217, 130, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 56, 0, 1, 0, 0, 0, 1, 0, 0, 0, 55, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 3, 0, 0, 0, 23, 0, 0, 0, 216, 170, 217, 134, 216, 174, 217, 136, 216, 167, 217, 135, 32, 218, 175, 216, 177, 216, 175, 216, 167, 217, 134, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 51, 0, 1, 0, 0, 0, 1, 0, 0, 0, 56, 0, 2, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 3, 0, 0, 0, 8, 0, 0, 0, 216, 168, 216, 167, 217, 134, 217, 131, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 53, 52, 0, 1, 0, 0, 0, 1, 0, 0, 0, 57, 0, 2, 0, 0, 0, 3, 0, 0, 0, 50, 50, 48, 0, 3, 0, 0, 0, 51, 0, 0, 0, 216, 167, 216, 179, 217, 134, 216, 167, 216, 175, 32, 216, 175, 216, 177, 32, 216, 172, 216, 177, 217, 138, 216, 167, 217, 134, 32, 217, 136, 216, 181, 217, 136, 217, 132, 32, 217, 134, 216, 178, 216, 175, 32, 216, 168, 216, 167, 217, 134, 217, 131, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 50, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 53, 53, 0, 1, 0, 0, 0, 2, 0, 0, 0, 49, 48, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 3, 0, 0, 0, 40, 0, 0, 0, 216, 167, 216, 180, 216, 174, 216, 167, 216, 181, 32, 216, 170, 216, 172, 216, 167, 216, 177, 219, 140, 32, 40, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 41, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 53, 0, 1, 0, 0, 0, 2, 0, 0, 0, 49, 49, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 50, 48, 0, 3, 0, 0, 0, 47, 0, 0, 0, 216, 167, 216, 180, 216, 174, 216, 167, 216, 181, 32, 216, 186, 217, 138, 216, 177, 32, 216, 170, 216, 172, 216, 167, 216, 177, 219, 140, 32, 40, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 41, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 55, 0, 1, 0, 0, 0, 2, 0, 0, 0, 49, 50, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 51, 48, 0, 3, 0, 0, 0, 38, 0, 0, 0, 216, 172, 216, 167, 216, 177, 219, 140, 32, 216, 180, 216, 177, 217, 131, 216, 167, 216, 161, 32, 40, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 41, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 50, 56, 0, 1, 0, 0, 0, 2, 0, 0, 0, 49, 51, 0, 2, 0, 0, 0, 3, 0, 0, 0, 52, 49, 48, 0, 3, 0, 0, 0, 34, 0, 0, 0, 217, 133, 217, 136, 216, 172, 217, 136, 216, 175, 219, 140, 32, 217, 131, 216, 167, 217, 132, 216, 167, 219, 140, 32, 216, 185, 217, 133, 217, 136, 217, 133, 219, 140, 0, 4, 0, 0, 0, 25, 0, 0, 0, 217, 133, 46, 32, 217, 131, 216, 167, 217, 132, 216, 167, 219, 140, 32, 216, 185, 217, 133, 217, 136, 217, 133, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 52, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 56, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 49, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 49, 48, 0, 3, 0, 0, 0, 28, 0, 0, 0, 217, 190, 217, 138, 216, 180, 226, 128, 140, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 226, 128, 140, 217, 135, 216, 167, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 52, 54, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 50, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 50, 48, 0, 3, 0, 0, 0, 43, 0, 0, 0, 216, 179, 217, 129, 216, 167, 216, 177, 216, 180, 216, 167, 216, 170, 32, 217, 131, 216, 167, 217, 132, 216, 167, 32, 217, 136, 32, 216, 167, 216, 185, 216, 170, 216, 168, 216, 167, 216, 177, 216, 167, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 50, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 51, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 51, 48, 0, 3, 0, 0, 0, 40, 0, 0, 0, 217, 131, 216, 167, 216, 177, 32, 216, 175, 216, 177, 32, 216, 172, 216, 177, 217, 138, 216, 167, 217, 134, 32, 217, 190, 216, 177, 217, 136, 218, 152, 217, 135, 226, 128, 140, 217, 135, 216, 167, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 52, 50, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 52, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 52, 48, 0, 3, 0, 0, 0, 55, 0, 0, 0, 216, 179, 216, 177, 217, 133, 216, 167, 217, 138, 217, 135, 226, 128, 140, 218, 175, 216, 176, 216, 167, 216, 177, 219, 140, 32, 216, 175, 216, 177, 32, 216, 179, 216, 167, 217, 138, 216, 177, 32, 216, 180, 216, 177, 217, 131, 216, 170, 226, 128, 140, 217, 135, 216, 167, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 52, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 51, 54, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 53, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 53, 48, 0, 3, 0, 0, 0, 31, 0, 0, 0, 217, 136, 216, 175, 216, 167, 217, 138, 216, 185, 32, 217, 136, 32, 216, 179, 217, 190, 216, 177, 216, 175, 217, 135, 226, 128, 140, 217, 135, 216, 167, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 53, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 50, 48, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 54, 0, 2, 0, 0, 0, 3, 0, 0, 0, 55, 54, 48, 0, 3, 0, 0, 0, 79, 0, 0, 0, 216, 179, 216, 167, 217, 138, 216, 177, 32, 216, 173, 216, 179, 216, 167, 216, 168, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 47, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 217, 134, 219, 140, 32, 40, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 217, 134, 219, 140, 41, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 54, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 50, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 55, 0, 2, 0, 0, 0, 3, 0, 0, 0, 56, 49, 48, 0, 3, 0, 0, 0, 39, 0, 0, 0, 216, 179, 216, 167, 217, 138, 216, 177, 32, 216, 175, 216, 167, 216, 177, 216, 167, 216, 166, 219, 140, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 172, 216, 167, 216, 177, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 56, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 50, 0, 9, 0, 0, 0, 1, 0, 0, 0, 49, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 50, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 56, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 3, 0, 0, 0, 35, 0, 0, 0, 216, 167, 217, 133, 217, 136, 216, 167, 217, 132, 32, 217, 136, 32, 217, 133, 216, 167, 216, 180, 217, 138, 217, 134, 226, 128, 140, 216, 162, 217, 132, 216, 167, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 51, 0, 9, 0, 0, 0, 1, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 52, 0, 1, 0, 0, 0, 2, 0, 0, 0, 50, 57, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 3, 0, 0, 0, 48, 0, 0, 0, 216, 175, 216, 167, 216, 177, 216, 167, 216, 166, 219, 140, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 175, 216, 177, 32, 216, 172, 216, 177, 217, 138, 216, 167, 217, 134, 32, 216, 170, 217, 131, 217, 133, 217, 138, 217, 132, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 51, 0, 9, 0, 0, 0, 1, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 50, 49, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 48, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 3, 0, 0, 0, 46, 0, 0, 0, 217, 133, 216, 174, 216, 167, 216, 177, 216, 172, 32, 217, 130, 216, 168, 217, 132, 32, 216, 167, 216, 178, 32, 216, 168, 217, 135, 216, 177, 217, 135, 226, 128, 140, 216, 168, 216, 177, 216, 175, 216, 167, 216, 177, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 51, 0, 9, 0, 0, 0, 1, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 55, 48, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 49, 0, 2, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 3, 0, 0, 0, 50, 0, 0, 0, 216, 179, 216, 177, 217, 133, 216, 167, 217, 138, 217, 135, 226, 128, 140, 218, 175, 216, 176, 216, 167, 216, 177, 219, 140, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 168, 217, 132, 217, 134, 216, 175, 32, 217, 133, 216, 175, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 51, 0, 9, 0, 0, 0, 1, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 49, 55, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 50, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 3, 0, 0, 0, 39, 0, 0, 0, 216, 179, 216, 167, 217, 138, 216, 177, 32, 216, 175, 216, 167, 216, 177, 216, 167, 216, 166, 219, 140, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 171, 216, 167, 216, 168, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 51, 0, 9, 0, 0, 0, 1, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 51, 48, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 51, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 3, 0, 0, 0, 25, 0, 0, 0, 216, 173, 217, 130, 32, 216, 167, 217, 132, 216, 167, 217, 133, 216, 170, 217, 138, 216, 167, 216, 178, 217, 135, 216, 167, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 52, 0, 9, 0, 0, 0, 1, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 53, 55, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 52, 0, 2, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 3, 0, 0, 0, 17, 0, 0, 0, 216, 173, 217, 130, 32, 216, 179, 216, 177, 217, 130, 217, 129, 217, 132, 219, 140, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 52, 0, 9, 0, 0, 0, 1, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 52, 52, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 53, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 3, 0, 0, 0, 36, 0, 0, 0, 216, 167, 216, 179, 217, 134, 216, 167, 216, 175, 32, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 217, 134, 219, 140, 32, 216, 168, 216, 167, 217, 134, 217, 131, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 49, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 53, 0, 9, 0, 0, 0, 1, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 53, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 54, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 3, 0, 0, 0, 52, 0, 0, 0, 217, 136, 216, 167, 217, 133, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 217, 134, 219, 140, 32, 217, 131, 217, 136, 216, 170, 216, 167, 217, 135, 226, 128, 140, 217, 133, 216, 175, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 50, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 53, 0, 9, 0, 0, 0, 1, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 51, 52, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 55, 0, 2, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 3, 0, 0, 0, 66, 0, 0, 0, 216, 173, 216, 181, 217, 135, 32, 216, 172, 216, 167, 216, 177, 219, 140, 32, 217, 136, 216, 167, 217, 133, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 217, 190, 216, 177, 216, 175, 216, 167, 216, 174, 216, 170, 217, 134, 219, 140, 32, 216, 168, 217, 132, 217, 134, 216, 175, 226, 128, 140, 217, 133, 216, 175, 216, 170, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 49, 51, 48, 0, 8, 0, 0, 0, 1, 0, 0, 0, 53, 0, 9, 0, 0, 0, 1, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 51, 55, 0, 1, 0, 0, 0, 2, 0, 0, 0, 51, 56, 0, 2, 0, 0, 0, 3, 0, 0, 0, 50, 49, 48, 0, 3, 0, 0, 0, 41, 0, 0, 0, 217, 190, 217, 138, 216, 180, 226, 128, 140, 216, 175, 216, 177, 217, 138, 216, 167, 217, 129, 216, 170, 32, 216, 167, 216, 178, 32, 217, 133, 216, 180, 216, 170, 216, 177, 217, 138, 216, 167, 217, 134, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 135, 226, 128, 140, 216, 180, 216, 175, 217, 135, 0, 4, 0, 0, 0, 45, 0, 0, 0, 216, 168, 217, 135, 46, 32, 217, 129, 46, 32, 216, 167, 217, 133, 217, 136, 216, 167, 217, 132, 32, 217, 136, 32, 217, 133, 216, 167, 216, 180, 217, 138, 217, 134, 226, 128, 140, 216, 162, 217, 132, 216, 167, 216, 170, 0, 6, 216, 168, 217, 135, 216, 167, 219, 140, 226, 128, 140, 216, 170, 217, 133, 216, 167, 217, 133, 226, 128, 140, 216, 180, 216, 175, 217, 135, 226, 128, 140, 219, 140, 32, 216, 179, 216, 177, 217, 133, 216, 167, 217, 138, 217, 135, 226, 128, 140, 218, 175, 216, 176, 216, 167, 216, 177, 219, 140, 226, 128, 140, 128, 140, 218, 175, 216, 176, 216, 167, 216, 177, 219, 140, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 168, 217, 132, 217, 134, 216, 135, 216, 167, 219, 140, 32, 216, 167, 217, 134, 216, 170, 216, 184, 216, 167, 217, 133, 219, 140, 0, 0, 216, 183, 216, 177, 217, 129, 32, 216, 173, 216, 179, 216, 167, 216, 168, 226, 128, 140, 217, 135, 216, 167, 219, 140, 32, 216, 167, 217, 134, 216, 170, 216, 184, 216, 167, 217, 133, 219, 140, 0, 6, 0, 0, 0, 5, 0, 0, 0, 102, 97, 108, 115, 101, 0, 7, 0, 0, 0, 3, 0, 0, 0, 55, 50, 48, 0, 8, 0, 0, 0, 2, 0, 0, 0, 49, 48, 0, 9, 0, 0, 0, 1, 0, 0, 0, 57, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 54, 51, 0, 1, 0, 0, 0, 2, 0, 0, 0, 55, 53, 0, 2, 0, 0, 0, 3, 0, 0, 0, 51, 49, 48, 0, 3, 0, 0, 0, 59, 0, 0, 0, 216, 168, 216, 177, 218, 175, 216, 180, 216, 170, 32, 216, 167, 216, 178, 32, 217, 129, 216, 177, 217, 136, 216, 180, 32, 217, 133, 217, 136, 216, 172, 217, 136, 216, 175, 219, 140, 32, 217, 131, 216, 167, 217, 132, 216, 167, 219, 140, 32, 216, 185, 217, 133, 217, 136, 217, 133, 219, 140, 0, 4, 0, 0, 0, 33, 0, 0, 0, 216, 168, 46, 32, 217, 129, 46, 32, 217, 133, 46, 32, 217, 131, 216, 167, 217, 132, 216, 167, 219, 140, 1]
and result should be:
1310 ریتجاfalse31010612320اشخ غ تریfalse3201013330جای
but i get result like:
1310 ÙÙÙfalse31010612320ÙÙÙÙÙfalse3201013330ÙÙÙ
It works for English characters but for character in Persian language it is not working. Any body can help me?
You're converting each byte separately to the string, while UTF-8 is multibyte encoding, only characters that could be represented are 0-127(0x00-0x7f) characters from old ASCII table (numbers, basic latin characters, etc.), other characters will be encoded using 2-4 bytes.
So, UInt8 sequence should be converted using code like this:
let data = Data(bytes: array)
let string = String(data: data, encoding: .utf8)

bytes convert to string swift (or swift2)

I am new in swift. i have this bytes:
Bytes: [11, 143, 102, 88, 132, 238, 0, 156, 100, 166, 72, 98, 226, 109, 51, 196, 124, 124, 207, 252, 204, 129, 233, 209, 112, 127, 66, 177, 37, 141, 169, 158, 122, 74, 215, 103, 13, 128, 74, 81, 221, 46, 219, 145, 107, 131, 90, 246, 37, 212, 91, 237, 32, 138, 74, 147, 238, 40, 182, 158, 12, 124, 197, 17, 92, 24, 184, 44, 150, 127, 147, 161, 175, 186, 227, 4, 248, 44, 21, 83, 0]
and i used this code:
let dencryptedBytes: [UInt8] = try! AES(key: UrlManager.CONNECTION_KEY, iv:UrlManager.CONNECTION_IV, blockMode: .CBC).encrypt(bytes)
and result like this:
Decoded Bytes: [157, 29, 111, 190, 188, 31, 233, 140, 152, 67, 196, 83, 214, 238, 232, 184, 101, 149, 45, 184, 155, 85, 184, 69, 155, 173, 196, 145, 123, 54, 238, 243, 34, 178, 190, 129, 106, 11, 26, 147, 19, 207, 204, 162, 142, 81, 6, 24, 21, 93, 80, 134, 247, 151, 83, 79, 214, 134, 80, 222, 10, 196, 64, 247, 53, 194, 195, 207, 230, 79, 215, 134, 87, 32, 37, 100, 82, 125, 59, 41, 235, 36, 144, 171, 64, 247, 195, 12, 115, 194, 124, 243, 109, 84, 44, 155]
but i need convert this bytes to string. i can not find answer. please advise me.
Thanks a lot !
Edit:
I found this:
var bytes: [UInt8] = [157, 29, 111, 190, 188, 31, 233, 140, 152, 67, 196, 83, 214, 238, 232, 184, 101, 149, 45, 184, 155, 85, 184, 69, 155, 173, 196, 145, 123, 54, 238, 243, 34, 178, 190, 129, 106, 11, 26, 147, 19, 207, 204, 162, 142, 81, 6, 24, 21, 93, 80, 134, 247, 151, 83, 79, 214, 134, 80, 222, 10, 196, 64, 247, 53, 194, 195, 207, 230, 79, 215, 134, 87, 32, 37, 100, 82, 125, 59, 41, 235, 36, 144, 171, 64, 247, 195, 12, 115, 194, 124, 243, 109, 84, 44, 155]
print(bytes2String(bytes))
func bytes2String(array:[UInt8]) -> String {
return NSString(data: NSData(bytes: array, length: array.count), encoding: NSUTF8StringEncoding)! as String
}
link: NSData to String in Swift Issues
but it don't work Why is it ?
Error: fatal error: unexpectedly found nil while unwrapping an Optional value
try this
(str=String(bytes: d, encoding: NSUTF8StringEncoding))
if the input data doesn't represent utf8 encoding string NSString constructor failed and return nil. if you unwrap nil value, the result is runtime error.
NSString(data: NSData(bytes: array, length: array.count), encoding: NSUTF8StringEncoding)!
it means exactly, that array bytes: [UInt8] is not representable as uft8 string. if i understand, you play with some crypto framework. are you sure that the framework does correct encryption, decryption? make some test first ...

Flip a Scala BitSet

In Java, you can flip a BitSet:
val javaBitSet = new java.util.BitSet(5)
javaBitSet.set(0)
javaBitSet.set(1)
javaBitSet.set(3)
javaBitSet.flip(0, 5)
javaBitSet: java.util.BitSet = {2, 4}
How do you idiomatically do this with Scala's BitSet?
(And why isn't this a method?)
scala> import collection.immutable.BitSet
import collection.immutable.BitSet
Your deleted example flips bit 2 but leaves bit 5 off:
scala> BitSet(1,2,3) &~ BitSet(2,5)
res3: scala.collection.immutable.BitSet = BitSet(1, 3)
but logical xor is what you want:
scala> BitSet(1,2,3) ^ BitSet(2,5)
res4: scala.collection.immutable.BitSet = BitSet(1, 3, 5)
or idiomatically
scala> implicit class `flipper of bits`(val bs: BitSet) extends AnyVal {
| def flip(lo: Int, hi: Int): BitSet = BitSet(lo until hi: _*) ^ bs
| }
defined class flipper$u0020of$u0020bits
scala> BitSet(2,5) flip (1,4)
res5: scala.collection.immutable.BitSet = BitSet(1, 3, 5)
for an "extension method." It's not efficient to build a BitSet from a range, since it invokes + n times. A bit better is to select a subrange of a bit set created from an array, as below. These hoops suggest it would be nice to have built-in support for ranged operations, as you requested.
Update:
For non-trivial ranges, better not to create BitSet from a Range.
scala> import collection.immutable.BitSet
import collection.immutable.BitSet
scala> val bs = BitSet(1, 69, 188)
bs: scala.collection.immutable.BitSet = BitSet(1, 69, 188)
scala> val lower = 32
lower: Int = 32
scala> val upper = 190
upper: Int = 190
scala> val n = (bs.last max upper) / 64 + 1
n: Int = 3
scala> val arr = Array.tabulate(n)(_ => -1L)
arr: Array[Long] = Array(-1, -1, -1)
scala> val mask = BitSet.fromBitMaskNoCopy(arr).range(lower, upper)
mask: scala.collection.immutable.BitSet = BitSet(32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189)
scala> val res = bs ^ mask
res: scala.collection.immutable.BitSet = BitSet(1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 189)
scala> res(69)
res0: Boolean = false