I have an array of string elements of various words. I need the characters of each word be split equally into the text component of 3 buttons. For example, the array could hold the elements "maybe", "his", "car". In each game one of these words will be pulled from the array and its characters divided into the 3 buttons. For example, button 1 will have "ma", button 2 will have "yb" and button 3 "e" (for the word maybe). I then hide the text element of one button for the user to drag and drop the correct missing letter(s) into the space. The purpose of the game is to help children learn to spell. Does anyone know how I could go about dividing the characters equally into the 3 buttons?
Here's a function that would split the word into the amount of segments you want. You can then iterate over that list to set each segment to a button.Text.
public List<string> SplitInSegments(string word, int segments)
{
int wordLength = word.Length;
// The remainder tells us how many segments will get an extra letter
int remainder = wordLength % segments;
// The base length of a segment
// This is a floor division, because we're dividing ints.
// So 5 / 3 = 1
int segmentLength = wordLength / segments;
var result = new List<string>();
int startIndex = 0;
for (int i = 0; i < segments; i++)
{
// This segment may get an extra letter, if its index is smaller then the remainder
int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);
string currentSegment = word.Substring(startIndex, currentSegmentLength);
// Set the startindex for the next segment.
startIndex += currentSegmentLength;
result.Add(currentSegment);
}
return result;
}
usage:
// returns ["ma", "yb", "e"]
var segments = SplitInSegments("maybe", 3);
Edit
I like the fact that this is for teaching children. So here comes.
Regarding your question on splitting the string based on specific letter sequences: After you've split the string using regex, you will have an array of strings. Then determine the amount of items in the splitted string and concatenate or split further based on the number of segments:
// sequences to split on first
static readonly string[] splitSequences = {
"el",
"ol",
"bo"
};
static readonly string regexDelimiters = string.Join('|', splitSequences.Select(s => "(" + s + ")"));
// Method to split on sequences
public static List<string> SplitOnSequences(string word)
{
return Regex.Split(word, regexDelimiters).Where(s => !string.IsNullOrEmpty(s)).ToList();
}
public static List<string> SplitInSegments(string word, int segments)
{
int wordLength = word.Length;
// The remainder tells us how many segments will get an extra letter
int remainder = wordLength % segments;
// The base length of a segment
// This is a floor division, because we're dividing ints.
// So 5 / 3 = 1
int segmentLength = wordLength / segments;
var result = new List<string>();
int startIndex = 0;
for (int i = 0; i < segments; i++)
{
// This segment may get an extra letter, if its index is smaller then the remainder
int currentSegmentLength = segmentLength + (i < remainder ? 1 : 0);
string currentSegment = word.Substring(startIndex, currentSegmentLength);
// Set the startindex for the next segment.
startIndex += currentSegmentLength;
result.Add(currentSegment);
}
return result;
}
// Splitword will now always return 3 segments
public static List<string> SplitWord(string word)
{
if (word == null)
{
throw new ArgumentNullException(nameof(word));
}
if (word.Length < 3)
{
throw new ArgumentException("Word must be at least 3 characters long", nameof(word));
}
var splitted = SplitOnSequences(word);
var result = new List<string>();
if (splitted.Count == 1)
{
// If the result is not splitted, just split it evenly.
result = SplitInSegments(word, 3);
}
else if (splitted.Count == 2)
{
// If we've got 2 segments, split the shortest segment again.
if (splitted[1].Length > splitted[0].Length
&& !splitSequences.Contains(splitted[1]))
{
result.Add(splitted[0]);
result.AddRange(SplitInSegments(splitted[1], 2));
}
else
{
result.AddRange(SplitInSegments(splitted[0], 2));
result.Add(splitted[1]);
}
}
else // splitted.Count >= 3
{
// 3 segments is good.
result = splitted;
// More than 3 segments, combine some together.
while (result.Count > 3)
{
// Find the shortest combination of two segments
int shortestComboCount = int.MaxValue;
int shortestComboIndex = 0;
for (int i = 0; i < result.Count - 1; i++)
{
int currentComboCount = result[i].Length + result[i + 1].Length;
if (currentComboCount < shortestComboCount)
{
shortestComboCount = currentComboCount;
shortestComboIndex = i;
}
}
// Combine the shortest segments and replace in the result.
string combo = result[shortestComboIndex] + result[shortestComboIndex + 1];
result.RemoveAt(shortestComboIndex + 1);
result[shortestComboIndex] = combo;
}
}
return result;
}
Now when you call the code:
// always returns three segments.
var splitted = SplitWord(word);
Here is another approach.
First make sure that the word can be divided by the desired segments (add a dummy space if necessary) , then use a Linq statement to get your parts and when adding the result trim away the dummy characters.
public static string[] SplitInSegments(string word, int segments)
{
while(word.Length % segments != 0) { word+=" ";}
var result = new List<string>();
for(int x=0; x < word.Count(); x += word.Length / segments)
result.Add((new string(word.Skip(x).Take(word.Length / segments).ToArray()).Trim()));
return result.ToArray();
}
You can split your string into a list and generate buttons based on your list. The logic for splitting the word into a string list would be something similar to this:
string test = "maybe";
List list = new List();
int i = 0, len = 2;
while(i <= test.Length)
{
int lastIndex = test.Length - 1;
list.Add(test.Substring(i, i + len > lastIndex? (i + len) - test.Length : len));
i += len;
}
HTH
Related
I tried with this code, but it only displays whether a given string is palindrome or not. I want to extract and display all the possible palindrome substrings in the given string.
public static boolean istPalindrom(char[] word){
int i1 = 0;
int i2 = word.length - 1;
while (i2 > i1) {
if (word[i1] != word[i2]) {
return false;
}
++i1;
--i2;
}
return true;
}
Expected output:
232
12321
b12321b
ab12321ba
343
kjjk
Here is an example:
using System;
public class Program
{
private static bool istPalindrom(string word){
int i1 = 0;
int i2 = word.Length - 1;
while (i2 > i1) {
if (word[i1] != word[i2]) {
return false;
}
++i1;
--i2;
}
return true;
}
private static void FindPalindromes(string s)
{
// Assume a palindrome string is at least 2 characters
const int MinLength = 2;
if (s.Length <= MinLength)
{
return;
}
// Test all substrings by removing i first characters
for (int i = 0; i < s.Length - MinLength; i++)
{
string sub = s.Substring(i);
if (istPalindrom(sub))
{
Console.WriteLine($"Found palindrome: {sub}");
}
}
// Test all strings by the last character
FindPalindromes(s.Substring(0, s.Length - 1));
}
public static void Main()
{
FindPalindromes("ab12321bakjjkh3432");
}
}
which uses your istPalindrom method to check (but with string instead of char[]). This tests all possible substrings of the given string. There are probably more efficient ways to do this, taking advantage of a palindrome of length n must contain a palindrom of length n - 2, meaning one could find all palindromes of length 3 and 4, and then try expanding those strings.
Output:
Found palindrome: 343
Found palindrome: kjjk
Found palindrome: ab12321ba
Found palindrome: b12321b
Found palindrome: 12321
Found palindrome: 232
Palindrome initial string
public static string PalindromeString { get; set; } = "ab12321bakjjkh3432";
Actual logic to print palindrome string from given string
for (float index = 0; index < PalindromeString.Length; index += (float).5)
{
// set nearest element radius
// on both left and right side
float palindromeNearestElementRadius = index - (int)index;
// if there is need to compare indexes and if it has desired elements
// and both sides of value matches for Example (212) etc.....
while ((index + palindromeNearestElementRadius) < PalindromeString.Length
&& (index - palindromeNearestElementRadius) >= 0
&& PalindromeString[(int)(index - palindromeNearestElementRadius)]
== PalindromeString[(int)(index + palindromeNearestElementRadius)])
{
var element = PalindromeString.Substring((int)(index - palindromeNearestElementRadius),
(int)(index + palindromeNearestElementRadius + 1) -
(int)(index - palindromeNearestElementRadius));
if (element.Length != 1)
{
Console.WriteLine(element);
}
// increasing the element radius by 1
// to point towards the
// next elements for both sides to move forward our comparision
//
palindromeNearestElementRadius++;
}
Output
232
12321
b12321b
ab12321ba
jj
kjjk
343
I got asked a question and now I am kicking myself for not being able to come up with the exact/correct result.
Imagine we have a function that splits a string into multiple lines but each line has to have x number of characters before we "split" to the new line:
private string[] GetPagedMessages(string input, int maxCharsPerLine) { ... }
For each line, we need to incorporate, at the end of the line "x/y" which is basically 1/4, 2/4 etc...
Now, the paging mechanism must also be part of the length restriction per line.
I have been overworked and overthinking and tripping up on things and this seems pretty straight forward but for the life of me, I cannot figure it out! What am I not "getting"?
What am I interested in? The calculation and some part of the logic but mainly the calculation of how many lines are required to split the input based on the max chars per line which also needs to include the x/y.
Remember: we can have more than a single digit for the x/y (i.e: not just 1/4 but also 10/17 or 99/200)
Samples:
input = "This is a long message"
maxCharsPerLine = 10
output:
This i 1/4 // << Max 10 chars
s a lo 2/4 // << Max 10 chars
ng mes 3/4 // << Max 10 chars
sage 4/4 // << Max 10 chars
Overall the logic is simple but its just the calculation that is throwing me off.
The idea: First, find how many digits is the number of lines:
(n = input.Length, maxCharsPerLine = 10)
if n <= 9*(10-4) ==> 1 digit
if n <= 9*(10-5) + 90*(10-6) ==> 2 digits
if n <= 9*(10-6) + 90*(10-7) + 900*(10-8) ==> 3 digits
if n <= 9*(10-7) + 90*(10-8) + 900*(10-9) + 9000*(10-10) ==> No solution
Then, subtract the spare number of lines. The solution:
private static int GetNumberOfLines(string input, int maxCharsPerLine)
{
int n = input.Length;
int x = maxCharsPerLine;
for (int i = 4; i < x; i++)
{
int j, sum = 0, d = 9, numberOfLines = 0;
for (j = i; j <= i + i - 4; j++)
{
if (x - j <= 0)
return -1; // No solution
sum += d * (x - j);
numberOfLines += d;
d *= 10;
}
if (n <= sum)
return numberOfLines - (sum - n) / (x - j + 1);
}
return -2; // Invalid
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
int numberOfLines = GetNumberOfLines(input, maxCharsPerLine);
if (numberOfLines < 0)
return null;
string[] result = new string[numberOfLines];
int spaceLeftForLine = maxCharsPerLine - numberOfLines.ToString().Length - 2; // Remove the chars of " x/y" except the incremental 'x'
int inputPosition = 0;
for (int line = 1; line < numberOfLines; line++)
{
int charsInLine = spaceLeftForLine - line.ToString().Length;
result[line - 1] = input.Substring(inputPosition, charsInLine) + $" {line}/{numberOfLines}";
inputPosition += charsInLine;
}
result[numberOfLines-1] = input.Substring(inputPosition) + $" {numberOfLines}/{numberOfLines}";
return result;
}
A naive approach is to start counting the line lengths minus the "pager"'s size, until the line count changes in size ("1/9" is shorter than "1/10", which is shorter than "11/20", and so on):
private static int[] GetLineLengths(string input, int maxCharsPerLine)
{
/* The "pager" (x/y) is at least 4 characters (including the preceding space) and at most ... 8?
* 7/9 (4)
* 1/10 (5)
* 42/69 (6)
* 3/123 (6)
* 42/420 (7)
* 999/999 (8)
*/
int charsRemaining = input.Length;
var lineLengths = new List<int>();
// Start with " 1/2", (1 + 1 + 2) = 4 length
var highestLineNumberLength = 1;
var lineNumber = 0;
do
{
lineNumber++;
var currentLineNumberLength = lineNumber.ToString().Length; // 1 = 1, 99 = 2, ...
if (currentLineNumberLength > highestLineNumberLength)
{
// Pager size changed, reset
highestLineNumberLength = currentLineNumberLength;
lineLengths.Clear();
lineNumber = 0;
charsRemaining = input.Length;
continue;
}
var pagerSize = currentLineNumberLength + highestLineNumberLength + 2;
var lineLength = maxCharsPerLine - pagerSize;
if (lineLength <= 0)
{
throw new ArgumentException($"Can't split input of size {input.Length} into chunks of size {maxCharsPerLine}");
}
lineLengths.Add(lineLength);
charsRemaining -= lineLength;
}
while (charsRemaining > 0);
return lineLengths.ToArray();
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
if (input.Length <= maxCharsPerLine)
{
// Assumption: no pager required for a message that takes one line
return new[] { input };
}
var lineLengths = GetLineLengths(input, maxCharsPerLine);
var result = new string[lineLengths.Length];
// Cut the input and append the pager
var previousIndex = 0;
for (var i = 0; i < lineLengths.Length; i++)
{
var lineLength = Math.Min(lineLengths[i], input.Length - previousIndex); // To cater for final line being shorter
result[i] = input.Substring(previousIndex, lineLength) + " " + (i + 1) + "/" + lineLengths.Length;
previousIndex += lineLength;
}
return result;
}
Prints, for example:
This 1/20
is a 2/20
long 3/20
strin 4/20
g tha 5/20
t wil 6/20
l spa 7/20
n mor 8/20
e tha 9/20
n te 10/20
n li 11/20
nes 12/20
beca 13/20
use 14/20
of i 15/20
ts e 16/20
norm 17/20
ous 18/20
leng 19/20
th 20/20
I should divide the elements into several small substrings with equal length. The count of the substrings should be equal to the given partitions. If the string cannot be exactly divided into the given partitions, I must make all partitions except the last with equal lengths, and make the last one – the longest.
I've tried to make the first part, but it's not working in all cases. Can you show me a way but if it's possible with for-loops, etc.?
For example:
{abcd}, 3 partitions -> {a, b, cd}; {qrstuvwxyz}, 5 partitions -> {qr st uv wx yz}
private static List<string> Divide(List<string> input, int index, int partitions)
{
string stringToDivide = input[index];
input.RemoveAt(index);
string add = "";
if (stringToDivide.Length % partitions == 0)
{
for (int i = 0; i < stringToDivide.Length; i++)
{
add += stringToDivide[i] + " ";
}
input.Insert(index, add.Trim());
}
else
{
}
return input;
Console.WriteLine(string.Join(' ', input));
}
You can do something like this:
private static List<string> Divide(List<string> input, int index, int partitions)
{
var stringToDivide = input[index];
input.RemoveAt(index);
var stringToAdd = "";
var partitionLength = stringToDivide.Length / partitions;
for (int i = 0, partitionNum = 0; i < stringToDivide.Length; i++)
{
if (i % partitionLength == 0 && partitionNum != partitions) // skip space in last part
{
if (i > 0) // do not add leading space
{
stringToAdd += " ";
}
partitionNum++;
}
stringToAdd += stringToDivide[i];
}
input.Insert(index, stringToAdd);
return input;
}
This code adds spaces each partitionLength, but skips space for last string. Note that for long strings it's better to use StringBuilder.
stringToDivide.Length % partitions is the number of characters left over after dividing into partitions number of partitions.
stringToDivide.Length / partitions is the number of characters that should be in each partition except the last, which should have the left-over characters appended to it.
So just take the first partitions number of stringToDivide.Length / partitions length chunks, and append what's left over to the last chunk.
When the string is evenly divisible, stringToDivide.Length % partitions is zero, so it's not a special case.
public static List<string> DivideIntoPartitions(string stringToDivide, int partitions)
{
var parts = new List<string>(partitions);
var len = stringToDivide.Length;
if (len < partitions)
{
throw new ArgumentException("partitions should be less than length");
}
if (len % partitions == 0)
{
var eachSubstrLength = len / partitions;
for (int i = 0; i < stringToDivide.Length; i += eachSubstrLength)
{
parts.Add(stringToDivide.Substring(i, eachSubstrLength));
}
}
else
{
var nextDivisibleNumber = len + (partitions - (len % partitions));
var lengthOfLastSubstr = nextDivisibleNumber / partitions;
var lastItem = stringToDivide.Substring((len - lengthOfLastSubstr));
stringToDivide = stringToDivide.Remove((len - lengthOfLastSubstr));
var chunksize = stringToDivide.Length / (partitions - 1);
for (int i = 0; i < stringToDivide.Length; i += chunksize)
{
parts.Add(stringToDivide.Substring(i, chunksize));
}
parts.Add(lastItem);
}
return parts;
}
var result = DivideIntoPartitions("qrstuvwxyz", 3);
My task is to add a very big number to another and print the result.
Here is my implementation, it should give 1000 as output but it writes 0000.
How it should work:
if the two number has equal length:
just /10 for the digit %10 for the remainder. If the length of the result is bigger than the original add the last remainder to the last element of the output array.
if the two number has different length:
sum the intersection part and add the remainder (in temp) to the relative complementl.
What is wrong?
static int[] SumOfBigNumbers(int[] firstNumber, int[] secondNumber)
{
int temp = 0;
int maxLength = (Math.Max(firstNumber.Length, secondNumber.Length));
int minLength = (Math.Min(firstNumber.Length, secondNumber.Length));
int[] output = new int[maxLength + 1];
//sum of equal part
for (int counter = 0; counter < minLength; counter++)
{
output[counter] = (firstNumber[counter] + secondNumber[counter] + temp) % 10;
temp = (firstNumber[counter] + secondNumber[counter] + temp) / 10;
}
//exceptions add the temp to the bigger array
if (temp!=0)
{
//if first array is bigger than the second
if (firstNumber.Length > secondNumber.Length)
{
for (int i = minLength; i < maxLength + 1; i++)
{
output[i] = (firstNumber[i] + temp) % 10;
temp = (firstNumber[i] + temp) / 10;
}
}
//if second array is bigger than the first
else if (firstNumber.Length < secondNumber.Length)
{
for (int i = minLength; i < maxLength + 1; i++)
{
output[i] = (secondNumber[i] + temp) % 10;
temp = (secondNumber[i] + temp) / 10;
}
}
//if two number has equal length but there is temp left
else
{
output[maxLength] = temp;
}
}
return output;
}
static void Main()
{
int[] firstArray = new int[3] { 0, 0, 5 };
int[] secondArray = new int[3] { 0, 0,5 };
int[] output = SumOfBigNumbers(firstArray, secondArray);
foreach (var i in output)
{
Console.WriteLine(output[i]);
}
}
Edit: better if I copy the task: Write a method that calculates the sum of two very long positive integer numbers. The numbers are represented as array digits and the last digit (the ones) is stored in the array at index 0. Make the method work for all numbers with length up to 10,000 digits.
While BigInteger is a better way to handle big numbers, I think your bug is in while printing the output. try this:
foreach (var i in output)
{
Console.WriteLine(i);
}
also this will print 0001, better reverse it while printing
Your code works fine but you have a small bug where you display the output array.
You do a foreach (var i in output) {, but you use the i as an index, which it isn't. It is already the actual value. Just write the i to the console.
foreach (var i in output)
{
Console.WriteLine(i);
}
// Output:
// 0
// 0
// 0
// 1
Or use a for loop to go through the array by index.
for (int i = 0; i < output.Length; i++)
{
Console.WriteLine(output[i]);
}
// Output:
// 0
// 0
// 0
// 1
For a string that may have zero or more hyphens in it, I need to extract all the different possibilities with and without hyphens.
For example, the string "A-B" would result in "A-B" and "AB" (two possibilities).
The string "A-B-C" would result in "A-B-C", "AB-C", "A-BC" and "ABC" (four possibilities).
The string "A-B-C-D" would result in "A-B-C-D", "AB-C-D", "A-BC-D", "A-B-CD", "AB-CD", "ABC-D", "A-BCD" and "ABCD" (eight possibilities).
...etc, etc.
I've experimented with some nested loops but haven't been able to get anywhere near the desired result. I suspect I need something recursive unless there is some simple solution I am overlooking.
NB. This is to build a SQL query (shame that SQL Server does't have MySQL's REGEXP pattern matching).
Here is one attempt I was working on. This might work if I do this recursively.
string keyword = "A-B-C-D";
List<int> hyphens = new List<int>();
int pos = keyword.IndexOf('-');
while (pos != -1)
{
hyphens.Add(pos);
pos = keyword.IndexOf('-', pos + 1);
}
for (int i = 0; i < hyphens.Count(); i++)
{
string result = keyword.Substring(0, hyphens[i]) + keyword.Substring(hyphens[i] + 1);
Response.Write("<p>" + result);
}
A B C D are words of varying length.
Take a look at your sample cases. Have you noticed a pattern?
With 1 hyphen there are 2 possibilities.
With 2 hyphens there are 4 possibilities.
With 3 hyphens there are 8 possibilities.
The number of possibilities is 2n.
This is literally exponential growth, so if there are too many hyphens in the string, it will quickly become infeasible to print them all. (With just 30 hyphens there are over a billion combinations!)
That said, for smaller numbers of hyphens it might be interesting to generate a list. To do this, you can think of each hyphen as a bit in a binary number. If the bit is 1, the hyphen is present, otherwise it is not. So this suggests a fairly straightforward solution:
Split the original string on the hyphens
Let n = the number of hyphens
Count from 2n - 1 down to 0. Treat this counter as a bitmask.
For each count begin building a string starting with the first part.
Concatenate each of the remaining parts to the string in order, preceded by a hyphen only if the corresponding bit in the bitmask is set.
Add the resulting string to the output and continue until the counter is exhausted.
Translated to code we have:
public static IEnumerable<string> EnumerateHyphenatedStrings(string s)
{
string[] parts = s.Split('-');
int n = parts.Length - 1;
if (n > 30) throw new Exception("too many hyphens");
for (int m = (1 << n) - 1; m >= 0; m--)
{
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i <= n; i++)
{
if ((m & (1 << (i - 1))) > 0) sb.Append('-');
sb.Append(parts[i]);
}
yield return sb.ToString();
}
}
Fiddle: https://dotnetfiddle.net/ne3N8f
You should be able to track each hyphen position, and basically say its either there or not there. Loop through all the combinations, and you got all your strings. I found the easiest way to track it was using a binary, since its easy to add those with Convert.ToInt32
I came up with this:
string keyword = "A-B-C-D";
string[] keywordSplit = keyword.Split('-');
int combinations = Convert.ToInt32(Math.Pow(2.0, keywordSplit.Length - 1.0));
List<string> results = new List<string>();
for (int j = 0; j < combinations; j++)
{
string result = "";
string hyphenAdded = Convert.ToString(j, 2).PadLeft(keywordSplit.Length - 1, '0');
// Generate string
for (int i = 0; i < keywordSplit.Length; i++)
{
result += keywordSplit[i] +
((i < keywordSplit.Length - 1) && (hyphenAdded[i].Equals('1')) ? "-" : "");
}
results.Add(result);
}
This works for me:
Func<IEnumerable<string>, IEnumerable<string>> expand = null;
expand = xs =>
{
if (xs != null && xs.Any())
{
var head = xs.First();
if (xs.Skip(1).Any())
{
return expand(xs.Skip(1)).SelectMany(tail => new []
{
head + tail,
head + "-" + tail
});
}
else
{
return new [] { head };
}
}
else
{
return Enumerable.Empty<string>();
}
};
var keyword = "A-B-C-D";
var parts = keyword.Split('-');
var results = expand(parts);
I get:
ABCD
A-BCD
AB-CD
A-B-CD
ABC-D
A-BC-D
AB-C-D
A-B-C-D
I've tested this code and it is working as specified in the question. I stored the strings in a List<string>.
string str = "AB-C-D-EF-G-HI";
string[] splitted = str.Split('-');
List<string> finalList = new List<string>();
string temp = "";
for (int i = 0; i < splitted.Length; i++)
{
temp += splitted[i];
}
finalList.Add(temp);
temp = "";
for (int diff = 0; diff < splitted.Length-1; diff++)
{
for (int start = 1, limit = start + diff; limit < splitted.Length; start++, limit++)
{
int i = 0;
while (i < start)
{
temp += splitted[i++];
}
while (i <= limit)
{
temp += "-";
temp += splitted[i++];
}
while (i < splitted.Length)
{
temp += splitted[i++];
}
finalList.Add(temp);
temp = "";
}
}
I'm not sure your question is entirely well defined (i.e. could you have something like A-BCD-EF-G-H?). For "fully" hyphenated strings (A-B-C-D-...-Z), something like this should do:
string toParse = "A-B-C-D";
char[] toParseChars = toPase.toCharArray();
string result = "";
string binary;
for(int i = 0; i < (int)Math.pow(2, toParse.Length/2); i++) { // Number of subsets of an n-elt set is 2^n
binary = Convert.ToString(i, 2);
while (binary.Length < toParse.Length/2) {
binary = "0" + binary;
}
char[] binChars = binary.ToCharArray();
for (int k = 0; k < binChars.Length; k++) {
result += toParseChars[k*2].ToString();
if (binChars[k] == '1') {
result += "-";
}
}
result += toParseChars[toParseChars.Length-1];
Console.WriteLine(result);
}
The idea here is that we want to create a binary word for each possible hyphen. So, if we have A-B-C-D (three hyphens), we create binary words 000, 001, 010, 011, 100, 101, 110, and 111. Note that if we have n hyphens, we need 2^n binary words.
Then each word maps to the output you desire by inserting the hyphen where we have a '1' in our word (000 -> ABCD, 001 -> ABC-D, 010 -> AB-CD, etc). I didn't test the code above, but this is at least one way to solve the problem for fully hyphenated words.
Disclaimer: I didn't actually test the code