Luhn Algorithm sorting out - c#

I am sorting this code:
bool checkLuhn(const string& cardNo)
{
int nDigits = cardNo.length();
int nSum = 0, isSecond = false;
for (int i = nDigits - 1; i >= 0; i--) {
int d = cardNo[i] - '0';
if (isSecond == true)
d = d * 2;
nSum += d / 10;
nSum += d % 10;
isSecond = !isSecond;
}
return (nSum % 10 == 0);
}
There is one mystery what i do not know. Have googled, but still mystery.
That code:
if (isSecond == true)
d = d * 2;
Where on the code program detects is it splitable with 2? I understand if it's not splitable with 2, program multiply it with 2.
I understand operational principle of the program, but there must be some method or something which tells program what is that isSecond. Help me guys.

Now i understand it.
Before the for loop isSecond is false because first ordernumber is (0). Then this isSecond = !isSecond; change false to true. Then it's turn of the second ordernumber (1) and isSecond = true; so method multiplies it with 2. And then it goes false again and not multiplies number 2. Then it goes true and multiply number 3.
What a brain-teaser :D

Related

Correct ICCID algo

I need to validate ICCID, I found only one algo:
int numberStringLength = 18;
int cs = 0;
int dodd;
for (int i = 0; i < numberStringLength; i += 2)
{
dodd = Convert.ToInt32(iccid.Substring(i + 1, 1)) << 1;
cs += Convert.ToInt32(iccid.Substring(i, 1)) + (int)(dodd / 10) + (dodd % 10);
}
cs = (10-(cs % 10)) % 10;
if (cs == Convert.ToInt32(iccid.Substring(numberStringLength, 1)))
{
return true;
}
else
{
return false;
}
but it returns false for 100% right ICCID (89148000005339755555). Where can I get real ICCID algo?
Thanks
According to Wikipedia, ICCIDs use the Luhn algorithm.
Your code that you found is a bit broken, as it assumes that the value has an odd number of digits (an even number of normal digits, plus 1 check digit). It starts parsing the value from the left-most digit, and assumes that this left-most digit ("8" in your example) is not doubled and the next one ("9") is doubled. But this is not correct if the value has an even number of digits. The "8" should be the one that's doubled in your case.
Thankfully, it's very easy to implement the Luhn algorithm ourselves, properly, using that Wikipedia page as reference:
string input = "89148000005339755555";
int sum = 0;
// We'll use index i = 0 means the right-most digit, i = 1 is second-right, etc
for (int i = 0; i < input.Length; i++)
{
// Get the digit at the i'th position from the right
int digit = int.Parse(input[input.Length - i - 1].ToString());
// If it's in an odd position (starting from the right), then double it.
if (i % 2 == 1)
{
digit *= 2;
// If it's now >= 10, subtract 9
if (digit >= 10)
{
digit -= 9;
}
}
sum += digit;
}
// It's a pass if the result is a multiple of 10
bool pass = sum % 10 == 0;
Console.WriteLine(pass ? "Pass" : "Fail");
See it on dotnetfiddle.net.

Calculation Not Updating

I have been running this syntax with one variable successfully, but now I am trying to change it to a foeach() loop and take a range of values and show the results as a message box. My issue with the syntax is that ecll always retains the value of the first number passed, and the calculation is never updated for each subsequent number in the array.
Where did I err that is preventing this from being updated for each subsequent number in the array?
private void btnGetData_Click(object sender, EventArgs e)
{
int start = 2;
int end = 10;
int[] nums = Enumerable.Range(start, end - start).ToArray();
foreach (int n in nums)
{
float tp_x = 0, tp_y = 0;
SAP = new List<PointF>();
float fbw = m_pd.bl[m_pd.bl.Count - 1].m_Width;
float Location1_X = tp_x + fbw;
float Location1_Y = tp_y;
SAP.Add(new PointF(Location1_X, Location1_Y));
float iBH = gbh(m_pd.bl.Count - 1);
float lbw = m_pd.bl[0].m_Width;
float Location2_X = tp_x + lbw;
float Location2_Y = tp_y + (iBH) + 1.5f;
PointF rip = new PointF();
if (!Getrip(ftp, rhep, ref rip))
{
SAP = null;
return;
}
for (int iRowIndex = saii; iRowIndex < m_pd.pp.Count; iRowIndex++)
{
float Xvalue = m_pd.pp[iRowIndex].X;
float Yvalue = m_pd.pp[iRowIndex].Y;
SAP.Add(new PointF(Xvalue, Yvalue));
if (Yvalue == LeftIntersectionPoint.Y)
{
pp.X = Xvalue;
pp.Y = Yvalue;
continue;
}
if (Xvalue >= rip.X)
{
Xvalue = rip.X;
SAP[SAP.Count - 1] = new PointF(rip.X, rip.Y);
}
if (Xvalue == rip.X)
{
break;
}
pp.X = Xvalue;
pp.Y = Yvalue;
}
double ecll = Getll(Location1_X, Location1_Y, rip.X, rip.Y);
Messagebox.Show(Convert.ToString(ec11));
txtLength.Text = ll.ToString("0.00");
}
}
I feel like this is more of a comment based on what's going on here, but I kind of need the code section to explain this better I believe.
Let's simplify away from your points, widths, etc. I think we can all agree that n is never used within your function, so let's do a similar example:
So I have a function I wrote that adds 1 to 1
var newNum = 1 + 1;
It does what is expected, sets newNum to 2, but let's say I wanted to enhance it so that it adds 1 to the numbers in nums (from your original function):
int start = 2;
int end = 10;
int[] nums = Enumerable.Range(start, end - start).ToArray();
but if I try to reuse my function outright:
foreach (int n in nums)
{
var newNum = 1 + 1;
}
Every single pass, I'm always going to have newNum set at 2 because I'm not using the variable.
what I should do is write this:
foreach (int n in nums)
{
var newNum = 1 + n;
}
so based on your 2 through 10, I should see newNum set to 3 through 11 at various iterations.
Each iteration in the 'Foreach' loop assigns a new value to 'n'.
However in the loop body, that value (n) is not used anywhere in the calculations (unless I am missing something). So, of course the result of these calculations will always be the same.
As soon as you include 'n' in some of the calclations, the result will change...

How to subtract two numbers and add the result to the third number in a sequence?

I am trying to write a C# program that takes an input value from user and then puts that value inside a sequence, then prints the result of every calculated number of the sequence inside a listBox. the sequence is like this:
S = 1 - X + X^2 / 2! - X^3 / 3! + X^4 / 4! - ...
First number that will be shown inside the listBox every time the program starts is 1. i am stuck at the part where i should subtract 1 from the user input (X) and then add the result to the third calculated number of the sequence. For example if user enters 2 as input, first output is 1, second output is -1 and then the program should add the result (-1) to the third calculated number of the sequence which is 2 and output should be 1. again subtract the result (1) from the fourth calculated number and again add the result to the fifth calculated number of the sequence and ...
so far i wrote this:
private void button1_Click(object sender, EventArgs e)
{
int x = Convert.ToInt32(textBox1.Text);
listBox1.Items.Clear();
listBox1.Items.Add("1".ToString());
double numerator = 1, Fact = 1, firstNum = 1, result;
for (int i = 1; i <= 20; i++)
{
numerator = x * numerator;
Fact = Fact * i;
result = numerator / Fact;
firstNum = firstNum - result;
listBox1.Items.Add(firstNum.ToString());
}
But i can't figure out how to write the code for the parts of sequence that should add the result to the next calculated number. Above codes will only subtract the result from next number and prints the result, but now how to add the result of subtraction to the next number and prints it again to the listbox?
First number of sequence - Second number of sequence = Result (show in listbox)
Result + Third number of sequence = Result (show in listbox)
Result - Fourth number of sequence = Result (show in listbox)
Result + Fifth number of sequence = Result (show in listbox)
I am very sorry if i explained the problem bad, i tried to be as specific as possible. I know i'm missing a very tiny piece, but i can't figure out what is it, and sorry for the writing, english is not my native language.
Thanks in advance
You are almost on the right track. Just missing few things.
Here is the corrected version of your program --->
private void button1_Click(object sender, EventArgs e)
{
int x = Convert.ToInt32(textBox1.Text);
listBox1.Items.Clear();
listBox1.Items.Add("1".ToString());
double numerator = 1, Fact = 1, firstNum = 1, result=0;
for (int i = 1; i <= 20; i++)
{
Fact = 1; // Reinitialising every time for new denomerator.
numerator = Math.Pow(x, i); // This is how power is calculated.
for (int j = 1; j<=i; j++) // One more inner loop is needed for Factorial.
Fact = Fact * j;
result = numerator / Fact;
firstNum = firstNum + (Math.Pow(-1, i) * result); // This is the main logic for alternate plus minus.
listBox1.Items.Add(firstNum.ToString());
}
}
I hope it solves your problem. :)
Maybe try to store the result of the subtraction(firstNum - result) to a variable and then add it to the next number?
Looks like the sequence formula is
f(i) = (-x)^i / i! for i in 0..N, 0! = 1
which can be produced as follows
private void button1_Click(object sender, EventArgs e)
{
int x = Convert.ToInt32(textBox1.Text);
listBox1.Items.Clear();
double numerator = 1, denominator = 1;
int i = 0;
while(true)
{
var result = numerator / denominator;
listBox1.Items.Add(result.ToString());;
if (++i > 20) break;
numerator *= -x;
denominator *= i;
}
}
var seqLimit = Convert.ToInt32(Textbox1.Text);
var numberX = Convert.ToInt32(XTextBox.Text);
ListBox1.Items.Clear();
var result = 1.0;
for (var i = 1; i <= seqLimit; i++)
{
ListBox1.Items.Add(result);
if (i%2 == 0) result = result + (Math.Pow(numberX, i)/Factorial(i));
else result = result - (Math.Pow(numberX, i)/Factorial(i));
}
static int Factorial(int n)
{
if (n <= 1)
return 1;
int result = 1;
for (int i = 2; i <= n; i++)
{
result = result * i;
}
return result;
}
Try this, it would work.

An algorithm for a number divisible to n

At first user gives a number (n) to program, for example 5.
the program must find the smallest number that can be divided to n (5).
and this number can only consist of digits 0 and 9 not any other digits.
for example if user gives 5 to program.
numbers that can be divided to 5 are:
5, 10, 15, 20, 25, 30, ..., 85, 90, 95, ...
but 90 here is the smallest number that can be divided to 5 and also consist of digits (0 , 9). so answer for 5 must be 90.
and answer for 9 is 9, because it can be divided to 9 and consist of digit (9).
my code
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
Int64 i ,j=1,y=x;
bool t = false;
for (i = x + 1; t == false; i++)
{
if (i % 9 == 0 && i % 10 == 0 && i % x == 0)
{
j = i;
for (; (i /= 10) != 0; )
{
i /= 10;
if (i == 0)
t = true;
continue;
}
}
}
lblAnswer.Text = Convert.ToString(j);
If you're happy to go purely functional then this works:
Func<IEnumerable<long>> generate = () =>
{
Func<long, IEnumerable<long>> extend =
x => new [] { x * 10, x * 10 + 9 };
Func<IEnumerable<long>, IEnumerable<long>> generate2 = null;
generate2 = ns =>
{
var clean = ns.Where(n => n > 0).ToArray();
return clean.Any()
? clean.Concat(generate2(clean.SelectMany(extend)))
: Enumerable.Empty<long>();
};
return generate2(new[] { 9L, });
};
Func<long, long?> f = n =>
generate()
.Where(x => x % n == 0L)
.Cast<long?>()
.FirstOrDefault();
So rather than iterate through all possible values and test for 0 & 9 and divisibility, this just generates only numbers with 0 & 9 and then only tests for visibility. It is much faster this way.
I can call it like this:
var result = f(5L); // 90L
result = f(23L); //990909L
result = f(123L); //99999L
result = f(12321L); //90900999009L
result = f(123212L); //99909990090000900L
result = f(117238L); //990990990099990990L
result = f(1172438L); //null == No answer
These results are super fast. f(117238L) returns a result on my computer in 138ms.
You can try this way :
string a = txtNumber.Text;
Int64 x = Convert.ToInt64(a);
int counter;
for (counter = 1; !isValid(x * counter); counter++)
{
}
lblAnswer.Text = Convert.ToString(counter*x);
code above works by searching multiple of x incrementally until result that satisfy criteria : "consist of only 0 and or 9 digits" found. By searching only multiple of x, it is guaranteed to be divisible by x. So the rest is checking validity of result candidate, in this case using following isValid() function :
private static bool isValid(int number)
{
var lastDigit = number%10;
//last digit is invalid, return false
if (lastDigit != 0 & lastDigit != 9) return false;
//last digit is valid, but there is other digit(s)
if(number/10 >= 1)
{
//check validity of digit(s) before the last
return isValid(number/10);
}
//last digit is valid, and there is no other digit. return true
return true;
}
About strange empty for loop in snippet above, it is just syntactic sugar, to make the code a bit shorter. It is equal to following while loop :
counter = 1;
while(!isValid(input*counter))
{
counter++;
}
Use this simple code
int inputNumber = 5/*Or every other number, you can get this number from input.*/;
int result=1;
for (int i = 1; !IsOk(result,inputNumber); i++)
{
result = i*inputNumber;
}
Print(result);
IsOk method is here:
bool IsOk(int result, int inputNumber)
{
if(result%inputNumber!=0)
return false;
if(result.ToString().Replace("9",string.Empty).Replace("0",string.Empty).Length!=0)
return false;
return true;
}
My first solution has very bad performance, because of converting a number to string and looking for characters '9' and '0'.
New solution:
My new solution has very good performance and is a technical approach since of using Breadth-first search(BFS).
Algorithm of this solution:
For every input number, test 9, if it is answer print it, else add 2 child numbers (90 & 99) to queue, and continue till finding answer.
int inputNumber = 5;/*Or every other number, you can get this number from input.*/
long result;
var q = new Queue<long>();
q.Enqueue(9);
while (true)
{
result = q.Dequeue();
if (result%inputNumber == 0)
{
Print(result);
break;
}
q.Enqueue(result*10);
q.Enqueue(result*10 + 9);
}
Trace of number creation:
9
90,99
900,909,990,999
9000,9009,9090,9099,9900,9909,9990,9999
.
.
.
I wrote this code for console, and i used goto command however it is not prefered but i could not write it with only for.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace main
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter your number");
Int64 x = Convert.ToInt64(Console.ReadLine());
Int64 y, j, i, k, z = x;
x = x + 5;
loop:
x++;
for (i = 0, y = x; y != 0; i++)
y /= 10;
for (j = x, k = i; k != 0; j /= 10, k--)
{
if (j % 10 != 9)
if (j % 10 != 0)
goto loop;
}
if (x % z != 0)
goto loop;
Console.WriteLine("answer:{0}",x);
Console.ReadKey();
}
}
}

Determine if number is in the binary sequence 1 2 4 8 16 32 64 etc [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to check if a number is a power of 2
I want to determine if a number is in
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
...
I tried this:
public static void Main(string[] args)
{
int result = 1;
for (int i = 0; i < 15; i++)
{
//Console.WriteLine(result);
Console.WriteLine(result % 2);
result *= 2;
}
}
As you can see it returns
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
...
How should I efficiently make the above print to be 0 for all of them including 1?
The following expression should be true if i is in your sequence.
(i & (i-1)) == 0)
http://rextester.com/JRH41036
How about something like this?
bool IsInBinarySequence( int number ){
var numbertocheck = 1;
do{
if( number == numbertocheck ) return true;
numbertocheck *= 2;
}while( numbertocheck <= number );
return false;
}
This has no specific limit on the number to check, but makes sure it stops checking if the number to check grows larger than the actual number we're trying to decide if is in the binary sequence.
Since the first time result is odd, you will get 1, since right after that you multiply it by 2, you will always get 0.
You need to print result if you want to get the list of powers of 2.
Console.WriteLine(result);
A primitive way to do that will be:
public static void Main(string[] args)
{
int result = 1;
int numToCheck = 141234;
boolean found = false;
for (int i = 0; i < 15; i++)
{
if (numToCheck == result) {
found = true;
break;
}
result *= 2;
}
if(found) Console.WriteLine("Awesome");
}
You can determine if a number is a power of 2 (including 2^0) by using the following method:
public bool IsPowerOfTwo(int x) {
return (x > 0) && ((x & (x - 1)) == 0)
}
Over here you can read why and how this works.
It's a bit of a hack, but this works ...
static void Main()
{
for (int i = 0; i < 40; i++)
{
var str = Convert.ToString(i, 2);
var bitCount = str.Count(c => c == '1');
Console.ForegroundColor = bitCount == 1 ? ConsoleColor.White : ConsoleColor.DarkGray;
Console.WriteLine(i + ": " + (bitCount == 1));
}
}
it seems you're actually asking if only one bit in the binary representation of the number is a 1
What you is not a test whether the number is in the sequence BUT it is a generator for such numbers... only the print part is containing some sort of a test...
Try this code for a test:
public static void Main(string[] args)
{
int result = 0;
int numToTest = 0;
if ( int.TryParse (args[0], out numToTest) )
{
result = ((from c in Convert.ToString (numToTest, 2) where c == '1' select c).Count() == 1 ) ? 1 : 0;
}
Console.WriteLine(result);
}
The above code takes a commandline argument and tests it for being in the binary sequence according to the criterion you posted... if so it prints 1, otherwise it prints 0.
Thats correct. 1 0 0 0 0 0 is the correct sequence.
Result is 1 in the first loop. 1 % 2 is 1.
Then result *= 2 gives result the value 2. In the next loop run 2 % 2 = 0. Then result *= 2 is 4. 4%2 is 0. 4 *= 2 is 8. 8 %2 is 0. Since result is always multiplied with 2 it keeps to be in the powers of 2 row and thus als MOD operations with 2 result to 0. So all is fine with that code.
your code will print only Binary sequences. as you are applying MOD 2 . so either you will get 0 or 1 . so it will be print in Binary Sequence.
Boolean result = false;
Int32 numberToTest = 64;
Int32 limit = 15;
for (int i = 0; i < limit && !result; i++)
{
if (Math.Pow(2, i).Equals(numberToTest))
{
result = true;
}
}
Console.WriteLine(String.Format("Number {0} {1} a power of 2.", numberToTest, result ? "is" : "is not"));

Categories

Resources