namespace HeuristicLab.Tests.Benchmark { using HeuristicLab.BenchmarkSuite; using HeuristicLab.BenchmarkSuite.Problems; using HeuristicLab.Core; using HeuristicLab.Problems.ProgramSynthesis.Push.Configuration; using HeuristicLab.Problems.ProgramSynthesis.Push.Expressions; using HeuristicLab.Problems.ProgramSynthesis.Push.Extensions; using HeuristicLab.Problems.ProgramSynthesis.Push.Interpreter; using HeuristicLab.Problems.ProgramSynthesis.Push.Parser; using HeuristicLab.Problems.ProgramSynthesis.Push.Problem.BenchmarkSuite; using HeuristicLab.Problems.ProgramSynthesis.Push.Stack; using HeuristicLab.Random; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class SolutionTests { private IRandom random; [TestInitialize] public void BeforeTest() { random = new MersenneTwister(1337); } private void TestProgram(PushProgram program, IBenchmarkSuiteDataDescriptor descriptor, string floatStringFormat = "R") { var data = descriptor.CreateProblemData(); var config = new PushConfiguration { EvalPushLimit = data.EvalLimit, MaxPointsInProgram = data.MaxSize, ErcOptions = data.ErcOptions, FloatStringFormat = floatStringFormat }; config.SetEnabledStacks((StackTypes)data.EnabledDataTypes); data.InitInExpressions(config); var evaluator = new PushBenchmarkSuiteEvaluator(data); var pool = new PushInterpreterPool(config); var result = evaluator.EvaluateTraining(pool, program, random); Assert.AreEqual(0, result.AvgQuality); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Checksum() { TestProgram( PushParser.ParseProgram("( IN1 0 STRING.ITERATE ( INTEGER.FROMCHAR INTEGER.+ ) 64 INTEGER.% \' \' INTEGER.FROMCHAR INTEGER.+ \"Check sum is \" PRINT.PRINTSTRING CHAR.FROMINTEGER PRINT.PRINTCHAR )"), new Checksum()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void CollatzNumbers() { TestProgram( PushParser.ParseProgram("( IN1 INTEGER.DUP 1 INTEGER.= BOOLEAN.NOT EXEC.WHILE ( INTEGER.DUP INTEGER.DUP 2 INTEGER.% 0 INTEGER.= EXEC.IF ( 2 INTEGER./ ) ( 3 INTEGER.* 1 INTEGER.+ ) INTEGER.DUP 1 INTEGER.= BOOLEAN.NOT ) INTEGER.POP INTEGER.STACKDEPTH )"), new CollatzNumbers()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void CompareStringLengths() { TestProgram( PushParser.ParseProgram("IN1 IN2 IN3 STRING.LENGTH STRING.LENGTH INTEGER.DUP STRING.LENGTH INTEGER.> INTEGER.> BOOLEAN.AND"), new CompareStringLengths()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void CountOdds() { TestProgram( PushParser.ParseProgram("( IN1 0 INTEGER[].ITERATE ( 2 INTEGER.% INTEGER.DUP 1 INTEGER.= -1 INTEGER.= BOOLEAN.OR EXEC.WHEN INTEGER.INC ) )"), new CountOdds()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Digits() { TestProgram( PushParser.ParseProgram("( IN1 INTEGER.DUP STRING.FROMINTEGER 0 INTEGER.< BOOLEAN.DUP EXEC.WHEN ( STRING.REST STRING.DUP STRING.FIRST STRING.SWAP STRING.REST ) STRING.REVERSE STRING.ITERATE ( PRINT.NEWLINE PRINT.PRINTCHAR ) EXEC.WHEN ( PRINT.NEWLINE \'-\' PRINT.PRINTCHAR PRINT.PRINTSTRING ) )"), new Digits()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void DoubleLetters() { TestProgram( PushParser.ParseProgram( @"IN1 STRING.ITERATE ( 3 EXEC.DO*COUNT CHAR.DUP CHAR.ISLETTER EXEC.WHEN PRINT.PRINTCHAR '!' CHAR.= EXEC.WHEN ( CHAR.DUP PRINT.PRINTCHAR PRINT.PRINTCHAR ) PRINT.PRINTCHAR )"), new DoubleLetters()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void EvenSquares() { TestProgram( PushParser.ParseProgram( @"IN1 INTEGER.DUP EXEC.DO*COUNT ( INTEGER.DUP 0 INTEGER.> EXEC.WHEN ( INTEGER.DUP 2 INTEGER.* INTEGER.DUP INTEGER.DUP INTEGER.* INTEGER.DUP 4 INTEGER.YANKDUP INTEGER.< EXEC.IF ( PRINT.PRINTINTEGER PRINT.NEWLINE ) EXEC.FLUSH INTEGER.POP ) INTEGER.POP )"), new EvenSquares()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void ForLoopIndex() { TestProgram( PushParser.ParseProgram( @"( IN1 IN2 IN3 STRING.FROMINTEGER INTEGER.SWAP true EXEC.WHILE ( INTEGER.DUP PRINT.NEWLINE PRINT.PRINTINTEGER STRING.DUP INTEGER.FROMSTRING INTEGER.+ INTEGER.DUP 2 INTEGER.YANKDUP INTEGER.< ) )"), new ForLoopIndex()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Grades() { TestProgram( PushParser.ParseProgram("( IN1 IN2 IN3 IN4 IN5 \"Student has a \" PRINT.PRINTSTRING INTEGER.DUP INTEGER.ROT INTEGER.> EXEC.WHEN ( \"F\" \" grade.\" STRING.CONCAT PRINT.PRINTSTRING EXEC.FLUSH ) INTEGER.DUP INTEGER.ROT INTEGER.> EXEC.WHEN ( \"D\" \" grade.\" STRING.CONCAT PRINT.PRINTSTRING EXEC.FLUSH ) INTEGER.DUP INTEGER.ROT INTEGER.> EXEC.WHEN ( \"C\" \" grade.\" STRING.CONCAT PRINT.PRINTSTRING EXEC.FLUSH ) INTEGER.DUP INTEGER.ROT INTEGER.> EXEC.WHEN ( \"B\" \" grade.\" STRING.CONCAT PRINT.PRINTSTRING EXEC.FLUSH ) \"A\" \" grade.\" STRING.CONCAT PRINT.PRINTSTRING )"), new Grades()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void LastIndexOfZero() { TestProgram( PushParser.ParseProgram("( IN1 INTEGER[].DUP INTEGER[].LENGTH INTEGER[].REVERSE 0 INTEGER[].INDEXOF INTEGER.- INTEGER.DEC )"), new LastIndexOfZero()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Median() { TestProgram( PushParser.ParseProgram("( IN1 IN2 IN3 INTEGER.ROT INTEGER.DUP 2 INTEGER.YANKDUP INTEGER.MAX 3 INTEGER.YANKDUP INTEGER.MIN INTEGER.ROT INTEGER.MIN INTEGER.MAX PRINT.PRINTINTEGER )"), new Median()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void MirrorImage() { TestProgram( PushParser.ParseProgram( @"( IN1 IN2 INTEGER[].PUSHALL INTEGER[].ITERATE ( INTEGER.= BOOLEAN.NOT EXEC.WHEN ( false EXEC.FLUSH ) ) true )"), new MirrorImage()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void NegativeToZero() { TestProgram( PushParser.ParseProgram("( IN1 INTEGER[].DUP INTEGER[].LENGTH INTEGER.DEC EXEC.DO*COUNT ( INTEGER.DUP INTEGER[].DUP INTEGER[].NTH 0 INTEGER.< EXEC.WHEN ( 0 INTEGER[].SET ) ) )"), new NegativeToZero()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void NumberIo() { TestProgram( PushParser.ParseProgram("IN1 IN2 FLOAT.FROMINTEGER FLOAT.+ PRINT.PRINTFLOAT"), new NumberIO()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void PigLatin() { TestProgram( PushParser.ParseProgram("@( IN1 STRING.SPLIT STRING.STACKDEPTH 0 INTEGER.= EXEC.WHEN EXEC.FLUSH STRING.STACKDEPTH EXEC.DO*TIMES ( STRING.DUP STRING.FIRST CHAR.ALLFROMSTRING CHAR.DUP \"aeiou\" STRING.CONTAINSCHAR EXEC.IF ( CHAR.POP ) ( STRING.REST STRING.CONJCHAR ) \"ay\" STRING.CONCAT STRING.STACKDEPTH 1 INTEGER.> EXEC.WHEN ( ' ' STRING.CONJCHAR ) PRINT.PRINTSTRING ) )"), new PigLatin()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void ReplaceSpaceWithNewLine() { TestProgram( PushParser.ParseProgram("IN1 STRING.DUP 0 STRING.ITERATE ( CHAR.DUP ' ' CHAR.= EXEC.IF ( CHAR.POP '\n' ) INTEGER.INC PRINT.PRINTCHAR )"), new ReplaceSpaceWithNewline()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void ScrabbleScore() { TestProgram( PushParser.ParseProgram("( IN1 STRING.ITERATE ( INTEGER.FROMCHAR INTEGER.DUP INTEGER.DUP 96 INTEGER.> 123 INTEGER.< BOOLEAN.AND EXEC.WHEN ( 32 INTEGER.- ) 65 INTEGER.- INTEGER.DUP INTEGER.DUP 0 INTEGER.>= 26 INTEGER.< BOOLEAN.AND EXEC.IF ( [1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10] INTEGER[].NTH INTEGER.+ ) ( INTEGER.POP ) ) )"), new ScrabbleScore()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Smallest() { TestProgram( PushParser.ParseProgram("( IN1 IN2 IN3 IN4 3 EXEC.DO*TIMES INTEGER.MIN )"), new Smallest()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void SmallOrLarge() { TestProgram( PushParser.ParseProgram( @"IN1 INTEGER.DUP 1000 INTEGER.< 2000 INTEGER.>= EXEC.WHEN ""large"" EXEC.WHEN ""small"" STRING.EMPTY EXEC.WHEN """" PRINT.PRINTSTRING"), new SmallOrLarge()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void StringDifferences() { TestProgram( PushParser.ParseProgram( @"IN1 IN2 CHAR.ALLFROMSTRING 0 STRING.ITERATE ( CHAR.DUP 2 CHAR.YANKDUP CHAR.= BOOLEAN.NOT EXEC.IF ( INTEGER.DUP PRINT.PRINTINTEGER ' ' PRINT.PRINTCHAR PRINT.PRINTCHAR ' ' PRINT.PRINTCHAR PRINT.PRINTCHAR PRINT.NEWLINE ) ( CHAR.POP CHAR.POP ) INTEGER.INC )"), new StringDifferences()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void StringLengthsBackwards() { TestProgram( PushParser.ParseProgram(@"IN1 STRING[].ITERATE ( STRING.LENGTH PRINT.NEWLINE PRINT.PRINTINTEGER )"), new StringLengthsBackwards()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void SumOfSquares() { TestProgram( PushParser.ParseProgram(@"( IN1 EXEC.DO*COUNT ( INTEGER.DUP INTEGER.* INTEGER.+ ) )"), new SumOfSquares()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void SuperAnagrams() { TestProgram( PushParser.ParseProgram(@"( IN1 IN2 STRING.SWAP STRING.DUP STRING.ITERATE ( CHAR.DUP STRING.DUP STRING.OCCURRENCESOFCHAR 1 STRING.YANKDUP STRING.OCCURRENCESOFCHAR INTEGER.> EXEC.WHEN ( false EXEC.FLUSH ) ) true )"), new SuperAnagrams()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void Syllables() { TestProgram( PushParser.ParseProgram("( IN1 \"aeiouy\" 0 STRING.ITERATE ( STRING.DUP STRING.OCCURRENCESOFCHAR INTEGER.+ ) \"The number of syllables is \" PRINT.PRINTSTRING PRINT.PRINTINTEGER )"), new Syllables()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void VectorAverage() { TestProgram( PushParser.ParseProgram("( IN1 FLOAT[].DUP FLOAT[].LENGTH FLOAT[].ITERATE FLOAT.+ FLOAT.FROMINTEGER FLOAT./ )"), new VectorAverage()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void VectorSummed() { TestProgram( PushParser.ParseProgram(@"( IN1 IN2 INTEGER[].PUSHALL INTEGER[].DUP INTEGER[].LENGTH INTEGER.DEC EXEC.DO*COUNT ( INTEGER.DUP INTEGER[].DUP INTEGER[].NTH INTEGER.SWAP INTEGER.ROT INTEGER.+ INTEGER[].SET ) )"), new VectorSummed()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void WallisPi() { TestProgram( PushParser.ParseProgram(@"( IN1 2 3 INTEGER.ROT INTEGER.ROT EXEC.DO*TIMES ( 2 EXEC.DO*TIMES ( 1 INTEGER.YANKDUP 1 INTEGER.YANKDUP ) FLOAT.FROMINTEGER FLOAT.FROMINTEGER FLOAT.SWAP FLOAT./ FLOAT.* INTEGER.< EXEC.IF ( INTEGER.SWAP 2 INTEGER.+ INTEGER.SWAP ) ( 2 INTEGER.+ ) ) )"), new WallisPi()); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void WordStats() { TestProgram( PushParser.ParseProgram("( IN1 STRING.DUP STRING.SPLIT STRING.STACKDEPTH 1 INTEGER.= BOOLEAN.NOT EXEC.WHEN ( true EXEC.WHILE ( STRING.LENGTH INTEGER.MAX STRING.STACKDEPTH 1 INTEGER.= BOOLEAN.NOT ) [0] 2 INTEGER.- INTEGER.DUP 0 INTEGER.>= EXEC.WHEN ( INTEGER.INC EXEC.DO*TIMES ( 0 INTEGER[].CONJ ) ) STRING.DUP STRING.SPLIT STRING.STACKDEPTH 1 INTEGER.> EXEC.WHILE ( STRING.LENGTH INTEGER.DEC INTEGER.DUP INTEGER[].DUP INTEGER[].NTH INTEGER.INC INTEGER[].SET STRING.STACKDEPTH 1 INTEGER.> ) INTEGER[].DUP INTEGER[].LENGTH INTEGER.DEC EXEC.DO*COUNT ( PRINT.NEWLINE \"words of length \" PRINT.PRINTSTRING INTEGER.DUP INTEGER.INC PRINT.PRINTINTEGER \": \" PRINT.PRINTSTRING INTEGER[].DUP INTEGER[].NTH PRINT.PRINTINTEGER ) \'.\' STRING.DUP STRING.OCCURRENCESOFCHAR \'!\' STRING.DUP STRING.OCCURRENCESOFCHAR INTEGER.+ \'?\' STRING.DUP STRING.OCCURRENCESOFCHAR INTEGER.+ INTEGER.DUP PRINT.NEWLINE \"number of sentences: \" PRINT.PRINTSTRING PRINT.PRINTINTEGER STRING.SPLIT STRING.STACKDEPTH FLOAT.FROMINTEGER FLOAT.FROMINTEGER FLOAT./ PRINT.NEWLINE \"average sentence length: \" PRINT.PRINTSTRING PRINT.PRINTFLOAT ) )"), new WordStats(), "0.0#########"); } [TestMethod] [TestProperty("Time", "Short")] [TestCategory("ProblemTest")] public void XWordLines() { TestProgram( PushParser.ParseProgram(@"( IN1 IN2 STRING.SPLIT STRING.EMPTY BOOLEAN.NOT INTEGER.DUP 1 INTEGER.= EXEC.IF ( EXEC.WHILE ( PRINT.NEWLINE PRINT.PRINTSTRING STRING.EMPTY BOOLEAN.NOT ) ) ( 2 INTEGER.- EXEC.WHILE ( STRING.STACKDEPTH 2 INTEGER.- 1 INTEGER.YANKDUP INTEGER.MIN INTEGER.DUP 0 INTEGER.>= EXEC.IF ( INTEGER.INC EXEC.DO*TIMES ( ' ' STRING.CONJCHAR STRING.SWAP STRING.CONCAT ) PRINT.NEWLINE PRINT.PRINTSTRING STRING.EMPTY BOOLEAN.NOT ) ( PRINT.NEWLINE PRINT.PRINTSTRING STRING.EMPTY BOOLEAN.NOT ) ) ) )"), new XWordLines()); } } }