Find next Aloha Number - objective-c

I found this problem in one of coding practice sites...Problem goes as below.
A number is said to be an aloha number if it is comprises entirely of 4s and 7s. Below are few examples of Aloha Numbers
4477
47744477
Your program will get an integer number of a non Aloha Number and your output must return the next Aloha number (in the form of string) for that input.
Example 1
Input : 1234
Output: 4444
Example 2
Input : 4472
Output: 4474
Input number represent the integer between 1 and 2*(10^9)
Input number is not Aloha Number
I tried to solve this problem as below..
- (NSString *) nextAlohaNumber:(NSUInteger) number{
// method convertNumberIntoDigit return a array of digits present in input number
NSMutableArray *numberDigits = [self convertNumberIntoDigit:number];
NSUInteger tempNum;
for(int index = 0; index < numberDigits.count; index++){
tempNum = [[numberDigits objectAtIndex:index] intValue];
if(4 != tempNum && 7 != tempNum){
if(4 > tempNum){
[numberDigits replaceObjectAtIndex:index withObject:[NSNumber numberWithInt:4]];
}else if (7 > tempNum){
[numberDigits replaceObjectAtIndex:index withObject:[NSNumber numberWithInt:7]];
}
else if(7 < tempNum){
[numberDigits replaceObjectAtIndex:index withObject:[NSNumber numberWithInt:4]];
int previousIndex = index-1;
int previousNum = [[numberDigits objectAtIndex:previousIndex] integerValue];
if(previousIndex ){
if(4 == previousNum){
[numberDigits replaceObjectAtIndex:previousIndex withObject:[NSNumber numberWithInt:7]];
}
else if(7 == previousNum){
[numberDigits replaceObjectAtIndex:index withObject:[NSNumber numberWithInt:4]];
}
}
}
}
}
return [self numberArrayToStr:numberDigits]; // convert strings with digit in Array
}
But this method doesn't pass all the test cases, for example it fails on input 4478, 790 etc.
Can any one please help me to solve this problem for all inputs with better time and space complexity.
PS: I'm ok with C,C++ code as well.
Thanks in advance.

Despite my comment above, I wondered about the "time and space complexity". It turned out to be trivial; this only takes 3 long integer variables and a single loop over each input digit (which can be incremented by this algorithm to use 1 more digit; and this will not cause an integer overflow).
Starting from the lowest digit, if it's lower than 4 replace it with 4. If it's lower than 7, replace it with 7. For 8 and 9, replace it with 4 and increment the next digit. Repeat until all digits are processed.
The following code returns the number itself for a proper "aloha" number, the next higher if not.
It requires long variables (using more than 32 bits), because the aloha number for the largest allowed input, 2*(10^9), is 4444444444 -- outside the range of a 32-bit integer.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
long not_aloha, aloha, digit;
if (argc != 2)
{
printf ("please give an aloha number\n");
return -1;
}
not_aloha = atoi (argv[1]);
printf ("not aloha: %ld\n", not_aloha);
aloha = 0;
digit = 1;
while (not_aloha)
{
if ( (not_aloha % 10) <= 4)
aloha += 4*digit;
else if ( (not_aloha % 10 ) <= 7)
aloha += 7*digit;
else
{
aloha += 4*digit;
not_aloha += 10;
}
digit *= 10;
not_aloha /= 10;
}
printf ("aloha: %ld\n", aloha);
return 0;
}

Related

Count number of zero(0) using objective-c

I want to count how many number of zero(0) before numeric number. Because I need to save those number which is present before numeric.
Exam:- suppose I have a number 0000102. So I want to calculate how many zero(0) before numeric start. In this exam we are see here is 4 zero's(0) are present. It is possible to calculate this?
for (i=0;i<string.length;i++)
{
if ([[string characterAtIndex:i] intValue] <= 9 || [[string characterAtIndex:i] intValue] > 0 )
{
i++;
}
else
{
numerOfZeros++;
}
}
int count = 0;
NSString *strr = #"0000102";
unichar findC;
for (int i = 0; i<strr.length; i++)
{
findC = [strr characterAtIndex:i];
if (findC == '0')
{
count++;
}
else
break;
}
NSLog(#"%d",count);
Recursive approach for a one liner:
#implementation NSString (category)
- (NSUInteger)zeroPrefixCount
{
return [string hasPrefix:#"0"] ? 1 + [[string substringFromIndex:1] zeroPrefixCount] : 0;
}
#end
This is not an optimal solution, performance-wise, but it's typical of your first days at programming classes.
usage
// x will be 4
NSUInteger x = [#"0000102" zeroPrefixCount];
I recommend you to save this kind of numbers as String itself and no need to further evaluate how many zeros are there rather do a string comparison if needed.
If you really want to count zeros in your number then you can consider converting it to a string and use NSRange and NSString helper methods to get what you want. Similar situation is answered here.
search if NSString contains value

Objective C calculator displaying scientific notation

So I've coded a calculator in objective C and I've formatted the display in .4g as I wanted only significant digits and 4 decimal places. This works fine :)
What I would like it to do is not display 2.34E+05 etc when it displays a longer number like 234,000. I've allowed it to autosize the text in the label so I know it isn't just that the label is too small.
Is there a piece of code that will make it display the actual number instead of the scientific notation?
Formatting with %f instead of %g won't use standard form.
Have a look at this specification.
Edit 1:
I found this answer to help with the rounding.
-(float) round:(float)num toSignificantFigures:(int)n {
if(num == 0) {
return 0;
}
double d = ceil(log10(num < 0 ? -num: num));
int power = n - (int) d;
double magnitude = pow(10, power);
long shifted = round(num*magnitude);
return shifted/magnitude;
}
I then combined these two options to get:
NSLog(#"%.0f", [self round:number toSignificantFigures:4]);
Edit 2:
What about this:
- (NSString *) floatToString:(float) val {
NSString *ret = [NSString stringWithFormat:#"%.5f", val];
unichar c = [ret characterAtIndex:[ret length] - 1];
while (c == 48 || c == 46) { // 0 or .
ret = [ret substringToIndex:[ret length] - 1];
c = [ret characterAtIndex:[ret length] - 1];
}
return ret;
}
I haven't tested this, but it looks as if it limits decimals to 5, then removes any trailing zeros or decimal points.
[Source]

Prime Generator not working

I want to write a really simple prime app. But i am having some problems with the code below it should generate primes from 0 to 99. But instead it just shows 99.
One problem is that only the last number is displayed. But the other one is that the prime "check" doesn't work. How can I fix those problems.
for (i=0; i<100; i++) {
for (n=2; n<i; n++) {
if (i%n == 0) break;
else primetext.text = [NSString stringWithFormat:#"%i, ", i];
}
}
There were a number of problems, I'll try to explain them
The problem with prime checking was that you had the if-else statement inside of the for loop that iterated through the numbers to check. So if your number wasn't divisible by ANY of the numbers you check it would be registered as prime. It would also be registered n times, where n is the number of times it was found to not be divisible.
All even numbers are not prime (aside from 2), so you can do i+=2 to double your speed
You only need to check up to the square root of a number to see if it's prime.
1 isn't a prime so you don't need to include it (especially because it can make your logic more complex).
You were reassigning the string instead of adding a component to it
You were using %i instead of %d. This can sometimes cause weird errors.
Here is your method revised with these points in mind.
int maxNum = 100;
primetext.text = #"2 "; //Start knowing that 2 is the lowest prime (avoid evaluating evens)
for (i=3; i<=maxNum; i+=2) //Start at 3 and add 2 (avoid 1 and 2 as well as even numbers)
{
bool isPrime = YES; //Assume that i is prime
for (n=2; n<sqrt(i); n++) //Divide by every number up to square root
{
if (i%n == 0) //If evenly divisible by n, not a prime
{
isPrime = NO;
break; //Don't need to check any more factors, so break
}
}
if (isPrime) //If isPrime was never set to NO, i is prime
{
NSString *temp = [NSString stringWithFormat:#"%d ", i];
primetext.text = [primetext.text stringByAppendingString:temp];
}
}
Hope this helps.
You should append the number to primetext.text instead of assigning. Right now it's being reassigned on every iteration.

random BOOLs in an efficient way for cocos2d

According to Steffen's post this is an efficient way to generate random BOOLs in cocos2d
+(BOOL) getYesOrNo
{
return (CCRANDOM_0_1() < 0.5f);
}
but how do I set a range for this? (e.g. 0 - 29 is the interval and 5 ones BOOL = NO, 25 ones BOOL = YES )
you can do something like this:
+(BOOL) getYesOrNo
{
int tmp = (arc4random() % 30)+1;
if(tmp % 5 == 0)
return YES;
return NO;
}
You should use arc4random for random number generator.
#include <stdlib.h>
u_int32_t
arc4random(void);
The arc4random() function uses the key stream generator employed by
the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be
in about (2*1700) states. The arc4random() function returns pseudo-
random numbers in the range of 0 to (2*32)-1, and therefore has twice the range of rand and random.
-(BOOL)foo4random
{
u_int32_t randomNumber = (arc4random() % ((unsigned)RAND_MAX + 1));
if(randomNumber % 5 ==0)
return YES;
return NO;
}
For more information on arc4random type
man arc4random
on terminal.
The following code will generate a random bool value:
-(BOOL) randomBool
{
int tmp = (arc4random() % 10);
if(tmp % 2 == 0)
return YES;
return NO;
}

obtaining objective c nsstring from c char[]

code below.
i'm tryind to obtain string answers like "a1", "c4"
this is what i'm having instead of "a1": "adresse finale: \340}00\214"
with this prinf:
printf("\nadresse finale: %s",[self convertCGPointToSquareAdress:self.frame.origin]);
the method is:
-(NSString *) convertCGPointToSquareAdress:(CGPoint ) point{
int x= point.x /PIECE_WIDTH;
int y=point.y/PIECE_WIDTH;
char lettreChiffre[2];
//char chiffre;
NSString *squareAdress;
//ascii a=97 , b=98... h=105
for (int i=97; i<105; i++) {
for (int j=8; j>0; j--) {
if(i-97==x && j-1==y ){
NSLog(#"enterrrrrrrrrred if convertCGPointToSquareAdress");
lettreChiffre[0]=i;
lettreChiffre[1]=(char) j;
printf(" lettreChiffre: %s ", lettreChiffre);
NSString *squareAdress=[NSString stringWithFormat:#"%s", lettreChiffre];
break;
}
}
}
return squareAdress;
}
can you please help me?
thanks in advance.
There are three problems I can see with your code:
1.
When you do
lettreChiffre[1]=(char) j;
remember j is a number between 1 and 8, so you're getting the ASCII character whose value is j, not the character 1...8. You should use
lettreChiffre[1]= '0' + j;
2.
lettreChiffre is a char array of length 2, which means there's no room for the terminal null character. This may work, but may give you gibberish. You should instead declare
char lettreChiffre[3];
lettreChiffre[2] = '\0';
3.
You're trying to use printf to print an NSString, which it can't do. Either use
NSLog(#"adresse finale: %#", mynsstring)
or convert the NSString back to a C-string:
printf("adresse finale: %s", [mynsstring UTF8String]);
Also, as noted by #dreamlax, you don't really need the loop. I assumed you were doing something else and ran into this trouble, so we're not really seeing the full code. But, if this is really the entirety of your code, then you can simply remove the loop as #dreamlax suggested.
What is the purpose of the loop? You have a loop that essentially brute forces a matrix to calculate the “square address”. Your method will also return an uninitialized pointer if x is greater than 8.
Your entire method could be made much simpler.
- (NSString *) convertCGPointToSquareAdress:(CGRect) point
{
unsigned int x = point.x / PIECE_WIDTH;
unsigned int y = point.y / PIECE_WIDTH;
// Do some range checking to ensure x and y are valid.
char lettreChiffre[3];
lettreChiffre[0] = 'a' + x;
lettreChiffre[1] = '1' + y;
lettreChiffre[2] = '\0';
return [NSString stringWithCString:letterChiffre encoding:NSASCIIStringEncoding];
}