14 August 2011 by Stuart Cam
There is a well known technique within black-hat SEO called content spinning. Content spinning involves writing an article using a specific syntax which allows a text processor to generate random variations. These variations can then be used for multiple purposes without fear of being labelled as duplicate content.
I was searching for a C# algorithm which I could re-purpose into a nAnt script, but a few searches on the internet gave no results. I found a python version which seemed good enough, so I rewrote it for C#.
public static class Spinner
{
private readonly static Random Randomizer = new Random();
public static string Spin(string content)
{
const char OPEN_BRACE = '{';
const char CLOSE_BRACE = '}';
const char DELIMITER = '|';
var start = content.IndexOf(OPEN_BRACE);
var end = content.IndexOf(CLOSE_BRACE);
if (start == -1 && end == -1 || start == -1 || end < start)
{
return content;
}
if (end == -1)
{
throw new ArgumentException("Unbalanced brace.");
}
var substring = content.Substring(start + 1, content.Length - (start + 1));
var rest = Spin(substring);
end = rest.IndexOf(CLOSE_BRACE);
if (end == -1)
{
throw new ArgumentException("Unbalanced brace.");
}
var splits = rest.Substring(0, end).Split(DELIMITER);
var item = splits[Randomizer.Next(0, splits.Length)];
return content.Substring(0, start) + item + Spin(rest.Substring(end + 1, rest.Length - (end + 1)));
}
}
Usage:
Spinner.Spin("{Hi|Hello|Good morning}, my name is {Matt|Bob} and I {certainly |might |should |}have {something {important|special} to {say|eat|share}|a favorite {toy|book|poem|song}}.");
04 September 2010 by Stuart Cam
There seems to be a lot of noise around CQRS and DDDD these days:
90108025-7c31-4034-afc7-76a883d02bb9|0|.0
Tags: cqrs, dddd
Categories: .NET
14 August 2010 by Stuart Cam
Thycotic have put up a Code Challenge.
Below is my heavily LINQ-oriented solution:
public interface IConverter
{
string Convert(int number);
int Convert(string number);
string ConvertUsing(IConverter convertor, string number);
}
public abstract class ConverterBase : IConverter
{
protected abstract string Chars { get; }
public string Convert(int number)
{
return this.Encode(number)
.Aggregate(string.Empty, (s, c) => s + c);
}
public int Convert(string number)
{
return number.Reverse()
.Select((c, i) => Chars.IndexOf(c) * (int)Math.Pow(this.Chars.Length, i))
.Sum();
}
public string ConvertUsing(IConverter convertor, string number)
{
return convertor.Convert(this.Convert(number));
}
private IEnumerable<char> Encode(int number)
{
var remainder = number % this.Chars.Length;
if (number - remainder > 0)
{
foreach (var power in this.Encode((number - remainder) / this.Chars.Length))
{
yield return power;
}
}
yield return this.Chars[remainder];
}
}
public class Converter : ConverterBase
{
protected override string Chars
{
get
{
return "0123456789xyz";
}
}
}
public class HexConverter : ConverterBase
{
protected override string Chars
{
get
{
return "0123456789abcdef";
}
}
}
public class BinaryConverter : ConverterBase
{
protected override string Chars
{
get
{
return "01";
}
}
}
public class OctalConverter : ConverterBase
{
protected override string Chars
{
get
{
return "01234567";
}
}
}
Note: The code doesn't handle negative inputs or exceptions.
21 October 2009 by Stuart Cam
Don't delay, download your copy today! Get the lowdown from Scott Guthrie.