Amazon.com Widgets Exercise 6.6
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 19, 2014, 03:02:26 AM
Home Help Search chat Login Register 
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+ Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+ Old Stuff
| |-+ Answers to Exercises
| | |-+ Chapter 6
| | | |-+ Exercise 6.6
Pages: [1] 2 3 ... 6 Go Down
Print
Author Topic: Exercise 6.6 (Read 21136 times)
WREllis
Newbie
*
Posts: 8


we412303
Email




on: February 08, 2009, 06:25:41 PM

Just thought I would share how I did this one. I took me about an hour to get this to work, and I think it is a hack at best. Perhaps someone could show me a better way to do this.

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   int number, remainder, counter;
   BOOL printZero = NO;
   
   NSLog(@"Type in your number.");
   scanf("%i", &number);
   
   if (number < 0)
   {
      number = -number;
      NSLog(@"negative");
   }
   
   for (counter = 1000000000; counter > 0; counter /= 10)
   {
      remainder = number / counter;
      
   switch (remainder)
      {
      case 0:
            if (printZero == YES)
            {
               NSLog(@"zero");
            }
         break;
      case 1:
         NSLog(@"one");
         printZero = YES;
         break;
      case 2:
         NSLog(@"two");
         printZero = YES;
         break;
      case 3:
         NSLog(@"three");
         printZero = YES;
         break;
      case 4:
         NSLog(@"four");
         printZero = YES;
         break;
      case 5:
         NSLog(@"five");
         printZero = YES;
         break;
      case 6:
         NSLog(@"six");
         printZero = YES;
         break;
      case 7:
         NSLog(@"seven");
         printZero = YES;
         break;
      case 8:
         NSLog(@"eight");
         printZero = YES;
         break;
      case 9:
         NSLog(@"nine");
         printZero = YES;
         break;
      default:
         break;
      }
      
      number = number - (counter * remainder);
   }
   
      
    [pool drain];
    return 0;
}

Logged
mdeh
Full Member
***
Posts: 166






Reply #1 on: February 08, 2009, 07:14:08 PM

Well...here was my attempt.
Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int number, reversedNumber = 0, digit;

    NSLog(@"Display integer in words");
NSLog(@"Enter an integer");
scanf("%i", &number);

if ( number < 0)
{
number = -number;
NSLog(@"minus");
}

if (number == 0)
NSLog(@"zero");

while (number != 0)
{
reversedNumber += number % 10;
if (number /= 10)
reversedNumber *= 10;
}

while (reversedNumber != 0) {
digit = reversedNumber % 10;
switch (digit) {
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
case 0:
NSLog(@"zero");
break;
default:
NSLog(@"Error: Unknown value");
reversedNumber = 0;
break;
}

reversedNumber /= 10;
}

    [pool drain];
    return 0;
}

Logged
WREllis
Newbie
*
Posts: 8


we412303
Email




Reply #2 on: February 08, 2009, 11:37:34 PM

Wow.
I had to test it to make sure it worked, and even then didn't understand it. This bit of code was the magic that makes it all happen.

while (number != 0)
   {
      reversedNumber += number % 10;
      if (number /= 10)
      reversedNumber *= 10;
   }

I had to set breakpoints at each line an follow along with a piece of paper to get what that did. You essentially reversed the number eliminating a lot of the code I had in my attempt. I haven't seen the if statement used to set values, only to test them.  Thanks for posting this, I hope that as I continue to learn Objective-C, I can become more efficient in my coding like you.

Would it be easier to do this by adding each remainder to a string or array? I haven't gotten that far, and that was not the point of the exercise, but I am just curious.
Logged
tyen
Newbie
*
Posts: 6






Reply #3 on: February 09, 2009, 11:23:58 PM

while (number != 0)
   {
      reversedNumber += number % 10;
      if (number /= 10)
      reversedNumber *= 10;
   }

I don't understand the if statement either and I found it unnecessary. It is clearer just to write out the steps explicitly:

while (number != 0)
   {
      reversedNumber += number % 10;
      reversedNumber *= 10;
      number /= 10;
   }
Logged
mdeh
Full Member
***
Posts: 166






Reply #4 on: February 10, 2009, 06:37:28 AM

If you do not check the value of "number"  being greater than 0, then you will get an extra "zero"  in your code. Try entering a single digit using your code.
Last Edit: February 10, 2009, 06:42:12 AM by mdeh Logged
tyen
Newbie
*
Posts: 6






Reply #5 on: February 10, 2009, 02:41:07 PM

Thanks mdeh, I did notice the extra "zero", but I have another problem. Reversing the integers does not deal with the case where the number ends in zeros. For example, the number 890 will be reversed as 98. Do you have any thoughts on that?
Logged
mdeh
Full Member
***
Posts: 166






Reply #6 on: February 10, 2009, 06:56:26 PM

Hi tyen,
OOps...so I thought I would **rapidly** correct it...but it's a real doozie. Arrays are not yet studied....I thought I would convert it to a string ...in that way a trailing zero would be recorded as a zero.
Boolean variables have been done, so I came up with this...it's a hack, but it seems to do the trick.
Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int number, reversedNumber = 0,   digit;

    NSLog(@"Display integer in words");
NSLog(@"Enter an integer");
scanf("%i", &number);

if ( number < 0)
{
number = -number;
NSLog(@"minus");
}


       BOOL endsInZero;
if (( number % 10 ) == 0)
endsInZero = YES;


if (number == 0){
NSLog(@"zero");
endsInZero = NO;
}


do   
{

reversedNumber = reversedNumber *10 + number % 10;

}  while ( number /= 10);

while (reversedNumber != 0) {
digit = reversedNumber % 10;
switch (digit) {
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
case 0:
NSLog(@"zero");
break;
default:
NSLog(@"Error: Unknown value");
reversedNumber = 0;
break;
}

reversedNumber /= 10;
}

if ( endsInZero == YES)
NSLog(@"zero");


    [pool drain];
    return 0;
}

Try it out and let me have some feedback.

ps...it will still not handle integers like '098', but is that really an integer...well I suppose it is  :-)

Last Edit: February 10, 2009, 09:44:09 PM by mdeh Logged
tyen
Newbie
*
Posts: 6






Reply #7 on: February 11, 2009, 01:52:04 AM

I noticed your code only checked for when the integer ends with one zero, so it wouldn't work for 900 for eg. I finally got it working by splitting it into two problems and deal with ending zeros separately.

Code:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
   
   int number, newNumber, reversedNumber = 0,   digit;
   
    NSLog(@"Display integer in words");
   NSLog(@"Enter an integer");
   scanf("%i", &number);
   
   
   
   if ( number < 0)
   {
      number = -number;
      NSLog(@"minus");
   }
   
   newNumber = number;
   
   
   if (number == 0)
   {
      NSLog(@"zero");
   }
   
   
   do   
   {
      
      reversedNumber = reversedNumber *10 + newNumber % 10;
      
   }  while ( newNumber /= 10);
   
   while (reversedNumber != 0) {
      digit = reversedNumber % 10;
      switch (digit) {
         case 1:
            NSLog(@"one");
            break;
         case 2:
            NSLog(@"two");
            break;
         case 3:
            NSLog(@"three");
            break;
         case 4:
            NSLog(@"four");
            break;
         case 5:
            NSLog(@"five");
            break;
         case 6:
            NSLog(@"six");
            break;
         case 7:
            NSLog(@"seven");
            break;
         case 8:
            NSLog(@"eight");
            break;
         case 9:
            NSLog(@"nine");
            break;
         case 0:
            NSLog(@"zero");
            break;
         default:
            NSLog(@"Error: Unknown value");
            reversedNumber = 0;
            break;
      }
      
      reversedNumber /= 10;
   }
   
   
   if (number != 0)
   {
      for ( number; number % 10 == 0; number /= 10 )
         NSLog(@"Zero");   
   }
   
   
    [pool drain];
    return 0;
}



PS. still wouldn't work with a number like '098' though
Logged
mdeh
Full Member
***
Posts: 166






Reply #8 on: February 11, 2009, 06:14:21 AM

tyen...you are giving me heartburn!!!

Try this...( hacks are awful, so I thought this might be a little more elegant..in the sense that it does not split the program into too many pieces...but, elegancy...is in the eye of the beholder!!!)
Code: (Objective-C)
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

int number, reversedNumber = 0,   digit;

    NSLog(@"Display integer in words");
NSLog(@"Enter an integer");
scanf("%i", &number);

if ( number < 0)
{
number = -number;
NSLog(@"minus");
}


if (number == 0)
NSLog(@"zero");


int x = 0;
BOOL endsInZero = NO;
while (( number % 10 ) == 0)
{
{
x++;
number /= 10;
}
endsInZero = YES;
}

do   
{

reversedNumber = reversedNumber *10 + number % 10;

}  while ( number /= 10);

while (reversedNumber != 0) {
digit = reversedNumber % 10;
switch (digit) {
case 1:
NSLog(@"one");
break;
case 2:
NSLog(@"two");
break;
case 3:
NSLog(@"three");
break;
case 4:
NSLog(@"four");
break;
case 5:
NSLog(@"five");
break;
case 6:
NSLog(@"six");
break;
case 7:
NSLog(@"seven");
break;
case 8:
NSLog(@"eight");
break;
case 9:
NSLog(@"nine");
break;
case 0:
NSLog(@"zero");
break;
default:
NSLog(@"Error: Unknown value");
reversedNumber = 0;
break;
}

reversedNumber /= 10;
}

if ( endsInZero == YES)
{

while (x--)
NSLog(@"zero");

}



    [pool drain];
    return 0;
}


Last Edit: February 11, 2009, 08:14:50 AM by mdeh Logged
tyen
Newbie
*
Posts: 6






Reply #9 on: February 11, 2009, 12:47:35 PM

mdeh, watch your heart, I can be very exasperating!

Your method does work but we are essentially doing the same thing, treating ending zeros as a separate problem, which I don't have a problem as integers are straightforward enough. You used a counter to count the number of zeros whereas I made a copy of the argument to use later.

By the way your program does not exit properly if the argument is 0. Checking for nonzero in the first while loop would do it.

Cheers
Logged
mdeh
Full Member
***
Posts: 166






Reply #10 on: February 11, 2009, 01:48:04 PM

Hi Tyen,
that's the problem when you get up early in the am before work to do a quick bit of coding && not testing!!!

Yes...you are correct.
Added this to the while loop.
Code: (Objective-C)
	if ( number != 0){
while (( number % 10 ) == 0)
{
{
x++;
number /= 10;
}
endsInZero = YES;
}

}

which finally seems to do it.   Grin


Logged
mdeh
Full Member
***
Posts: 166






Reply #11 on: February 12, 2009, 06:02:07 PM

mdeh, watch your heart, I can be very exasperating!

Your method does work but we are essentially doing the same thing, treating ending zeros as a separate problem, which I don't have a problem as integers are straightforward enough. You used a counter to count the number of zeros whereas I made a copy of the argument to use later.

By the way your program does not exit properly if the argument is 0. Checking for nonzero in the first while loop would do it.

Cheers

tyen
Going through the later chapters, and realized that we could also have simply done this.
Code: (Objective-C)
if (number == 0){
NSLog(@"zero");
return 0;
}

Now...I am not sure if it is "correct" to have 2 "return 0" expressions, but in a sense they are both correct.


Logged
Razz2
Newbie
*
Posts: 11






Reply #12 on: March 18, 2009, 05:10:40 PM

Could not have done this without your help, all of you, so thanks. With that said, I am curious to your thoughts:

Maybe it is just me but in all the books I have read, I have never had exercises that require this type of workout. In understanding the concepts, and / or learning to, trying to reverse a multi-digit number seems like an odd thing to throw out to beginners in Obj-C. I have been working with loops and conditional statements for years and understand them well. Still, I am no math wiz so calculating the solution needed here is crazy. Having never tackled a language as complex as any C variant maybe this is normal, but there had to have been examples that could have been used to re-enforce the chapter material that allowed the reader to focus on that material and not the math.
Last Edit: March 18, 2009, 05:12:30 PM by Razz2 Logged
sir
Full Member
***
Posts: 118


Email




Reply #13 on: March 18, 2009, 05:14:34 PM

Yeah, this exercise is definately one of the headiest challenges of the exercises I have come across so far.  I think it is good to have a few of those, because after you get the hang of a concept, thinking about it in a more advanced level let's you *permanantly remember the concept.


Logged
Razz2
Newbie
*
Posts: 11






Reply #14 on: March 18, 2009, 05:19:53 PM

@sir: I completely agree. Love difficult examples and I think they do help -embed- the materiel in your mind. But, I am having serious issues just following the written out examples here math wise. (Not as smart as I hoped I would be ;-) Not the concepts of the chapter, just the math. I will write it all out I guess.

@skochan: I love the book, just confused by the example choices. Thanks for the book though.
Logged
Pages: [1] 2 3 ... 6 Go Up
Print
Jump to:



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.