Kaprekar in C++ ?

I need to make a program in C to obtain the number series of the Kaprekar operation. The first integer must be requested from the standard entry and must be positive with four significant digits.

The use of arrangements is not allowed.

A run of the program should look like this:

5368 <- note: entry without prompt
(0) 5368
(1) 5085
(2) 7992
(3) 7173
(4) 6354
(5) 3087
(6) 8352
(7) 6174
1. You do homework for the purpose that you learn. You won't learn (much) if you don't do it.

2. What is "Kaprekar operation"? You have to list the required steps with detail. That list becomes algorithm. Algorithm turns into code.

3. "use of arrangements"? No idea what that is.


You could start from:
read value (where 999<value<10000)
old = value
new = 0
iteration = 0
ready = false
DO
  print "(iteration) old"
  compute new from old
  IF we are at the end of series
  THEN ready = true
  old = new
  ++iteration
WHILE not ready
Kaprekar's operation: https://plus.maths.org/content/mysterious-number-6174

The way to write a program is to break the problem down into smaller problems. They you break those down into smaller problems. Eventually you get to steps that can be translated to code.

I look at Kaprekar's operation and see the following sub-problems:
- break a number up into it's digits.
- Sort the digits.
- Create the largest number with the 4 digits: (largest digit) (next digit) (next digit) (smallest digit)
- Create the smallest number from the 4 digits: (smallest digit) (next digit) (next digit) (largest digit)

If you can write code to do these 4 things then the creating the program is trivial.

Have you learned about functions? You could make each one of these a function. Write it. Test it. Then write the next. When the functions work, use them in the main() program to solve the problem.
Well, I already made something, but I don't know if it will works, I undestand what my teacher says, if he could explains so...


#include <stdio.h>
#include <locale.h>

int main (void){
int num,a,b,c,d;
setlocale(LC_ALL,"");

printf("4 digits number\n");
(scanf("%d",&num));


a= num/1000;
printf("%d",a);
b= (num%1000)/100;
printf("%d",b);
c= (num%100)/10;
printf("%d",c);
d= (num%10);
printf("%d",d);


return 0;
}

I have a feeling this is cheating ...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
   string N, Nold;           // ahem!!
   int counter = 0;
   cout << "Enter a 3- or 4-digit number with at least two distinct digits: ";   cin >> N;
   while ( N != Nold )
   {
      cout << "(" << counter++ << ") " << N << '\n';
      Nold = N;
      sort( N.begin(), N.end() );
      string ReverseN = N;
      reverse( ReverseN.begin(), ReverseN.end() );
      N = to_string( stoi( ReverseN ) - stoi( N ) );
   }
}


Enter a 3- or 4-digit number with at least two distinct digits: 5368
(0) 5368
(1) 5085
(2) 7992
(3) 7173
(4) 6354
(5) 3087
(6) 8352
(7) 6174


Enter a 3- or 4-digit number with at least two distinct digits: 123
(0) 123
(1) 198
(2) 792
(3) 693
(4) 594
(5) 495
Yep, that's exactly the strategy I would use in Ruby. This sort of problem reminds me of some of the instances when I'd take a string and split(//) it, which kinda uses regex to quickly convert it to an array. I tried to use less variables but had trouble with the comparison =S
You have a small bug because you didn't 0-pad the next string. "332" or "1000" quickly goes to 0 because of the lost digit. I ran into this too until I processed it against "%03d" or "%04d", respectively.

Ruby, running at https://repl.it/repls/SlateblueLastingLinkedlist :
1
2
3
4
5
6
7
8
9
10
print "Enter a 3- or 4-digit number with at least two distinct digits: "
n = gets.chomp
sz = n.size
11.times {|x|
  puts "(#{x}) #{n}"
  ar = n.split(//)
  m = ar.sort.join
  n = "%0#{sz}d" % (m.reverse.to_i - m.to_i)
  break if ar.join == n
}


Enter a 3- or 4-digit number with at least two distinct digits:  332
(0) 332
(1) 099
(2) 891
(3) 792
(4) 693
(5) 594
(6) 495


Enter a 3- or 4-digit number with at least two distinct digits:  5200
(0) 5200
(1) 5175
(2) 5994
(3) 5355
(4) 1998
(5) 8082
(6) 8532
(7) 6174
icy1 wrote:
You have a small bug because you didn't 0-pad the next string. "332" or "1000" quickly goes to 0 because of the lost digit.

Yes, you are quite right, @icy, it needs padding. My error.

I think this revision will do the job.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
   string N, Nold;
   int counter = 0;
   cout << "Enter a 3- or 4-digit number with at least two distinct digits: ";   cin >> N;
   int size = N.size();

   while ( N != Nold )
   {
      cout << "(" << counter++ << ") " << N << '\n';
      Nold = N;
      sort( N.begin(), N.end() );
      string ReverseN = N;
      reverse( ReverseN.begin(), ReverseN.end() );
      N = to_string( stoi( ReverseN ) - stoi( N ) );
      if ( N.size() < size ) N = string( size - N.size(), '0' ) + N;   // fix the loss-of-zeroes problem
   }
}
Topic archived. No new replies allowed.