Skip to main content
1 of 5

Tarmo's ascii printing language, 47 bytes.

1 /\| /_/\|/__\_\2 \__|/ 0n{n-a-1{½1}1a{2#1}$} 

Just by looking to such odd programming languages like CJam, it's makes me bit dizzy how complex, unnatural and cryptic language can be, that I wanted to "boldly go where no man has gone before", and invent my own language. As a result I've created my own language for ascii patterns printing.

Basic idea is that you can define first patten and then printing - using same kind of character '1' or '2' or whatever number - you can define your own print pattern.

Once pattern is defined (Starts from number till number end) - next numbers will execute pattern printing.

For example

1 /\| /_/\|/__\_\01 

Outputs like this:

 /\ /_/\ /__\_\ 

Will define pattern 1 and then print it right away. Pattern is defined everything separated with '|' character. 0 at the end - acts like pattern termination.

Special characters like '$' are reserved as line-feed, and '½' is reserved for spacing - half - of specific pattern.

1 /\| /_/\|/__\_\01$½11$½1½11 

Will outputs text like this:

 /\ /_/\ /__\_\ /\ /_/\ /__\_\ /\ /_/\ /__\_\ 

Next goes for-loops. That one needs to be easily visible - so I've retained {} brackets for for-loops, but variable names are auto-named - so first bracket will use 'a' variable, second 'b' and so on. Iteration will go always from 0 to specific number - and that number is defined before {} brackets.

'n' is reserved variable for whole function input.

So code:

1 /\| /_/\|/__\_\0n{1$} 

Will outputs ( With n == 4 ):

 /\ /_/\ /__\_\ /\ /_/\ /__\_\ /\ /_/\ /__\_\ /\ /_/\ /__\_\ 

And '#' is special modifier for trim lead whitespace.

And finally whole solution:

Program.cs:

using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.CSharp; namespace TestCSharp { class Program { static public String prog = @"1 /\| /_/\|/__\_\2 \__|/ 0n{n-a-1{½1}1a{2#1}$}"; static Dictionary<char, String[]> patterns = new Dictionary<char,string[]>(); static string Tabs(int n) { if( n < 0 ) n = 0; String r = ""; for( int i = 0; i < n ; i++ ) r += " "; return r; } static int[] left = new int[10]; static int top = Console.CursorTop; static int lastTop = Console.CursorTop; static public void DoPrint(char c, char modifier = ' ') { if (c == '$') { for (int i = 0; i < left.Length; i++) left[i] = 0; top = lastTop + 1; return; } if (!patterns.ContainsKey(c)) return; if (modifier == '½') { int maxSize = patterns[c].Select(x => x.Length).Max(); for( int i = 0; i < left.Length; i++ ) left[i] += maxSize / 2; return; } int iLine = 0; foreach (var l in patterns[c]) { Console.SetCursorPosition(left[iLine], top + iLine); if( top + iLine > lastTop ) lastTop = top + iLine; String s = l; if (modifier == '#') s = s.TrimStart(' '); Console.WriteLine(s); left[iLine] += s.Length; iLine++; } } static void Main(string[] args) { DrawTriangles(4); } static void DrawTriangles( int nTris ) { String todo = ""; String code = ""; char nextVar = 'a'; String lf = "\r\n"; int align = 1; char lastModifier = ' '; code += "using System;" + lf; code += "public class ExecClass { static void Exec( int n, Action<char, char> print ) { " + lf; for( int i = 0; i < prog.Length; i++ ) { char c = prog[i]; // Define pattern. if (c >= '0' && c <= '9' && !patterns.ContainsKey(c)) { String p = Regex.Match(prog.Substring(i + 1), "[^0-9]*").Groups[0].Value; patterns[c] = p.Split('|'); i += p.Length; if( prog[i + 1] == '0' ) i++; continue; } String procRemain = prog.Substring(i); switch ( c ) { case '{': code += Tabs(align); code += "for ( int " + nextVar + " = 0; " + nextVar + " < " + todo + " ; " + nextVar + "++ )" + lf; code += Tabs(align); code += "{" + lf; nextVar++; todo = ""; align++; break; case '}': align--; code += Tabs(align); code += "}" + lf; break; default: if (((c >= '0' && c <= '9') || c == '<' || c == '$') && todo == "") { code += Tabs(align); code += "print('" + c + "' , '" + lastModifier + "');" + lf; lastModifier = ' '; continue; } if( c == '½' || c == '#' ) { lastModifier = c; continue; } if( c == '\r' || c == '\n' ) continue; todo += c; break; } } //for code += "} };"; int line = 1; String lineNumberedCode =Regex.Replace(code, "^(.*)$", delegate(Match m) { return (line++) + ": " + m.Value; }, RegexOptions.Multiline ); Console.WriteLine(lineNumberedCode); Console.WriteLine(); Console.WriteLine(); left[0] = Console.CursorLeft; for( int i = 1; i < left.Length; i++ ) left[i] = left[0]; top = Console.CursorTop; try { var p = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true }; p.ReferencedAssemblies.Add("System.dll"); var compileResult = new CSharpCodeProvider().CompileAssemblyFromSource( p, code); if (compileResult.Errors.HasErrors) { foreach (CompilerError ce in compileResult.Errors) { if (ce.IsWarning) continue; Console.WriteLine("{0}({1},{2}: error {3}: {4}", ce.FileName, ce.Line, ce.Column, ce.ErrorNumber, ce.ErrorText); } return; } var method = compileResult.CompiledAssembly.GetType("ExecClass").GetMethod("Exec", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); method.Invoke(null, new object[] { nTris, new Action<char, char>(DoPrint) }); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.SetCursorPosition(1, lastTop); Console.WriteLine(); Console.WriteLine(); } //Main } } 

Will outputs this:

1: using System; 2: public class ExecClass { static void Exec( int n, Action<char, char> print ) { 3: for ( int a = 0; a < n ; a++ ) 4: { 5: for ( int b = 0; b < n-a-1 ; b++ ) 6: { 7: print('1' , '½'); 8: } 9: print('1' , ' '); 10: for ( int c = 0; c < a ; c++ ) 11: { 12: print('2' , ' '); 13: print('1' , '#'); 14: } 15: print('$' , ' '); 16: } 17: } }; /\ /_/\ /__\_\ /\ \__/\ /_/\/ /_/\ /__\_\/__\_\ /\ \__/\ \__/\ /_/\/ /_/\/ /_/\ /__\_\/__\_\/__\_\ /\ \__/\ \__/\ \__/\ /_/\/ /_/\/ /_/\/ /_/\ /__\_\/__\_\/__\_\/__\_\