Created
December 12, 2016 00:30
-
-
Save jianminchen/28b656f16aa58a00687e823eb0aaf212 to your computer and use it in GitHub Desktop.
Stepping Number - C# code - code review post: http://codereview.stackexchange.com/a/149456/123986
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace FindAllSteppingNumbers | |
{ | |
/* | |
* Dec. 11, 2016 | |
* Julia does code review on stepping numbers: | |
* http://codereview.stackexchange.com/a/149456/123986 | |
*/ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
List<int> result = SteppingNumbersInclusivelyBetween(10, 20); | |
Debug.Assert(result[0] == 12 || result[0] == 10); | |
Debug.Assert(result[1] == 12 || result[1] == 10); | |
} | |
public static int CountDigits(int number) | |
{ | |
// Does not handle number <= 0 | |
return (int)Math.Floor(Math.Log10(number)) + 1; | |
} | |
/* | |
* Dec. 11, 2016 | |
* Julia - you should also name the variable more meannful: | |
* digitPosition is better than using position | |
* | |
* | |
* Function arguments: | |
* steppingNumbers - | |
* number - | |
* digit - | |
* digitPostion | |
* numDigits - | |
*/ | |
public static void ConstructSteppingNumbers( | |
ref List<int> steppingNumbers, | |
int number, | |
int digit, | |
int digitPosition, | |
int numDigits) | |
{ | |
// Not a valid digit | |
if (digit < 0 || digit > 9) | |
{ | |
return; | |
} | |
// Construct the next Stepping Number | |
number = 10 * number + digit; | |
// Stopping Condition | |
if (digitPosition == numDigits - 1) | |
{ | |
steppingNumbers.Add(number); | |
return; | |
} | |
// Create a (digitIndex+1)-digit Stepping Number from a digitIndex-digit Stepping Number | |
// Test appending digit-1 before digit+1 to keep the output sorted | |
ConstructSteppingNumbers(ref steppingNumbers, number, digit - 1, digitPosition + 1, numDigits); | |
ConstructSteppingNumbers(ref steppingNumbers, number, digit + 1, digitPosition + 1, numDigits); | |
} | |
// Let number be a Stepping Number and let n be the number of digits in number | |
// This function adds any valid (n+1)-digit Stepping Numbers with prefix 'number' to the list | |
/* | |
* Julia's code review: | |
* 1. First, learn the style - variable name: LeastSignificantDigit | |
* use full name, very instructional. Do not use short name. | |
* 2. steppingNumbers - very good name | |
* | |
*/ | |
public static void ConstructNextDigitSteppingNumbers( | |
ref List<int> steppingNumbers, | |
int number) | |
{ | |
var LeastSignificantDigit = number % 10; | |
// Check digit-1 before digit+1 to keep the output sorted | |
if (LeastSignificantDigit - 1 >= 0) | |
{ | |
steppingNumbers.Add(10 * number + LeastSignificantDigit - 1); | |
} | |
if (LeastSignificantDigit + 1 <= 9) | |
{ | |
steppingNumbers.Add(10 * number + LeastSignificantDigit + 1); | |
} | |
} | |
/* | |
* code review: | |
* 1. Function name is very accurate, using word: Inclusively | |
* SteppingNumbers - | |
* Inclusively - | |
* Between - word between is very meaningful with two input arguments start and stop. | |
*/ | |
public static List<int> SteppingNumbersInclusivelyBetween(int start, int stop) | |
{ | |
var steppingNumbers = new List<int>(); | |
if (start <= 0 || stop <= 0) | |
{ | |
return steppingNumbers; | |
} | |
var minNumDigits = CountDigits(start); | |
var maxNumDigits = CountDigits(stop); | |
// Construct all possible Stepping Numbers on minNumDigits digits | |
for (int digit = 1; digit < 9; digit++) | |
{ | |
ConstructSteppingNumbers(ref steppingNumbers, 0, digit, 0, minNumDigits); | |
} | |
// The start of (numDigit-1)-digit Stepping Numbers | |
var a = 0; | |
// Reuse our work from earlier to generate Stepping Numbers on a higher | |
// number of digits if necessary. While we could have generated these | |
// Stepping Numbers earlier, the output would not be sorted if we had. | |
for (var numDigits = minNumDigits + 1; numDigits <= maxNumDigits; numDigits++) | |
{ | |
// The end of (numDigit-1)-digit Stepping Numbers | |
var b = steppingNumbers.Count(); | |
// Construct numDigit-digit Stepping Numbers from (numDigit-1)-digit Stepping Numbers | |
for (var i = a; i < b; i++) | |
{ | |
ConstructNextDigitSteppingNumbers(ref steppingNumbers, steppingNumbers[i]); | |
} | |
a = b; | |
} | |
// Filter the Stepping Numbers to be within the range | |
steppingNumbers.RemoveAll(number => (number < start || number > stop)); | |
return steppingNumbers; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The problem statement:
The stepping number:
A number is called as a stepping number if the adjacent digits have a difference of 1. e.g 123 is stepping number, but 358 is not a stepping number.
Example:
N = 10, M = 20
All stepping numbers are 10, 12
Return the numbers in sorted order.
And the algorithm is from the stackexchange.com post:
http://codereview.stackexchange.com/questions/149096/given-n-and-m-find-all-stepping-numbers-in-range-n-to-m/149598#149598
Advanced topic by
http://codereview.stackexchange.com/a/149456/123986