wizzard: (Default)
[personal profile] wizzard

Вчера после разнообразных бредодискуссий мне внезапно вспомнилось вот это: Multi-Dimensional Analog Literals

(Для тех, кто не понял, что это такое и зачем оно:
каждая такая штука это выражение. после его вычисления получается обьект со свойствами Width, Height и Depth, соответствующими реальным размерам обьекта в коде :))

Где-то 15 минут втыкания на темплейты, “блин, я их не понимаю. и еще, а почему в C# нет темплейтов?” –> хм, стоп, а зачем нам здесь вообще темплейты?

Линейный литерал получился достаточно тривиальным, жаль, что не с таким красивым синтаксисом, плоский – тоже достаточно быстро. С трехмерным пришлось помучиться. Но не прошло и 4 часов, как на свет явилось


чудовище:

Использование:

private static void Main(string[] args)
{
var I = new AnalogLiteral();
var o = new AnalogLiteral();
var L = new AnalogLiteral();
//2
Console.WriteLine((o-0-o).ToString());
//Point (a point does not have a size)
Console.WriteLine((o).ToString());
//6
Console.WriteLine(o-o-0-o-0-o-o);
//7x3
var a = o-o-0-o-o-o-o-o
| !
! !
! !
o-o-o-o-0-o-o-o;
Console.WriteLine(a.ToString());
//8x3
var b = o-0-0-o-0-o-o-o-o
| !
! !
! !
o-o-o-o-o-0-o-o-o;
Console.WriteLine(b.ToString());
//8x4
var b2 = o-o-0-o-o-o-o-o-0
| !
! !
! !
! !
o-o-0-o-o-o-o-o-o;
Console.WriteLine(b2.ToString());
//2x4x2
var c = o-o-o
|L & L
| L & L
| o-o-o
| ! !
o | !
L | !
L| !
o-o-o;
Console.WriteLine(c.ToString());
//3x4x2
var d = o-0-o-o
|L & L
| L & L
| o-o-o-o
| ! !
o | !
L | !
L| !
o-0-o-o;

Console.WriteLine(d.ToString());
//3x5x2
var d2= o-o-o-o
|L & L
| L & L
| o-o-0-o
| ! !
! ! !
o | !
L | !
L| !
o-o-o-o;

Console.WriteLine(d2.ToString());
//3x5x3
var d3= 0-o-o-0
|L & L
| L & L
| L & L
| 0-o-o-o
| ! !
! ! !
o | !
L | !
L | !
L| !
o-0-o-o;

Console.WriteLine(d3.ToString());
//3x12x3
var e = o-o-o-o
|L & L
| L & L
| L & L
| o-o-o-o
| ! !
! ! !
! ! !
! ! !
! ! !
! ! !
! ! !
! ! !
o | !
L | !
L | !
L| !
o-o-o-o;
Console.WriteLine(e.ToString());
//5x14x5
var f = o-o-o-o-o-o
|L & L
| L & L
| L & L
| L & L
| L & L
| o-o-o-o-o-o
| ! !
! ! !
! ! !
! ! !
! ! !
! ! !
! ! !
! ! !
o | !
L | !
L | !
L | !
L | !
L| !
o-o-o-o-o-o;
Console.WriteLine(f.ToString());
Console.ReadLine();
}

Сам класс:


чудовище 2:
 
 



public class AnalogLiteral
{
int d1, d2, d3;
/// <summary>
/// Is the literal already constructed and frozen?
/// </summary>
public bool Frozen { get; private set; }
AnalogLiteral(int d1, int d2, int d3)
{
if (d1 <= 0) throw new ArgumentException("d1");
if (d2 <= 0) throw new ArgumentException("d2");
if (d3 <= 0) throw new ArgumentException("d3");
this.d1 = d1;
this.d2 = d2;
this.d3 = d3;
this.Frozen = false;
}
AnalogLiteral(int d1, int d2) : this(d1, d2, 1) { }
AnalogLiteral(int d1) : this(d1, 1, 1) { }
public AnalogLiteral() : this(1, 1, 1) { }
public static implicit operator int(AnalogLiteral a)
{
int w, h, d;
int sz = Freeze(out w, out h, out d, a);
return sz;
}
public static implicit operator AnalogLiteral(int i)
{
if (i == 0) return new AnalogLiteral(); // 0 = point
if (i < 0) throw new ArgumentException("i");
return new AnalogLiteral(i) { Frozen = true };
}
/// <summary>
/// convert from evil form to normal form
/// </summary>
static int Freeze(out int w, out int h, out int d, AnalogLiteral a)
{
if (a.Frozen)
{
w = a.d1;
h = a.d2;
d = a.d3;
}
else
{
if (a.d1 == 1 && a.d2 == 1 && a.d3 == 1)
{
throw new InvalidOperationException("You can't freeze point literals!");
}
a.Frozen = true;
if (a.d3 == 1)
{
w = a.d1 - 1;
h = 1;
d = 1;
}
else if (a.d3 == 2)
{
w = ((a.d1 - 2) / 2);
h = ((a.d2 - 1) / 2);
d = 1;
}
else
{
d = (a.d3 - 4) / 3;
h = (a.d2 - 1) / 3;
w = (a.d1 - 2 - d * 2) / 3;
}
a.d1 = w;
a.d2 = h;
a.d3 = d;
}
return w * h * d;
}
public int Width
{
get
{
int w, h, d;
int sz = Freeze(out w, out h, out d, this);
return w;
}
}
public int Height
{
get
{
int w, h, d;
int sz = Freeze(out w, out h, out d, this);
return h;
}
}
public int Depth
{
get
{
int w, h, d;
int sz = Freeze(out w, out h, out d, this);
return d;
}
}
public static AnalogLiteral operator |(AnalogLiteral a, AnalogLiteral b)
{
if (a.Frozen || b.Frozen) throw new ArgumentException("You can't modify frozen literals!");
return new AnalogLiteral(a.d1 + b.d1,
a.d2 + b.d2, a.d3 + b.d3);
}
public static AnalogLiteral operator !(AnalogLiteral a)
{
if (a.Frozen) throw new ArgumentException("You can't modify frozen literals!");
return new AnalogLiteral(a.d1, a.d2 + 1, a.d3);
}
public static AnalogLiteral operator -(AnalogLiteral a, AnalogLiteral b)
{
if (a.Frozen || b.Frozen) throw new ArgumentException("You can't modify frozen literals!");
return new AnalogLiteral(Math.Max(a.d1, b.d1) + 1,
Math.Max(a.d2, b.d2), Math.Max(a.d3, b.d3));
}

public static AnalogLiteral operator &(AnalogLiteral a, AnalogLiteral b)
{
if (a.Frozen || b.Frozen) throw new ArgumentException("You can't modify frozen literals!");
return new AnalogLiteral(Math.Max(a.d1, b.d1),
Math.Max(a.d2, b.d2), Math.Max(a.d3, b.d3) + 1);
}

public override string ToString()
{
if (d1 == 1 && d2 == 1 && d3 == 1 && Frozen == false)
{
return "<Point>";
}
else
{
return String.Format("<{0}; {1}; {2}>", this.Width, this.Height, this.Depth);
}
}

}

 
На умножение и деление меня, правда, не хватило. Но их, вроде, достаточно тривиально дописать…
(will be screened)
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

Profile

wizzard: (Default)
wizzard

January 2019

S M T W T F S
  12 345
6789101112
1314 1516171819
202122 23242526
2728293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 21st, 2025 09:08 pm
Powered by Dreamwidth Studios