Is long long in C++ known to be very nasty in terms of precision? - c++

The Given Problem:
Given a theater with n rows, m seats, and a list of seats that are reserved. Given these values, determine how many ways two friends can sit together in the same row.
So, if the theater was a size of 2x3 and the very first seat in the first row was reserved, there would be 3 different seatings that these two guys can take.
The Problem That I'm Dealing With
The function itself is supposed to return the number of seatings that there are based on these constraints. The return value is a long long.
I've gone through my code many many times...and I'm pretty sure that it's right. All I'm doing is incrementing this one value. However, ALL of the values that my function return differ from the actual solution by 1 or 2.
Any ideas? And if you think that it's just something wrong with my code, please tell me. I don't mind being called an idiot just as long as I learn something.

Unless you're overflowing or underflowing, it definitely sounds like something is wrong with your code. For integral types, there are no precision ambiguities in c or c++

First, C++ doesn't have a long long type. Second, in C99, long long can represent any integral value from LLONG_MIN (<= -2^63) to LLONG_MAX (>= 2^63 - 1) exactly. The problem lies elsewhere.

Given the description of the problem, I think it is unambiguous.
Normally, the issue is that you don't know if the order in which the combinations are taken is important or not, but the example clearly disambiguate: if the order was important we would have 6 solutions, not 3.
What is the value that your code gives for this toy example ?
Anyway I can add a few examples with my own values if you wish, so that you can compare against them, I can't do much more for you unless you post your code. Obviously, the rows are independent so I'm only going to show the result row by row.
X occupied seat
. free seat
1: X..X
1: .X..
2: X...X
3: X...X..
5: ..X.....
From a computation point of view, I should note it's (at least) an O(N) process where N is the number of seats: you have to inspect nearly each seat once, except the first (and last) ones in case the second (and next to last) are occupied; and that's effectively possible to solve this linearly.
From a technic point of view:
make sure you initialize your variable to 0
make sure you don't count too many seats on toy example
I'd be happy to help more but I would not like to give you the full solution before you have a chance to think it over and review your algorithm calmly.

Related

C++/ Help me understand the logic

I was told to solve this problem:
given a1, ..., an are real numbers. Need to calculate min(a1, -a1a2, a1a2a3, ...,(-1)^(n+1) a1a2,... an)
but I cannot understand the logic of the task. Could you tell me what I should do?
For example, what is (-l)^n+1? I've never seen it before.
What you should do is:
use the n real numbers of input to ...
... calculate the n numbers defined by the quoted formula (though you only need one value at a time to be more efficient)
while doing so keep track of the smallest number you encounter, that is the final result
concerning the (-1)^(n+1), it is reasonable to assume (as e.g. in the comment by Weather Vane and others) that it means powers of -1 (in a lazy and unexplained but non-C++ syntax)
note that you can easily calculate one value from the previous one by simple multiplication
probably you should do all of that by writing a program, an assumption based on the fact that you are asking on StackOverflow and tag a programming language

Permutations of English Alphabet of a given length

So I have this code. Not sure if it works because the runtime for the program is still continuing.
void permute(std::vector<std::string>& wordsVector, std::string prefix, int length, std::string alphabet) {
if (length == 0) {
//end the recursion
wordsVector.push_back(prefix);
}
else {
for (int i = 0; i < alphabet.length(); ++i) {
permute(wordsVector, prefix + alphabet.at(i), length - 1, alphabet);
}
}}
where I'm trying to get all combinations of characters in the English alphabet of a given length. I'm not sure if the approach is correct at the moment.
Alphabet consists of A-Z in a string of length 26. WordsVectors holds all the different combinations of words. prefix is meant to pass through recursively until a word is made and length is self explanatory.
Example, if I give the length of 7 to the function, I expect a size of 26 x 25 x 24 x 23 x 22 x 21 x 20 = 3315312000 if I'm correct, following the formula for permutations.
I don't think programs are meant to run this long so either I'm hitting an infinite loop or something is wrong with my approach. Please advise. Thanks.
Surely the stack would overflow but concentrating on your question even if you write an iterative program it will take a long time ( not an infinite loop just very long )
[26L, 650L, 15600L, 358800L, 7893600L, 165765600L, 3315312000L, 62990928000L, 1133836704000L, 19275223968000L, 308403583488000L, 4626053752320000L, 64764752532480000L, 841941782922240000L, 10103301395066880000L, 111136315345735680000L, 1111363153457356800000L, 10002268381116211200000L, 80018147048929689600000L, 560127029342507827200000L, 3360762176055046963200000L, 16803810880275234816000000L, 67215243521100939264000000L, 201645730563302817792000000L, 403291461126605635584000000L, 403291461126605635584000000L]
The above list is the number of possibilities for 1<=n<=26. You can see as n increases number of possibilities increases tremendously. Say you have 1GHz processor that does 10^9 operations per second. Say consider number of possibilities for n=26 its 403291461126605635584000000L. Its evident that if you sit down to list all possibilities its so so long ( so so many years ) that
you will feel it has hit an infinite loop. Finally I have not looked that closely into your code , but in nutshell even if you write it correctly,iteratively and don't store (again can't have this much memory) and just print all possibilities its going to take long time for larger values of n.
EDIT
As jaromax and others said if you just want to write it for smaller values of n,
say less than 10-12 you can write an iterative program to list/print them. It will run quite fast for small values. But if you also want to store them them then n will have to be say less than 5 say. (Really depends on how much RAM is available or you could find some permutations write them to disk, then depends on how much disk memory you can spare, again refer the number of possibilities list I posted above. It gives a rough idea of both time and space complexity).
I think there could be quite a problem that you do this on stack. A large part of the calculation you do recursively and this means every time allocated space for function.
Try to reformulate it linearly. I think I had such a problem before.
Your question implies you think there are 26x25x24x ... permutations
Your code doesn't have anything I can see to avoid "AAAAAAA" being a permutation, in which case there are 26x26x26x ...
So in addition to being a very complicated way of counting in base 26, I think it's also giving bad answers?

generating a list in arrays and use of functions

I am wondering how to make an array with values that start at 1111 and go all the way up to 8888. I am asking this because I need to generate a list of 4 digit numbers with each digit ranging from 1-8. I would like to have this in a loop form. Also, I am lost on my functions trim, methodicalEliminate, guessAndEliminate, and guessThreeThenEliminate in my following program. Here are the directions:
This assignment focuses on the use of arrays in a program, including using one as a parameter to a function.
PROBLEM DESCRIPTION
In the game of Mastermind, a player is only given a finite number of guesses to try to identify the hidden combination (such as twelve guesses). Often that is the only constraint in playing the game.
But some players might make a competition with each other to see who can guess the other's combination in fewer tries. In this case, the problem is not only to come up with a strategy that can find the answer within a specified limit, but to find one that is likely to require the minimal number of guesses.
Here is where the computer comes in -- one can write a program that would try out different guessing strategies, and see how they work out. Since a computer can do the analysis and computations more rapidly than a person, it could just pretend to play Mastermind on our behalf using any strategy we choose, and tell us how long it took to do that.
OVERALL SOLUTION
Of course, it would be extremely difficult to teach the computer to reason along the same lines as a person. For example, if we guessed a combination 1111 and got one black peg, we would make a mental note that the answer has exactly one 1 in it, and then proceed to make other guesses with that one fact in mind. If we next guesses 1222 and got one white peg, we would know there were no 2's, and that the single 1 is not in the first position. But how to keep track of such information after a series of guesses would be rather hard.
Fortunately, for a computer simulation with an array, we can record all of our known facts in a different way. We just maintain a list of all possible answers that there could be, and then remove numbers from the list that could no longer be the solution. If our first guess tells us there is exactly one 1 digit, we would remove all the numbers that do not have that feature. When we find out there are no 2's, we eliminate all the values that contain 2's. Eventually, the only number left would be the correct answer.
SOME SIMPLE STRATEGIES
This is a strategy that many players use, resembling what was described above. Just methodically got through the possibilities in a straightforward fashion. The first guess of 1111 would answer how many 1's are in the solution; the next guess would answer how many 2's are in the solution, and also say something about where any 1's might be, and so on.
With our list approach, which contain a whole lot of possibilities in order beginning with 1111, 1112, 1113, 1114, etc., our next guess would always be the first in the list.
The next strategy is for those who like a little more excitement. The guesses appear to be more or less random, with the hopes that a lot more information can be discovered. Simulating this approach is surprisingly simple -- if you have a list of numbers, just pick one at random. If you have 837 possibilities to choose from in an array, just pick a random subscript in the range of 0 to 836.
This third strategy considers the possibility that answers that give similar results to a given guess are in a sense similar to each other. So to try to get a little more information, it will still pick some numbers at random without regard to how they were evaluated, and then only start thinking about the results.
To implement this one, let us just pick any three possible answers and guess them, temporarily ignoring how many black pegs and white pegs they earn us. Only after making those guesses will we trim the list of possibilities, then proceeding as the second strategy above.
SAMPLE INTERFACE
These are the sample results from the current implementation: Please enter a combination to try for, or 0 for a random value: 0
Guessing at 2475
Guessing 1111...
Guessing 2222...
Guessing 2333...
Guessing 2444...
Guessing 2455...
Guessing 2456...
Guessing 2475...
Methodical Eliminate required 7 tries.
Guessing 6452...
Guessing 2416...
Guessing 2485...
Guessing 2445...
Guessing 2435...
Guessing 2425...
Guessing 2475...
Guess and Eliminate required 7 tries.
Guessing 7872...
Guessing 6472...
Guessing 1784...
Guessing 2475...
Guess Three then Eliminate required 4 tries.
Play another game? (y/n) y
Please enter a combination to try for, or 0 for a random value: 0
Guessing at 4474
Guessing 1111...
Guessing 2222...
Guessing 3333...
Guessing 4444...
Guessing 4445...
Guessing 4464...
Guessing 4474...
Methodical Eliminate required 7 tries.
Guessing 3585...
Guessing 7162...
Guessing 4474...
Guess and Eliminate required 3 tries.
Guessing 8587...
Guessing 1342...
Guessing 1555...
Guessing 7464...
Guessing 6764...
Guessing 4468...
Guessing 4474...
Guess Three then Eliminate required 7 tries.
NOTE: This program allows each digit to go up to 8 instead of 6. Even though there are 4096 possible answers, it still finds them rather rapidly.
PROGRAM SPECIFICATIONS
The assigned program must implement all of the following functions. Additional ones are permitted as desired -- these below are required. Future assignments will not detail the functions as below -- but will instead require the students to design their own function descriptions in advance to writing the program. main:
Simply governs the overall behavior of the program. A number will be
chosen as the target combination, and then each strategy will attempt
to find it.
Calls: generateAnswer, (to compare all three must have the same answer)
methodicalEliminate, guessAndEliminate, guessThreeThenEliminate
generateAnswer:
Either lets the user at the keyboard choose the mystery combination,
or gives the option to have the computer generate a random combination.
(For a competitive game, it might be interesting to know what sorts
of combinations would be the hardest to guess!)
Parameters: none!
Returns: a 4-digit combination, each digit in the range 1 to 8
generateSearchSpace:
Populates an array with all possible combinations of four-digit
values in the range 1 to 8.
Parameters:
guesses (modified int array) list of guesses
length (output int) number of values in list
Pre-condition:
The array must be allocated to no fewer than 4096 elements.
trim:
Analyzes the response to a particular guess and then eliminates
any values from the list of possibilities that are no longer
possible answers. In each case, it assumes that a value in the
list is an answer, and evaluates the guess accordingly. If the
number of black and white pegs is not the same as those specified,
then it cannot be the correct answer.
Parameters:
guesses (modified int array) list of guesses
length (modified int) number of values in list
guess (input int) a guess that has been evaluated
black (input int) how many black pegs that guess earned
white (input int) how many white pegs that guess earned
Pre-condition:
black and white actually do contain the results of comparing
the guess with the actual answer
Post-condition:
length has been reduced (we learned something)
the viable answers occupy the first 'length' positions
in the guesses array (so the list is shorter)
Calls: evaluate
methodicalEliminate:
beginning with a list of all possible candidate answers
continually guesses the first element in the list, and
trim answers accordingly, until an answer is found
Parameter:
answer (input int) the actual answer
(necessary to get black/white pegs)
Returns: number of guesses required to find the answer
Calls: generateSearchSpace, evaluate, trim
gusssAndEliminate:
beginning with a list of all possible candidate answers
continually guesses a random element in the list, and
trim answers accordingly, until an answer is found
Parameter:
answer (input int) the actual answer
Returns: number of guesses required to find the answer
Calls: generateSearchSpace, evaluate, trim
gusssThreeThenEliminate:
beginning with a list of all possible candidate answers
first guesses three answers at random before trimming
the list of possibilites, and then narrows on the answer
one random guess at a time
Parameter:
answer (input int) the actual answer
Returns: number of guesses required to find the answer
Calls: generateSearchSpace, evaluate, trim
NOTE: These last functions use the correct answer to evaluate
each guess and then use the black/white pegs for the guessing
strategy. NOne of these strategies may peek at the answer to
decide what to do next!
ALSO: The following functions should also appear in this program
from the previous assignment, though they are not themselves
part of the grade for this one.
evaluate:
evaluates a combination by comparing it with the answer
Correctness is indicated by black pegs (correct digit in correct position)
and white pegs (correct digit in incorrect position)
Parameters:
answer (input int) the correct combination
guess (input int) the current guess
black (output int) number of black pegs
white (output int) number of white pegs
pre-conditions:
answer and guess are both 4-digit numbers with no zero digits
post-conditions:
black and white are both > 0 and their sum is <= 4
Calls: nthDigit, clearNthDigit
nthDigit:
identified the n'th digit of a combination
whether digits count from left to right or right to left is unspecified
Parameters:
combination (input int) combination to examine
position (input int) which digit to examine
(returned) (output int) the value of the actual digit
pre-conditions:
combination has the appropriate number of digits, and
0 < position <= number of digits
post-condition:
0 <= returned digit <= 9 (single digit)
clearNthDigit:
ears the n'th digit of a combination to zero, so it will no longer match
digits must be counted in the same manner as nthDigit above.
parameters:
combination (in/out int) combination to modify
position (input int) which digit to set to 0
pre-condition:
same as those for nthDigit above
post-condition:
corresponding digit is set to zero
Calls: nthDigit (optional, depending on the implementation)
Thank you for reading such this long question, and I hope you can help me on arrays!
Just because your guesses have the form of 1111 through to 8888, it does not mean they are numbers.
They are numbers if it makes sense to do arithmetic calculations on them. It does not make sense to define arithmetic calculations on the guesses: what would it mean to add a guess 4571 to a guess 6214?
If your guesses are not numbers, don't use a representation that is reserved for numbers. You can, however, use an array of four integers:
int guesses[4][4096];
int g = 0;
for (int i = 1; i <= 8; ++i)
for (int j = 1; j <= 8; ++j)
for (int k = 1; k <= 8; ++k)
for (int m = 1; m <= 8; ++m)
guesses[g++] = {i, j, k, m};
I am pretty convinced that putting all possible guesses into the array guesses like that is not a good idea either; the code mainly demonstrates how the guesses could be generated.
Go through the other functions, think of what high level operations should be performed on the remaining gueses (like "eliminate all guesses that has a certain number in the thrid position" etc). This should give you an idea about what would be a better data structure to replace the guesses array.

Magic Numbers In Arrays? - C++

I'm a fairly new programmer, and I apologize if this information is easily available out there, I just haven't been able to find it yet.
Here's my question:
Is is considered magic numbers when you use a literal number to access a specific element of an array?
For example:
arrayOfNumbers[6] // Is six a magic number in this case?
I ask this question because one of my professors is adamant that all literal numbers in a program are magic numbers. It would be nice for me just to access an element of an array using a real number, instead of using a named constant for each element.
Thanks!
That really depends on the context. If you have code like this:
arr[0] = "Long";
arr[1] = "sentence";
arr[2] = "as";
arr[3] = "array.";
...then 0..3 are not considered magic numbers. However, if you have:
int doStuff()
{
return my_global_array[6];
}
...then 6 is definitively a magic number.
It's pretty magic.
I mean, why are you accessing the 6th element? What's are the semantics that should be applied to that number? As it stands all we know is "the 6th (zero-based) number". If we knew the declaration of arrayOfNumbers we would further know its type (e.g. an int or a double).
But if you said:
arrayOfNumbers[kDistanceToSaturn];
...now it has much more meaning to someone reading the code.
In general one iterates over an array, performing some operation on each element, because one doesn't know how long the array is and you can't just access it in a hardcoded manner.
However, sometimes array elements have specific meanings, for example, in graphics programming. Sometimes an array is always the same size because the data demands it (e.g. certain transform matrices). In these cases it may or may not be okay to access the specific element by number: domain experts will know what you're doing, but generalists probably won't. Giving the magic index number a name makes it more obvious to those who have to maintain your code, and helps you to prevent typing the wrong one accidentally.
In my example above I assumed your array holds distances from the sun to a planet. The sun would be the zeroth element, thus arrayOfNumbers[kDistanceToSun] = 0. Then as you increment, each element contains the distance to the next farthest planet: mercury, venus, etc. This is much more readable than just typing the number of the planet you want. In this case the array is of a fixed size because there are a fixed number of planets (well, except the whole Pluto debacle).
The other problem is that "arrayOfNumbers" tells us nothing about the contents of the array. We already know its an array of numbers because we saw the declaration somewhere where you said int arrayOfNumers[12345]; or however you declared it. Instead, something like:
int distanceToPlanetsFromSol[kNumberOfPlanets];
...gives us a much better idea of what the data actually is and what its semantics are. One of your goals as a programmer should be to write code that is self-documenting in this manner.
And then we can argue elsewhere if kNumberOfPlanets should be 8 or 9. :)
You should ask yourself why are you accessing that particular position. In this case, I assume that if you are doing arrayOfNumbers[6] the sixth position has some special meaning. If you think what's that meaning, you probably realize that it's a magic number hiding that.
another way to look at it:
What if after some chance the program needs to access 7th element instead of 6th? HOw would you or a maintainer know that? If for example if the 6th entry is the count of trees in CA it would be a good thing to put
#define CA_STATE_ENTRY 6
Then if now the table is reordered somebody can see that they need to change this to 9 (say). BTW I am not saying this is the best way to maintain an array for tree counts by state - it probably isnt.
Likewise, if later people want to change the program to deal with trees in oregon, then they know to replace
trees[CA_STATE_ENTRY]
with
trees[OR_STATE_ENTRY]
The point is
trees[6]
is not self-documenting
Of course for c++ it should be an enum not a #define
You'd have to provide more context for a meaningful answer. Not all literal numbers are magic, but many are. In a case like that there is no way at all to tell for sure, though most cases I can think of off-hand with an explicit array index >>1 probably qualify as magic.
Not all literals in a program really qualify as "magic numbers" -- but this one certainly seems to. The 6 gives us no clue of why you're accessing that particular element of the array.
To not be a magic number, you need its meaning to be quite clear even on first examination (or at least minimal examination) why that value is being used. Just for example, a lot of code will do things like: &x[0]. In this case, it's typically pretty clear that the '0' really just means "the beginning of the array."
If you need to access a particular element of the array, chances are you're doing it wrong.
You should almost always be iterating over the entire array.
It's only not a magic number if your program is doing something very special involving the number six specifically. Could you provide some context?
That's the problem with professors, they're often too academic. In theory he's right, as usual, but usually magic numbers are used in a stricter context, when the number is embedded in a data stream, allowing you to detect certain properties of the stream (like the signature header of a file type for instance).
See also this Wikipedia entry.
Usually not all constant values in software are called magic numbers.
A java class files always starts with the hex value 0xcafebabe a windows .exe
file with MZ 0x4d, 0x5a , this allows you quickly (but not for sure) to identify
the content of a binary file.
In a MISRA compliant system, all values except 0 and 1 are considered magic numbers. My opinion has always been if the constant value is obvious or likely won't change then leave it as a number. If in doubt create a unique constant since long term maintenance will be easier.

How does this C++ function use memoization?

#include <vector>
std::vector<long int> as;
long int a(size_t n){
if(n==1) return 1;
if(n==2) return -2;
if(as.size()<n+1)
as.resize(n+1);
if(as[n]<=0)
{
as[n]=-4*a(n-1)-4*a(n-2);
}
return mod(as[n], 65535);
}
The above code sample using memoization to calculate a recursive formula based on some input n. I know that this uses memoization, because I have written a purely recursive function that uses the same formula, but this one much, much faster for much larger values of n. I've never used vectors before, but I've done some research and I understand the concept of them. I understand that memoization is supposed to store each calculated value, so that instead of performing the same calculations over again, it can simply retrieve ones that have already been calculated.
My question is: how is this memoization, and how does it work? I can't seem to see in the code at which point it checks to see if a value for n already exists. Also, I don't understand the purpose of the if(as[n]<=0). This formula can yield positive and negative values, so I'm not sure what this check is looking for.
Thank you, I think I'm close to understanding how this works, it's actually a bit more simple than I was thinking it was.
I do not think the values in the sequence can ever be 0, so this should work for me, as I think n has to start at 1.
However, if zero was a viable number in my sequence, what is another way I could solve it? For example, what if five could never appear? Would I just need to fill my vector with fives?
Edit: Wow, I got a lot of other responses while checking code and typing this one. Thanks for the help everyone, I think I understand it now.
if (as[n] <= 0) is the check. If valid values can be negative like you say, then you need a different sentinel to check against. Can valid values ever be zero? If not, then just make the test if (as[n] == 0). This makes your code easier to write, because by default vectors of ints are filled with zeroes.
The code appears to be incorrectly checking is (as[n] <= 0), and recalculates the negative values of the function(which appear to be approximately every other value). This makes the work scale linearly with n instead of 2^n with the recursive solution, so it runs a lot faster.
Still, a better check would be to test if (as[n] == 0), which appears to run 3x faster on my system. Even if the function can return 0, a 0 value just means it will take slightly longer to compute (although if 0 is a frequent return value, you might want to consider a separate vector that flags whether the value has been computed or not instead of using a single vector to store the function's value and whether it has been computed)
If the formula can yield both positive and negative values then this function has a serious bug. The check if(as[n]<=0) is supposed to be checking if it had already cached this value of computation. But if the formula can be negative this function recalculates this cached value alot...
What it really probably wanted was a vector<pair<bool, unsigned> >, where the bool says if the value has been calculated or not.
The code, as posted, only memoizes about 40% of the time (precisely when the remembered value is positive). As Chris Jester-Young pointed out, a correct implementation would instead check if(as[n]==0). Alternatively, one can change the memoization code itself to read as[n]=mod(-4*a(n-1)-4*a(n-2),65535);
(Even the ==0 check would spend effort when the memoized value was 0. Luckily, in your case, this never happens!)
There's a bug in this code. It will continue to recalculate the values of as[n] for as[n] <= 0. It will memoize the values of a that turn out to be positive. It works a lot faster than code without the memoization because there are enough positive values of as[] so that the recursion is terminated quickly. You could improve this by using a value of greater than 65535 as a sentinal. The new values of the vector are initialized to zero when the vector expands.