I have a project in Automata theory, and I want to convert an algorithm into programming language( no matter what programming language used to solve this question)
Well, I have these orders
we enter a string and then we convert it to char so we can compare,
for example we entered this input
01001
to make it clear, I will add more inputs to know what I mean,
01000001
{valid input}
101101
{Wrong input}
0
{Wrong input}
we will check if the first digit is 0 if yes, we copy this string to another array 1, and then convert it to with 1 if it's same we copy it to array 2, then here we will need to enter a loop using for or foreach, we want to check if the next values are 0 ( without last char) so I used a.length-1 to make sure it's won't use last one, and when we see new value which is 1, we move to the last array and must be 1.
we will message using Console.WriteLine(""); that the program follows the order
I made something similar which is this (in C#):
string s= Console.ReadLine();
var a = s.ToCharArray();
Console.WriteLine("Original String: {0}",s);
//for (int k = 4; k < a.Length; k++) {
if (a[0] == '0' && a[1] == '1' && a[a.Length-1] == '1') {
for (int r = 2; r < a.Length-1; r++) {
if (a[r] == '0')
{
Console.WriteLine("The Language is Right.");
}
}
}
how do I make new arrays and copy and use it to check out
The straightforward way of implementing a finite automaton is to loop over the input and store the state in a variable:
string s= Console.ReadLine();
int state = 0;
foreach (char c in s.ToCharArray())
{
if (state == 0 && c == '0')
state = 1;
else if (state == 0 && c == '1')
state = -1;
else if (state == 1 && c == '1')
state = 2;
else if (state == 1 && c == '0')
state = -1;
else if (state == 2 && c == '1')
state = 3;
else if (state == 3)
state = -1;
}
bool accepted = state == 3;
Console.WriteLine(accepted);
Related
I was doing a LeetCode exercise for c# and made my own solution for the following prompt:
"Given a binary array nums, return the maximum number of consecutive 1's in the array."
"Input: nums = [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3."
My solution had a hardcoded array value, and i found a solution online that worked and ran fine. However, im having a really hard time understanding what the isStart and isEnd bools do. The code is below:
public class Solution {
public int FindMaxConsecutiveOnes(int[] nums)
{
if(nums == null || nums.Length == 0)
{
return 0;
}
var start = 0;
var length = nums.Length;
var maxLength = 0;
for(int i = 0; i < length; i++)
{
var current = nums[i];
bool isStart = current == 1 && (i == 0 || nums[i - 1] == 0);
bool isEnd = current == 1 && (i == length - 1 || nums[i + 1] == 0);
if (isStart)
{
start = i;
}
if(isEnd)
{
var currentOnes = i - start + 1;
maxLength = currentOnes > maxLength ? currentOnes : maxLength;
}
}
return maxLength;
}
I assume isStart and isEnd determine if we are at the Start or End of the array? I dont really understand what the operators do either. Any help could be appreciated. Thanks :)
I want to start by saying I am very new (1 week) into learning C#, so I sincerely apologize if this question is obvious. I do understand the reason for the exception, diverse.Length has to be 0 or greater. However, I am required to have the formula in my code so as to get the numbered-positions of the last 2 characters of an ever changing string (diverse).
Below, are 3 sets of code....
Firstly my working method.
static void Main(string[] args)
{
try
{
// Sample data - inputs 3 ints.
Console.WriteLine(Solution1(6, 1, 1));
Console.WriteLine(Solution1(1, 3, 1));
Console.WriteLine(Solution1(0, 1, 8));
Console.WriteLine(Solution1(5, 2, 4));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static string Solution1(int A, int B, int C)
{
string a = "a"; // a/b/c are added to string diverse when needed.
string b = "b";
string c = "c";
string diverse = "";
int totalLength = A + B + C; // Length of all 3 arrays
for(int i = 1; i <= totalLength; i++)
{
if (A >= B && A >= C && A > 0) { diverse = diverse + a; A = A - 1; }
if (B >= A && B >= C && B > 0) { diverse = diverse + b; B = B - 1; }
if (C >= A && C >= B && C > 0) { diverse = diverse + c; C = C - 1; }
}
return diverse;
}
What I am trying to do is add an additional check to my code. This check will take the printed letters and check to see if 2 of the same letter has previously been printed. If so, it will not print a 3rd. To do this I made a solution that would find the last 2 characters of the string (as I mentioned above) and compare it to the conditional check in the if statement.
Below is the code with this additional check, that I need to get working...
static string Solution1(int A, int B, int C)
{
string a = "a"; // a/b/c are added to string diverse when needed.
string b = "b";
string c = "c";
string diverse = "";
int totalLength = A + B + C; // Length of all 3 arrays
for (int i = 1; i <= totalLength; i++)
{
// Finds the last 2 characters in the diverse string.
int LastTwoChars = diverse.Length - 2;
string twoCharCheck = diverse.Substring(LastTwoChars, 2);
if (A > 0 && B < 2 && C < 2 && twoCharCheck != "aa")
{
diverse = diverse + a; A = A - 1;
}
if (B > 0 && A < 2 && C < 2 && twoCharCheck != "bb")
{
diverse = diverse + b; B = B - 1;
}
if (C > 0 && B < 2 && A < 2 && twoCharCheck != "cc")
{
diverse = diverse + c; C = C - 1;
}
}
return diverse;
}
You can have the string check only after you have at least 2 characters:
int LastTwoChars = diverse.Length - 2;
string twoCharCheck = LastTwoChars >= 0 ? diverse.Substring(LastTwoChars, 2) : string.Empty; // identical with if (LastTwoChars >= 0) twoCharCheck = diverse.Substring(LastTwoChars, 2); else twoCharCheck = string.Empty
if (A > 0 && B < 2 && C < 2 && (LastTwoChars < 0 || twoCharCheck != "aa")) // check the end only if you have at least 2 chars;
{
...
}
....
As you can see the code gets ugly very fast, so I would propose using a helper method:
// returns the last two chars in a string format, or a default user string
private static string LastTwoCharsOrDefault(string input, string default)
{
var lastTwoCharsIdx = input.Length - 2;
if (lastTwoCharsIdx > 0 )
{
return input.Substring(lastTwoCharsIdx, 2);
}
// we don't have at least 2 chars, so lets just return the default
return default;
}
Then you can change your code like this:
if (A > 0 && B < 2 && C < 2 && string.Equals("aa", LastTwoCharsOrDefault(diverse, "aa"), StringComparison.OrdinalIgnoreCase))
...
You can find more about string comparison here.
If I read your code right, you initialize Diverse as: string diverse = "";
and then execute string twoCharCheck = diverse.Substring(LastTwoChars, 2);
LastTwoChars is going to be -2 the first time through the loop.
I was wondering how am i able to negate away the special character.
For example when i key aaa for my decrypted text and move 3 space behind, it shows it ^^^ instead of www. Is there anything wrong with my coding?
This is all the code that i have inside my c#
static void Main(string[] args)
{
string UserInput = "";
int shift;
Shift OBSHIFT = new Shift();
Console.WriteLine("Welcome to Ceasar Shift Program:");
Console.WriteLine("********************************");
Console.WriteLine("type a string to encrypt:");
UserInput = Console.ReadLine();
Console.WriteLine("How many chars would you like to shift?: :");
shift = int.Parse(Console.ReadLine());
Console.Write("Your encrypted string is: ");
Console.WriteLine(OBSHIFT.Decrypt(UserInput, -shift));
Console.Read();
}
class Shift
{
public string Decrypt(string cipherString, int shift)
{
string userOutput = "";
char[] a = cipherString.ToCharArray();
for (int i = 0; i < cipherString.Length; i++)
{
char c = a[i];
int temp;
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
{
temp = (int)(a[i] + shift);
if ((c >= 'A' && c <= 'Z' && temp > 'Z') || (c >= 'a' && c <= 'z' && temp > 'z'))
temp = temp + 26;
else
temp = (int)(a[i] + (shift));
}
else
temp = c;
userOutput += (char)temp;
}
return userOutput;
}
}
The problem is with this piece of code which does the actual shifting:
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
{
temp = (int)(a[i] + shift);
if ((c >= 'A' && c <= 'Z' && temp > 'Z') || (c >= 'a' && c <= 'z' && temp > 'z'))
temp = temp + 26;
else
temp = (int)(a[i] + (shift));
}
I would suggest restructuring in a few ways:
Make sure your shift is always positive to start with, so you only need to worry about going "past" the end of a particular set of characters
Use two separate branches, one for a-z and one for A-Z
Use a StringBuilder to build your string instead of repeated string concatenation
So for example:
public string ShiftText(string input, int shift)
{
// This makes sure the shift is *always* in the range 0-25.
shift = ((shift % 26) + 26) % 26;
StringBuilder output = new StringBuilder();
foreach (char c in input)
{
if (c >= 'a' && c <= 'z')
{
// We'll sort this later
}
else if (c >= 'A' && c <= 'Z')
{
// We'll sort this later
}
else
{
output.Append(c);
}
}
return output.ToString();
}
Now the bits inside the "sort this later" are simpler to work with. For the a-z part, for example:
int shifted = c + shift;
if (shifted > 'z')
{
shifted -= 26;
}
output.Append((char) shifted);
... and then the same for A-Z, but testing against 'Z' instead of 'z'. Yes, this is effectively duplicate code - but it's only there twice, and I think it's simpler to have that duplication than extract it out.
I would suggest going with this type of code instead:
public class Shift
{
public string Decrypt(string cipherString, int shift)
{
var alphabet =
Enumerable
.Concat(
Enumerable.Range((int)'a', 26),
Enumerable.Range((int)'A', 26))
.Select(i => (char)i)
.ToArray();
var map =
alphabet
.Zip(
alphabet.Concat(alphabet).Concat(alphabet).Skip(alphabet.Length + shift),
(c0, c1) => new { c0, c1 })
.ToDictionary(x => x.c0, x => x.c1);
return String.Join("", cipherString.Select(x => map.ContainsKey(x) ? map[x] : x));
}
}
The three parts are nicely distinct. (1) the alphabet is built. It can contain any number of characters, so long as there are no repeats. (1) the map is simply a dictionary built by mapping the alphabet to the alphabet shifted by shift characters. (3) returns the input cypherString mapped by the map where the key exists.
This is a complete un compressed IP address 2001:0008:0000:CD30:0000:0000:0000:0101
I need to compress it like this
2001:8:0:CD30::101
But i was only able to compress the zeroes in blocks like this
2001:8:0:CD30:0:0:0:101
using this code
string output = "";
string a = textBox1.Text;
if (a.Length != 39 )
MessageBox.Show("Invalid IP please enter the IPv6 IP in this format 6cd9:a87a:ad46:0005:ad40:0000:5698:8ab8");
else
{
for (int i = 0; i < a.Length; i++)
{
if ((a[i] >= '1' && a[i] <= '9') || (Char.ToLower(a[i]) >= 'a' && Char.ToLower(a[i]) <= 'f') || ((i + 1) % 5 == 0 && a[i] == ':'))
{
output = output + a[i];
}
else if ((a[i]=='0' && a[i-1]==':') || (a[i]=='0' && a[i-1]=='0' && a[i-2]==':') || (a[i]=='0' && a[i-1]=='0' && a[i-2]=='0' && a[i-3]==':'))
{
}
else if (a[i] == '0')
{
output = output + a[i];
}
else
{
MessageBox.Show("Invalid IP please enter the IPv6 IP in this format 6cd9:a87a:ad46:0005:ad40:0000:5698:8ab8");
}
}
textBox2.Text = output;
}
Im using c# but i only need the programming logic about how can whole blocks of zeroes be deleted the problem is there could be more then 1 group of blocks containing all zeros in an ip but only one should be abbreviated.
Was far more tricky than I expected, but here you got the way to do it with regular expressions:
private static string Compress(string ip)
{
var removedExtraZeros = ip.Replace("0000","*");
//2001:0008:*:CD30:*:*:*:0101
var blocks = ip.Split(':');
var regex = new Regex(":0+");
removedExtraZeros = regex.Replace(removedExtraZeros, ":");
//2001:8:*:CD30:*:*:*:101
var regex2 = new Regex(":\\*:\\*(:\\*)+:");
removedExtraZeros = regex2.Replace(removedExtraZeros, "::");
//2001:8:*:CD30::101
return removedExtraZeros.Replace("*", "0");
}
If you would like to achieve the same result without using Regex:
public string Compress(string value)
{
var values = value.Split(",");
var ints = values.Select(i => int.Parse(i, System.Globalization.NumberStyles.HexNumber));
var result = ints.Select(Conversion.Hex);
return string.Join(":", result);
}
Didn't spend time on micro-optimizations (stackalloc, spans, etc.) but this gives an idea. For reference on optimization, you can look at the implementation of the IPAddress.Parse in the .net core. Do mind that result of the IPAddress.Parse will give a different result than the example above:
Compress -> 2001:8:0:CD30:0:0:0:101
IPAddress.Parse -> 2001:8:0:cd30::101
This could be "cleaned" up by moving into some object and other ideas.
Edit:
After chatting with one of my colleagues, I spent some time writing an "optimized" version of this. I haven't spent time cleaning up the code, so maybe one of the future edits will be even cleaner.
public string Compress(string value)
{
Span<char> chars = stackalloc char[value.Length];
const char zero = '0';
const char colon = ':';
int index = 0;
int positionInSegment = 0;
bool startsWithZero;
while (index < _originalValue.Length)
{
startsWithZero = value[index] == zero && positionInSegment == 0;
positionInSegment++;
if (startsWithZero)
{
if (index == value.Length - 1)
{
chars[index] = zero;
break;
}
if (value[index + 1] == colon)
{
chars[index] = zero;
positionInSegment = 0;
index++;
continue;
}
positionInSegment = 0;
index++;
continue;
}
if (value[index] == colon)
{
positionInSegment = 0;
chars[index] = colon;
index++;
continue;
}
chars[index] = value[index];
index++;
}
return chars.ToString();
}
I have also created a public gist for future references:
https://gist.github.com/DeanMilojevic/7b4f1d060ce8cfa191592694b11234d7
I'm having problems with a task. I need to find and alert the user if the number is prime or not.
Here is my code:
int a = Convert.ToInt32(number);
if (a % 2 !=0 )
{
for (int i = 2; i <= a; i++)
{
if (a % i == 0)
{
Console.WriteLine("not prime");
}
else
{
Console.WriteLine("prime");
}
Console.WriteLine();
}
}
else
{
Console.WriteLine("not prime");
}
Console.ReadLine();
Where did I go wrong, and how can I fix it?
Prime numbers is divisible by 1 and themselves you will need to check if number has exactly two divisor starting from one till number then it is prime.
int devisors = 0;
for (int i = 1; i <= a; i++)
if (a % i == 0)
devisors++;
if (devisors == 2)
Console.WriteLine("prime");
else
Console.WriteLine("not prime");
You can skip one iteration as we know all whole numbers are divisible by 1 then you will have exactly on divisor for prime numbers. Since 1 has only one divisor we need to skip it as it is not prime. So condition would be numbers having only one divisor other then 1 and number should not be one as one is not prime number.
int devisors = 0;
for (int i = 2; i <= a; i++)
if (a % i == 0)
devisors++;
if (a != 1 && devisors == 1)
Console.WriteLine("prime");
else
Console.WriteLine("not prime");
You just printed prime or not prime, and continued with the loop, rather than stopping. The %2 check is not really needed. Modified appropriately:
int a = Convert.ToInt32(number);
bool prime = true;
if (i == 1) prime = false;
for (int i = 2; prime && i < a; i++)
if (a % i == 0) prime = false;
if (prime) Console.WriteLine("prime");
else Console.WriteLine("not prime");
Console.ReadLine();
public bool isPrime(int num)
{
for (int i = 2; i < num; i++)
if (num % i == 0)
return false;
return num == 1 ? false : true;
}
Presumably your code is outputting lots of messages, which seem jumbled and meaningless? There are 3 key issues:
You arn't breaking out of your for loop when you've decided it can't be prime
You are assuming it is prime when it might not be, see the comments in the code below.
You are comparing to a itself, and that will always be divisible by a, the <= in the for condition needs to be <
Code:
int a = Convert.ToInt32(number);
if (a % 2 != 0)
{
for (int i = 3 i < a; i += 2) // we can skip all the even numbers (minor optimization)
{
if (a % i == 0)
{
Console.WriteLine("not prime");
goto escape; // we want to break out of this loop
}
// we know it isn't divisible by i or any primes smaller than i, but that doesn't mean it isn't divisible by something else bigger than i, so keep looping
}
// checked ALL numbers, must be Prime
Console.WriteLine("prime");
}
else
{
Console.WriteLine("not prime");
}
escape:
Console.ReadLine();
As other have mentioned, you could only loop to the square root of the a, by per-evaluating the square root and replacing this line:
for (int i = 3 i < a; i += 2)
with this:
float sqrRoot = (Int)Math.Sqrt((float)a);
for (int i = 3 i <= sqrRoot; i += 2)
It is important to per-evaluate it else your program will run much slower, rather than faster, as each iteration will involve a square root operation.
If you don't like goto statements (I love goto statements), post a comment and I'll replace it will a breakout boolean (or see Dukeling's more recent answer).
I've done far too much prime checking.
I did this:
bool isPrime = true;
List<ulong> primes = new List<ulong>();
ulong nCheck, nCounted;
nCounted = 0;
nCheck = 3;
primes.Add(2);
for (; ; )
{
isPrime = true;
foreach (ulong nModulo in primes)
{
if (((nCheck / 2) + 1) <= nModulo)
{ break; }
if (nCheck % nModulo == 0)
{ isPrime = false; }
}
if (isPrime == true)
{
Console.WriteLine("New prime found: " + (nCheck) + ", prime number " + (++nCounted) + ".");
primes.Add(nCheck);
}
nCheck++;
nCheck++;
}
This is not EXACTLY what you are looking for though, so what I'd do is put this in a background worker, but with the list of ulongs as a concurrent list, or something that you can access in 2 threads. Or just lock the list while it's being accessed. If the prime hssn't been worked out yet, wait until it is.
Yet another optimized way is to use Sieve of Eratosthenes algorithm.
From Wikipedia
To find all the prime numbers less than or equal to a given integer n by Eratosthenes' method:
1. Create a list of consecutive integers from 2 to n: (2, 3, 4, ..., n).
2. Initially, let p equal 2, the first prime number.
3. Starting from p, count up in increments of p and mark each of these numbers greater than p itself in the list. These will be multiples of p: 2p, 3p, 4p, etc.; note that some of them may have already been marked.
4. Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this number (which is the next prime), and repeat from step 3.
When the algorithm terminates, all the numbers in the list that are not marked are prime.
C# code
int[] GetPrimes(int number) // input should be greater than 1
{
bool[] arr = new bool[number + 1];
var listPrimes = new List<int>();
for (int i = 2; i <= Math.Sqrt(number); i++)
{
if (!arr[i])
{
int squareI = i * i;
for (int j = squareI; j <= number; j = j + i)
{
arr[j] = true;
}
}
for (int c = 1; c < number + 1; c++)
{
if (arr[c] == false)
{
listPrimes.Add(c);
}
}
}
return listPrimes.ToArray();
}
private static void checkpirme(int x)
{
for (int i = 1; i <= x; i++)
{
if (i == 1 || x == i)
{
continue;
}
else
{
if (x % i == 0)
{
Console.WriteLine(x + " is not prime number");
return;
}
}
}
Console.WriteLine(x + " is prime number");
}
where x is number to check it if prime or not