How to get the round number if use the given rule - objective-c

I have a requirement:
I want there is a function, like this, if the number is:323.01 I want return 500.
If the number is 678.60, I want to get the 1000.
If the number is 20.0, I want get 50.
If the number is 8, I want get 10.
like this: if the first number of the number, if less than 5, I want get 5, if more than 5, I want 10.
How to realize this function in Objective-C?
I just think about the this, I only know use % to get the last number of given number, I don't know how to get the first number of the given number.

First I would get number of digits (e.g. for 456 it is 3):
var originalNumber = 456
var counter = 0
var number = originalNumber
while(number != 0){
counter = counter + 1
number = number / 10
}
From there, you can test it for 5 or 10 with exponent of counter.
if (originalNumber < pow(10, counter - 1) * 5){
number = pow(10, counter - 1) * 5
}
else {
number = pow(10, counter)
}
I reused number variable, you can either return it or assign to other variable.
EDIT: just noticed that flag is Objective - C, same applies
Double originalNumber = 456;
int counter = 0;
int number = (int) originalNumber;
while(number != 0) {
counter = counter + 1;
number = number / 10;
}
if(originalNumber < pow(10,counter - 1) * 5){
number = pow(10, counter -1) * 5;
}
else {
number = pow(10, counter)
}

Related

Palindrome of a number - No console log

So I tried to write a code that finds the largest palindromic number from two (3 spaces long) multiplied numbers. Does my code work fine or are there no palindromes for this?
function checkPalindrom(str) {
return str === str.split('').reverse().join('');
}; //Declares the funciton to check if a string is a palindrome
var x = 999;
var y = 999;
var z = 0;
var n = z.toString(); //Declares that n is the string of z
for (i=0; i<899; i++) { //For loop: counts from 0 to 899
x*y===z; //Is this correct? z is set equal to x*y
if(checkPalindrom(n) === true) { //If n is a palindrome,
console.log(n); //Write out the palindrome
} else {
x-=1; //subtract 1 from x and run again
}
};
Also, what is the best way to check for all combinations of 3 digit numbers? Because right now I am just checking for any number from 100 to 999, but I actually need to check for all combinations...
Your post has a few problems, as well as multiple questions in it. I'll try to hone in on the major stuff but, as this is a fairly standard type of Programming 101 homework question, I'm not going to give you an exact answer right out.
First off, there are three different 'equals' in javascript, =, ==, and ===. A single = is an assignment operator and it always works from right to left. Thus,
var x = 2;
assigns the value of 2 to the variable x. In your code,
x*y === z;
has a couple of problems. First off, it is backwards. Secondly, it uses === but should be using =.
z = x*y;
That is what you were trying to put here.
In javascript, == and === are both comparitives. The triple === adds type comparison and is stronger but generally unnecessary. In almost all cases, == is sufficient. But, what it does is compare the values like inside an if statement:
if(x == 2)
This just checks if the value of x is equal to the value of 2, but the values themselves do not change.
Ok, for your other question: "number from 100 to 999, but I actually need to check for all combinations..."
The best way to handle this is a double loop:
var z;
for(var x = 100; x < 1000; x++)
for(var y = x; y < 1000; y++)
z = x*y;
This will first let x = 100, then check 100 * every number from 100 to 999. Then you let x = 101 and check 101* every number from 101 to 999.
function checkPalindrom(str) {
return str === str.split('').reverse().join('');
}; //Declares the funciton to check if a string is a palindrome
var x;
var y;
var z;
var n;
var max = 0;
for (x=999; x >= 100; x--) {
for (y=999; y >= 100; y--) {
z = x*y;
n = z.toString();
if(checkPalindrom(n) === true && max < z) {
console.log(n);
max = z;
}
}
}

Getting a values most significant digit in Objective C

I currently have code in objective C that can pull out an integer's most significant digit value. My only question is if there is a better way to do it than with how I have provided below. It gets the job done, but it just feels like a cheap hack.
What the code does is that it takes a number passed in and loops through until that number has been successfully divided to a certain value. The reason I am doing this is for an educational app that splits a number up by it's value and shows the values added all together to produce the final output (1234 = 1000 + 200 + 30 + 4).
int test = 1;
int result = 0;
int value = 0;
do {
value = input / test;
result = test;
test = [[NSString stringWithFormat:#"%d0",test] intValue];
} while (value >= 10);
Any advice is always greatly appreciated.
Will this do the trick?
int sigDigit(int input)
{
int digits = (int) log10(input);
return input / pow(10, digits);
}
Basically it does the following:
Finds out the number of digits in input (log10(input)) and storing it in 'digits'.
divides input by 10 ^ digits.
You should now have the most significant number in digits.
EDIT: in case you need a function that get the integer value at a specific index, check this function out:
int digitAtIndex(int input, int index)
{
int trimmedLower = input / (pow(10, index)); // trim the lower half of the input
int trimmedUpper = trimmedLower % 10; // trim the upper half of the input
return trimmedUpper;
}

Checking a series of numbers for consistency

I maintain an array of integers. It is important that at all times the integers in this array are in sequence from 0. For example, if there are 5 integers in the array, their values must be 0, 1, 2, 3, 4 (though in any order).
I would like to design a simple, efficient method that checks this. It will return true if the array contains all positive integers in sequence from 0 to array.count - 1.
I would love to hear some different ideas for handling this!
Or, given the integers [0..N-1] if you raise 2 to the power of each in turn the sum will be -1+2^N. This is not a property that any other set of N integers has.
I offer this as an alternative, making no claim about suitability, performance or efficiency, and I recognise that there will be problems as N gets large.
Basically what you want to test is if your array is a permutation of [0...n-1]. There are easy algorithms for this that are O(n) in both time and memory. See for example this PDF file.
Sometimes I use a very simple check that is O(n) in time and O(1) in memory. It can in theory return false positives, but it is a good way to find most mistakes. It is based on the following facts:
0 + 1 + 2 + ... + n-1 == n * (n-1) / 2
0 + 1² + 2² + ... + (n-1)² == n * (n-1) * (2 * n - 1) / 6
I don't know objective-c, but the code would look like this in C#:
bool IsPermutation(int[] array)
{
long length = array.Length;
long total1 = 0;
long total2 = 0;
for (int i = 0; i<length; i++)
{
total1 += array[i];
total2 += (long)array[i] * array[i];
}
return
2 * total1 == length * (length - 1) &&
6 * total2 == length * (length - 1) * (2 * length - 1);
}
This isn't too different from your itemsSequencedCorrectlyInSet: method, but it uses a mutable index set which will be faster than doing -[NSSet containsObject:]. Probably not an issue until you've got thousands of table rows. Anyway, the key insight here is that the Pigeonhole Principle says if you've got N integers less than N and none is duplicated, then you have each of 0...N-1 exactly once.
-(BOOL)listIsValid:(NSArray*)list
{
NSMutableIndexSet* seen = [NSMutableIndexSet indexSet];
for ( NSNumber* number in list )
{
NSUInteger n = [number unsignedIntegerValue];
if ( n >= [array count] || [seen containsIndex:n] )
return NO;
[seen addIndex:n];
}
return YES;
}
Here's my current implementation (testSet is a set of NSNumbers) -
- (BOOL)itemsSequencedCorrectlyInSet:(NSSet *)testSet{
for (NSInteger i = 0; i < testSet.count; i++) {
if (![testSet containsObject:[NSNumber numberWithInteger:i]]) {
return NO;
}
}
return YES;
}

What's wrong with my pascal's triangle?

I've been looking for some simple coding challenges recently, and discovered about Pascal's triangle (here), and I've tried to generate one myself in C/Objective-C. For those that don't know what it is, that link explains it pretty well.
I'm starting to get oddness after the fourth row, and I just can't figure out why.
My output for 5 iterations currently looks like this:
1
1 1
1 2 1
1 3 3 1
4 6 3 1
It should look like this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Here is my code so far. The first loop is just a reset loop (setting all the values to 0). The actual logic happens mostly in the second loop. The third loop is where the values are concatenated and formatted in a string.
I've commented this code much more than I would for myself just to aid readability.
int iterations, i, b, mid, chars, temp;
NSLog(#"Please enter the number of itereations");
scanf("%i",&iterations); // take users input and store it in iterations
// calculate where the first 1 should go.
if (iterations % 2 == 0) mid = (iterations)/2;
else mid = (iterations+1)/2;
chars = iterations*2;
int solutions[iterations][chars];
// reset loop
for (i = 0; i<iterations; i++) {
for (b = 0; b<chars; b++) {
solutions[i][b] = 0;
}
}
solutions[0][mid] = 1; // place the initial 1 in first row
for (int row = 1; row<iterations; row++) {
for (int chi = 0; chi<chars; chi++) {
temp = 0;
if (chi > 0) {
temp += solutions[row-1][chi-1]; // add the one diagonally left
}
if (chi < iterations) {
temp += solutions[row-1][chi+1]; // add the one diagonally right
}
solutions[row][chi] = temp; // set the value
}
}
// printing below...
NSMutableString *result = [[NSMutableString alloc] initWithString:#"\n"];
NSMutableString *rowtmp;
for (i = 0; i<iterations; i++) {
rowtmp = [NSMutableString stringWithString:#""];
for (b = 0; b<chars; b++) {
if (solutions[i][b] != 0) [rowtmp appendFormat:#"%i",solutions[i][b]];
else [rowtmp appendString:#" "]; // replace any 0s with spaces.
}
[result appendFormat:#"%#\n",rowtmp];
}
NSLog(#"%#",result);
[result release];
I have a feeling the problem may be to do with the offset, but I have no idea how to fix it. If anyone can spot where my code is going wrong, that would be great.
It appears (from a brief look) that the original midpoint calculation is incorrect. I think it should simply be:
mid = iterations - 1;
In the example of 5 iterations, the midpoint needs to be at array position 4. Each iteration "moves" one more position to the left. The 2nd iteration (2nd row) would then place a 1 at positions 3 and 5. The 3rd iteration at 2 and 6. The 4th at 1 and 7. And the 5th and last iteration would fill in the 1s at 0 and 8.
Also, the second if statement for the temp addition should be as follows otherwise it reads past the end of the array bounds:
if (chi < iterations - 1) {

Non repeating random numbers in Objective-C

I'm using
for (int i = 1, i<100, i++)
int i = arc4random() % array count;
but I'm getting repeats every time. How can I fill out the chosen int value from the range, so that when the program loops I will not get any dupe?
It sounds like you want shuffling of a set rather than "true" randomness. Simply create an array where all the positions match the numbers and initialize a counter:
num[ 0] = 0
num[ 1] = 1
: :
num[99] = 99
numNums = 100
Then, whenever you want a random number, use the following method:
idx = rnd (numNums); // return value 0 through numNums-1
val = num[idx]; // get then number at that position.
num[idx] = val[numNums-1]; // remove it from pool by overwriting with highest
numNums--; // and removing the highest position from pool.
return val; // give it back to caller.
This will return a random value from an ever-decreasing pool, guaranteeing no repeats. You will have to beware of the pool running down to zero size of course, and intelligently re-initialize the pool.
This is a more deterministic solution than keeping a list of used numbers and continuing to loop until you find one not in that list. The performance of that sort of algorithm will degrade as the pool gets smaller.
A C function using static values something like this should do the trick. Call it with
int i = myRandom (200);
to set the pool up (with any number zero or greater specifying the size) or
int i = myRandom (-1);
to get the next number from the pool (any negative number will suffice). If the function can't allocate enough memory, it will return -2. If there's no numbers left in the pool, it will return -1 (at which point you could re-initialize the pool if you wish). Here's the function with a unit testing main for you to try out:
#include <stdio.h>
#include <stdlib.h>
#define ERR_NO_NUM -1
#define ERR_NO_MEM -2
int myRandom (int size) {
int i, n;
static int numNums = 0;
static int *numArr = NULL;
// Initialize with a specific size.
if (size >= 0) {
if (numArr != NULL)
free (numArr);
if ((numArr = malloc (sizeof(int) * size)) == NULL)
return ERR_NO_MEM;
for (i = 0; i < size; i++)
numArr[i] = i;
numNums = size;
}
// Error if no numbers left in pool.
if (numNums == 0)
return ERR_NO_NUM;
// Get random number from pool and remove it (rnd in this
// case returns a number between 0 and numNums-1 inclusive).
n = rand() % numNums;
i = numArr[n];
numArr[n] = numArr[numNums-1];
numNums--;
if (numNums == 0) {
free (numArr);
numArr = 0;
}
return i;
}
int main (void) {
int i;
srand (time (NULL));
i = myRandom (20);
while (i >= 0) {
printf ("Number = %3d\n", i);
i = myRandom (-1);
}
printf ("Final = %3d\n", i);
return 0;
}
And here's the output from one run:
Number = 19
Number = 10
Number = 2
Number = 15
Number = 0
Number = 6
Number = 1
Number = 3
Number = 17
Number = 14
Number = 12
Number = 18
Number = 4
Number = 9
Number = 7
Number = 8
Number = 16
Number = 5
Number = 11
Number = 13
Final = -1
Keep in mind that, because it uses statics, it's not safe for calling from two different places if they want to maintain their own separate pools. If that were the case, the statics would be replaced with a buffer (holding count and pool) that would "belong" to the caller (a double-pointer could be passed in for this purpose).
And, if you're looking for the "multiple pool" version, I include it here for completeness.
#include <stdio.h>
#include <stdlib.h>
#define ERR_NO_NUM -1
#define ERR_NO_MEM -2
int myRandom (int size, int *ppPool[]) {
int i, n;
// Initialize with a specific size.
if (size >= 0) {
if (*ppPool != NULL)
free (*ppPool);
if ((*ppPool = malloc (sizeof(int) * (size + 1))) == NULL)
return ERR_NO_MEM;
(*ppPool)[0] = size;
for (i = 0; i < size; i++) {
(*ppPool)[i+1] = i;
}
}
// Error if no numbers left in pool.
if (*ppPool == NULL)
return ERR_NO_NUM;
// Get random number from pool and remove it (rnd in this
// case returns a number between 0 and numNums-1 inclusive).
n = rand() % (*ppPool)[0];
i = (*ppPool)[n+1];
(*ppPool)[n+1] = (*ppPool)[(*ppPool)[0]];
(*ppPool)[0]--;
if ((*ppPool)[0] == 0) {
free (*ppPool);
*ppPool = NULL;
}
return i;
}
int main (void) {
int i;
int *pPool;
srand (time (NULL));
pPool = NULL;
i = myRandom (20, &pPool);
while (i >= 0) {
printf ("Number = %3d\n", i);
i = myRandom (-1, &pPool);
}
printf ("Final = %3d\n", i);
return 0;
}
As you can see from the modified main(), you need to first initialise an int pointer to NULL then pass its address to the myRandom() function. This allows each client (location in the code) to have their own pool which is automatically allocated and freed, although you could still share pools if you wish.
You could use Format-Preserving Encryption to encrypt a counter. Your counter just goes from 0 upwards, and the encryption uses a key of your choice to turn it into a seemingly random value of whatever radix and width you want.
Block ciphers normally have a fixed block size of e.g. 64 or 128 bits. But Format-Preserving Encryption allows you to take a standard cipher like AES and make a smaller-width cipher, of whatever radix and width you want (e.g. radix 2, width 16), with an algorithm which is still cryptographically robust.
It is guaranteed to never have collisions (because cryptographic algorithms create a 1:1 mapping). It is also reversible (a 2-way mapping), so you can take the resulting number and get back to the counter value you started with.
AES-FFX is one proposed standard method to achieve this. I've experimented with some basic Python code which is based on the AES-FFX idea, although not fully conformant--see Python code here. It can e.g. encrypt a counter to a random-looking 7-digit decimal number, or a 16-bit number.
You need to keep track of the numbers you have already used (for instance, in an array). Get a random number, and discard it if it has already been used.
Without relying on external stochastic processes, like radioactive decay or user input, computers will always generate pseudorandom numbers - that is numbers which have many of the statistical properties of random numbers, but repeat in sequences.
This explains the suggestions to randomise the computer's output by shuffling.
Discarding previously used numbers may lengthen the sequence artificially, but at a cost to the statistics which give the impression of randomness.
The best way to do this is create an array for numbers already used. After a random number has been created then add it to the array. Then when you go to create another random number, ensure that it is not in the array of used numbers.
In addition to using secondary array to store already generated random numbers, invoking random no. seeding function before every call of random no. generation function might help to generate different seq. of random numbers in every run.