Determine the current output to the speaker C++ Beginner - c++

Recently, I've began learning C++ in college and was asked to make a looping sequence of "*" with the sequence going like this:
*
***
*****
*******
*********
*********
*******
*****
***
*
[continues indefinitely until it goes x lines, where x is specified at the start]
How I did it if you need a visualisation:
#include<iostream>
#include<windows.h>
using namespace std;
int main() {
int hFar=0; //Variable that will be used to find out how many parts into the sequence the user would like to travel.
unsigned long int fibSequenceA = 0; //Unsigned doesn't overflow as easilly. This is the first value of the fibunacci sequence, it's defined as 0 to start.
unsigned long int fibSequenceB = 1; // Second Value of fibbunacci sequence. Defined at 1 to start.
int sPart = 1;//Used for the * sequence, it is the part of the sequence that the loop is on. It changes dynamically by either +2 or -2 every loop.
int cValue = 0;// also for the * sequence, it is the current number of * typed.
int sDirection = 0; // used to change from subtracting 2, and adding 2.
int redo = 1; // used to ensure that every 9 and every 1 the sequence repeats that number a second time. Starts at one because the sequence starts with only 1 single * rather then 2 *.
cout << "How far into the second sequence would you like to travel?" << endl; //Requests how far into the * sequence you'd like to go.
cin >> hFar; //inputs answer into variable.
for(int i = 0; i < hFar; i++ ) {//begins for statement. Notice there's no hfar/2. There will only be 1 output per line now.
while(cValue < sPart) { //Basic while loop to input the ammount of * on the current line. Works by adding a * depending on what part of the sequence it is.
cout << "*"; //self explainitory.
cValue++; //raises the cValue in order to keep track of the current number of *. Also prevents infinite loop.
}
if(sPart == 9 && redo == 0) { //Checks if the sequence part is 9, meaning that the value begins to reduce to 1 again. But first, it must repeat 9 to keep with the sequence.
sDirection = 3; //sets the direction to 3 to make sure that the value of sPart stays at 9, instead of reducing by 2.
redo = 1; //resets the redo.
cValue = 8; //changes the value of the current number of 8. Not sure if this is important, It gets done again later to make sure anyway.
sPart = 9; //Changes the sPart to 9, the needed number of *. Also redone later, but to make sure, I kept this here.
}
else if(sPart == 9 && redo == 1) { // if the sequence has already redone the 9th *
sDirection = 1; //sets the direction to 1; The sequence will reverse.
redo = 0; //returns redo to 0 to ensure that next time it reaches 1, it repeats the 1 * again.
}
else if(sPart == 1 && redo == 0) { //when the value reaches one for the second time, it needs to repeat that value.
sDirection = 3; //sets the direction to 3 again to stop the change.
redo = 1; //resets the redo.
cValue = 0;//also might be redundant.
}
else if(sPart == 1 && redo == 1) { // stops the duplicate number of *
sDirection = 0; //sets the direction to +2 again.
redo = 0;//resets the redo.
}
Sleep(50);
cout << endl; //adds a new line. This ensures that we get a new line after every part rather then 900 * on one line.
if(sDirection == 0) { //if the direction is positive.
sPart += 2; //adds 2 to the spart to keep with the sequence.
cValue = 0; //resets the cValue to 0 so the while statement works again.
}
else if(sDirection == 1) { //if the direction is negative
sPart -=2; //subtracts 2 from the spart to keep with the sequence.
cValue = 0; //resets the cValue to keep the while statement working.
}
else if(sDirection = 3) { //if the change is
//Could have been done differently. Could have just set the values to themselves, but it wasn't working. not sure why.
if(sPart == 9){ //if the spart is currently 9.
sPart = 9; //keeps it at 9.
cValue = 0; //resets the cValue.
}
else if(sPart == 1){ //if the spart is currently 1
sPart = 1; //keeps it at one.
cValue = 0; //resets the cValue.
}
}
}
return 1;//ends the code.
}
[Sorry about all the comments, I'm trying to make sure I understand what I'm doing, like I said, I'm learning :)]
While fooling around with the loops, I ended up putting the Sleep() function in, so that it produced a wave effect when generating the sequence. This got me thinking, and I wanted to know if it would be possible to make the command prompt act like a makeshift volume visualizer. (The more "*" the higher the volume at that point in time).
So, when playing a song on my computer, the program would find the total output to the speaker, and put a number of "*" that correlate to that volume, and would continue this until the program ends, producing (hopefully) an interesting effect. (if you're confused, play a song on your computer, right click on the speaker icon on the task bar, and click open volume mixer, and look at the volume levels change, this is the type of effect that I'm looking for)
Would this be possible? I've been googling the issue, (found things like This and I've found a number of ways to find out the current MASTER volume, and change that, But I'm looking for more of the actual volume that one hears, not the maximum volume that my speakers can output.
Here's somewhat of what I'm looking to do.
int sPart = x; //x = the current output of the speaker
int cValue = 0 //the current number of "*" output
while([somecondition I'm not sure when i want the sequence to stop yet]) {
while(cValue < sPart) {
cout << "*";
cValue++;
}
cout << endl; //ends the current line, making room for the next value of the volume.
Sleep(50); //waits 50ms before finding the next volume value.
sPart = [current speaker value]; //finds the value of the speaker again.
cValue = 0; //resetting the number of "*" back to zero.
}
//I just reused the variables from my original code.
Would this be possible? If so, would a beginner be capable of this? Again, If so, how would it be done?

Related

Can someone explain me this code which generates all the possible permuations of a given set?

I found a recursion code in the
competitive programmer's handbook to do the same but I'm struggling to understand the logic behind it.
It states that:
Like subsets, permutations can be generated using recursion. The following
function search goes through the permutations of the set {0,1,...,n¡1}. The
function builds a vector permutation that contains the permutation, and the
search begins when the function is called without parameters.
void search() {
if (permutation.size() == n) {
// process permutation
} else {
for (int i = 0; i < n; i++) {
if (chosen[i]) continue;
chosen[i] = true;
permutation.push_back(i);
search();
chosen[i] = false;
permutation.pop_back();
}
}
}
Each function call adds a new element to permutation. The array chosen
indicates which elements are already included in the permutation. If the size of
permutation equals the size of the set, a permutation has been generated.
I can't seem to understand the proper intuition and the concept used.
Can somemone explain me what the code is doing and what's the logic behind it?
I will try to give you some intuition . The main idea is to backtrack . You basically build a solution until you face a dead end. When you do face a dead end , go back to the last position where you can do something different than what you did the last time . Let me walk through this simulation I have drawn for n = 3 .
First you have nothing . Take 1 , then 2 and then 3 . You have nowhere to go now i.e Dead End . You print your current permutation which is 123 What do you do now ? go back to 1 because you know you can make another path by taking 3 this time . So what do you get this time the same way ? 132 . Can you do anything more using 1 ? Nope . Now go back to having nothing and start the same thing over , now taking 2 . You get the point now , right ?
For the same thing which is happening where in the code :
void search() {
if (permutation.size() == n) /// DEAD END
{
// process permutation
}
else {
for (int i = 0; i < n; i++) {
if (chosen[i]) continue; /// you have already taken this in your current path , so ignore it now
chosen[i] = true; /// take it , as you haven't already
permutation.push_back(i);
search(); // go to the next step after taking this item
chosen[i] = false; // you have done all you could do with this , now get rid of it
permutation.pop_back();
}
}
}
You can split up the code like this:
void search() {
if (permutation.size() == n) {
// we have a valid permutation here
// process permutation
} else {
// The permutation is 'under construction'.
// The first k elements are fixed,
// n - k are still missing.
// So we must choose the next number:
for (int i = 0; i < n; i++) {
// some of them are already chosen earlier
if (chosen[i]) continue;
// if i is still free:
// signal to nested calls that i is occupied
chosen[i] = true;
// add it to the permutation
permutation.push_back(i);
// At the start of this nested call,
// the permutation will have the first (k + 1)
// numbers fixed.
search();
// Now we UNDO what we did before the recursive call
// and the permutation state becomes the same as when
// we entered this call.
// This allows us to proceed to the next iteration
// of the for loop.
chosen[i] = false;
permutation.pop_back();
}
}
}
The intuition could be that search() is "complete the current partially constructed permutation in every way possible and process all of them".
If it is already complete, we only need to process the one possible permutation.
If not, we can first choose the first number in every way possible, and, for each of those, complete the permutation recursively.

Deciphering RayW Poker Hand Evaluator

I am attempting to decipher this code: https://github.com/tangentforks/TwoPlusTwoHandEvaluator/blob/master/generate_table.cpp
The code is used to generate a massive lookup table that is then used to look up hand ranks of 7 card hands. I am having difficulty deciphering exactly why the main method is written the way it is. From what I can make of it, the first for loop bruteforces every single combination of cards, substituting the appropriate suit abstractions when necessary, but I am not sure why that is repeated in the next section, or why it is scaled by a factor of 53 and then added 53 to. Could anyone shed any light on this?
This is the code in question::
printf("\nGetting Card IDs!\n");
// Jmd: Okay, this loop is going to fill up the IDs[] array which has
// 612,967 slots. as this loops through and find new combinations it
// adds them to the end. I need this list to be stable when I set the
// handranks (next set) (I do the insertion sort on new IDs these)
// so I had to get the IDs first and then set the handranks
for (IDnum = 0; IDs[IDnum] || IDnum == 0; IDnum++) {
// start at 1 so I have a zero catching entry (just in case)
for (card = 1; card < 53; card++) {
// the ids above contain cards upto the current card. Now add a new card
ID = MakeID(IDs[IDnum], card); // get the new ID for it
// and save it in the list if I am not on the 7th card
if (numcards < 7) holdid = SaveID(ID);
}
printf("\rID - %d", IDnum); // show progress -- this counts up to 612976
}
// main()
printf("\nSetting HandRanks!\n");
// this is as above, but will not add anything to the ID list, so it is stable
for (IDnum = 0; IDs[IDnum] || IDnum == 0; IDnum++) {
// start at 1 so I have a zero catching entry (just in case)
for (card = 1; card < 53; card++) {
ID = MakeID(IDs[IDnum], card);
if (numcards < 7) {
// when in the index mode (< 7 cards) get the id to save
IDslot = SaveID(ID) * 53 + 53;
} else {
// if I am at the 7th card, get the equivalence class ("hand rank") to save
IDslot = DoEval(ID);
}
maxHR = IDnum * 53 + card + 53; // find where to put it
HR[maxHR] = IDslot; // and save the pointer to the next card or the handrank
}
if (numcards == 6 || numcards == 7) {
// an extra, If you want to know what the handrank when there is 5 or 6 cards
// you can just do HR[u3] or HR[u4] from below code for Handrank of the 5 or
// 6 card hand
// this puts the above handrank into the array
HR[IDnum * 53 + 53] = DoEval(IDs[IDnum]);
}
printf("\rID - %d", IDnum); // show the progress -- counts to 612976 again
}
Doing the same currently. It is shifted by 53 because there are 52 cards. Once you point to an invalid state, you transition to 0. From there, any card that you pick must still result in an invalid state, so the first 53 entries 0 + 52 ranks point to 0. The first meaningful entry comes at 53..(53+53).
Try to understand the concept first. The table is a huge directed graph, where each node has 52 childnodes and one „evaluate-current-handrank-node“ at index 0. poker-ai.org and the original thread provide lots of useful information. Also look at CactusKevs idea to obtain handrank-order on cards by using prime numbers. Genius. It all goes into this.

How to input a multi-digit integer into an Arduino using a 4x4 keypad?

I am trying to make a combination lock using an Arduino, a keypad and a Servo but I have come across an obstacle.
I can't find a way to store a 4 digit value in a variable. since keypad.getKey only allows to store one digit.
After some browsing on the internet I came upon a solution for my problem on a forum but the answer didn't include a code sample, and I couldn't find anything else about in on the internet.
The answer said to either use a time limit for the user to input the number or a terminating character (which would be the better option according to them).
I would like to know more bout these terminating characters and how to implement them, or if anybody could suggest a better solution that would be much appreciated as well.
Thank you in advance,
To store 4 digit values, the easiest and naive way to do it is probably to use an array of size 4. Assuming keypad.getKey returns an int, you could do something like this: int input[4] = {0};.
You will need a cursor variable to know into which slot of the array you need to write when the next key is pressed so you can do some kind of loop like this:
int input[4] = {0};
for (unsigned cursor = 0; cursor < 4; ++cursor) {
input[cursor] = keypad.getKey();
}
If you want to use a terminating character (lets say your keyboard have 0-9 and A-F keys, we could say the F is the terminating key), the code changes for something like:
bool checkPassword() {
static const int expected[4] = {4,8,6,7}; // our password
int input[4] = {0};
// Get the next 4 key presses
for (unsigned cursor = 0; cursor < 4; ++cursor) {
int key = keypad.getKey();
// if F is pressed too early, then it fails
if (key == 15) {
return false;
}
// store the keypress value in our input array
input[cursor] = key;
}
// If the key pressed here isn't F (terminating key), it fails
if (keypad.getKey() != 15)
return false;
// Check if input equals expected
for (unsigned i = 0; i < 4; ++i) {
// If it doesn't, it fails
if (expected[i] != input[i]) {
return false;
}
}
// If we manage to get here the password is right :)
return true;
}
Now you can use the checkPassword function in your main function like this:
int main() {
while (true) {
if (checkPassword())
//unlock the thing
}
return 0;
}
NB: Using a timer sounds possible too (and can be combined with the terminating character option, they are not exclusive). The way to do this is to set a timer to the duration of your choice and when it ends you reset the cursor variable to 0.
(I never programmed on arduino and don't know about its keypad library but the logic is here, its up to you now)
In comment OP says a single number is wanted. The typical algorithm is that for each digit entered you multiply an accumulator by 10 and add the digit entered. This assumes that the key entry is ASCII, hence subtracting '0' from it to get a digit 0..9 instead of '0'..'9'.
#define MAXVAL 9999
int value = 0; // the number accumulator
int keyval; // the key press
int isnum; // set if a digit was entered
do {
keyval = getkey(); // input the key
isnum = (keyval >= '0' && keyval <= '9'); // is it a digit?
if(isnum) { // if so...
value = value * 10 + keyval - '0'; // accumulate the input number
}
} while(isnum && value <= MAXVAL); // until not a digit
If you have a backspace key, you simply divide the accumulator value by 10.

Finding values above threshold extremely slow

I've got code which needs to find at what points in time a laser has been fired. The laser is indicated by a DC of above 500 on the dataset, and comes in bulks of 3 lasers at a time, in rather quick, but not entirely deterministic, time gaps.
The code I am using right now:
//std::vector<short>& laserData; this one comes from the function call, this is the definition
int count = 0;
for(unsigned int index = 0; index < laserData.size(); ++index) {
if(laserData.at(index) > 500) {
times.push_back(index);
count = (count + 1)%3;
if(count == 0) {
int dif1 = times.at(times.size()-1) - times.at(times.size()-2);
int dif2 = times.at(times.size()-1) - times.at(times.size()-3);
if(dif1 > 60000 || dif2 > 60000) {
times.erase(times.begin() + times.size() - 2);
times.erase(times.begin() + times.size() - 2);
count = 1;
}
}
switch(count) {
case 0: index += 90000;
default: index += 2000;
}
}
}
I can't be entirely sure that all 3 laser impulses always happen, and if they don't, the complete set of those 1 or 2 laser impulses needs to be removed.
The dataset is 130,000,000 samples long, and I get about 3300 laser impulses in total, so that works fine, its just darned slow. It takes about 45 seconds to parse that vector, and I wonder if there is a faster way to do that.
First: Unless you intended the switch statement to fall-through, add in a break:
switch(count)
{
case 0:
index += 90000;
break;
default:
index += 2000;
}
Ok. now we have a potential error out of the way, we can look at speeding up your code.
The first thing to do is to eliminate as much of the vector resizing as possible.
you said there were about 3300 laser pulses in total. Lets add ~10% margin of error to that and resize the vector of pulses in advance:
times.reserve(3600);
Now the vector should not need to be resized multiple times. If there are more, we should only have the vector realovating once.
Next, we want to get rid of the times.erase() function calls.
To do this, we cache the three most recent values separately, and only push them into the vector once they have been validified:
const int pulse_interval = 2000;
const int burst_interval = 90000;
int cache[3];
times.reserve(3600);
for(unsigned int index = 0; index < laserData.size(); ++index)
{
if(laserData[index] > 500)
{
//this next if block acts as our guard clause
if (count > 0)
{
diff = index - cache[count-1];
if (diff > 60000)
{
count = 1;
cache[0]=index;
index+= pulse_interval;
continue;
// if gap between pulses is too big reset and start again, setting most recent value to first of next sequence.
}
}
//now we actually store data in the cache and if needed add to the vector. No invalid data (not part of a three burst set) should reach here due to guard
cache[count]=index;
if (count == 2)
{
for (int i=0; i<3; i++)
{times.push_back(cache[i]);}
count = 0;
index += burst_interval;
}
else
{
count++;
index += pulse_interval;
}
//updating count at the end is easier to follow
//goes to 0 after 3rd pulse detected
}
}
This removes vector access with invalid data and should speed up the code as much as a quick answer here can do.
edit: added in your index skipping parameters. If I got the logic wrong, let me know. In this case, the switch isnt needed as the logic could be encapsulated in the existing logic from the algorithm.
If you can't turn optimisation on, then you can try unrolling the push_back loop. Cache array can be reduced to two cells, and storing of the index can be moved to the else (for the third value just push_back(index);
This removes the loop overhead and one assignment for each time you find a full burst. Your compiler would handle this normally.
If still slow. then you need to profile. Make sure that your index skips are of the right size (too small means you search too much, but too large and you risk loosing valid data)
You could also do this in parallel as a commenter suggested. You could do this splitting the search space into a number of sections and spawning a thread for each section.

check if a random move has already been made, and to ignore previous move in the randomisation process?

Im positioning sprites in a sliding puzzle game, but I have trouble to randomise the tile position
How can I check if a random move (arc4random) has already been made, and to ignore previous move in the randomisation process?
the tiles do randomise/reshuffle, but sometimes the repeat the random move made
eg tile 23 slides to tile 24 position and back several times, counting as a random move
(which means the board doesn't shuffle properly)
int count = 0;
int moveArray[5];
int GameTile;
int EmptySq;
//loop through the board and find the empty square
for (GameTile = 0; GameTile <25; ++GameTile) {
if (boardOcc[GameTile]== kEMPTY) {
EmptySq = GameTile;
break;
}
}
int RowEmpty = RowNumber[GameTile];
int colEmpty = ColHeight[GameTile];
if (RowEmpty <4) moveArray[count++] = (GameTile +5);//works out the current possible move
if (RowEmpty >0) moveArray[count++] = (GameTile -5);//to avoid unsolvable puzzles
if (colEmpty <4) moveArray[count++] = (GameTile +1);
if (colEmpty >0) moveArray[count++] = (GameTile -1);
int RandomIndex = arc4random()%count;
int RandomFrom = moveArray[RandomIndex];
boardOcc[EmptySq] = boardOcc[RandomFrom];
boardOcc[RandomFrom] = kEMPTY;
There are few - if not many possibilities.
One possibility would be to create a stack-like buffer array, which would contain, let's say 10 steps. (Stack - goes in from one end, goes out from other end)
For example:
NSMutableArray *_buffer = [NSMutableArray new];
So - game starts, buffer array is empty. You generate first random move, and also insert it into the buffer array:
[_buffer insertObject:[NSNumber numberWithInt:RandomIndex] atIndex:0];
Then run a check if our array contains more that 10 elements and remove last one if so:
if([_buffer count] > 10)
{
[_buffer removeObjectAtIndex:10];
}
We need to remove only one item, as we only add one object each time.
And then we add the checking, so that next 'RandomIndex' would be something else than previous 10 indexes. We set 'RandomIndex' to some neutral value (-1) and then launch a while loop (to set 'RandomIndex' to some random value, and second time check if '_buffer' contains such value. If it contains, it will regenerate 'RandomIndex' and check again.. it could do so indefinitely, but if the 'count' is a much bigger number, then it will take 2-3 while loops, tops. No worries.
int RandomIndex = -1;
while(RandomIndex == -1 || [_buffer containsObject:[NSNumber numberWithInt:RandomIndex]])
{
RandomIndex = arc4random()%count;
}
But You could add some safety, to allow it to break out of the loop if after, say, 5 cycles: (But then it will keep the repeating value..)
int RandomIndex = -1;
int safetyCounter = 0;
while(RandomIndex == -1 || [_buffer containsObject:[NSNumber numberWithInt:RandomIndex]])
{
RandomIndex = arc4random()%count;
if(safetyCounter == 5)
{
break;
}
safetyCounter++;
}
You could also decrease the buffer size to - 3 or five, then it will work perfectly in 99.9999999% cases or even 100%. Just to disable that case, when randomly it picks the same number each second time as You described. Anyways - no worries.
But still. Let's discuss another - a bit more advanced and safer way.
Other possibility would be to create two separate buffers. One - as in previous example - would be used to store last 10 values, and second would have all the other possible unique moves.
So:
NSMutableArray *_buffer = [NSMutableArray new];
NSMutableArray *_allValues = [NSMutableArray new];
At the beginning '_buffer' is empty, but for '_allValues', we add all possible moves:
for(int i = 0; i < count; i++)
{
[_allValues addObject:[NSNumber numberWithInt:i]];
}
and again - when we calculate a random value - we add it to the '_buffer' AND remove from '_allValues'
[_buffer insertObject:[NSNumber numberWithInt:RandomIndex] atIndex:0];
[_allValues removeObject:[NSNumber numberWithInt:RandomIndex]];
after that - we again check if _buffer is not larger than 10. If Yes, we remove last object, and add back to _allValues:
if([_buffer count] > 10)
{
[_allValues addObject:[_buffer objectAtIndex:10]];
[_buffer removeObjectAtIndex:10];
}
And most importantly - we calculate 'RandomIndex from the count of _allValues and take corresponding object's intValue:
RandomIndex = [[_allValues objectAtIndex:(arc4random()%[_allValues count])] intValue];
Thus - we don't need any safety checking, because in this way, each time calculated value will be unique for the last 10 moves.
Hope it helps.. happy coding!