My initial code is 'A0AA' and I need a code/function in C# that will increment it until it goes to 'Z9ZZ'.
for example.
first code is 'D9ZZ'
the next code should be 'E0AA'
sorry maybe my example is quite confusing.. here's another example.. thanks.
first code is 'D9AZ'
the next code should be 'D9BA'
string start = "A9ZZ";
int add = 1;
string next = String.Concat(start.Reverse().Select((x,i) =>
{
char first = i == 2 ? '0' : 'A';
char last = i == 2 ? '9' : 'Z';
if ((x += (char)add) > last)
{
return first;
}
else
{
add = 0;
return x;
}
})
.Reverse());
This should fix it.
private static IEnumerable<string> Increment(string value)
{
if (value.Length != 4)
throw new ArgumentException();
char[] next = value.ToCharArray();
while (new string(next) != "Z9ZZ")
{
next[3]++;
if (next[3] > 'Z')
{
next[3] = 'A';
next[2]++;
}
if (next[2] > 'Z')
{
next[2] = 'A';
next[1]++;
}
if (next[1] > '9')
{
next[1] = '0';
next[0]++;
}
yield return new string(next);
}
}
Example of calling this code:
IList<string> values = Increment("A0AA").Take(100).ToList();
foreach (var value in values)
{
Console.Write(value + " ");
}
Here's a pretty clean solution that checks every character starting at the end:
public SomeMethod()
{
var next = Increment("A2CZ"); // A2DZ
}
public string Increment(string code)
{
var arr = code.ToCharArray();
for (var i = arr.Length - 1; i >= 0; i--)
{
var c = arr[i];
if (c == 90 || c == 57)
continue;
arr[i]++;
return new string(arr);
}
return code;
}
Related
public static class Inova
{
public static bool IsPangram(string str)
{
int compteur = 26;
for (int i = 0; i <= str.Length; i++)
{
if (('A' <= str[i] && str[i] <= 'Z') || ('a' <= str[i] && str[i] <= 'z'))
{
for (int j = str[i + 1]; j <= str.Length; j++)
{
if (compteur != 0 && str[i] != str[j])
{
compteur = compteur - 1;
}
}
}
if (compteur == 0)
{
return true;
}
else
{
return false;
}
}
}
}
There are multiple things incorrect:
for (int j = str[i + 1]; j <= str.Length; j++)
this does not do what you think, it will convert the next char to an int, you want to loop all letters until end, beginning from the current letter + 1.
The if ... else belong to the end of the method, outside of the loop, otherwise you return false after the first iteration in the for-loop
So you want to know if it's a perfect pangram? First we need to say what a pangram is: a sentence containing every letter of the alphabet. It seems you want to check if it's even a perfect pangram, so every letter should appear exactly once. Here is a method not using any fancy LINQ(which might not be allowed) that supports perfect/imperfect pangrams:
public static class Inova
{
private const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static bool IsPangram(string str, bool mustBePerfect)
{
HashSet<char> remaingLetters = new HashSet<char>(alphabet);
foreach (char c in str)
{
char letter = char.ToUpperInvariant(c);
if (!alphabet.Contains(letter)) continue;
bool repeatingLetter = !remaingLetters.Remove(letter);
if (mustBePerfect && repeatingLetter)
{
return false; // already removed
}
}
return remaingLetters.Count == 0;
}
}
Usage:
bool isPangram = Inova.IsPangram("abcdefghijklmnopqrstuvwxyZZ", false);
Since z appears twice this method returns false for perfect and true for not perfect.
Demo: https://dotnetfiddle.net/gEXuvG
Side-note: i wanted to keep it simple, if you want you can still improve it. You can return true in the loop: if(!mustBePerfect && remaingLetters.Count == 0) return true.
I would check for existence of each letter in the string, so
public static bool IsPangram(string str) {
str = str.ToLower();
for (int i = 0; i < 26; i++) {
char c = Convert.ToChar(i + 97);
if (!str.Contains(c)) {
return false;
}
}
return true;
}
Console.WriteLine(IsPangram("hello world"));
Console.WriteLine(IsPangram("abcdefghi jkl mno pqrstuvwxyz"));
// output:
False
True
I'm working on a program that encodes and decodes letters to numbers. I have the Encoding properly built but the decoding is giving me problems. I'm using int to char conversions with the ASCII table as the key. It doesn't seem like the conversion logic for the decoding is right but I really have no idea how to fix it. This is my first time using this conversion method so I still don't fully understand it.
*edit This is on a windows form app that has three buttons and two text boxes. Encode is one button, and you type in a sentence and it outputs in in numbers for each letter. Decode is another but it does the opposite type in numbers and get words. the third button is clear so thats not important. Sorry I left this out of the initial question.
class LetterCodeLogic
{
public static string Encode(string msg)
{
string result = "";
string m = msg.ToUpper();
char c;
int x;
for(int i = 0; i < m.Length; i++)
{
c = Convert.ToChar(m[i]);
x = c;
if (x == 32)
{
x = 0;
}
else
{
x -= 64;
if (x < 1 || x > 26)
{
x = 99;
}
}
result += x.ToString() + " ";
}
return result;
}
public static string Decode(string msg)
{
string result = "";
string[] nums = msg.Split(',');
char c;
int x;
for (int i = 0; i < msg.Length; i++)
{
x = Convert.ToChar(msg[i]);
c = (char)x;
if (c == 0)
{
c = (char)32;
}
else
{
c -= (char)64;
if (c < 65 || c > 90)
{
c = (char)35;
}
}
result += c.ToString() + " ";
}
return result;
}
}
I find problems like this are far easier when you break them into parts. First, write functions that convert a single character to a number or vice versa.
static public byte Encode(char c)
{
if (c == ' ') return 0;
if (c >= 'A' && c <= 'Z') return (byte)(c - 'A' + 1);
return 99;
}
static public char Decode(byte n)
{
if (n == 0) return ' ';
if (n >= 1 && n <= 27) return (char)(n + 'A' - 1);
return '#';
}
Now the functions you need are very easy to write:
static public string Encode(string stringInput)
{
return string.Join(" ", stringInput.Select(Encode).Select( b => b.ToString() ));
}
static public string Decode(string numericInput)
{
return new string(numericInput.Split(' ').Select( n => byte.Parse(n)).Select(Decode).ToArray());
}
The string has to be split into 4 pairwise different non-empty parts. For example,
"happynewyear" could become ["happy", "new", "ye" and "ar"]
No deletion, change of order of characters is permitted.
This question was part of an online competition, which is now over. I have written the following C# code which works for the test cases which I have run but it failed in 3 test cases after submission. I am not sure what cases I might be missing, can anyone help?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hackerearth___India_Hacks
{
class Program
{
static void Main(string[] args)
{
var line1 = System.Console.ReadLine().Trim();
var N = Int32.Parse(line1);
string[] s = new string[N];
string result = "";
for (var i = 0; i < N; i++)
{
s[i] = System.Console.ReadLine().Trim();
result = result + "\n" + check(s[i]);
}
System.Console.Write(result);
Console.ReadKey();
}
static string check(string s)
{
if (s.Length > 3)
{
string[] s1 = new string[4];
int k = 0;
string c = "";
foreach (char ch in s)
{
c = c + ch.ToString();
// Console.WriteLine("C :" +c);
if (k == 0)
{
s1[k] = c;
c = "";
k = 1;
}
else
for (int i = 0; i < k; i++)
{
int f = 0;
for (int j = 0; j < k; j++)
{
if (s1[j].Equals(c) || c == "")
f=1;
}
if (f == 1)
break;
s1[k] = c;
c = "";
if (k == 3 && s1[k] != null)
return "YES";
k++;
// Console.WriteLine("K :"+s[k]);
}
}
return "NO";
}
else
{
return "NO";
}
}
}
}
This would be an example which would not work with your algorithm: "aababa". The 4 strings should be ["aa", "b", "a","ba"] given your criteria, but your algorithm always assumes that the first character is the first string in the solution. This assumption is false. If "a" is the first string in the example I give, your algorithm would fail because it would make the first 3 strings ["a", "ab", "aba",...] that last one would fail with your algorithm because it has no more characters to add to the array.
A recursive solution makes sense to me... here's some code that I think would work.
EDIT: it does work... here's a dotnetfiddle
public static List<string> FindStrings(string s, int n) {
if (n == 0) {
if (string.IsNullOrEmpty(s)) {
return new List<string>{ };
}
return null; // null means invalid
}
for (var i=s.Length-1; i>=0; i--){
var startOfString = s.Substring(0, i);
var endOfString = s.Substring(i);
var list = FindStrings(startOfString, n-1);
// invalid... gotta continue to next try
if (list == null) continue;
// make sure there are no matches so far
if (list.Contains(endOfString)) continue;
// bingo!
if (list.Count == n-1) {
list.Add(endOfString);
return list;
}
}
return null; // null means invalid
}
One way to tackle this problem is to solve the problem of creating all possible substrings. Then going through all the possibilities and making sure the results are distinct.
private static void Main(string[] args)
{
var N = int.Parse(Console.ReadLine());
for (var i = 0; i < N; i++)
{
Console.WriteLine(IsPairwiseUnquie(Console.ReadLine(), 4) ? "YES" : "NO");
}
}
public static bool IsPairwiseUnquie(string s, int count)
{
return s.AllSubstrings(4).Any(subs => subs.Count == subs.Distinct().Count());
}
public static IEnumerable<List<string>> AllSubstrings(this string str, int count)
{
if(str.Length < count)
throw new ArgumentException("Not enough characters");
if(count <= 0)
throw new ArgumentException("Must be greater than 0", nameof(count));
// Base case of only one substring, just return the original string.
if (count == 1)
{
yield return new List<string> { str };
yield break;
}
// break the string down by making a substring of all possible lengths from the first n
// then recursively call to get the possible substrings for the rest of the string.
for (int i = 1; i <= str.Length - count + 1; i++)
{
foreach (var subsubstrings in str.Substring(i).AllSubstrings(count - 1))
{
subsubstrings.Insert(0, str.Substring(0, i));
yield return subsubstrings;
}
}
}
I was wondering if someone could help. I am trying to change a string in the below format:
goeirjew98rut34ktljre9t30t4j3der
to be outputted as below:
geo_irje_w
98r_ut34_k
tlj_re9t_3
0t4_j3de_r
So insert an underscore after the third and seventh characters and insert a new line after the eighth.
After doing some reading I thought the best way to do this might be via a regular expression such as the example at the below link:
http://msdn.microsoft.com/en-us/library/xwewhkd1(v=vs.110).aspx
However I am not sure how to modify this for my needs. Any help what so ever would be greatly appreciated.
Thanks
It can be easily solved by a regular expression and a Replace, like this:
var s = "goeirjew98rut34ktljre9t30t4j3der";
Regex.Replace(s, #"(\w{3})(\w{4})(\w{1})", "$1_$2_$3\n").Dump();
This is definitely something that is best solved with a quick loop:
string s = "goeirjew98rut34ktljre9t30t4j3der";
var outputs = new List<string>();
for (var i = 0; i < s.Length; i += 8)
{
string sub = s.Substring(i, Math.Min(8, s.Length - i));
if(sub.Length > 3)
sub = sub.Insert(3, "_");
if (sub.Length > 8)
sub = sub.Insert(8, "_");
outputs.Add(sub);
}
I think you can not insert char in string by this rule, but I hope this code be useful for you.
public string Decode(string str)
{
var state = 0;
var c = 0;
var newStr = string.Empty;
foreach (var ch in str)
{
c++;
newStr += ch;
if (state == 0 && c == 3)
{
newStr += "_";
state = 1;
c = 0;
}
if (state == 1 && c == 4)
{
newStr += "_";
state = 2;
c = 0;
}
if (state == 2 && c == 1)
{
newStr += "\r\n";
state = 0;
c = 0;
}
}
return newStr;
}
I would make it so u can change everything on the fly and use stringextentions
class Program
{
static void Main(string[] args)
{
string str = "goeirjew98rut34ktljre9t30t4j3der";
var parts = str.SplitInParts(8); //Split in different parts
foreach (var part in parts)
{
string formattedString = part.MultiInsert("_", 2, 6); //Insert your char on all position u want
Console.WriteLine(formattedString);
}
Console.ReadKey();
}
}
static class StringExtensions
{
public static IEnumerable<String> SplitInParts(this String s, Int32 partLength)
{
if (s == null)
throw new ArgumentNullException("s");
if (partLength <= 0)
throw new ArgumentException("Part length has to be positive.", "partLength");
for (var i = 0; i < s.Length; i += partLength)
yield return s.Substring(i, Math.Min(partLength, s.Length - i));
}
public static string MultiInsert(this string str, string insertChar, params int[] positions)
{
StringBuilder sb = new StringBuilder(str.Length + (positions.Length * insertChar.Length));
var posLookup = new HashSet<int>(positions);
for (int i = 0; i < str.Length; i++)
{
sb.Append(str[i]);
if (posLookup.Contains(i))
sb.Append(insertChar);
}
return sb.ToString();
}
}
I am trying to create a function that will create all permutations of a string in an incremental fashion. I would like to start at:
AAAAA
...
AAAAB
...
ACCCC
...
...
ZZZZZ
I have looked around, and can't seem to find anything of that sort. I tried to create it, but it wasn't incrementally.
Any suggestions?
The "permutation" you are describing is better known as the Cartesian product. If you have an arbitrary number of sequences that you need to form the Cartesian product of, see my answer to this question on the subject:
Generating all Possible Combinations
Normally I wouldn't help these brute force type results... but seeing how many useless result you will get out of the set I figured I'd just toss this in.
var query = from c0 in Enumerable.Range(0, 26)
from c1 in Enumerable.Range(0, 26)
from c2 in Enumerable.Range(0, 26)
from c3 in Enumerable.Range(0, 26)
from c4 in Enumerable.Range(0, 26)
select new string(
new [] {
(char)('A' + c0),
(char)('A' + c1),
(char)('A' + c2),
(char)('A' + c3),
(char)('A' + c4),
}
);
BTW... if you just want the next value you can do something like this...
public static string Increment(string input)
{
var array = input.ToCharArray();
if (array.Any(c => c < 'A' || c > 'Z'))
throw new InvalidOperationException();
for (var i = array.Length-1; i >= 0; i--)
{
array[i] = (char)(array[i] + 1);
if (array[i] > 'Z')
{
array[i] = 'A';
if (i == 0)
return 'A' + new string(array);
}
else
break;
}
return new string(array);
}
A different variant where I had the idea of using modulo arithmetic. Note that I lowered the character to {A,B,C} to test it, since going up to Z for 5 letters is a lot of strings.
public IEnumerable<char[]> AlphaCombinations(int length = 5, char startChar = 'A', char endChar = 'C')
{
int numChars = endChar - startChar + 1;
var s = new String(startChar, length).ToCharArray();
for (int it = 1; it <= Math.Pow(numChars, length); ++it)
{
yield return s;
for (int ix = 0; ix < s.Length; ++ix)
if (ix == 0 || it % Math.Pow(numChars, ix) == 0)
s[s.Length - 1 - ix] = (char)(startChar + (s[s.Length - 1 - ix] - startChar + 1) % numChars);
}
}
...
foreach (var s in AlphaCombinations(5))
{
Console.WriteLine(s);
}
Bashed out quickly - I expect this could be done better:
public static IEnumerable<string> GenerateStrings(int length = 5)
{
var buffer = new char[length];
for (int i = 0; i < length; ++i)
{
buffer[i] = 'A';
}
for(;;)
{
yield return new string(buffer);
int cursor = length;
for(;;)
{
--cursor;
if (cursor < 0)
{
yield break;
}
char c = buffer[cursor];
++c;
if (c <= 'Z')
{
buffer[cursor] = c;
break;
}
else
{
buffer[cursor] = 'A';
}
}
}
}
Here is the LINQPad friendly code and it uses lambda expression.
void Main()
{
var chars = Enumerable.Range(65, 26);
var strings = chars.SelectMany (a =>
{
return chars.SelectMany (b => chars.SelectMany (c =>
{
return chars.SelectMany (d =>
{
return chars.Select (e => {return new string(new char[] {(char)a, (char)b, (char)c, (char)d, (char)e});});
});
}));
});
strings.Dump();
}