Print all unique digit numbers - c#

Question: Print all the number who has unique digits only.
Input : n =15
output: 1 2 3 4 5 6 7 8 9 10 12 13 14 15
Here 11 is not included because it has 1 two times, same way 123, 456 .. are also valid but 121 1344 are not valid because there is same digit more than once.
I am running loop from 1- n and checking each number.
I am using Hash-map to determine the uniqueness of number.
Is there any better solution of above problem.

i'm not sure , but something like that..
List<int> numbers = new List<int>(){};
numbers =numbers.Where(p=>validCheck(p)==true).ToList();
static bool validCheck(int n)
{
return (n.ToString().Length==n.ToString().Disctinct().Count());
}

You could use LINQ, convert the number into a string and check if the length of the string is equal to the number of distinct charchters.
for (int i = 1; i < n; i++){
if (i.ToString().Length == i.ToString().Distinct().Count())
Console.Out.Write(i + " ");
}

as a semi useful library function where you seed it with a start and how many you want.
public static IEnumerable<int> UniqueDigits(int start, int count)
{
for (var i = start; i < (start + count); i++)
{
var s = i.ToString();
if (s.Distinct().Count() == s.Length)
{
yield return i;
}
}
}
then
UniqueDigits(0,15).ToList().ForEach(Console.WriteLine);
or
foreach (var digit in UniqueDigits(100,50))
{
Console.WriteLine(digit);
}

This is how I eliminate the numbers that have a duplicate characters.
Console.Write("Input:");
int number = int.Parse(Console.ReadLine());
List<int> numbers = new List<int>();
List<int> acceptedNumbers = new List<int>();
for (int i = 1; i <= number; i++)
{
numbers.Add(i);
}
foreach (var num in numbers)
{
bool rejected = false;
char[] numChars = num.ToString().ToCharArray();
foreach (var numChar in numChars)
{
if (numChars.Where(n => n == numChar).Count() > 1)
{
rejected = true;
}
}
if (!rejected)
{
acceptedNumbers.Add(num);
}
}
acceptedNumbers.ForEach(n => Console.Write($"{n} "));
Console.Read();

A string is an IEnumerable - so you can use a LINQ statement to solve your problem:
Numbers.Where(N => N.ToString().Distinct().Count() == N.ToString().Length);
The query is checking how many characters of the string of your number distinct and comares this number with the number of total characters.
Here is the whole code printing out all distinct numbers until 20:
List<int> Numbers = new List<int>();
for (int i = 1; i <= 20; i++)
{
Numbers.Add(i);
}
IEnumerable<int> AcceptedNumbers = Numbers.Where(N => N.ToString().Distinct().Count() == N.ToString().Length);
foreach (int AcceptedNumber in AcceptedNumbers)
{
Console.WriteLine(AcceptedNumber);
}

My thoughts:
Run the Loop from 0 to n
For each batch of 10 ( like from 0 to 9 , 10 to 19, 230 to 239..), pick the digits apart from the last one. These digits map to the counter which tends to be skipped. Rest all are to be emitted. For eg : for batch 12x , pick 1 & 2 , now we know that we have to skip numbers at position 1 and 2 , and rest all are acceptable so no need to do any processing for them.
Keep the above digits in sorted manner in an arrayList and keep a pointer at index 0. Lets call it 'ptr'. While running through that batch, check if count ( which moves from 0 to 9 ) for each batch is equal to the array[ptr]. If no, emit the number out. Else, skip it and do ptr++.
When you are doing step 2, check if any digits are duplicate. If yes, skip the entire batch of 10.
There are no string operations happening, so it should bring in the efficiency

Another solution is using integer division and modulo (no number to string conversion). You can verify the uniqueness of a number with the following method (assume digits is int array having 10 elements).
public static bool IsUnique(int num) {
int[] digits = new int[10];
num = Math.Abs(num);
while (num > 0) {
int r = num % 10;
num /= 10;
digits[r] ++;
if (digits[r] > 1) {
return false;
}
}
return true;
}
Working example http://ideone.com/9emEoz

There are only 9 * 9! / (10 - n)! unique-digit numbers with n digits. For larger n, you might want a next lexicographic algorithm to avoid unnecessary iterations. (For example, there are only 544,320 7-unique-digit numbers, yet your program would need to iterate through almost 10 million numbers to produce them!)
Here's my attempt at a next lexicographic procedure for a set of n-unique-digit numbers (where n > 1):
(1) From left to right, start with the digits 10, then ascend from 2.
For example, the first 4-digit number would be 1023.
(2) Increment the right-most digit that can be incremented to the next available
higher digit unused by digits to its left. Ascend to the right of the
incremented digit with the rest of the available digits, starting with lowest.
Examples: 1023 -> 1024 (4 is unused by the digits left of 3)
^
9786 -> 9801 (8 is unused be the digits left of 7)
^
9658 -> 9670 (7 is unused by the digits left of 5)
^

Related

c# find if whether the number is happy or not

Im trying to understund how do I find whether the number is Happy Number or not,
I know that i need to check if the unit digit and the digit in the highest number location are greater
then the numbers in the middele.
`example:
given number: 63240
the unit: 6
the number in the highest location:0
are both of them greater then 3 and 2 and4(middle) ? yes
result: true (for that case)
the quation is:
write a program that get a number from user, the program will print if the given number from the user is a happy number or not
I know how to find the units and the highest number location, but got stack figure it out how to
how to use the digits in the middle in order to find the answer for that..
notice that the only class we've learned so fat is Math,(not even string yes)
we also learned while and for but nothing so far..
I also know that in order to go through all digit in given number i need to use the while loop,
but I dont know how do I use it in order to use them to get to the answer..
my code so far:
int number;
int units;
int highestDigitLoc;
bool isHappyNumber = true;
int count = 0;
Console.WriteLine("enter a number:");
number = int.Parse(Console.ReadLine());
while(number > 0)
{
count++;
units = number % 10;
highestDigitLoc = number / 10;
}
thanks
This link explains what Happy Number's are in a simple way. Basically you have to keep suming the square of each digit present in the number, until the result equals 1. This proccess can go on indefinitely, but fortunately we know for certain that if the sum equals 4, it will never result in a Happy Number. Therefore, we can do the following:
private static bool IsHappy(int n)
{
if (n == 1)
return true;
else if (n == 0 || n == 4)
return false;
else
return IsHappy(SumDigitSquares(n));
}
private static int SumDigitSquares(int n)
{
if (n < 10)
return n * n;
else
return SumDigitSquares(n % 10) + SumDigitSquares(n / 10);
}
Usage:
bool result = IsHappy(63240); //false
Well, your question very vague, however, we can turn the number into an array of digits int[] digits
using System.Linq;
...
int[] digits = null;
while (true) {
Console.WriteLine("enter a number:");
// string : let's solve for arbitrary long numbers (no necessary int)
string number = Console.ReadLine().Trim();
if (string.IsNullOrEmpty(number))
Console.WriteLine("Empty string is not enough");
else if (number.All(c => c >= '0' && c <= '9')) {
// This code preserves leading zeroes
digits = number.Select(c => c - '0').ToArray();
// This code removes leading zeroes
//digits = number
// .SkipWhile(c => c == '0')
// .Select(c => c - '0')
// .DefaultIfEmpty()
// .ToArray();
break;
}
else
Console.Write("Not a valid integer value. Please, try again.");
}
Then we can use this int[] digits to implement any logic required.
Please, note, that we preserve leading zeroes:
"63240" -> int[] {6, 3, 4, 2, 0}
"063240" -> int[] {0, 6, 3, 4, 2, 0}
e.g.
let a number be happy if and only if
It contains at least 3 digits (in order to have middle ones)
Max of the first and last digits is greater than max of all the other digits
In our case with 63240
63240 has 5 digits, the condition holds
Max(0, 6) == 6 > Max(3, 2, 4) == 4, the condition holds
Code:
bool isHappyNumber =
digits.Length >= 3 &&
Math.Max(digits[0], digits[digits.Length - 1]) >
digits.Skip(1).Take(digits.Length - 2).Max();
Edit: let's implement isHappyNumber with good old for loops:
int maxFirstAndLast = digits[0] > digits[digits.Length - 1]
? digits[0]
: digits[digits.Length - 1];
int maxMiddle = 0;
for (int i = 1; i < digits.Length - 1; ++i)
if (digits[i] > maxMiddle) then
maxMiddle = digits[i];
bool isHappyNumber =
digits.Length >= 3 &&
maxFirstAndLast > maxMiddle;
//Remeber to add using System.Linq;
public static bool IsHappyNumber(int num)
{
var numbers = new List<int>();
while (true)
{
int sum = 0;
var digits = num.ToString().Select(x => int.Parse(x.ToString())).ToList();
foreach (var digit in digits)
sum += digit * digit;
if (numbers.Contains(sum))
break;
numbers.Add(sum);
num = sum;
}
return numbers.LastOrDefault() == 1;
}

Is it okay to exit a loop when an exception is thrown?

I solved a task on Hackerrank.com, where the problem was like this:
You have an Array. This Array contains numbers.
Now you enter two numbers:
The first one describes a sum
The second one describes the amount of indexes (sequence length) you add together
In the end you get the amount of sequences whose sum is your defined number
For example:
Your array is [ 1, 2, 3, 4], your sum is 3 and your sequence length is 2.
Now you take the first two indexes and output the sum: [1, 2] = 3.
This is equal to your sum, so now you have found one sequence.
The next sequence is [ 2, 3 ] = 5. This is not equal to 3, so your sequence counter stays 1.
The last sequence is [3, 4] = 7. This is also not equal to 3 and in the end, you found one sequence.
I wrote this code for that:
static int GetSequences(List<int> s, int d, int m)
{
//m = segment-length
//d = sum
int count = 0;
int j = 0;
int k = 0;
do
{
try
{
List<int> temp = new List<int>();
for (int i = 0; i < m; i++)
{
temp.Add(s[i + k]);
}
if (temp.Sum() == d)
{
count++;
}
j++;
k++;
}
catch (ArgumentOutOfRangeException)
{
break;
}
} while (true);
return count;
}
As I didn't know how often I have to count
(For example a 6-Length-Array with a sequence-length of 3 has 4 sequences (1,2,3 | 2,3,4 | 3,4,5 | 4,5,6)),
I am stopping the while loop when the index is out of range. but I'm not sure if this solution is okay. Not just with program speed, but also with code cleanliness. Is this code acceptable, or is it better to use a for loop, which loops for example exactly 4 times for a 6-length array with 3-Length sequences?
It's not recommended, no. Exceptions should be reserved for stuff that isn't supposed to happen, not flow control or validation.
What you want is to use conditional logic (if statements) and the break keyword.
Also, codereview.stackexchange.com is better suited for these kinds of questions.
It would be better to fix your code so that it doesn't routinely throw exceptions:
You sum each of these segments:
0 1 2 3 start = 0
| | summing indexes: 0, 1
+--+
0 1 2 3 start = 1
| | summing indexes: 1, 2
+--+
0 1 2 3 start = 2
| | summing indexes: 2, 3
+--+
The bracket starts at the index start, and has a size of m. The length of s is given by s.Count. Therefore we want to keep going until start + m == s.Count.
(I always find it's useful to draw these things out, and put sample numbers in, in order to make sure you've got the maths right. In the sample above, you can see that we stop when start (2) + m (2) == the array size (4))
static int GetSequences(List<int> s, int d, int m)
{
//m = segment-length
//d = sum
int count = 0;
for (int start = 0; start + m <= s.Count; start++)
{
List<int> temp = new List<int>();
for (int i = 0; i < m; i++)
{
temp.Add(s[start + i]);
}
if (temp.Sum() == d)
{
count++;
}
}
return count;
}
However, you can improve your code a bit:
Use meaningful variable names
Don't create a new temporary list each time, just to sum it
Check your inputs
static int GetSequences(List<int> numbers, int targetSum, int segmentLength)
{
if (numbers == null)
throw new ArgumentNullException(nameof(numbers));
if (segmentLength > numbers.Count)
throw new ArgumentException("segmentLength must be <= numbers.Count");
int count = 0;
for (int start = 0; start + segmentLength <= numbers.Count; start++)
{
int sum = 0;
for (int i = 0; i < segmentLength; i++)
{
sum += numbers[start + i];
}
if (sum == targetSum)
{
count++;
}
}
}
Usually except for switch/case there is often no real reason to use break.
Also an exception MUST be as the name says exceptional, so it MUST NOT be a part of your logic.
As said Jeppe you can use the methods and attributes the framework provides you to do as you like.
Here s.Count seems to be the way to go.
int[] arr = new[] { 1, 2, 1, 2 };
// Sum and len are given by the task.
// 'last' is the last index where we should stop iterating.
int sum = 3, len = 2, last = arr.Length - len;
// One of the overloads of Where accepts index, i.e. the position of element.
// 1) We check that we don't go after our stop-index (last).
// 2) Avoid exception by using '&&'.
// 3) We use C# 8 Range (..) to get the slice of the numbers we need:
// we start from the current position (index) till then index,
// calculated as current index + length given by the task.
// 4) Sum all the numbers in the slice (Sum()) and compare it with the target sum,
// given by the task (== sum).
// 5) The count of all matches (Count()) is the sought amount of sequences.
int count = arr.Where((z, index) => index <= last && arr[index..(index+len)].Sum() == sum).Count();

Get all n-digit numbers whose sum of digits equals to given sum

How can I get all n-digit numbers whose sum of digits equals to given sum? I need the fastest solution because n can be equal with 9 and sum can be equal with 1000.
I have implemented the solution below but it's too slow...
List<int> l = new List<int>();
void findNDigitNumsUtil(int n, int sum, char[] ou, int index)
{
if (index > n || sum < 0)
return;
if (index == n)
{
if (sum == 0)
{
ou[index] = '\0';
string s = new string(ou);
l.Add(Int32.Parse(s));
}
return;
}
for (int i = 0; i <= 9; i++)
{
ou[index] = (char)(i + '0');
findNDigitNumsUtil(n, sum - i, ou,
index + 1);
}
}
void findNDigitNums(int n, int sum)
{
char[] ou = new char[n + 1];
for (int i = 1; i <= 9; i++)
{
ou[0] = (char)(i + '0');
findNDigitNumsUtil(n, sum - i, ou, 1);
}
}
I need the fastest solution
No, you need a fast-enough solution. You are probably unwilling to spend even a million dollars on custom hardware to get the fastest possible solution.
How can I get all n-digit numbers whose sum of digits equals to given sum?
Here, I'll give you the solution for a slightly different problem:
What are all the sequences of n digits drawn from 0-9 that sum to sum?
This is different because this counts 01 and 10 as sequences of length two that sum to 1, but 01 is not a two-digit number.
I'll give you a hint for how to solve this easier problem. You then take that solution and adapt it to your harder problem.
First, can you solve the problem for one-digit numbers? That's pretty easy. The one-digit numbers whose digits sum to n are the digit n if n is 0 through 9, and there is no solution otherwise.
Second: Suppose n > 1. Then the n-digit numbers that sum to sum are:
0 followed by all the n-1 digit numbers that sum to sum
1 followed by all the n-1 digit numbers that sum to sum-1
2 followed by all the n-1 digit numbers that sum to sum-2
...
9 followed by all the n-1 digit numbers that sum to sum-9
Write an implementation that solves that problem, and then adapt it to solve your problem.
You can treat n-digit number as an array of n digits. Then you can increment a particular number to the next number that also adds up to the sum. Stepping through all the next answers, you have generated all possible combinations.
Using a generator to yield each n-digit combination as an IEnumerable<int> (in fact, an int[]), you start with the "smallest" n-digit combination that yields the sum, and go through each one.
IEnumerable<IEnumerable<int>> DigitsToSum(int n, int sum) {
if (sum > 9 * n)
yield return Enumerable.Empty<int>();
else {
var ans = new int[n];
void distribute(int wsum, int downto) {
for (var j1 = n - 1; j1 > downto; --j1) {
if (wsum > 9) {
ans[j1] = 9;
wsum -= 9;
}
else {
ans[j1] = wsum;
wsum = 0;
}
}
}
ans[0] = Math.Max(1, sum-9*(n-1));
distribute(sum-ans[0], 0);
bool nextAns() {
var wsum = ans[n-1];
for (var j1 = n - 2; j1 >= 0; --j1) {
wsum += ans[j1];
if (ans[j1] < Math.Min(9, wsum)) {
++ans[j1];
distribute(wsum - ans[j1], j1);
return true;
}
}
return false;
}
do {
yield return ans;
} while (nextAns());
}
}
This is tremendously faster than my recursive double generator solution (somewhat like #EricLippert's suggestion) to iterate over all possibilities (e.g. using Count()).
You can put the digits back together to get a final numeric string for each number:
var ans = DigitsToSum(n, sum).Select(p => String.Join("", p));

Efficient way to count the number of appearances of a digit in a number

I need to count the number of times a single digit (not 0) appears in a number (positive integer) of varying length.
The obvious solution is to convert the number to a string, the digit to a character and iterate over the string to count the number of times the character appears in the string.
static int CountDigitInString(string searchString, char digit)
{
int sum = 0;
for (int i = 0; i < searchString.Length; i++)
{
if (searchString[i] == digit)
sum++;
}
return sum;
}
The problem with this method, however, is that it is too slow for my purposes as I am running it many times.
public static void Run()
{
for (int i = 0; i < 1000000; i++)
{
CountDigitInString(i.ToString(), (char)j);
}
}
After I noted that the process took too much time, the CPU sampling profiler showed me that the problem was with the conversion to string.
So, how do I efficiently count the number of times a digit (single digit only, not a number) appears in a number (of any length)?
Here is more optimized version of #shaitibber solution. It replaces one division with multiplying and returns 1 for 0,0. It is about 20% faster.
static int CountDigitsInString2(int number, int digit)
{
int sum = 0;
do
{
int n2 = number / 10;
if (number - n2 * 10 == digit)
sum++;
number = n2;
} while (number != 0);
return sum;
}
And here is solution about three times faster than that (but does not work for 0 digit, which is not required). It precalculates results for numbers 0..9999.
private static int[][] cache = new int[10][];
private const int cacheSize = 10000;//or 100000
private static int[] initCache(int digit)
{
var ca = cache[digit] = new int[cacheSize];
for (int i = 0; i < ca.Length; ++i)
{
ca[i] = CountDigitsInString2(i, digit);
}
return ca;
}
static int CountDigitsInString3(int number, int digit)
{
var ca = cache[digit] ?? initCache(digit);
int sum = 0;
while (number != 0)
{
int n2 = number / cacheSize;
sum += ca[number - n2 * cacheSize];
number = n2;
};
return sum;
}
I found a way which turned out to be about 3 times as fast on average (checked using a Stopwatch):
static int CountDigitsInString(int number, int digit)
{
int sum = 0;
while (number != 0)
{
if (number % 10 == digit)
sum++;
number /= 10;
}
return sum;
}
EDIT:
I found a way which is over 4 times as fast as the one above. Before I start, note that this solution is valid only for cases in which you are counting appearances of a digit in consecutive numbers.
It occurred to me that if you counted the number of times the digit "d" appeared in a number "A", then you don't neccessarily have to recount the number of times "d" appears in "A + 1" to know what it is.
For example, if I know that the digit 3 appears 4 times in the number 35312336, I can know for a fact that it will still appear 4 times in the next consecutive number 35312337, without actually counting.
The reason I can do this is that the count would only change in one of three cases:
1) When the last digit of "A - 1" was a 9, "A" can change entirely due to numbers being carried over. This is the only case in which we actually have to count (although you could, theoretically, optimize this further by checking the numbers carried over to see if they affect the total but this strikes me as overly complicated).
2) When the last digit of "A - 1" was "d - 1", we know that the number of times "d" appears in "A" has increased by one.
3) When the last digit of "A - 1" was "d", we know that the number of times "d" appears in "A" has decreased by one.
This means that you only have to count the appearances of "d" in "A" using arithmetical operations in one out of 10 cases!
public static void Run()
{
int digit = 1;
int count = 0;
for (int i = 0; i < 100000; i++)
{
int previousLastDigit = (i - 1) % 10;
if (previousLastDigit == (digit - 1))
count++;
else if (previousLastDigit == 9)
count = CountDigitsInString(i, digit);
else if (previousLastDigit == digit)
count--;
Console.WriteLine(digit + " appears " + count + " times in the number " + i);
}
}
The CountDigitsInString function is the one above.
Here is a little snip with LINQ to give you another way to do it (didn't ran a stopwatch)
var number = 11334511;
var digit = 1;
var digitAsChar = Convert.ToChar(digit.ToString().ToLower());
// Occurence will be 4
var occurence = number.ToString().ToLower().Count(s => s == digitAsChar);
I suggest you use LINQ on string.
Source: https://msdn.microsoft.com/en-us/library/mt693025.aspx
static int CountDigitInString(string number, char digit)
{
int count = number.Count(ns => ns == digit);
return count;
}

Palindrome is not working [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I check if a number is a palindrome?
Hello All i want to make program to check whether palindrome number or not when user input the number. But my work does not work at all... Can you guys help me...
class Program
{
static void Main(string[] args)
{
int i = 0, j = 0 ;
int numbers =Convert.ToInt32( Console.ReadLine());
i = numbers % 10;
do
{
j = numbers / 10;
}
while (j < 10);
if (i == j)
{
Console.WriteLine(" this is palindrome number");
}
else
{
Console.WriteLine("not a palindrome");
}
The quickest way is to reverse the string and compare it to the original. You don't really need the integer conversion.
You may want to filter or correct the user's input by stripping leading zeroes (i.e. in 010). For example : string number = Convert.ToInt32(Console.ReadLine()).ToString();
You don't have to convert it to integer.
You can check it from the string.
Take the first character and the last character compare those .
Iterate the first pointer +1 and the last pointer -1 then compare.
Continue this process upto you are in middle of the string.
First of all by converting the digits to an Int32, the number of digits a user can enter are limited.
By using the modulo operation, the i variable will contain the last digit of the entered number.
By dividing the number by 10, j should eventually contain the first digit entered. However you aren't dividing it "until j is smaller than 10", but you're dividing it "while j is smaller than 10", effectively making the contents of j depend on the number of digits entered.
Even if you would fix the while condition, this code will only check the first and last digit, making it function only for 1, 2 and 3 digit numbers.
You'll need something like this:
bool isPalindrome = true;
string s = "300212003";
for (int i = 0; i < (s.Length / 2); i++)
{
if (s[i] != s[s.Length - i - 1])
{
isPalindrome = false;
break;
}
}
Console.WriteLine(isPalindrome);
It's faster than reverting a string and comparing it, only need O(n/2) operations.
a disscussion
palindrome check
C# code to check palindrome
You can follow these links .
#include<stdio.h>
#include<math.h>
void main()
{
long int n, num, rev = 0, dig;
clrscr();
printf("\n\n\t ENTER A NUMBER...: ");
scanf("%ld", &num);
n = num;
while(num>0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
if (n == rev)
printf("\n\t GIVEN NUMBER IS A PALINDROME");
else
printf("\n\t GIVEN NUMBER NOT A PALINDROME");
getch();
}
Something is palindrome when you can read it either way, so when the reverse is the same as the original.
So just reverse your input string and compare it to the original.

Categories

Resources