Amazon.com Widgets Exercise 6.6
Welcome, Guest. Please login or register.
Did you miss your activation email?
October 02, 2014, 07:28:49 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 ... 3 4 [5] 6 Go Down
Print
Author Topic: Exercise 6.6 (Read 20266 times)
dbender
Newbie
*
Posts: 2






Reply #60 on: February 22, 2010, 12:54:36 PM

Here's one more solution.  I used the pow() and log10() functions, which have not yet been introduced, but I thought that was less a leap than writing a stack class and using it to reverse the digits in the number.  Smiley

Duane
#import <Foundation/Foundation.h>

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

   int num, count, digit;
   
   NSLog(@"Enter an integer.");
   scanf("%i", &num);
   
   if (num < 0) NSLog(@"minus");
   num = abs (num);
   if (num == 0) NSLog(@"zero"); 

   count = log10(num);
   while (count >= 0) {
      digit = num / pow(10, count);   
      switch (digit % 10) {
         case 0:
            NSLog(@"zero");
            break;
         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;
      }
      num = num % (int) pow(10, count);
      --count;         
   }
      
    [pool drain];
    return 0;
}
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #61 on: February 22, 2010, 12:58:53 PM

Hmm, I like the idea of a stack class!   Could be used for implementing all sorts of things, like RPN calculators.

It is too advanced for this point in the text, as it would involve the use of arrays.

Cheers,

Steve Kochan
Logged
jdelamater
Newbie
*
Posts: 3






Reply #62 on: April 16, 2010, 08:41:09 AM

Here's my variation on the solution to exercise 6.6. For me, the hardest part was creating a reverse of the number as one whole entity. Once that was done, it was pretty easy, although coming up with a check for ending zeros had me perplexed for a minute, especially if there was a zero inside the number, as that initially was throwing the code off. but that was an easy fix.

Question though, if i knew the syntax for arrays in Obj-C that would have been my preferred method for displaying the english word for the number over switch. I find switch kind of cumbersome to deal with. Is there any benefit to using one method over the other, say performance or memory-management wise?

Code: (Objective-C)
#import <Foundation/Foundation.h>

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

// declare variables
// used long int, because it was required for testing a phonenumber
long int number, reverseNumber;
int right_digit, zeroCount = 0;

// prompt
NSLog (@"Enter a number: ");
scanf ("%li", &number);

// negative handling
if (number < 0){
number *= -1;
NSLog (@"minus");
}

while (number != 0){
// ending zero handling
if (number > 0 && number % 10 == 0)
zeroCount++;

// create a reverse of the number
// get the remander, and if number is larger than zero,
// multiple reverse number by ten, to make room for next digit
reverseNumber += number % 10;
if (number /= 10)
reverseNumber *= 10;
}

while (reverseNumber != 0) {
// spit out number in english in correct order,
// then remove end number
right_digit = reverseNumber % 10;
reverseNumber /= 10;

switch (right_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");
zeroCount--; // correct for middle zeros
break;
}
}

// print ending zeros
for (int i = 0; i < zeroCount; i++){
NSLog(@"zero");
}
 
    [pool drain];
    return 0;
}
Last Edit: April 16, 2010, 08:45:53 AM by jdelamater Logged
mitchb
Full Member
***
Posts: 142






Reply #63 on: May 06, 2010, 01:32:11 PM

I took a different tact and just reverse built the number, then printed it.


Code: (Objective-C)
#import <Foundation/Foundation.h>

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

    int number, right_digit, revNum;
char sign;

number = right_digit = revNum = 0; // Init all int.

printf("Enter a number: ");
scanf("%i", &number);

do
{
if (number < 0)  // Deal with negative number.
{
number = -number;
sign = '-';
}
right_digit = number % 10;

revNum += right_digit;  // Build number in reverse.
revNum *= 10;
number /= 10;
}
    while (number != 0);

revNum /= 10;     // Logic above results in X 10 one time to many.
      // correct here.

if (sign == '-')  // print - sign if needed.
printf("%c\n", sign);

// print number. I'm using the C function "puts()" to save me some typing.

do
{
right_digit = revNum % 10;

switch ((char)right_digit)
{
case 0:
puts("zero");
break;

case 1:
puts("one");
break;

case 2:
puts("two");
break;

case 3:
puts("three");
break;

case 4:
puts("four");
break;

case 5:
puts("five");
break;

case 6:
puts("six");
break;

case 7:
puts("seven");
break;

case 8:
puts("eight");
break;

case 9:
puts("nine");
break;

default:
break;
}

revNum /= 10;

} while (revNum != 0);

printf("\nDone!");

    [pool drain];
    return 0;
}
Logged

If you give a man a program, you will frustrate him for a day;
If you teach him how to program, you will frustrate him for a lifetime;
     - Anonymous
edelaney05
Newbie
*
Posts: 6






Reply #64 on: May 17, 2010, 09:30:18 PM

I'd like to echo @jdelamater's question...

In this thread alone we've seen a lot of similar approaches given what we are suppose to know at this point in Kochan's book, but it's also been illustrated there are other options that use other math tools (exponents and / or log) or that convert the input as a string or an array (kinda the same thing). Probably each of those has two or three unique solutions.

Which is the best?

I'm sure they all have trade offs, but where should we focus our efforts as we learn to program?
- Straight forward code that is "readable"
- Elegant algorithms that reduce loops and decision trees
- Making sure that resources aren't wasted on unnecessary data structures

I am guessing the answer will be "d. all the above" :-) But, there was clearly more than one path to the answer here, and ultimate I'm curious to know if it *really* matters.
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #65 on: May 18, 2010, 06:15:07 AM

One of the things about programming is that it is truly a creative process.  There will almost always be multiple solutions to a problem.  Tradeoffs of code size versus program efficiency sometimes have to be made.  Issues of program style factor in as well.   You will learn to make these tradeoffs based on the task at hand, your deadlines, and your experience.  The answer really is "all of the above."   You should rarely sacrifice program readability in making any of the other tradeoffs.  If you have to do that, you need to make sure the program is well-documented with comments.

Cheers,

Steve
Logged
cprogrammer
Newbie
*
Posts: 7


Email




Reply #66 on: May 31, 2010, 09:08:37 AM

Here's my try.  Is there a method, using the knowledge we have obtained from this book so far, to print all the digits of a number composed solely of zeros (like 0000) or a number that begins with several zeros (like 000123)?

Thanks Stephen for your great book - I've never done any programming before,  so I consider your book a fantastic introduction to programming for a beginner.

Randy

Code: (Objective-C)
#import <Foundation/Foundation.h>
//this program does not work right if number entered has a zero at the begining.  It divides the number by multiple powers of ten, and uses the modulus funtion to extract digits.
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


int number, memory, digitsXten = 1;

NSLog (@"Please enter your number");
scanf  ("%i", &number);

memory = number;

//displays zero if the number entered is 0 or a string of 0s
if (number == 0)
NSLog (@"zero");

else

//this loop counts the number of digits and converts the result to a multiple of ten
while (number != 0)
{
digitsXten=digitsXten * 10; //each pass through the loop increases digitsXten by a factor of 10
number = number/10; //each pass decreases number by a factor of ten (1 decimal place)
}

digitsXten = digitsXten / 10; //corrects the fact that digitsXten will always have one more decimal place then is needed

while (digitsXten > 0) //continue looping while there is at least 1 decimal place in the number
{
number = memory / digitsXten;

if (number < 10) //this loop is used if there is only one number entered, also to extract the final digit of our number.
if (number == 0)
NSLog (@"zero");
else if (number == 1)
NSLog (@"one");
else if (number == 2)
NSLog (@"two");
else if (number == 3)
NSLog (@"three");
else if(number == 4)
NSLog (@"four");
else if(number == 5)
NSLog (@"five");
else if(number == 6)
NSLog (@"six");
else if(number == 7)
NSLog (@"seven");
else if(number == 8)
NSLog (@"eight");
else NSLog (@"nine");
else
{
number = number % 10; //this loop is used if more then one number is entered
if (number == 0)
NSLog (@"zero");
else if (number == 1)
NSLog (@"one");
else if (number == 2)
NSLog (@"two");
else if (number == 3)
NSLog (@"three");
else if(number == 4)
NSLog (@"four");
else if(number == 5)
NSLog (@"five");
else if(number == 6)
NSLog (@"six");
else if(number == 7)
NSLog (@"seven");
else if(number == 8)
NSLog (@"eight");
else NSLog (@"nine");
}
digitsXten = digitsXten / 10;
}


    [pool drain];
       return 0;
}
Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #67 on: May 31, 2010, 09:34:00 AM

You may want to think about restructuring the code so you don't have to use that if-else to effectively repeat the same code twice.

Cheers,

Steve
Logged
cprogrammer
Newbie
*
Posts: 7


Email




Reply #68 on: May 31, 2010, 10:11:04 AM

Thanks for your help Stephen!  Here's the updated code -- it turns out that first if-else was not even necessary.

Randy

Code: (Objective-C)
#import <Foundation/Foundation.h>
//this program does not work right if number entered has a zero at the begining.  It divides the number by multiple powers of ten, and uses the modulus funtion to extract digits.
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


int number, memory, digitsXten = 1;

NSLog (@"Please enter your number");
scanf  ("%i", &number);

memory = number;

//displays zero if the number entered is 0 or a string of 0s
if (number == 0)
NSLog (@"zero");

else

//this loop counts the number of digits and converts the result to a multiple of ten
while (number != 0)
{
digitsXten=digitsXten * 10; //each pass through the loop increases digitsXten by a factor of 10
number = number/10; //each pass decreases number by a factor of ten (1 decimal place)
}

digitsXten = digitsXten / 10; //corrects the fact that digitsXten will always have one more decimal place then is needed

while (digitsXten > 0) //continue looping while there is at least 1 decimal place in the number
{
number = memory / digitsXten;

number = number % 10;
if (number == 0)
NSLog (@"zero");
else if (number == 1)
NSLog (@"one");
else if (number == 2)
NSLog (@"two");
else if (number == 3)
NSLog (@"three");
else if(number == 4)
NSLog (@"four");
else if(number == 5)
NSLog (@"five");
else if(number == 6)
NSLog (@"six");
else if(number == 7)
NSLog (@"seven");
else if(number == 8)
NSLog (@"eight");
else NSLog (@"nine");

digitsXten = digitsXten / 10;
}


    [pool drain];
       return 0;
}

Logged
skochan
Administrator
Hero Member
*****
Posts: 3114







Reply #69 on: May 31, 2010, 10:38:56 AM

That's better!  In answer to your previous question, any leading zeroes would be stripped by scanf and not stored in the number (in fact [tt[scanf[/tt] would interpret the number with leading zeroes and being expressed in octal--base 8--notation).   To handle leading zeroes, you'd have to read the number as a string of characters.   You don't need to worry about adding that level of complication here.

Cheers,

Steve
Logged
davidtspf
Newbie
*
Posts: 1






Reply #70 on: July 10, 2010, 06:58:29 PM

Here is a method that relies only on functions already taught in the chapter:

Code: (Objective-C)
#import <Foundation/Foundation.h>

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

int counter, n, digits, number, divisor, leftDigit;

digits = 0;
divisor = 1;

    NSLog(@"Enter your number:");
scanf("%i", &number);

// first figure out how many digits the number is

counter = number;

do {
counter /= 10;
++digits;
}
while (counter != 0);

NSLog(@"Number you entered: %i", number);
NSLog(@"Digits: %i", digits);

// next, do a loop "digits - 1" number of times to get the first divisor

for (n = digits - 1; n > 0; --n)
{
divisor *= 10;
}

// NSLog(@"Divisor: %i", divisor);

// next, do a loop "digits - 1" number of times to print the numbers

for (n = digits - 1; n >= 0; --n)
{

// isolate the left digit
leftDigit = number / divisor;
// NSLog(@"leftDigit: %i", leftDigit);

// print the left digit
switch (leftDigit) {
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:
break;
}

// take away the left digit
number -= leftDigit * divisor;
// NSLog(@"New number: %i", number);

// reduce the divisor
divisor /= 10;
// NSLog(@"New divisor: %i", number);
}


    [pool drain];
    return 0;
}
Logged
Amadeus
Newbie
*
Posts: 7


Email




Reply #71 on: August 12, 2010, 03:22:20 AM

This was the first one I had to give up on and check what others have done!

I got it working nicely using a switch and shorted out the negative number issue.
All that in about 15 mins but I spent a further 3 hours trying to work out a formula for reversing the digits.
1 o'clock in the blooming morning I got to bed...

Looked at some examples here and I would never have got them.
Was tempted to use an array ( read from a C book ) but I wanted to stick to knowledge from the book so far.

Can anyone recommend a book of mathematical formulas that I can use as a reference manual for problems like this?
Logged
MartyRey
Newbie
*
Posts: 6






Reply #72 on: November 14, 2010, 02:00:06 PM

My solution:

#import <Foundation/Foundation.h>


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

   int number = 0;
   int digit = 0;
   int x = 1000000;
   BOOL printZero = NO;
   
   NSLog(@"Enter the number: ");
   scanf("%i", &number);
   
   if (number < 0)
   {
      NSLog(@"negative");
      number = -number;
   }
   
   if (number == 0)
   {
      NSLog(@"zero");
   }
   else
   {
      for (x = 10000000; x > 0; x /= 10)
      {
         digit = number / x;
         if ((digit > 0) && (printZero == NO)) printZero = YES;
         
         if (printZero == YES)
         {
            switch (digit)
            {
               case 0:
                  NSLog(@"zero");
                  break;
               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;
               default:
                  NSLog(@"unknown digit");
                  break;
            }
            number -= digit * x;
         }
      }
   }

    [pool drain];
    return 0;
}
Logged
mykdw
Newbie
*
Posts: 16


Email




Reply #73 on: December 01, 2010, 08:10:33 PM

This statement confuses me... why the += instead of just = ?
   
Code: (Objective-C)
	while (number != 0)
{
reversedNumber += number % 10;
if (number /= 10)
reversedNumber *= 10;
}



Logged
bpalma
Guest




Reply #74 on: January 03, 2011, 05:59:48 PM

After going through Stephen's Programming In C book and seeing the same exercise, I had an idea that I don't believe has been posted yet.  I haven't posted my code for this problem but I will if someone would like to see it. 

I decided to set up a variable that counted the number of digits in the number being entered.  Then I used that variable as the limit in my for loop (you can also use a while loop). After proceeding through a switch statement which seems to be the norm, I was able to print my number in reverse to the console. 

I am not sure as to how efficient and succinct my code is, but it works to the best of my knowledge.

Meliora,

Brian
Logged
Pages: 1 ... 3 4 [5] 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.