Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created December 12, 2016 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jianminchen/28b656f16aa58a00687e823eb0aaf212 to your computer and use it in GitHub Desktop.
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
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;
}
}
}
@jianminchen
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment