patterncsharpMinor
Given N and M find all stepping numbers in range N to M
Viewed 0 times
allrangenumbersfindandgivenstepping
Problem
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.
The code I wrote does accomplish what is asked, but the complexity is \$O(n^2)\$ I think, and I'm sure there is a better way of doing this.
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.
The code I wrote does accomplish what is asked, but the complexity is \$O(n^2)\$ I think, and I'm sure there is a better way of doing this.
class Solution {
public List stepnum(int A, int B) {
List result = new List();
for (int i=A;i=2) //0 - 1
{
for(int j=0;j(int)Char.GetNumericValue(num[j+1]))
{
ascending=false;
}
if(ascending)
less=(int)Char.GetNumericValue(num[j+1])-(int)Char.GetNumericValue(num[j]);
else
less=(int)Char.GetNumericValue(num[j])-(int)Char.GetNumericValue(num[j+1]);
if(less!=1)
{
step=false;
break;
}
}
}
if(step)
{
result.Add(Convert.ToInt32(num));
}
}
else
result.Add(Convert.ToInt32(num));
}
return result;
}
}Solution
Code review
-
Avoid unnecessary indentation whenever possible. An early exit block should always be on top. What I mean by that is this:
-
Use intermediary variables if the code gets too long and loses its meaning
BTW, this can be simplfied to remove
Or, even better:
-
Put spaces around operators and control structures like
The Task
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.
Basically, we need to (1)extract the digits, and (2)check if the adjacent digits have a difference of 1.
-
If you understand the positional notation, the extraction is pretty straightforward :
Due to the nature of this algorithm, the digits are in reserve order (right to left). Although it is really simple to re-reverse it (by chaining
-
To compare adjacent items in a sequence, we can pair up a sequence with itself offset-ed by 1:
To enumerate all step numbers in a defined range, we can use the following method:
-
Avoid unnecessary indentation whenever possible. An early exit block should always be on top. What I mean by that is this:
for(...)
{
// this saves your 1-level of indentation
if (amount < 2)
{
// update result
continue;
}
// rest of code here
}-
Use intermediary variables if the code gets too long and loses its meaning
int current = (int)Char.GetNumericValue(num[j]), next = (int)Char.GetNumericValue(num[j+1]);
if(current > next)
{
ascending=false;
}
if(ascending)
less = next - current;
else
less = current - next;BTW, this can be simplfied to remove
ascending variable:if(current > next)
{
less = current - next;
}
else
{
less = next - current;
}Or, even better:
Math.Abs(current - next)-
Put spaces around operators and control structures like
for, if, while.- You can also compare the
chardirectly, as "the value of acharobject is a 16-bit numeric (ordinal) value":'2' - '1' == 1
- Don't work on numbers as a string and convert it back. It is highly inefficient.
- Divide your code. The block inside the first for-loop can be extracted into a
bool IsStepNumber(int).
The Task
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.
Basically, we need to (1)extract the digits, and (2)check if the adjacent digits have a difference of 1.
-
If you understand the positional notation, the extraction is pretty straightforward :
public static IEnumerable GetDigitsReverse(int value)
{
while(value > 0)
{
yield return value % 10;
value /= 10;
}
}Due to the nature of this algorithm, the digits are in reserve order (right to left). Although it is really simple to re-reverse it (by chaining
.Reverse()), it doesn't matter in which direction we are check the adjacent digits.-
To compare adjacent items in a sequence, we can pair up a sequence with itself offset-ed by 1:
public static bool IsSteppingNumber(int value)
{
var digits = GetDigitsReverse(value).ToList();
return digits
.Zip(digits.Skip(1), Tuple.Create)
.All(x => Math.Abs(x.Item1 - x.Item2) == 1);
}To enumerate all step numbers in a defined range, we can use the following method:
public static IEnumerable ListSteppingNumbersBetween(int a, int b)
{
return Enumerable.Range(a, b - a + 1)
.Where(IsSteppingNumber);
}Code Snippets
for(...)
{
// this saves your 1-level of indentation
if (amount < 2)
{
// update result
continue;
}
// rest of code here
}int current = (int)Char.GetNumericValue(num[j]), next = (int)Char.GetNumericValue(num[j+1]);
if(current > next)
{
ascending=false;
}
if(ascending)
less = next - current;
else
less = current - next;if(current > next)
{
less = current - next;
}
else
{
less = next - current;
}public static IEnumerable<int> GetDigitsReverse(int value)
{
while(value > 0)
{
yield return value % 10;
value /= 10;
}
}public static bool IsSteppingNumber(int value)
{
var digits = GetDigitsReverse(value).ToList();
return digits
.Zip(digits.Skip(1), Tuple.Create)
.All(x => Math.Abs(x.Item1 - x.Item2) == 1);
}Context
StackExchange Code Review Q#149096, answer score: 4
Revisions (0)
No revisions yet.