for example:
Input: Testing 123 for my letter count program.
Output: t = 5 e = 3 g = 2 n = 2 c = 1 i = 1 p = 1 u = 1 r = 4 o = 3 m
= 2 a = 1 f = 1 l = 1 s = 1 y = 1
I try to code this question, but didn't worked. This is my code:
#!/usr/bin/perl
use utf8;
use warnings;
$line = <STDIN>;
$len = length($line);
$count = 0;
while($count < $len){
print "$line[$count]\n";
$count += 1;
}
So help me to code this question. Because i don't understand how to code this question
use strict;
use warnings;
my $input = 'Testing 123 for my letter count program.';
my %seen;
my #order = grep { !$seen{$_}++ } lc($input) =~ /([a-z])/ig;
print "$_ = $seen{$_}\n" for #order;
output
t = 5
e = 3
s = 1
i = 1
n = 2
g = 2
f = 1
o = 3
r = 4
m = 2
y = 1
l = 1
c = 1
u = 1
p = 1
a = 1
#!/usr/bin/perl
use strict; use warnings;
my $input = 'Testing 123 for my letter count program.';
my %hash = ();
map { $hash{lc($_)}++ } grep /[a-zA-Z]/, split('', $input);
print "Output: ";
print "$_ = $hash{$_} " for(keys %hash);
OUTPUT:
Output: e = 3 y = 1 a = 1 r = 4 s = 1 g = 2 c = 1 n = 2 l = 1 t = 5 i = 1 p = 1 f = 1 m = 2 u = 1 o = 3
I'm trying to figure out why this keeps printing the "majority element" candidate in every cycle.
The code I've been trying to make work is a Majority Element search (to find an element that is repeated more than half of the length of a list).
I can't separate the processes of finding the candidate and testing against the array because my input is a text file that has an indeterminate number of arrays. It's an exercise from rosalind.info that has different inputs every time you try to solve it.
An example of the input would be
-5 5 5 5 5 5 5 5 -8 7 7 7 1 7 3 7 -7 1 6 5 10 100 1000 1 -5 1 6 7 1 1 10 1
Here's what I've written so far.
foreach my $currentrow (#lists) {
my #row = ();
#row = split( /\s/, $currentrow );
my $length = $#row;
my $count = 0;
my $i = 0;
for $i ( 0 .. $length - 1 ) {
if ( $count == 0 ) {
$candidate = $row[$i];
$count++;
}
if ( ( $count > 0 ) and ( $i = $length - 1 ) ) {
my $counter2 = 0;
for my $j ( 0 .. $length - 1 ) {
if ( $row[$j] == $candidate ) {
$counter2++;
}
}
if ( $counter2 <= ( $#row / 2 ) and ( $i = $length - 1 ) ) {
$candidate = -1;
print $candidate, " ", $i, " ";
}
if ( $counter2 > ( $#row / 2 ) and ( $i = $length - 1 ) ) {
print $candidate, " ", $i, " ";
}
}
if ( $candidate == $row[$i] and $count > 0 ) {
$count = $count + 1;
}
if ( $candidate != $row[$i] and $count > 0 ) {
$count = $count - 1;
}
}
}
Do you have use strict and use warnings 'all' in place?
I imagine that your problem may be because of the test $i = $length - 1, which is an assignment, and should be $i == $length - 1
To find a majority element I would use a hash:
perl -nae '%h=(); $h{$_}+=2 for #F; $h{$_}>#F and print for keys %h; print "\n"'
Each line of input is treated separately. Each line of output matches a line of input and presents its majority element or is empty if there is no such element.
Edit: Now the solution uses autosplit (-a), which is shorter and work not only for numbers.
I need to proccess a waveform from a text file.
I need to remove an element only when Y2-Y1 < 30
Currently I run
s/[0-9.]{3,} [0-9.]{3,} m\n[0-9.]{3,} [0-9.]{3,} l\nS/0 0 m\n0 0 l\nS/g
but this removes more than I need. Is this even possible in perl?
The format is
X1 Y1 m
X2 Y2 l
S
Sample Data:
1560 5940 m
1560 5374 l
S
1548 5964 m
1572 5964 l
S
1572 5964 m
1572 5940 l
S
Desired output:
1560 5940 m
1560 5374 l
S
0 0 m
0 0 l
S
0 0 m
0 0 l
S
This expects to be called with your input filename as an argument:
use strict;
use warnings;
my #queue;
while (<>) {
next unless /\S/;
push(#queue, $_);
if (/^S/) {
my ($x1, $y1) = split(/\s+/, shift(#queue));
my ($x2, $y2) = split(/\s+/, shift(#queue));
if ($y2 - $y1 < 30) {
$x1 = $y1 = $x2 = $y2 = 0;
}
print "$x1 $y1 m\n$x2 $y2 l\nS\n\n";
#queue = ();
}
}
If it is looking like a record what about reading it like a records:
#!/usr/bin/env perl
use strict;
use warnings;
local $/ = "S\n\n";
while (<>) {
my ( $x1, $y1, $x2, $y2 ) = m/(\d+)\s+(\d+)\s+m\n(\d+)\s+(\d+)\s+l/;
next unless defined $x1;
$_ = "0 0 m\n0 0 l\nS\n\n" if $y1 - $y2 < 30;
}
continue {
print;
}
BTW, your example output doesn't correspond with your Y2-Y1 < 30 condition.
This sounds like a job for if() {} instead of regex.
Apologies if the following needs editing - my Perl is rusty.
My snippet assumes two input arrays #y1 and #y2, both of the same known length $array_length.
my $i = 0;
my $y1 = 0;
my $y2 = 0;
for ( i = 0; i < $array_length; i++ )
{
$y1 = $y1[i];
$y2 = $y2[i];
if ( $y2 - $y1 < 30 )
{
#your output code here
}
else
{
#output 0s here
}
}
There's ways to simplify that to have only one output block.
I have a script that downloads data from a database.
But I am having trouble formatting the data into rows.
#!/perl/bin/perl
use FOOConf;
FOOConf::makeDBConnection(production);
$dbh=$EVTConf::dbh;
use Data::Dumper ;
my %extend_hash = %{#_[0]};
my $query = "select level_id,e_risk_symbol,e_exch_dest,penny,specialist from etds_extend";
if(!$dbh) {
print "Error connecting to DataBase; $DBI::errstr\n";
}
my $cur_msg = $dbh->prepare($query) or die "\n\nCould not prepare statement: ".$dbh->errstr;
$cur_msg->execute();
my (#row);
while (#row = $cur_msg->fetchrow_array ) {
#foreach $row(#row) {
#print "$row \n" ;
printf "%-8s %-4s %-2s %-2s %-2s\n ", $row[0], $row[1], $row[2], $row[3], $row[4], $row[5];
#printf "%-12s %6.2f\n", $row[0], $row[3];
#for (my $i = 0; $i < scalar(#row); $i++) {
# printf "%-12s = %s\n", $cur_msg->{NAME}[$i], $row[$i];
# }
#}
}
i am using this to format the rows. The format is all mesed up
printf "%-8s %-4s %-2s %-2s %-2s\n ", $row[0], $row[1], $row[2], $row[3],
this is what the format is :
5 MRO CS 1 0
5 FFIV CS 1 0
5 GM CS 1 0
5 MCP CS 1 0
5 RVBD CS 1 0
6 OIS_SPIN XISX 0 1
6 CVEO XISX 0 1
6 MRVL AMXO 0 1
6 MRX AMXO 0 1
6 MS XISX 0 1
6 MTG XISX 0 1
if I just use this loop
while (#row = $cur_msg->fetchrow_array ) {
foreach $row(#row) {
print "$row \n" ;
}
}
each row gets printed out one line at a time - the thread starts with a 5 - which seems to screw up the formatting. How do i factor this out first 5 ?
[ walt]$ ./test_db_data_format.very_simple | head -20
5
MRO
CS
1
0
5
FFIV
CS
1
0
5
GM
CS
1
0
5
MCP
CS
1
0
when i use I this loop this format - which is really nice.
That level id comes in at beginning without being attached to a symbol - screwing me up.
while (#row = $cur_msg->fetchrow_array ) {
for (my $i = 0; $i < scalar(#row); $i++) {
printf "%-12s = %s\n", $cur_msg->{NAME}[$i], $row[$i];
}
}
This is the results with the rows from the data base:
LEVEL_ID = 5
E_RISK_SYMBOL = MRO
E_EXCH_DEST = CS
PENNY = 1
SPECIALIST = 0
LEVEL_ID = 5
E_RISK_SYMBOL = FFIV
E_EXCH_DEST = CS
PENNY = 1
SPECIALIST = 0
LEVEL_ID = 5
E_RISK_SYMBOL = GM
E_EXCH_DEST = CS
PENNY = 1
SPECIALIST = 0
LEVEL_ID = 5
What I need is the E_RISK_SYMBOL to start and a newline after LEVEL_ID to start a new row.
It should look just like this just like this:
MRO CS 1 0 5
FFIV CS 1 0 5
GM CS 1 0 5
MCP CS 1 0 5
RVBD CS 1 0 6
OIS_SPIN XISX 0 1 6
It looks like your primary problem was just a trailing space in your format string after the \n and the fact that you were printing the $row[0] first instead of last.
You can also simplify your code by including the my declaration in the while (COND) and also using an array slice instead of listing out a bunch of individual array elements.
while (my #row = $cur_msg->fetchrow_array ) {
printf "%-8s %-4s %-2s %-2s %-2s\n", #row[1..4,0];
}
Note: You were also passing 6 values to a format string with only 5 spots in your first code. If you actually want the 6th variable to be displayed, you'll have to specify its format as well.
while (#row = $cur_msg->fetchrow_array ) {
printf "%-8s %-4s %-2s %-2s %-2s\n", $row[1], $row[2], $row[3], $row[4], $row[0];
}
Personally, I'd probably fetch it as a hashref to aide in making it more readable/understandable/maintainable.
while (my $row = $cur_msg->fetchrow_hashref ) {
printf "%-8s %-4s %-2s %-2s %-2s\n", $row->{e_risk_symbol},
$row->{e_exch_dest},
$row->{penny},
$row->{specialist},
$row->{level_id};
}
I have the following sparse matrix A.
2 3 0 0 0
3 0 4 0 6
0 -1 -3 2 0
0 0 1 0 0
0 4 2 0 1
Then I would like to capture the following information from there:
cumulative count of entries, as matrix is scanned columnwise.
Yielding:
Ap = [ 0, 2, 5, 9, 10, 12 ];
row indices of entries, as matrix is scanned columnwise.
Yielding:
Ai = [0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 ];
Non-zero matrix entries, as matrix is scanned columnwise.
Yielding:
Ax = [2, 3, 3, -1, 4, 4, -3, 1, 2, 2, 6, 1];
Since the actual matrix A is potentially very2 large, is there any efficient way
in Perl that can capture those elements? Especially without slurping all matrix A
into RAM.
I am stuck with the following code. Which doesn't give what I want.
use strict;
use warnings;
my (#Ax, #Ai, #Ap) = ();
while (<>) {
chomp;
my #elements = split /\s+/;
my $i = 0;
my $new_line = 1;
while (defined(my $element = shift #elements)) {
$i++;
if ($element) {
push #Ax, 0 + $element;
if ($new_line) {
push #Ai, scalar #Ax;
$new_line = 0;
}
push #Ap, $i;
}
}
}
push #Ai, 1 + #Ax;
print('#Ax = [', join(" ", #Ax), "]\n");
print('#Ai = [', join(" ", #Ai), "]\n");
print('#Ap = [', join(" ", #Ap), "]\n");
A common strategy for storing sparse data is to drop the values you don't care about (the zeroes) and to store the row and column indexes with each value that you do care about, thus preserving their positional information:
[VALUE, ROW, COLUMN]
In your case, you can economize further since all of your needs can be met by processing the data column-by-column, which means we don't have to repeat COLUMN for every value.
use strict;
use warnings;
use Data::Dumper;
my ($r, $c, #dataC, #Ap, #Ai, #Ax, $cumul);
# Read data row by row, storing non-zero values by column.
# $dataC[COLUMN] = [
# [VALUE, ROW],
# [VALUE, ROW],
# etc.
# ]
$r = -1;
while (<DATA>) {
chomp;
$r ++;
$c = -1;
for my $v ( split '\s+', $_ ){
$c ++;
push #{$dataC[$c]}, [$v, $r] if $v;
}
}
# Iterate through the data column by column
# to compute the three result arrays.
$cumul = 0;
#Ap = ($cumul);
$c = -1;
for my $column (#dataC){
$c ++;
$cumul += #$column;
push #Ap, $cumul;
for my $value (#$column){
push #Ax, $value->[0];
push #Ai, $value->[1];
}
}
__DATA__
2 3 0 0 0
3 0 4 0 6
0 -1 -3 2 0
0 0 1 0 0
0 4 2 0 1
This is what you are looking for, I guess:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper::Simple;
my #matrix;
# Populate #matrix
while (<>) {
push #matrix, [ split /\s+/ ];
}
my $columns = #{ $matrix[0] };
my $rows = #matrix;
my ( #Ap, #Ai, #Ax );
my $ap = 0;
for ( my $j = 0 ; $j <= $rows ; $j++ ) {
for ( my $i = 0 ; $i <= $columns ; $i++ ) {
if ( $matrix[$i]->[$j] ) {
$ap++;
push #Ai, $i;
push #Ax, $matrix[$i]->[$j];
}
}
push #Ap, $ap;
}
print Dumper #Ap;
print Dumper #Ai;
print Dumper #Ax;
Updated based on FM's comment. If you do not want to store any of the original data:
#!/usr/bin/perl
use strict;
use warnings;
my %matrix_info;
while ( <DATA> ) {
chomp;
last unless /[0-9]/;
my #v = map {0 + $_ } split;
for (my $i = 0; $i < #v; ++$i) {
if ( $v[$i] ) {
push #{ $matrix_info{$i}->{indices} }, $. - 1;
push #{ $matrix_info{$i}->{nonzero} }, $v[$i];
}
}
}
my #cum_count = (0);
my #row_indices;
my #nonzero;
for my $i ( sort {$a <=> $b } keys %matrix_info ) {
my $mi = $matrix_info{$i};
push #nonzero, #{ $mi->{nonzero} };
my #i = #{ $mi->{indices} };
push #cum_count, $cum_count[-1] + #i;
push #row_indices, #i;
}
print(
"\#Ap = [#cum_count]\n",
"\#Ai = [#row_indices]\n",
"\#Ax = [#nonzero]\n",
);
__DATA__
2 3 0 0 0
3 0 4 0 6
0 -1 -3 2 0
0 0 1 0 0
0 4 2 0 1
Output:
C:\Temp> m
#Ap = [0 2 5 9 10 12]
#Ai = [0 1 0 2 4 1 2 3 4 2 1 4]
#Ax = [2 3 3 -1 4 4 -3 1 2 2 6 1]
Ap is easy: simply start with zeroes and increment each time you meet a nonzero number. I don't see you trying to write anything into #Ap, so it's no surprise it doesn't end up as you wish.
Ai and Ax are trickier: you want a columnwise ordering while you're scanning rowwise. You won't be able to do anything in-place since you don't know yet how many elements the columns will yield, so you can't know in advance the elements' position.
Obviously, it would be a hell lot easier if you could just alter the requirement to have a rowwise ordering instead. Failing that, you could get complex and collect (i, j, x) triplets. While collecting, they'd naturally be ordered by (i, j). Post-collection, you'd just want to sort them by (j, i).
The code you provided works on a row-by-row basis. To get results sequential by columns you have to accumulate your values into separate arrays, one for each column:
# will look like ([], [], [] ...), one [] for each column.
my #columns;
while (<MATRIX>) {
my #row = split qr'\s+';
for (my $col = 0; $col < #row; $col++) {
# push each non-zero value into its column
push #{$columns[$col]}, $row[$col] if $row[$col] > 0;
}
}
# now you only need to flatten it to get the desired kind of output:
use List::Flatten;
#non_zero = flat #columns;
See also List::Flatten.