How do I separate residue from long long number? - c

I'm taking the CS50 course on edx.org; it's called Introduction to Computer Science.
I'm trying to solve 1st week problem set. So user inputs credit card number and I have to develop some sort of algorithm to check if it's number is valid. To do so I need to separate whole 16-digit number to digits. And I'm stuck here. I guess I need to do this in loop, at getting at each step digit by digit and to do so I wanted to divide user's input by 10 each step and somehow get the residue.
I can't convert to type int because of int's restrictions on number of digits it can hold. How can I implement this kind of function? I tried this, but then realized it leads to nothing... At first glance at least. cre_num stays for credit number.
long long check(long long cre_num)
{
double part, i;
for (i = 0.1; i <= 1; i = i+0.1)
{
if (cre_num/10 == i)
{
part = i;
}
}
return part;
}

You need to put in a vector, or kind of it, 16 digits of a number (long int)?
When you % a number by 10, you get the last digit of it, like this:
13%10 = 3
3%10 = 3 (03 = 3)
523%10 = 3
So, if you %10 you get the last digit and put in your vector, and than you /10, because /10 will remove the last digit, the one that you have already saved.
If you want, I can try to code it, but I think that you've already that kind of done.

Related

Get unique random number every hour

I was wondering what the best way to get a unique random number every hour in C was. I have integers of hour, month, day of month, and day of week and want to get a random number between 0 and 8 every hour. Initially I tried doing (hour* month* day_month*week_month)%8 but I think it repeats certain numbers often. Would there be a better way of doing this?
One easy way would be to do something like the following:
int hourly_random()
{
srand(time(NULL)/3600);
return rand() % 8;
}
Just simply multiplying non-random integers will not give you something random. Just to illustrate some of the many problems: if one of the values is 0, the result will be 0. If you swap the value of two input variables, the result will still be the same.
This is also the case if you use that result as the seed for a random generator. Because the seed has definite pattern, the resulting random numbers will follow the same pattern.
If you want to use the variables you mentioned, you should combine them such that they don't "interfere" with each other. An obvious way is to multiply the subparts by the maximum value you are adding. That is, something like hours + 24*(months + 12*(...)).
When making your own way to generate random numbers, perhaps you should look at how existing random number generators work. That said, in general you really don't want to make such a thing yourself because of all the pitfalls. It's probably better to rely on the work that as already been done before.
Rather than reseeding the random number generator each time, you can simply keep track of when the last call was done. If it was in the same hour, return the same value, otherwise get a new random value.
int hourly_random()
{
static time_t last = 0;
static int rand_val = 0;
time_t current;
current = time(NULL);
if (!last) {
srand(current+getpid());
}
if ((current/3600) > (last/3600)) {
last = current;
rand_val = rand() % 8;
}
return rand_val;
}

Is there a way to find the 2 whole factors of an int that are closest together?

I'm a beginner still learning to us C and I don't know how to find the factors of an int that are the closest to each other.
For example, if the input was the number 6, the output would be [2,3]. If the input was 24, then the output would be [4,6].
Is there a way to do this? Any help would be appreciated.
The algorithm to do this is simple; take the square root of your number as an integer (you want to truncate, not round). Test if that value is a factor of your input; if so, your input divided by that number are your answer. Otherwise, subtract 1 from your previous value and try again.
In code (the array literal is the wrong syntax, but the theory is correct):
//this code assumes that your input is > 0, will not work otherwise
function int[] getClosestFactors(int input) {
int testNum = (int)sqrt(input);
while (input % testNum != 0) {
testNum--;
}
return {testNum, input / testNum};
}
Basically, you know that in any pair of factors, the lowest factor must be less than or equal to the square root. So if you start at the integer equal to or less than the square root of your input, and count down, the first factor you find will be the smaller of the pair of closest factors. This terminates for all integers > 0 because you will eventually reach 1, which is a factor of all other numbers.

Looping an array then display the Odd and Even values in each arrays

So I have this problem.
Input # of rooms: 4
room1:6
room2:4
room3:7
room4:3
(if I type 5 in "Input # of rooms" there would also be room5)
Odd: 7 3
Even: 6 4
I have to display the odd and even numbers, so I came up with this code:
System.out.print("Input # of rooms: ");
int rms=Integer.parseInt(io.readLine());
int[] array=new int[rms];
int a=0;
int b=1;
do {
System.out.print("room "+b+":");
array[a] = Integer.parseInt(io.readLine());
a++;
b++;
} while (a<rms);
I don't know how to display which are Odd numbers and which are Even numbers?
you want to find the remainder or modulus when the param is divided by 2.
3 % 2 = 1 so odd
4 % 2 = 2 so even
if(param % 2 == 1){
Print odd number
}else{
Print even number
}
Should get you started
The use of the modulo operator (%) will be invaluable here - it performs integer division and returns the remainder of the quotient - kind of like short division.
The rules for determining the type of number are simple:
If the number is even, it is divisible by 2.
Otherwise, it is odd.
As for the printing part: I would recommend accumulating the values in two separate StringBuffers or Strings if you prefer, adding a space between when we get another of the type of value we want. Then, we can print it out pretty after we're done iterating through the array.
One last thing - you should only need one loop - preferably a for loop, since you know exactly how many elements you're going to iterate over. You can use the above rules for modulus to determine which number gets appended to which variable.

Problems with my random number generator

Im learning basic C on my own and trying to create a poker client. I have an array with cards (called kortArray) and a players hand (called kortHand). My implementation does not shuffle the deck, but add all 52 cards in sequence and then randomly selecting 5 cards from the deck. I've added a flag (called draget) which tells if a card has been picked up befor or not.
Now, when I run the algorithm below, it usually generates five random numbers which makes the player's or computer's hand. But sometimes it generates less then five numbers, even though I've specifically stated to generate five accepted values.
I have two loops, one that runs five times, and the other is nested and runs until it finds a card which hasn't yet been picked. The printf in the middle tells me that this algorithm doesn't always generate five accepted numbers, and when that happens the player's hand contains cards with nonsense-values.
srand((unsigned)(time(0)));
for(i = 0; i < 5; i++) {
int x = rand()%52 + 1;
while (kortArray[x].draget!=1) {
x = rand()%52 + 1;
if (kortArray[x].draget != 1) {
printf("%i\n", x);
kortArray[x].draget = 1;
kortHand[i] = kortArray[x];
}
}
}
The problem still lies in the +1 for the random numbers.
Also, you are first checking in the the first assignment to x if the card is already picked, and than you assign it to an other card.
Why not use something like:
int nr_cards_picked = 0 /* Number of uniquely picked cards in hand */
/* Continue picking cards until 5 unique cards are picked. */
while (nr_cards_picked < 5) {
x = rand() % 52; /* Take a random card */
if (kortArray[x].draget == 0) {
/* Pick this card. */
kortArray[x].draget = 1; /* Card is picked */
kortHand[i] = kortArray[x]; /* Add picked card to hand */
nr_cards_picked++;
}
}
Forgive compiler errors; I don't have a compiler near here.
This case you only have one time a random number call.
Theoretically it might never end but this is not likely.
You have:
int x = rand()%52+1;
while (kortArray[x].draget!=1){
x = rand()%52;
Arrays in C are indexed starting at 0. Your first call to rand() will generate a value starting at 1. Assuming that you declared kortArray[] to hold 52 values, there is about a 2% chance that you will overrun the array.
Your first call to rand() generates values in the range 1..52. Your second call generates 0..51. ONE OF THEM IS WRONG.
A few things of note.
First of all, random number generators are not guaranteed to be random if you do a mod operation on them. Far better is to divide it out into the 52 segments, and choose like that.
Secondly, you would be far better off moving your call to generate a random number inside the while loop to the end, or just not generate one at the beginning of the for loop.
Where your problem is coming into play is that you are sometimes leaving the while loop without actually entering it, because you are randomly generating a number before you enter the loop.
Given all of this, I would do code somewhat as follows:
srand((unsigned)(time(0)));
for(i=0;i<5;i++){
x=-1;
while (kortArray[x].draget!=1){
x = floor(rand()*52);
}
printf("%i\n", x);
kortArray[x].draget=1;
kortHand[i]=kortArray[x];
}
The nested loop is only entered when kortArray[x].draget is not 1. So everytime it is 1, nothing is done and no card is assigned. First make sure you have a unique x and then in all cases update kortHand[i]
I'd suggest a different algorithm:
create a random number between 0 and number of cards in deck
assign the card from that position to the appropriate hand
swap the last card to that postion
decrease the number of cards in the deck by 1.
continue with 1 until the necessary number of cards are dealt.
This way, you get rid of the flag and you can guarantee linear performance. No need to check whether a card has already been dealt or not.

Finding an element in an array where every element is repeated odd number of times (but more than single occurrence) and only one appears once

You have an array in which every number is repeated odd number of times (but more than single occurrence). Exactly one number appears once. How do you find the number that appears only once?
e.g.: {1, 6, 3, 1, 1, 6, 6, 9, 3, 3, 3, 3}
The answer is 9.
I was thinking about having a hash table and then just counting the element whose count is 1.
This seems trivial and i am not using the fact that every other element is repeated an odd no of times. Is there a better approach.
I believe you can still use the basic idea of XOR to solve this problem in a clever fashion.
First, let's change the problem so that one number appears once and all other numbers appear three times.
Algorithm:
Here A is the array of length n:
int ones = 0;
int twos = 0;
int not_threes, x;
for (int i=0; i<n; ++i) {
x = A[i];
twos |= ones & x;
ones ^= x;
not_threes = ~(ones & twos);
ones &= not_threes;
twos &= not_threes;
}
And the element that occurs precisely once is stored in ones. This uses O(n) time and O(1) space.
I believe I can extend this idea to the general case of the problem, but possibly one of you can do it faster, so I'll leave this for now and edit it when and if I can generalize the solution.
Explanation:
If the problem were this: "one element appears once, all others an even number of times", then the solution would be to XOR the elements. The reason is that x^x = 0, so all the paired elements would vanish leaving only the lonely element. If we tried the same tactic here, we would be left with the XOR of distinct elements, which is not what we want.
Instead, the algorithm above does the following:
ones is the XOR of all elements that have appeared exactly once so far
twos is the XOR of all elements that have appeared exactly twice so far
Each time we take x to be the next element in the array, there are three cases:
if this is the first time x has appeared, it is XORed into ones
if this is the second time x has appeared, it is taken out of ones (by XORing it again) and XORed into twos
if this is the third time x has appeared, it is taken out of ones and twos.
Therefore, in the end, ones will be the XOR of just one element, the lonely element that is not repeated. There are 5 lines of code that we need to look at to see why this works: the five after x = A[i].
If this is the first time x has appeared, then ones&x=ones so twos remains unchanged. The line ones ^= x; XORs x with ones as claimed. Therefore x is in exactly one of ones and twos, so nothing happens in the last three lines to either ones or twos.
If this is the second time x has appeared, then ones already has x (by the explanation above), so now twos gets it with the line twos |= ones & x;. Also, since ones has x, the line ones ^= x; removes x from ones (because x^x=0). Once again, the last three lines do nothing since exactly one of ones and twos now has x.
If this is the third time x has appeared, then ones does not have x but twos does. So the first line let's twos keep x and the second adds x to ones. Now, since both ones and twos have x, the last three lines remove x from both.
Generalization:
If some numbers appear 5 times, then this algorithm still works. This is because the 4th time x appears, it is in neither ones nor twos. The first two lines then add x to ones and not twos and the last three lines do nothing. The 5th time x appears, it is in ones but not twos. The first line adds it to twos, the second removed it from ones, and the last three lines do nothing.
The problem is that the 6th time x appears, it is taken from ones and twos, so it gets added back to ones on the 7th pass. I'm trying to think of a clever way to prevent this, but so far I'm coming up empty.
For the problem as stated it is most likely that the most efficient answer is the O(n) space answer. On the other hand, if we narrow the problem to be "All numbers appear n times except for one which only appears once" or even "All numbers appear a multiple of n times except for one which only appears once" then there's a fairly straightforward solution for any n (greater than 1, obviously) which takes only O(1) space, which is to break each number into bits and then count how many times each bit is turned on and take that modulo n. If the result is 1, then it should be turned on in the answer. If it is 0, then it should be turned off. (Any other answer shows that the parameters of the problem did not hold). If we examine the situation where n is 2, we can see that using XOR does exactly this (bitwise addition modulo 2). We're just generalizing things to do bitwise addition modulo n for other values of n.
This, by the way, is what the other answer for n=3 does, it's actually just a complex way of doing bit-wise addition where it stores a 2-bit count for each bit. The int called "ones" contains the ones bit of the count and the int called "twos" contains the twos bit of the count. The int not_threes is used to set both bits back to zero when the count reaches 3, thus counting the bits modulo 3 rather than normally (which would be modulo 4 since the bits would wrap around). The easiest way to understand his code is as a 2-bit accumulator with an extra part to make it work modulo 3.
So, for the case of all numbers appearing a multiple of 3 times except the one unique number, we can write the following code for 32 bit integers:
int findUnique(int A[], int size) {
// First we set up a bit vector and initialize it to 0.
int count[32];
for (int j=0;j<32;j++) {
count[j] = 0;
}
// Then we go through each number in the list.
for (int i=0;i<size;i++) {
int x = A[i];
// And for each number we go through its bits one by one.
for (int j=0;j<32;j++) {
// We add the bit to the total.
count[j] += x & 1;
// And then we take it modulo 3.
count[j] %= 3;
x >>= 1;
}
}
// Then we just have to reassemble the answer by putting together any
// bits which didn't appear a multiple of 3 times.
int answer = 0;
for (int j=31;j>=0;j--) {
answer <<= 1;
if (count[j] == 1) {
answer |= 1;
}
}
return answer;
}
This code is slightly longer than the other answer (and superficially looks more complex due to the additional loops, but they're each constant time), but is hopefully easier to understand. Obviously, we could decrease the memory space by packing the bits more densely since we never use more than two of them for any number in count. But I haven't bothered to do that since it has no effect on the asymptotic complexity.
If we wish to change the parameters of the problem so that instead the numbers are repeated 5 times, we just change the 3s to 5s. Or we can do likewise for 7, 11, 137, 727, or any other number (including even numbers). But instead of using the actual number, we can use any factor of it, so for 9, we could just leave it as 3, and for even numbers we can just use 2 (and hence just use xor).
However, there is no general bit-counting based solution for the original problem where a number can be repeated any odd number of times. This is because even if we count the bits exactly without using modulo, when we look at a particular bit, we simply can't know whether the 9 times it appears represents 3 + 3 + 3 or 1 + 3 + 5. If it was turned on in three different numbers which each appeared three times, then it should be turned off in our answer. If it was turned on in a number which appeared once, a number which appeared three times, and a number which appeared five times, then it should be turned on in our answer. But with just the count of the bits, it's impossible for us to know this.
This is why the other answer doesn't generalize and the clever idea to handle the special cases is not going to materialize: any scheme based on looking at things bit by bit to figure out which bits should be turned on or off does not generalize. Given this, I don't think that any scheme which takes space O(1) works for the general case. It is possible that there are clever schemes which use O(lg n) space or so forth, but I would doubt it. I think that the O(n) space approach is probably the best which can be done in the problem as proposed. I can't prove it, but at this point, it's what my gut tells me and I hope that I've at least convinced you that small tweaks to the "even number" technique are not going to cut it.
I know that the subtext of this question is to find an efficient or performant solution, but I think that the simplest, readable code counts for a lot and in most cases it is more than sufficient.
So how about this:
var value = (new [] { 1, 6, 3, 1, 1, 6, 6, 9, 3, 3, 3, 3, })
.ToLookup(x => x)
.Where(xs => xs.Count() == 1)
.First()
.Key;
Good old LINQ. :-)
Test Score 100% with c#
using System;
using System.Collections.Generic;
// you can also use other imports, for example:
// using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(int[] A) {
Dictionary<int, int> dic =new Dictionary<int, int>();
foreach(int i in A)
{
if (dic.ContainsKey(i))
{
dic[i]=dic[i]+1;
}
else
{
dic.Add(i, 1);
}
}
foreach(var d in dic)
{
if (d.Value%2==1)
{
return d.Key;
}
}
return -1;
}
}
Java, Correctness 100%, Performance 100%, Task score 100%
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.HashMap;
class Solution {
/*Simple solution
Will be using HashMap(for performance) as Array,
only Key set is needed.
Initially tried with ArryList but there was performance issue with
that so switch to HashMap.
Iterate over the given array and if item is there in key set
remove it(coz you found your pair) otherwise add as new Key.
After full Iteration only one key will be there in the Map that is
your solution.
In Short: If pair is found, remove it from Map's Key set,
Last Key will be your solution
*/
public int solution(int[] A) {
//Map but used as Array
final HashMap<Integer, Boolean> mapHave = new HashMap<>();
//Iterate over given Array
for (int nIdx = 0; nIdx < A.length; nIdx++) {
//Current Item
Integer nVal = A[nIdx];
//Try to remove the current item, if item does not exists will
//return null and if condition will be true
if (mapHave.remove(nVal) == null) {
//current item not found, add it
mapHave.put(nVal, Boolean.TRUE);
}
}
//There will be only one key remaining in the Map, that is
//your solution
return mapHave.keySet().iterator().next();
}
}

Resources