Printing number of items in a range from an array in Kotlin - arrays

Currently working on a little school assignment, trying to figure out if there is a specific way to print items out of a randomized array. Teacher wants us to generate 200 random numbers in a range of 1 through 100, store them, and then print them with the amount of each range(10s, 20s, 30s, etc). I've gotten the randomization and storage down, but I'm having a little issue trying to figure out how to properly display these.
We should have them separated by how many random numbers are 1-10, 11-20, etc etc, but also with a histograph to the side. I think I can figure out the histograph well enough, but I could use some help on how to display the numbers for each range! I hope this makes sense, any help is appreciated!
What I have so far is very simple, just having a rough time figuring out what goes in the println()
fun main() {
val rnds = (1..200).map { (1..100).random() }
println() // <-- ???
}
it should look something like:
1 - 10: # // <-- number of randomized numbers in that range here
11 - 20: # // <-- number of randomized numbers in that range here
21 - 30: # // <-- number of randomized numbers in that range here
etc etc, all the way until 91 - 100
I should also mention that I'm VERY new to kotlin, and still pretty green to programming in general. The easier the solution, the better, at least until I have a better understanding at what I'm seeing.

You can create your range buckets by using the map function on a range of each starting number of a bucket, and then associateWith to sort the original lists into these buckets:
val byRanges: Map<IntRange, List<Int>> = (1..100 step 10)
.map { it..(it + 9) }
.associateWith { range -> rnds.filter { it in range } }
Then when you want to convert this to text, you can use the joinToString() function on the map entries to format each item as text:
val asText: String = byRanges.entries.joinToString("\n") { (range, list) ->
"${range.start} - ${range.endInclusive}: # ${list.size}"
}

You can increase the "for" loop by range value and filter the list with desired condition to get the item count.
fun main() {
val randomRangeStart = 1
val randomRangeEnd = 100
val list = (1..200).map { (randomRangeStart..randomRangeEnd).random() }
for (i in randomRangeStart..randomRangeEnd step 10) {
println("Range $i - ${i+9}: ${list.filter { it >= i && it <= i+9 }.count()}")
}
}

Related

Using C functions to select array values of index positions [3], [4] and [5]

I haven’t posted to a forum like this before, so I’ve tried to explain as clearly as possible, in as much detail as possible, to try to help anyone understand the problem I’m stuck on. I should add I’ve tried to dig for ages for a suitable function to help me in C but without resorting to parsing by looping on iterations of arrays, it seems no function(s) exist in C to get the job done more elegantly?
Anyway, I have a script which, when complete, will allow me to send specific integer value data, via a serial signal, to a dot matrix display.
I’m able to send the raw HEX data from an array/buffer to a dot matrix display using the script as it is. I also have the dot matrix script working well too so it displays the whole array of HEX data well. However, I want to refine the data by not only changing the data types in an array or buffer (named tempBuffer) from HEX to INT (or whatever is appropriate) but to also specifically select three items of data from their respective index positions in that eight item array/buffer (tempBuffer).
The problem looks like this:-
tempBuffer {0x4 0x41 0xC 0xB 0x90 0x0 0x0 0x0} // Raw hex data in array (buffer) - index positions 0 through 7.
I would like to select index positions [2], [3] and [4] in the above tempBuffer array and then place them consecutively into another array pending further processing (i.e. eventually adding item [3] and [4] together to produce one INT value representing a temperature, for example).
For example:
tempBuffer index item [2] would then be placed as Index item [0] in a new array, newArray . tempBuffer Items [3] & [4] would obviously become items [1] & [2] in newArray.
I plan to use newArray index item [0] as a condition check, for example, an if or case statement etc. The outcome of the clause would determine what happens next to the subsequent index items in [1] & [2]. It won’t always be necessary to use item [2] for data checking of a certain condition if item [0] is not met.
I could use a messy C loop/parsing iteration to extract the values I need from tempBuffer and place them in newArray. However, I wondered if there is a more elegant or existing function set existing in C which will allow me to get the job done more efficiently?
My query also applies I guess to possible function solutions in C to add the index values [1] and [2] together in newArray but if anyone can point me to a pre-existing function or an efficient means to iterate the arrays from above I should be grateful for any guidance, advice or pointers to further reading. Else, (excuse the pun) its back to using unwieldy looping and iteration in C statements to achieve the same outcome.
In the unlikely event anyone is following my original posting . . .
Thank you to those who tried to help.
Please excuse my syntax below, I'm 20 years out of practice with any coding. However, I don't care - it works!
I've managed to resolve my query and now have an adapted script (see section relating to my original stackoverflow query) running the way I want it to.
My adapted and integrated script now achieves the following:-
Read and *display (static, scroll, reverse & invert) Ford **ECU PID data (500Kb/11bit) relating to Vehicle Speed and RPM to a 10 x (8x8) LED Matrix display strip.
***Parse NEMA sentences to display on said matrix altitude and time-of-day data.
• I plan to change to Mikal Hart's TinyGPS++ libraries soon and adapt the script further to make it more efficient.
• I also plan to present a YouTube tutorial about my project.
*Thank you to Marco Colli (MajicDesigns) Parola libraries.
****Thank you to Seeed Studio's example script, OBDII_PIDs, as a base starting point.**
*** Thank you to "ludektalian" for further inspiration.
Thank you,
**# Define this_that_and_the_other;
String = "Only fraction of script";
blah - - -
blah - - -
blah . . .
unsigned char newArray[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char serialOutArray[3] = {0,0,0};
if(CAN_MSGAVAIL == CAN.checkReceive()) // check data acquisition
{
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
for(int i = 0; i<len; i++) // print the data
{
newArray [i] = buf[i], HEX;
}
serialOutArray [0] = newArray [2]; // create 3 item array (new array)
serialOutArray [1] = newArray [3]; // from original 8 item array (buf) which
serialOutArray [2] = newArray [4]; // assign 'new array' to
delay(100); //'serialOutArray'
for (int y = 0; y<13; y++)
{
if (int(serialOutArray [0]) == 5) // Coolant in Celsius
{
delay(100);
colSub = int(serialOutArray[1]);
colTot = (colSub-40);
P.print(colTot + "C");
delay(500);
colSub = 0;
colTot = 0;
break;
}
if (int(serialOutArray [0]) == 12) // RPM
{
rpmA = int(serialOutArray [1])*256;
rpmB = int(serialOutArray [2]);
subRPM = (rpmA + rpmB);
rpmTot = subRPM/4;
P.print(rpmTot + "RPM");
break;
}
if (int(serialOutArray [0]) == 13) // MPH
{
mphA = serialOutArray[1];
mphTot = mphA*0.621371192;
P.print(mphTot + "MPH");
break;
}

Trouble with iterative addition in C

I have several huge matrices of data to process, 1000 x 1000 x 400,000. I usually use Matlab, and my Matlab script takes 9 hours to process one data set. So I'm trying to put it into C.
The problem is, when I calculate the standard deviation of my data, C and Matlab don't match. They are not even close.
for(std=0;std<Ndat;std++)
{
for(j=0;j<MAXPAIR;j++)
{
dist=distance(polymer[GoPair[j].a1],polymer[GoPair[j].a2]);
if(dist<=(GoPair[j].dist+PREFACTOR))
{
Stan[j] += ((1-Prob[j])*(1-Prob[j]));;
}
else if(dist>(GoPair[j].dist+PREFACTOR))
{
Stan[j] += ((0-Prob[j])*(0-Prob[j]));
}
}
}
for(j=0;j<MAXPAIR;j++)
{
stnDev[j] = sqrt(Stan[j]/Ndat);
}
The idea is that Stan[j] should have (1-Prob[j])^2 or (0-Prob[j])^2 added to what ever is already in that array position each time the loop runs, but it's not returning the same values that Matlab does for virtually the same script.
Do any of you see basic errors or have any idea why this isn't working for me?

ActionScript 3 sort an array with numbers and letters not working as expected

I'm trying to sort the users cards in a card game, for example all user's aces to stand close to each other.
I'm using this:
p1cards is an array with elements like "c8", "d9", "h1", letters stand from card symbol (Club, Diamond, Hearts) and number is the card value (1 is Ace, 2 is 2, and so on)
p1cards.sort(sortOrder);
function sortOrder(a,b)
{
var aN = parseInt(a.substr(1));
var bN = parseInt(b.substr(1));
if (aN > bN)
{
return 1;
}
else
{
return -1;
}
}
The problem is that sorted card like the 8d, 8c are switching places to 8c, 8d, kind of randomly, when I draw a new card.
Any help will be apreciated.
See in picture below:
http://i.stack.imgur.com/2Ticj.jpg
You don't define in your sort what to do when the values are the same, so depending what item gets slotted in as a and which is b (which you have no control over) will determine the order. Tell your sort function what to do when the items are the same:
function sortOrder(a,b)
{
var aN = parseInt(a.substr(1));
var bN = parseInt(b.substr(1));
if(aN == bN){
//they are the same, so add a secondary sort based off suit
var aS = a.substr(0,1); //grab the first character which is the suit
var bS = b.substr(0,1);
if(aS > bS) return 1;
if(bS > aS) return -1;
return 0;
}
if (aN > bN)
{
return 1;
}
else
{
return -1;
}
}
If you have an undefined behaviour that you are not happy with, simply define the behaviour that you like.
In your case, if both numbers are the same, evaluate the card symbol additionally.
this makes the order of two cards unambigiously clear and the sort operation (for these two cards) idempotent.

Pascal fpc_dynarray_rangecheck on recursion

I have a problem with my code. I originally wrote it in Lazarus, but compiling it on fpc compiler on Windows and Linux still gives me problems. Linux gives "Segmentation fault" and windows external SIGSEV.
My goal is to generate permutations with this program.
It is just for curiosity and learning.
Program source:
program CombinationGeneration;
{$mode objfpc}{$H+}
const
K = 6; // Number of elements chosen
N = 26; // Number of elements to choose from
ALPHABET: Array[1..N] of Char = ('A','B','C','D','E','F','G','H','I','J','K','L','M', // Elements
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'); //
Type
TCombination = Array of Byte; // Combination elemnts array type
PCombination = ^TCombination; // Pointer to combination elements array
{ Rotate
Rotate digits forward in alphabet.
If last item in alphabet is reached, then rotate element before current in combination. }
procedure Rotate( const Combination:PCombination; Element:integer );
begin
{ Check if rotation is completed }
if Combination^[Element] = High(ALPHABET) then
begin
{ If rotation is completed:
* rewind element to first in ALPHABET Low()
* Check if the the element before current exists, then rotate it. }
Combination^[Element] := Low(ALPHABET);
if Element > Low(Combination^) then
Rotate( Combination, Element-1 )
else
Writeln('The end. ');
end else
{ Rotation is not complete and just rotate forward the current element. }
begin
inc(Combination^[Element]);
{:: Write out combination HERE!!! ::}
{ If it is not the last element in combination,
we must rotate the others after it. So go back to High(). }
if Element < High(Combination^) then
Rotate( Combination, High(Combination^) )
else
Rotate( Combination, Element );
end;
end;
var
Comb : TCombination; // Holds the current combination
i : integer; // Iterator for various stuff
begin
{ Set the first combination, length is K }
SetLength(Comb,K);
{ Fill with initial values }
for i:=Low(Comb) to High(Comb) do
begin
Comb[i]:=Low(ALPHABET); // Probably [0,0,0]
end;
{ Calculate permutations }
rotate(#Comb, High(Comb));
readln;
end.
It can do about 694 000 calls of "rotation" function, and then it crashes.
It used to do about 59 000, but i made the Combination array pass by reference and later i
made it pass by pointer.( Last edition made no improvement, or can you tell me any ?)
If I decrease the N and K values until the max permutations value becomes smaller
than this 694 000, then it runs perfect. No errors.
For example let's say we have 14 elemnts in alphabet and k = 5.
The formula is 14^5 = 537 824 . And it is generated flawlessly.
Also full alphabet(26) and 4 chosen works fine - 26^4=456 976
Some output from call stack(Copying text crashes Lazarus):
So.. can you spot any errors... memory leaks, waste.. ?
Laz ver. 1.0.8
Fpc ver. 2.6.2
Thanks!

How can I read a random line from a notecard in LSL?

I have a notecard with a different word on each line, and I'd like to be able to select from the lines randomly. How can I do that?
First, as you mention, you need a notecard. For this example, I'm using one named "colors" with the following contents:
red
blue
green
yellow
orange
purple
With that notecard present, the following script will read and chat a random line from the card each time the prim is touched.
//this script will grab and chat a random line from the "colors" notecard each time the prim is touched.
string card = "colors";
key linecountid;
key lineid;
integer linemax;
integer random_integer( integer min, integer max )
{
return min + (integer)( llFrand( max - min + 1 ) );
}
default
{
state_entry()
{
//get the number of notecard lines
linecountid = llGetNumberOfNotecardLines(card);
}
touch_start(integer total_number)
{
lineid = llGetNotecardLine(card, random_integer(0, linemax));
}
dataserver(key id, string data)
{
if (id == linecountid)
{
linemax = (integer)data - 1;
}
else if (id == lineid)
{
llSay(0, data);
}
}
}
It's not clear why you do such unnecessary math with adding one and then substracting it again later in the answer you give yourself above.
If you want to make sure you have a more random number as there are known issues with the randomness of llFrand you could do (without checking whether the number is even or odd):
integer max;
integer random = llFrand((integer)(max/2)) + llFrand((integer)(max/2));
The second issue with your code above is that you are not checking against CHANGED_INVENTORY and I'm not quite sure why you'd not do that. Following up on this second issue, why do you ask a question to get a random notecard line number and give an answer that provides a random within a range? And what will you do if the notecard changes? Change the code and the notecard? This seems to be redundant to me.
NOTECARD named colors or whatever you set in the script:
blue
red
green
yellow
black
SCRIPT within the same prim:
// this script reads from a notecard which is named whatever you set in init
// in this example from a notecard named "colors"
string ncName;
key ncNumOfLinesReqId;
key ncReqId;
integer numOfLines;
init()
{
// Put the name of your notecard as in the prim's inventory here.
ncName = "colors";
}
default
{
changed(integer change)
{
// reset script to make sure you have the current number of lines
// CHANGED_OWNER has the integer value 0x80 (128)
// CHANGED_INVENTORY has the integer value 0x01 (1)
if (change & (CHANGED_OWNER | CHANGED_INVENTORY))
{
llResetScript();
}
}
state_entry()
{
init();
// get the number of notecard lines
ncNumOfLinesReqId = llGetNumberOfNotecardLines(ncName);
}
touch_start(integer num_detected)
{
// if the number of lines is 0
if (!numOfLines)
{
// PUBLIC_CHANNEL has the integer value 0
llSay(PUBLIC_CHANNEL, "~!~ Unconfigured, check notecard ~!~");
}
else // if number of lines not 0
{
ncReqId = llGetNotecardLine(ncName, (integer)llFrand(numOfLines));
}
}
dataserver(key reqId, string data)
{
if (reqId == ncNumOfLinesReqId)
{
// make sure you typecast!
numOfLines = (integer)data;
}
else if (reqId == ncReqId)
{
// PUBLIC_CHANNEL has the integer value 0
llSay(PUBLIC_CHANNEL, data);
}
}
}
Further information:
The notecard you are reading from does not necessarily have to be in the same prim. If you know the UUID of the notecard, you can read from it as long as it's transferable (and not deleted). Be warned that changing the contents of the notecard and saving, stores the new content under a different UUID. But if you're that skilled, you might as well store the text on a web service and get the text snippet count and text snippets from there.
More on the official Second Life wiki.

Resources