Production of strings based on a simple grammar
This is the solution for the problem http://acm.tju.edu.cn/toj/showp1021.html.
The
problem deals with the generation of strings based on a very limited grammar. Given
the constraints given (only two chars in the allowed alphabet, and the max
string length no greater than 15) the problem becomes suitable for a
brute-force with few but important optimizations along the way: restrict the
search using the length, restrict the search if you have processed that same
string before. Note that functional programming seems the ideal tool for this
kind of problem (hence, I have changed the coding style to mimic functional
programming):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace LSystem
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 5)
{
Console.WriteLine("LSystem - solution to problem http://acm.tju.edu.cn/toj/showp1021.html");
Console.WriteLine("Usage: LSystem.exe <'a' production> <'b' production> <init string> <target string> <length limit>");
Console.WriteLine("Example: LSystem.exe aa bb ab aaabb 15");
return;
}
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 5)
{
Console.WriteLine("LSystem - solution to problem http://acm.tju.edu.cn/toj/showp1021.html");
Console.WriteLine("Usage: LSystem.exe <'a' production> <'b' production> <init string> <target string> <length limit>");
Console.WriteLine("Example: LSystem.exe aa bb ab aaabb 15");
return;
}
Hashtable htAlreadyUsed = new Hashtable();
bool result = IsThereAMatch(args[3],
args[2],
args[0],
args[1],
Convert.ToInt32(args[4]),
ref htAlreadyUsed);
bool result = IsThereAMatch(args[3],
args[2],
args[0],
args[1],
Convert.ToInt32(args[4]),
ref htAlreadyUsed);
Console.WriteLine("{0}", result?"YES":"NO");
}
}
static bool IsThereAMatch(string target,
string current,
string aProduction,
string bProduction,
int lengthLimit,
ref Hashtable htAlreadyUsed)
{
if (target == null || current == null) return false;
if (current == target) return true;
if (current.Length > lengthLimit || current.Length > target.Length) return false;
if (htAlreadyUsed.ContainsKey(current)) return false;
if (!htAlreadyUsed.ContainsKey(current)) htAlreadyUsed.Add(current, true);
string current,
string aProduction,
string bProduction,
int lengthLimit,
ref Hashtable htAlreadyUsed)
{
if (target == null || current == null) return false;
if (current == target) return true;
if (current.Length > lengthLimit || current.Length > target.Length) return false;
if (htAlreadyUsed.ContainsKey(current)) return false;
if (!htAlreadyUsed.ContainsKey(current)) htAlreadyUsed.Add(current, true);
for (int i = 0; i < current.Length; i++)
{
string firstPart = (i == 0) ? "" : current.Substring(0, i);
string secondPart = (i == current.Length - 1) ? "" : current.Substring(i + 1);
{
string firstPart = (i == 0) ? "" : current.Substring(0, i);
string secondPart = (i == current.Length - 1) ? "" : current.Substring(i + 1);
if(current[i] == 'a')
if(IsThereAMatch(target, firstPart + aProduction + secondPart, aProduction, bProduction, lengthLimit, ref htAlreadyUsed))
return true;
if(current[i] == 'b')
if(IsThereAMatch(target, firstPart + bProduction + secondPart, aProduction, bProduction, lengthLimit, ref htAlreadyUsed))
return true;
}
if(IsThereAMatch(target, firstPart + aProduction + secondPart, aProduction, bProduction, lengthLimit, ref htAlreadyUsed))
return true;
if(current[i] == 'b')
if(IsThereAMatch(target, firstPart + bProduction + secondPart, aProduction, bProduction, lengthLimit, ref htAlreadyUsed))
return true;
}
return false;
}
}
}
}
}
}
Comments
Post a Comment