Find all combinations in a string separated - c#

I'm trying to get all combinations in a string in c# with that idea in mind:
Given a string like foo I want to get a List<string> with the values:
f o o
fo o
foo
f oo
As you can see it's not as easy as get all the substring but get ALL the chars in a string separated by spaces.
I've tried doing something like:
List<string> result = new List<string>();
string text = "foo";
for (int i = 1; i < foo.Lenght; i++)
{
//I'm stucked --> everything I think is too stupid and I don't know how to procede or not fast enough. I'm really stuck.
}
EDIT:
There are some correct answers but it's clear that any of them won't do since the strings I am working with have between 55 and 85 chars each one so that means that the best function in the answers will give me something between 2^54 and 2^84 possible combinations and that is just a bit too much.
It is clear now that find all the combinations and afterwards do something with them won't do. I'll have to drop it.

First things first: if the string length is n, you get 2^n strings as output.
So, if you want to treat strings of length 70, you have a problem.
You can use a counter, enumerating from 0 to 2^n, and treat it as a bitwise mask: if the first bit is 1, you put a space between the first and the second char, if it's zero, you don't.
So, an unsigned long of length 64 is barely enough to treat strings of length 65.
An example implementation, without recursion (it's slightly more verbose than the other examples), but should be a lot faster than the other implementations for long inputs:
public IEnumerable<string> GetPartitionedStrings(string s)
{
if (s == null) yield break;
if (s == "")
{
yield return "";
yield break;
}
if (s.Length > 63) throw new ArgumentOutOfRangeException("String too long...");
var arr = s.ToCharArray();
for(ulong i = 0, maxI = 1UL << (s.Length - 1); i < maxI; i++)
{
yield return PutSpaces(arr, i);
}
}
public string PutSpaces(char[] arr, ulong spacesPositions)
{
var sb = new StringBuilder(arr.Length * 2);
sb.Append(arr[0]);
ulong l = 1;
for (int i = 1; i < arr.Length; i++, l <<= 1)
{
if ((spacesPositions & l) != 0UL) sb.Append(" ");
sb.Append(arr[i]);
}
return sb.ToString();
}
Probably you could get away with a bit field, but we are already in the billions of strings, so I would try to reformulate a bit the problem.

Here is one more recursive solution to consider:
private static IEnumerable<string> Permute(string target) {
if (target.Length <= 1) {
yield return target;
yield break;
}
var c = target[0];
foreach (var rest in Permute(target.Remove(0, 1))) {
yield return c + rest;
yield return c + " " + rest;
}
}
For your test string produces desired result. Basically we combine first char + either space or no space + the rest of the string (without first char) recursively.
To get a list, just do Permute("foo").ToList();
For "abcde" string the result is:
abcde
a bcde
ab cde
a b cde
abc de
a bc de
ab c de
a b c de
abcd e
a bcd e
ab cd e
a b cd e
abc d e
a bc d e
ab c d e
a b c d e

A number of answers have suggested recursive solutions, which is fine. But here's a sketch of a non-recursive solution.
Suppose your word has x letters where x is less than 64.
Compute long n = 2(x - 1)
Make a loop where i goes from 0 to n - 1
Decompose i into the (x-1) low bits.
Output the first letter.
If the first bit is set, output a space, otherwise no space.
Output the second letter.
If the second bit is set, output a space, otherwise no space.
And so on.
Can you implement the method given that sketch?

You can do it using recursion, starting with an empty string, you call recursively adding an space and without add it, and adding current character:
static IEnumerable<string> SplitString(string s, int max)
{
return SplitString(s, 0, max, max);
}
private static IEnumerable<string> SplitString(string s, int idx, int available, int maxLength)
{
if (idx == s.Length) yield return string.Empty;
else
{
if (available > 0)
foreach (var item in SplitString(s, idx + 1, available - 1, maxLength))
yield return s[idx] + item;
if (idx > 0)
foreach (var item in SplitString(s, idx + 1, maxLength - 1, maxLength))
yield return " " + s[idx] + item;
}
}
For an input like abcde, SplitString("abcde", 3) get this output:
abc de
abc d e
ab cde
ab cd e
ab c de
ab c d e
a bcd e
a bc de
a bc d e
a b cde
a b cd e
a b c de
a b c d e

You could try something recursive. You start with a string, hello.
For each character that's not a space, if it's not followed by a space, add one at that location in the string and run the function on that string. On the first iteration, you have:
h ello
he llo
hel lo
hell o
hello
Repeat until all characters are followed by spaces. This will create duplicates though.

What you could do is convert the string into a char array like this:
char characters[] = text.toCharArray()
Then in your for loop iterate through this array
for (int i = 1; i < foo.Lenght; i++)
{
System.out.println(characters[i]);
}

Related

What takes too long on this code?

Trying to solve another SO question, I came up with the following algorithm which I thought is quite optmized. However while running DotNetBenchmark on all solutions, I was very surprised that my code was running on a whopping average of 387 ms compared to the ~ 20-30 ms some of the other answers acheived.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
int CalcMe(string input) // I used Marc Gravel's input generation method
{
var operands = input.Split(' ');
var j = 1; // operators index
var result = int.Parse(operands[0]); // output
// i = numbers index
for (int i = 2; i < operands.Length; i += 2)
{
switch (operands[j])
{
case "+":
result += int.Parse(operands[i]);
break;
case "-":
result -= int.Parse(operands[i]);
break;
case "*":
result *= int.Parse(operands[i]);
break;
case "/":
try
{
result /= int.Parse(operands[i]);
break;
}
catch
{
break; // division by 0.
}
default:
throw new Exception("Unknown Operator");
}
j += 2; // next operator
}
return result;
}
Just by extracting the String.Split() to the caller Main() method, I lowered the execution to 110 ms, but that still does not solve the mystery since all other answers handle the input directly.
I am just trying to understand to perhaps change my way of thinking toward optimizations. I couldn't see any keywords that I only use. switch, for and int.Parse() are pretty much on every other solution.
EDIT 1: Test input generation
The input generation is copied form Marc answer on the original quetsion as below:
static string GenerateInput()
{
Random rand = new Random(12345);
StringBuilder input = new StringBuilder();
string operators = "+-*/";
var lastOperator = '+';
for (int i = 0; i < 1000000; i++)
{
var #operator = operators[rand.Next(0, 4)];
input.Append(rand.Next(lastOperator == '/' ? 1 : 0, 100) + " " + #operator + " ");
lastOperator = #operator;
}
input.Append(rand.Next(0, 100));
return input.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Won't achieve almost anything here. Inlining is used when you want to tell to compiler to just copy and paste your code on multiple places to avoid unnecessary method invocations. And it's pretty damn smart to know when to do it on it's own in most of occasions.
var operands = input.Split(' ');
Causes the JIT to go through the whole string, do a search, split a string and fill the array, which can take a long time.
switch (operands[j])
Switching on strings can also have an impact since it has to call equals on cases. You'd want to use simple types in switch if you're looking at performance(char for example).
int.Parse
This actually does a bunch of allocations and even deals with unsafe code. You can see the code for parsing here:
https://referencesource.microsoft.com/#mscorlib/system/number.cs,698
Or if the link goes down:
[System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int32 i = 0;
StringToNumber(s, style, ref number, info, false);
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToInt32(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}
}
else {
if (!NumberToInt32(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}
}
return i;
}
[System.Security.SecuritySafeCritical] // auto-generated
private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal) {
if (str == null) {
throw new ArgumentNullException("String");
}
Contract.EndContractBlock();
Contract.Assert(info != null, "");
fixed (char* stringPointer = str) {
char * p = stringPointer;
if (!ParseNumber(ref p, options, ref number, null, info , parseDecimal)
|| (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) {
throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
}
}
}
I think comparing of strings much more complicated than comparing of chars
Below the key difference
switch (operands[j])
{
case "+":
...
switch (cOperator)
{
case '+':
...
Interesting problem! I was interested in implementing this for myself, and checking what I can come up with, as well as how it compares to other implementations. I did it in F# but since both F# and C# are strongly-typed CLR languages, and the insights gained below are (arguably) independent of C#, I hope you'll agree that the following is not quite off-topic.
First I needed a few functions for creating a suitable expression string (adapted from your posting), measuring time, and running a bunch of functions with the generated string:
module Testbed =
let private mkTestCase (n : int) =
let next (r : System.Random) i = r.Next (0, i)
let r = System.Random ()
let s = System.Text.StringBuilder n
let ops = "+-*/"
(s.Append (next r 100), {1 .. n})
||> Seq.fold (fun s _ ->
let nx = next r 100
let op = ops.[next r (if nx = 0 then 3 else 4)]
s.Append (" " + string op + " " + string nx))
|> string
let private stopwatch n f =
let mutable r = Unchecked.defaultof<_>
let sw = System.Diagnostics.Stopwatch ()
sw.Start ()
for i = 1 to n do r <- f ()
sw.Stop ()
(r, sw.ElapsedMilliseconds / int64 n)
let runtests tests =
let s, t = stopwatch 100 (fun () -> mkTestCase 1000000)
stdout.Write ("MKTESTCASE\nTime: {0}ms\n", t)
tests |> List.iter (fun (name : string, f) ->
let r, t = stopwatch 100 (fun () -> f s)
let w = "{0} ({1} chars)\nResult: {2}\nTime: {3}ms\n"
stdout.Write (w, name, s.Length, r, t))
For a string of 1 million operations (around 4.9 million chars), the mkTestCase function ran in 317ms on my laptop.
Next I translated your function to F#:
module MethodsToTest =
let calc_MBD1 (s : string) =
let inline runop f a b =
match f with
| "+" -> a + b
| "-" -> a - b
| "*" -> a * b
| "/" -> a / b
| _ -> failwith "illegal op"
let rec loop (ops : string []) r i j =
if i >= ops.Length then r else
let n = int ops.[i]
loop ops (runop ops.[j] r n) (i + 2) (j + 2)
let ops = s.Split ' '
loop ops (int ops.[0]) 2 1
This ran in 488ms on my laptop.
Next I wanted to check if string matching is really that much slower than character matching:
let calc_MBD2 (s : string) =
let inline runop f a b =
match f with
| '+' -> a + b
| '-' -> a - b
| '*' -> a * b
| '/' -> a / b
| _ -> failwith "illegal op"
let rec loop (ops : string []) r i j =
if i >= ops.Length then r else
let n = int ops.[i]
loop ops (runop ops.[j].[0] r n) (i + 2) (j + 2)
let ops = s.Split ' '
loop ops (int ops.[0]) 2 1
Common wisdom would say that character matching should be significantly faster, given that it involves only a primitive comparison instead of calculating a hash, but the above ran in 482ms on my laptop, so the difference between primitive character comparison, and comparing hashes of strings of length 1 is almost negligible.
Lastly I checked whether hand-rolling the number parsing would provide a significant saving:
let calc_MBD3 (s : string) =
let inline getnum (c : char) = int c - 48
let parse (s : string) =
let rec ploop r i =
if i >= s.Length then r else
let c = s.[i]
let n = if c >= '0' && c <= '9'
then 10 * r + getnum c else r
ploop n (i + 1)
ploop 0 0
let inline runop f a b =
match f with
| '+' -> a + b
| '-' -> a - b
| '*' -> a * b
| '/' -> a / b
| _ -> failwith "illegal op"
let rec loop (ops : string []) r i j =
if i >= ops.Length then r else
let n = parse ops.[i]
loop ops (runop ops.[j].[0] r n) (i + 2) (j + 2)
let ops = s.Split ' '
loop ops (parse ops.[0]) 2 1
This ran in 361ms on my laptop, so the saving is significant but the function is still an order of magnitude slower than my own creation (see below), leading to the conclusion that the initial string splitting takes the bulk of the time.
Just for comparison, I also translated the OP's function from the posting you referenced to F#:
let calc_OP (s : string) =
let operate r op x =
match op with
| '+' -> r + x
| '-' -> r - x
| '*' -> r * x
| '/' -> r / x
| _ -> failwith "illegal op"
let rec loop c n r =
if n = -1 then
operate r s.[c + 1] (int (s.Substring (c + 3)))
else
operate r s.[c + 1] (int (s.Substring (c + 3, n - (c + 2))))
|> loop n (s.IndexOf (' ', n + 4))
let c = s.IndexOf ' '
loop c (s.IndexOf (' ', c + 4)) (int (s.Substring (0, c)))
This ran in 238ms on my laptop, so using substrings is not as slow as splitting the string but still it is far from optimal.
Finally my own implementation of an expression interpreter, taking into account that the fastest way of processing is doing it manually character by character, iterating the string only once, and that heap allocation (by way of creating new objects, such as strings or arrays) should be avoided inside the loop as much as possible:
let calc_Dumetrulo (s : string) =
let inline getnum (c : char) = int c - 48
let inline isnum c = c >= '0' && c <= '9'
let inline isop c =
c = '+' || c = '-' || c = '*' || c = '/'
let inline runop f a b =
match f with
| '+' -> a + b
| '-' -> a - b
| '*' -> a * b
| '/' -> a / b
| _ -> failwith "illegal op"
let rec parse i f a c =
if i >= s.Length then
if c = -1 then a else runop f a c
else
let k, j = s.[i], i + 1
if isnum k then
let n = if c = -1 then 0 else c
parse j f a (10 * n + getnum k)
elif isop k then parse j k a c
elif c = -1 then parse j f a c
else parse j f (runop f a c) -1
parse 0 '+' 0 -1
This ran in a satisfactory 28ms on my laptop. You can express this the same way in C#, except for the tail-recursion, which should be expressed by a for or while loop:
static int RunOp(char op, int a, int b)
{
switch (op)
{
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
default: throw new InvalidArgumentException("op");
}
}
static int Calc_Dumetrulo(string s)
{
int a = 0, c = -1;
char op = '+';
for (int i = 0; i < s.Length; i++)
{
char k = s[i];
if (k >= '0' && k <= '9')
c = (c == -1 ? 0 : 10 * c) + ((int)k - 48);
else if (k == '+' || k == '-' || k == '*' || k == '/')
op = k;
else if (c == -1) continue;
else
{
a = RunOp(op, a, c);
c = -1;
}
}
if (c != -1) a = RunOp(op, a, c);
return a;
}

Generate range between two strings [AA] -> [CD] or [CCC] -> [DMK]

I want to generate a sequence of strings between two groups that can be either 1 letter [A] -> [F] , 2 letters such as [AA] -> [CD] or any other length like 3 or 4 letters using c#.
For example I can specify the start and end values, and it will generate the sequence.
From [AA] to [CD] should generate
AA
AB
AC
AD
BA
BB
BC
BD
CA
CB
CC
CD
I tried to utilize base-26 algorithm to generate the required sequence but failed to get the required output.
string from ="AA";
string to = "CD";
IEnumerable<string> mysequence = Enumerable.Range(ConvertNumber(from), ConvertNumber(to) - ConvertNumber(from)).Select(ConvertAlpha).ToList();
public static string ConvertAlpha(int value)
{
const int a = (int)'A';
value = value - 1;
var returnValue = new StringBuilder();
while (value > -1)
{
var remainder = value % 26;
returnValue.Insert(0, (char)(a + remainder));
value = value / 26 - 1;
}
return returnValue.ToString();
}
public static int ConvertNumber(string value)
{
const int a = (int)'A' - 1;
int returnValue = 0;
foreach (var character in value.ToUpper())
{
returnValue *= 26;
returnValue += (int)character - a;
}
return returnValue;
}
Using recursion (but with brute-force rather than elegance):
static void Main(string[] args)
{
string fromStr = "AAA";
string toStr = "CDE";
List<string> outputList = new List<string>();
BuildSequence(fromStr, toStr, outputList);
outputList.ForEach(s => { Console.WriteLine(s); });
Console.ReadLine();
}
private static void BuildSequence(
string fromStr,
string toStr,
List<string> outputList,
int index = 0,
string prev = "")
{
IEnumerable<string> newStrList = Enumerable
.Range(fromStr[index], toStr[index] - fromStr[index] + 1)
.Select(c => String.Concat(prev, (char)c));
index += 1;
if (index < fromStr.Length)
{
foreach (string newStr in newStrList)
{
BuildSequence(fromStr, toStr, outputList, index, newStr);
}
}
else
{
outputList.AddRange(newStrList);
}
}
The problem you describe is harder than just converting a base-26 representation to an integer, doing some calculation, and then converting back. Your alpha strings aren't necessarily base-26. For example, you say that given AA and CD, you want to generate
AA, AB, AC, AD
BA, BB, BC, BD
CA, CB, CC, CD
What you really have is a base-4 system that uses the characters A, B, C, and D to represent the numbers 0, 1, 2, and 3. What you're saying here is that you want to generate all the 2-digit, base-4 numbers from 00 through 33.
Given CCC => DMK, it's a base-11 system using digits C through M. It's unclear from your description whether you want:
CCC, CCD, CCE ... CCK
CDC, CDD, CDE ... CDK
...
Or if you want
CCC, CCD, CCE ... CCM
CDC, CDD, CDE ... CDM
...
If you want the former, then each digit position is a different base, and things get even more complicated.
How you define things changes how you would write the code to generate the values.
Regardless or how you want to interpret your alpha values, it's clear that your base-26 conversion functions are incorrect.
Your conversion from int to string has a few errors. In particular, subtracting 1 from the value is going to give you trouble. You can see that if you were to pass 0 to the function. The result would be an empty string.
Here's a correct function:
static string ConvertToBase26(int value)
{
const int a = (int)'A';
var result = new StringBuilder();
do
{
var remainder = value % 26;
value /= 26;
result.Insert(0, (char)(a + remainder);
} while (value > 0);
return result.ToString();
}
Your conversion from base26 to integer has similar errors, due to subtracting 1 from things. Remember, A acts like 0. The corrected function:
static int ConvertFromBase26(string value)
{
const int a = (int)'A';
int result = 0;
foreach (var c in value.ToUpper())
{
result = (result * 26) + (c - a);
}
return result;
}
I recommend renaming your base conversion functions. Your ConvertAlpha function converts an integer to a base-26 string. That's not at all clear in the name, as one could misconstrue "ConvertAlpha" to mean "ConvertFromAlpha". I would recommend ConvertToBase26 and ConvertFromBase26, which are much more explicit and unambiguous.

Generating a unique, incremental char array [duplicate]

I need assistance with Combinations with Repetition. Have searched all over the net and although I found a few examples I can't understand them completely. My goal is simple a function (CombinationsWithRepetiion) receives list with items (in this case integer values) and length (that represents how long each combination can be) and returns a list containing the result.
List<int> input = new List<int>() {1, 2, 3}
CombinationsWithRepetition(input, length);
result:
length = 1: 1, 2, 3
length = 2: 11,12,13,21,22,23,31,32,33
length = 3: 111,112 ....
I hope someone helps me and thank you in advance!
recursion
Ok,
here is the C# version - I walk you through it
static IEnumerable<String> CombinationsWithRepetition(IEnumerable<int> input, int length)
{
if (length <= 0)
yield return "";
else
{
foreach(var i in input)
foreach(var c in CombinationsWithRepetition(input, length-1))
yield return i.ToString() + c;
}
}
First you check the border-cases for the recursion (in this case if length <= 0) - in this case the answer is the empty string (btw: I choose to return strings as you did not say what your really needed - should be easy to change).
In any other case you look at each input i and recursivley take the next-smaller combinations and just plug em together (with String-concatination because I wanted strings).
I hope you understand the IEnumerable/yield stuff - if not say so in the comments please.
Here is a sample output:
foreach (var c in CombinationsWithRepetition(new int[]{1,2,3}, 3))
Console.WriteLine (c);
111
112
113
...
332
333
converting numbers
The following uses the idea I sketched in the comment below and has no problems with stack-overflow exceptions (recursion might for big lenght) - this too assumes strings as they are easier to work with (and I can do a simple PadLeft to simplify things)
static String Convert(string symbols, int number, int totalLen)
{
var result = "";
var len = symbols.Length;
var nullSym = symbols [0];
while (number > 0)
{
var index = number % len;
number = number / len;
result = symbols [index] + result;
}
return result.PadLeft (totalLen, nullSym);
}
static IEnumerable<String> CombinationsWithRepetition(string symbols, int len)
{
for (var i = 0; i < Math.Pow(symbols.Length,len); i++)
yield return Convert (symbols, i, len);
}
string[] items = {"1", "2", "3"};
var query = from i1 in items
from i2 in items
from i3 in items
select i1 + i2 + i3 ;
foreach(var result in query)
Console.WriteLine(result);
Console.ReadKey();

Find All Possible Permutations In Certain Range C#

I want to make a program to find all valid stock symbols from Yahoo Finance and I already found this: Quickest way to enumerate the alphabet
However, I wan't it to go from A - Z and then AA - AZ and then ABA - ABZ and so on and so forth. What is the best way to do this? More clear example: A B C D ect.
AA AB AC AD ect. ABA ABB ABC ABD ect.
Using Eric Lippert's Cartesian Product,
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int maxlen = 3;
var query = Enumerable.Range(1, maxlen)
.SelectMany(i => Enumerable.Repeat(chars, i)
.CartesianProduct()
.Select(x => String.Concat(x)));
foreach(var str in query)
{
Console.WriteLine(str);
}
PS: Just for the completeness:
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
// base case:
IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
foreach (var sequence in sequences)
{
var s = sequence; // don't close over the loop variable
// recursive case: use SelectMany to build the new product out of the old one
result =
from seq in result
from item in s
select seq.Concat(new[] { item });
}
return result;
}
Not sure how fast it is, but I did the following when I needed to do something similar:
for (int i = 0; i < numCols && i < 26; i++)
{
char start = 'A';
char colChar = (char)(start + (char)(i));
Console.WriteLine(string.Format("{0}", colChar), typeof(string));
}
for (int i = 26; i < 52 && i < numCols; i++)
{
char start = 'A';
char colChar = (char)(start + (char)(i-26));
Console.WriteLine(string.Format("A{0}", colChar), typeof(string));
}
the second for loop obviously only returns AA thru AZ, but if you put that in a function, made the first A as an input, then you could loop through A-Z for the first character, and you have all the two character results. Creating a third function with a 2 character input as the preceeding string will get you the three character set.
26*26*26 is a lot of output, but the above pattern should get it for you.

list produces specific set of combinations

I have a C# list:
A
B
A
C
D
A
How can I find all the combinations of letters in which the index of the following letter is always bigger. So in this case, combinations could be: A, AB, ABA, C, CD, ADA... BUT NOT DC, CB... since B index comes before C index for last example. Using indexes, 1, 12, 123, 146, 134 would be accepted, but something like 143 would not be accepted since 4 is greater than 3.
Simply generate all nonempty subsets of set {1,2,3,4,5,6}. For each such subset, just take its numbers (in increasing order) and convert them to the corresponding letters. This way you'll get all possible letter sequences. Then you'll have to remove duplicates, if necessary - for example A will be generated three times by sets {1}, {3} and {6}.
This code generates all the combination ( as the sequence of list ) :
static void Main(string[] args)
{
GetCombination(new List<char> { 'A','B','C' });
Console.ReadKey();
}
static void GetCombination(List<char> list)
{
for (int i = 1; i < Convert.ToInt32(Math.Pow(2, list.Count)); i++)
{
int temp = i;
string str = "";
int j = Convert.ToInt32( Math.Pow(2, list.Count - 1));
int index = 0;
while (j > 0)
{
if (temp - j >= 0)
{
str += list[index];
temp -= j;
}
j /= 2;
index++;
}
Console.WriteLine(str);
}
}
And the output is :
C
B
BC
A
AC
AB
ABC

Categories