Perl: getting count for range of values - perl

I want to perform a count for a range of values, i.e, I have 900 values of X between 1 to 75x10^6. I need to count the number of times these X's fall in range like 1-1000000, 1000001-2000000, 2000001-3000000 ... 750 ranges, then return the counts of these ranges.
I have the values of X stored in an array so I could have done it with for loop and if..else, but giving 750 if-else's is no solution and I don't know how to implement value range in hash-keys. Please help
Thank you in advance :)

For each value, you can subtract 1, divide by 1000000, and cut off any decimals. That gives you the index of the range as a number between 0 and 749 (inclusive).
Example:
use strict;
use warnings;
my #values = (...); # filled from somewhere
my #range_count;
for my $value (#values) {
my $x = int(($value - 1) / 1e6);
$range_count[$x]++;
}
Now $range_count[0] contains the number of values in the first range, $range_count[1] the number of values in the second range, etc.
However, if there were no values in some range, the count will be undef, not 0. If this difference is important, define #range_count as
my #range_count = (0) x 750;
instead.

Related

Libreoffice calc - how to write a same value into a range

I know how to 'select' a range in LO (7.2.4.1) Calc BASIC ....
ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
But how to write a value, e.g. "1", into that range using BASIC?
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
myRange.Value = 1
Gives an "property or method not found" error. But I can't find any properties or values to go after Range to allow me to do what I want. Flailing around and trying
myRange.setValue = 1
myRange.writeValue = 1
myRange.setString = "1"
and numerous other variants don't work either.
Would really appreciate the solution. Thanks.
You can edit the value of an individual cell, but not the entire range. You will have to iterate over all the cells in the range one at a time, changing the value of each of them.
Sub Set1ToD1H6
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
For i = 0 To myRange.getRows().getCount()-1
For j = 0 To myRange.getColumns().getCount()-1
myRange.getCellByPosition(j, i).setValue(1)
Next j
Next i
End Sub
But since the read-write operation to a cell is comparable in time to the read-write operation to a whole range, it is preferable to use another method - to prepare data in an array and write from it to a range in one operation:
Sub Set1ToRange
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
dataOfRange = myRange.getData()
For i = LBound(dataOfRange) To UBound(dataOfRange)
For j = LBound(dataOfRange(i)) To UBound(dataOfRange(i))
dataOfRange(i)(j) = 1
Next j
Next i
myRange.setData(dataOfRange)
End Sub
(For your example, this will be approximately 30 times faster, for a larger range the time winnings will be even more significant)
The .getData() and .setData() methods work on numeric range values. To work with text strings (and numbers), use .getDataArray() and .setDataArray(), for working with cell formulas use .getFormulaArray() and .setFormulaArray()

How to round off ten random numbers in array?

Trying to generate ten numbers which are random and without decimal point.
my #randoms = map { rand } (1..10)
This code returns ten random numbers yet with decimal like
0.218220758325518.
I want round off these numbers.
Need a help. Thanks.
rand can take a parameter that specifies the supremum of the generated numbers. Just call int to truncate it:
my #randoms = map int rand 20, 1 .. 10;
It generates numbers in the range 0 .. 19.

How do I display a large number in scientific notation?

Using AutoIt, when I multiply 1 by 10^21, I get 1e+021. But in separate steps, such as multiplying 1 by 10^3 seven times, I get the overflow value of 3875820019684212736.
It appears AutoIt cannot handle numbers with more than eighteen digits. Is there a way around this? For example, can I multiply 10,000,000,000,000,000 by 1000 and have the result displayed as 1e+019?
Try this UDF : BigNum UDF
Example :
$X = "9999999999999999999999999999999"
$Y = "9999999999999999999999999999999"
$product = _BigNum_Mul($X, $Y)

Splitting up number by certain amount

I'm trying to split up numbers by a given value (4000) and have the numbers placed in an array
Example:
max value given is: 8202
So the split_array should be split by 4000 unless it gets to the end and it's less than 4000
in which case it just goes to the end.
start_pos, end_pos
0,4000
4001,8001
8002,8202
so the first row in the array would be
[0 4000]
second row would be
[4001 8001]
third row would be
[8002 8202]
please note that the max value can change from (8202) to be any other number like (16034) but never a decimal
How can I go about doing this using matlab / octave
This should produce what you want
n = 8202;
a = [0:4001:n; [4000:4001:n-1 n]]'
returns
a =
0 4000
4001 8001
8002 8202

How do I factor integers using Perl?

I want split integers into their factors. For example, if the total number of records is:
169 - ( 13 x 13 times)
146 - ( 73 x 2 times)
150 - ( 50 x 3 times)
175 - ( 25 x 7 times)
168 - ( 84 x 2 )
160 - ( 80 x 2 times)
When it's more than 10k - I want everything on 1000
When it's more than 100k - I want everything on 10k
In this way I want to factor the number. How to achieve this? Is there any Perl module available for these kinds of number operations?
Suppose total number of records is 10k. It should be split by 1000x10 times only; not by 100 or 10s.
I can use sqrt function. But it's not always what I am expecting. If I give the input 146, I have to get (73, 2).
You can use the same algorithms you find for other languages in Perl. There isn't any Perl special magic in the ideas. It's just the implementation, and for something like this problem, it's probably going to look very similar to the implementation in any language.
What problem are you trying to solve? Maybe we can point you at the right algorithm if we know what you are trying to do:
Why must numbers over 10,000 use the 1,000 factor? Most numbers won't have a 1,000 factor.
Do you want all the factors, or just the largest and its companion?
What do you mean that the sqrt function doesn't work as you expect? If you're following the common algorithm, you just need to iterate up to the floor of the square root to test for factors. Most integers don't have an integral square root.
If the number is not a prime you can use a factoring algorithm.
There is an example of such a function here: http://www.classhelper.org/articles/perl-by-example-factoring-numbers/factoring-numbers-with-perl.shtml
Loop through some common numbers in an acceptable range (say, 9 to 15), compute the remainder modulo your test number, and choose the lowest.
sub compute_width {
my ($total_records) = #_;
my %remainders;
for(my $width = 9; $width <= 15; $width += 1) {
my $remainder = $total_records % $width;
$remainders{$width} = $remainder;
}
my #widths = sort {
$remainders{$a} <=> $remainders{$b} ||
$a <=> $b
} keys %remainders;
return $widths[0];
}