From e0cf76549ee80559014bcf3bd16daf4fc711ce56 Mon Sep 17 00:00:00 2001 From: WhiteBlackGoose <wbg@angouri.org> Date: Sun, 27 Jun 2021 14:05:19 +0300 Subject: [PATCH 1/3] Working on ASCII output --- Sources/Samples/Samples/Program.cs | 125 ++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 3 deletions(-) diff --git a/Sources/Samples/Samples/Program.cs b/Sources/Samples/Samples/Program.cs index 6d8efcab1..c72eacfee 100644 --- a/Sources/Samples/Samples/Program.cs +++ b/Sources/Samples/Samples/Program.cs @@ -1,8 +1,127 @@ - +using AngouriMath; +using HonkSharp.Fluency; using System; +using System.Collections.Generic; +using System.Collections; +using static AngouriMath.Entity; -var a = 3; -Console.WriteLine(a); +Console.WriteLine(Draw("213/43 + 3/4")); + + + + + + + + +static Figure Draw(Entity expr) + => expr switch + { + Number n => new BlockFigure(n.ToString()), + Divf(var a, var b) => new RationalFigure(Draw(a), Draw(b)), + Sumf(var a, var b) => new BinaryOpFigure(Draw(a), Draw(b), '+'), + _ => throw new() + }; + + + + +public abstract class Figure +{ + // should be protected + public readonly char[,] table; + + public int Width => table.GetLength(1); + public int Height => table.GetLength(0); + + private protected Figure(char[,] table) + => this.table = table; + + public override string ToString() + => "\n" + .Join( + (..(Height - 1)).Select(h => + (..(Width - 1)).Select(w => table[h, w]).AsString() + ) + ); +} + +public sealed class BlockFigure : Figure +{ + public BlockFigure(string s) : base(GenerateTable(s)) { } + + private static char[,] GenerateTable(string source) + { + var res = new char[1, source.Length]; + foreach (var (index, ch) in source.Enumerate()) + res[0, index] = ch; + return res; + } +} + +public sealed class RationalFigure : Figure +{ + public RationalFigure(Figure num, Figure den) : base(GenerateTable(num, den)) { } + + private static char[,] GenerateTable(Figure num, Figure den) + { + var res = new char[num.Height + 1 + den.Height, Math.Max(num.Width, den.Width) + 2].WithSpaces(); + + num.table.CopyWidthAlignedCenterTo(res, 0); + den.table.CopyWidthAlignedCenterTo(res, num.Height + 1); + + foreach (var x in 0..(res.GetLength(1) - 1)) + res[num.Height, x] = '-'; + + return res; + } +} + +public sealed class BinaryOpFigure : Figure +{ + public BinaryOpFigure(Figure left, Figure right, char op) : base(GenerateTable(left, right, op)) { } + + private static char[,] GenerateTable(Figure left, Figure right, char op) + { + var res = new char[Math.Max(left.Height, right.Height), left.Width + 3 + right.Width].WithSpaces(); + + left.table.CopyHeightAlignedCenterTo(res, 0); + right.table.CopyHeightAlignedCenterTo(res, left.Width + 3); + + res[res.GetLength(0) / 2, left.Width + 1] = op; + + return res; + } +} + + + +public static class ArrayExtensions +{ + public static void CopyWidthAlignedCenterTo(this char[,] src, char[,] dst, int heightOffset) + { + var widthOffset = (dst.GetLength(1) - src.GetLength(1)) / 2; + foreach (var x in 0..(src.GetLength(1) - 1)) + foreach (var y in 0..(src.GetLength(0) - 1)) + dst[y + heightOffset, x + widthOffset] = src[y, x]; + } + + public static void CopyHeightAlignedCenterTo(this char[,] src, char[,] dst, int widthOffset) + { + var heightOffset = (dst.GetLength(0) - src.GetLength(0)) / 2; + foreach (var x in 0..(src.GetLength(1) - 1)) + foreach (var y in 0..(src.GetLength(0) - 1)) + dst[y + heightOffset, x + widthOffset] = src[y, x]; + } + + public static char[,] WithSpaces(this char[,] chars) + { + foreach (var x in 0..(chars.GetLength(0) - 1)) + foreach (var y in 0..(chars.GetLength(1) - 1)) + chars[x, y] = ' '; + return chars; + } +} From 7774d3fa34808fd3a9e6b15d103e691d4960fed6 Mon Sep 17 00:00:00 2001 From: WhiteBlackGoose <wbg@angouri.org> Date: Sun, 27 Jun 2021 18:14:44 +0300 Subject: [PATCH 2/3] Radical --- Sources/Samples/Samples/Program.cs | 57 +++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/Sources/Samples/Samples/Program.cs b/Sources/Samples/Samples/Program.cs index c72eacfee..a17596e0d 100644 --- a/Sources/Samples/Samples/Program.cs +++ b/Sources/Samples/Samples/Program.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using System.Collections; using static AngouriMath.Entity; +using static AngouriMath.Entity.Number; - -Console.WriteLine(Draw("213/43 + 3/4")); +Console.WriteLine(Draw("sqrt(213/43 + 3/4)")); @@ -22,6 +22,7 @@ static Figure Draw(Entity expr) Number n => new BlockFigure(n.ToString()), Divf(var a, var b) => new RationalFigure(Draw(a), Draw(b)), Sumf(var a, var b) => new BinaryOpFigure(Draw(a), Draw(b), '+'), + Powf(var a, Rational(Integer(1), Integer(2))) => new RadicalFigure(Draw(a), null), _ => throw new() }; @@ -97,20 +98,58 @@ public BinaryOpFigure(Figure left, Figure right, char op) : base(GenerateTable(l } +public sealed class RadicalFigure : Figure +{ + public RadicalFigure(Figure expr, Figure? pow) : base(GenerateTable(expr, pow)) { } + + private static char[,] GenerateTable(Figure expr, Figure? pow) + { +// +// /----| <-- this is right glyph (the '|' thing) +// / HHH +// \ / HHH +// \/ HHH +// ^ +// this is left glyph + const double LeftGlyphShare = 0.3; + const double RightGlyphShare = 0.2; + + var leftGlyphSize = (int)(LeftGlyphShare * expr.Height) + 1; + var rightGlyphSize = (int)(RightGlyphShare * expr.Height) + 1; + + var resWidth = leftGlyphSize + expr.Height + expr.Width + 1; + var resHeight = expr.Height + 1; + + var res = new char[resHeight, resWidth].WithSpaces(); + expr.table.CopyTo(res, 1, leftGlyphSize + expr.Height); + + foreach (var i in 0..(leftGlyphSize - 1)) + res[resHeight - i - 1, i] = '\\'; + + foreach (var (y, x) in (0..(resHeight - 1)).AsRange().Enumerate()) + res[resHeight - y - 1, x + 1] = '/'; + + foreach (var i in resHeight..(resWidth - resHeight + 2)) + res[0, i + 1] = '-'; + + foreach (var i in ..(rightGlyphSize - 1)) + res[i, resWidth - 1] = '|'; + + return res; + } +} + public static class ArrayExtensions { public static void CopyWidthAlignedCenterTo(this char[,] src, char[,] dst, int heightOffset) - { - var widthOffset = (dst.GetLength(1) - src.GetLength(1)) / 2; - foreach (var x in 0..(src.GetLength(1) - 1)) - foreach (var y in 0..(src.GetLength(0) - 1)) - dst[y + heightOffset, x + widthOffset] = src[y, x]; - } + => src.CopyTo(dst, heightOffset, (dst.GetLength(1) - src.GetLength(1)) / 2); public static void CopyHeightAlignedCenterTo(this char[,] src, char[,] dst, int widthOffset) + => src.CopyTo(dst, (dst.GetLength(0) - src.GetLength(0)) / 2, widthOffset); + + public static void CopyTo(this char[,] src, char[,] dst, int heightOffset, int widthOffset) { - var heightOffset = (dst.GetLength(0) - src.GetLength(0)) / 2; foreach (var x in 0..(src.GetLength(1) - 1)) foreach (var y in 0..(src.GetLength(0) - 1)) dst[y + heightOffset, x + widthOffset] = src[y, x]; From c45a52a4e37b6a1afbdb724030f7c0778a43c5ac Mon Sep 17 00:00:00 2001 From: WhiteBlackGoose <wbg@angouri.org> Date: Tue, 29 Jun 2021 12:51:02 +0300 Subject: [PATCH 3/3] Refactored to records --- Sources/Samples/Samples/Program.cs | 75 +++++++++++++----------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/Sources/Samples/Samples/Program.cs b/Sources/Samples/Samples/Program.cs index a17596e0d..178829af2 100644 --- a/Sources/Samples/Samples/Program.cs +++ b/Sources/Samples/Samples/Program.cs @@ -6,8 +6,9 @@ using System.Collections; using static AngouriMath.Entity; using static AngouriMath.Entity.Number; +using HonkSharp.Laziness; -Console.WriteLine(Draw("sqrt(213/43 + 3/4)")); +Console.WriteLine(Draw("sqrt((((1/a + 1)/b + 1)/c + 1)/d)")); @@ -19,7 +20,7 @@ static Figure Draw(Entity expr) => expr switch { - Number n => new BlockFigure(n.ToString()), + Number or Variable => new BlockFigure(expr.ToString()), Divf(var a, var b) => new RationalFigure(Draw(a), Draw(b)), Sumf(var a, var b) => new BinaryOpFigure(Draw(a), Draw(b), '+'), Powf(var a, Rational(Integer(1), Integer(2))) => new RadicalFigure(Draw(a), null), @@ -29,80 +30,70 @@ static Figure Draw(Entity expr) -public abstract class Figure +public abstract record Figure { - // should be protected - public readonly char[,] table; + public int Width => Table.GetLength(1); + public int Height => Table.GetLength(0); - public int Width => table.GetLength(1); - public int Height => table.GetLength(0); - - private protected Figure(char[,] table) - => this.table = table; + protected abstract char[,] GenerateTable(); + internal protected char[,] Table => table.GetValue(@this => @this.GenerateTable(), this); + private readonly LazyPropertyA<char[,]> table; public override string ToString() => "\n" .Join( (..(Height - 1)).Select(h => - (..(Width - 1)).Select(w => table[h, w]).AsString() + (..(Width - 1)).Select(w => Table[h, w]).AsString() ) ); } -public sealed class BlockFigure : Figure +public sealed record BlockFigure(string Source) : Figure { - public BlockFigure(string s) : base(GenerateTable(s)) { } - - private static char[,] GenerateTable(string source) + protected override char[,] GenerateTable() { - var res = new char[1, source.Length]; - foreach (var (index, ch) in source.Enumerate()) + var res = new char[1, Source.Length]; + foreach (var (index, ch) in Source.Enumerate()) res[0, index] = ch; return res; } } -public sealed class RationalFigure : Figure +public sealed record RationalFigure(Figure Numerator, Figure Denominator) : Figure { - public RationalFigure(Figure num, Figure den) : base(GenerateTable(num, den)) { } - - private static char[,] GenerateTable(Figure num, Figure den) + protected override char[,] GenerateTable() { - var res = new char[num.Height + 1 + den.Height, Math.Max(num.Width, den.Width) + 2].WithSpaces(); + var res = new char[Numerator.Height + 1 + Denominator.Height, Math.Max(Numerator.Width, Denominator.Width) + 2].WithSpaces(); - num.table.CopyWidthAlignedCenterTo(res, 0); - den.table.CopyWidthAlignedCenterTo(res, num.Height + 1); + Numerator.Table.CopyWidthAlignedCenterTo(res, 0); + Denominator.Table.CopyWidthAlignedCenterTo(res, Numerator.Height + 1); foreach (var x in 0..(res.GetLength(1) - 1)) - res[num.Height, x] = '-'; + res[Numerator.Height, x] = '-'; return res; } } -public sealed class BinaryOpFigure : Figure +public sealed record BinaryOpFigure(Figure Left, Figure Right, char Operator) : Figure { - public BinaryOpFigure(Figure left, Figure right, char op) : base(GenerateTable(left, right, op)) { } - - private static char[,] GenerateTable(Figure left, Figure right, char op) + protected override char[,] GenerateTable() { - var res = new char[Math.Max(left.Height, right.Height), left.Width + 3 + right.Width].WithSpaces(); + var res = new char[Math.Max(Left.Height, Right.Height), Left.Width + 3 + Right.Width].WithSpaces(); - left.table.CopyHeightAlignedCenterTo(res, 0); - right.table.CopyHeightAlignedCenterTo(res, left.Width + 3); + Left.Table.CopyHeightAlignedCenterTo(res, 0); + Right.Table.CopyHeightAlignedCenterTo(res, Left.Width + 3); - res[res.GetLength(0) / 2, left.Width + 1] = op; + res[res.GetLength(0) / 2, Left.Width + 1] = Operator; return res; } } -public sealed class RadicalFigure : Figure +public sealed record RadicalFigure(Figure Expression, Figure? Power) : Figure { - public RadicalFigure(Figure expr, Figure? pow) : base(GenerateTable(expr, pow)) { } - - private static char[,] GenerateTable(Figure expr, Figure? pow) + protected override char[,] GenerateTable() { // // /----| <-- this is right glyph (the '|' thing) @@ -114,14 +105,14 @@ public RadicalFigure(Figure expr, Figure? pow) : base(GenerateTable(expr, pow)) const double LeftGlyphShare = 0.3; const double RightGlyphShare = 0.2; - var leftGlyphSize = (int)(LeftGlyphShare * expr.Height) + 1; - var rightGlyphSize = (int)(RightGlyphShare * expr.Height) + 1; + var leftGlyphSize = (int)(LeftGlyphShare * Expression.Height) + 1; + var rightGlyphSize = (int)(RightGlyphShare * Expression.Height) + 1; - var resWidth = leftGlyphSize + expr.Height + expr.Width + 1; - var resHeight = expr.Height + 1; + var resWidth = leftGlyphSize + Expression.Height + Expression.Width + 1; + var resHeight = Expression.Height + 1; var res = new char[resHeight, resWidth].WithSpaces(); - expr.table.CopyTo(res, 1, leftGlyphSize + expr.Height); + Expression.Table.CopyTo(res, 1, leftGlyphSize + Expression.Height); foreach (var i in 0..(leftGlyphSize - 1)) res[resHeight - i - 1, i] = '\\';