|
I have a Number class and a Polynomial class. Certain algorithms are applicable to both by virtue of the fact that both support the arithmetic operations and have additive and multiplicative identities. In order to make the algorithms available to both without code duplication, I'm trying to add a common abstract base class for them, which I'm calling ArithmeticObject. This class needs to provide, among other things, a way to access the identities. When operating on Number objects, the identities are necessarily of type Number, while for Polynomials, they are of type Polynomial. This suggests to me that I need abstract methods with return type ArithmeticObject, which Number and Polynomial each override to return the appropriate objects. On the other hand, the identities are conceptually associated with the types Number and Polynomial, not with specific instances of them, so some kind of static method seems appropriate, but abstract methods can't be static. What is the recommended way to handle this?
|
|
|
|
|
Giving the methods a type argument would allow me to get around making them abstract, which would allow me to make them static and avoid having to call them with respect to an instance:
static ArithmeticObject AdditiveIdentity(Type type)
{
if (type.Equals(typeof(Number)))
return Zero;
return new Polynomial(new List<Integer>());
}
static ArithmeticObject MultiplicativeIdentity(Type type)
{
if (type.Equals(typeof(Number)))
return One;
return new Polynomial(new List<Integer> { One });
}
This still leaves one annoyance, which I didn't mention in the original question: I'm going to have to cast the return value every time I call the method, to either Integer or Polynomial. Since the type of the return value is easy to predict based on the argument, it seems like there might be a way to avoid it, but I've dealt for a long time with similar issues when overloading arithmetic operators, and haven't figured out a good approach yet.
|
|
|
|
|
After more tinkering, though a common base class makes conceptual sense to me, I don't think I can make the details work. The algorithms that apply to both Numbers and Polynomials need to know that the objects they're acting on can be added and multiplied, so I figured I would put methods for those operations in the base class. The problem is, it shouldn't be possible to multiply a Number with a Polynomial, which rules out the obvious choice of something like
protected abstract ArithmeticObject Multiply(ArithmeticObject a);
Maybe I can do something with a generic method?
T Multiply<T>(T a);
Perhaps defining an IArithmetic<t> interface that contains all the necessary operations, and having Number and Polynomial each implement it.
|
|
|
|
|
I was going to suggest this, but you beat me to it.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
I have gotten the code factored and functioning using this interface method, but it does still have the minor annoyance that GetAdditiveIdentity() and GetMultiplicativeIdentity() have to be called with respect to an instance even though they don't depend on the instance - my solution for when they were base class methods doesn't seem to apply when they're interface methods. Is there some other way to make them act static-like?
modified 2-Apr-18 15:02pm.
|
|
|
|
|
public bool IsNumber {get {return (this is Number);} }
public bool IsPolynomial {get {return (this is Polynomial);} }
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
@alexanderkindle
I wonder if a combination of Classes and Extension Methods would be useful ?
Note that in the 'Polynomial class, the overloaded + operator concatenates the two internal List<int> ... but, in the Extension Method 'Add for two 'PolyNomial instances, an actual addition is performed based on ordinal position ... this variation is not meant to be anything but my guessing at the functionality you want
using System.Collections.Generic;
using System.Linq;
namespace YourNameSpace
{
public interface IArithmetic<T>
{
T TValue { set; get; }
}
public interface INumber : IArithmetic<int>
{
}
public interface IPolynomial : IArithmetic<List<int>>
{
}
public interface IOperators<T>
{
T TAdd(T t1, T t2);
}
public class Number : INumber, IOperators<Number>
{
public Number(int value = 0)
{
TValue = value;
}
public int TValue { get; set; }
public static Number operator +(Number n1, Number n2)
{
Number newNumber = new Number();
newNumber.TValue = n1.TValue + n2.TValue;
return newNumber;
}
public Number TAdd(Number t1, Number t2)
{
return t1 + t2;
}
}
public class Polynomial : IPolynomial, IOperators<Polynomial>
{
public Polynomial(params int[] ints)
{
TValue = ints.ToList();
}
public List<int> TValue { get; set; }
public static Polynomial operator +(Polynomial p1, Polynomial p2)
{
Polynomial newPolynomial = new Polynomial();
newPolynomial.TValue = p1.TValue.Concat(p2.TValue).ToList();
return newPolynomial;
}
public Polynomial TAdd(Polynomial t1, Polynomial t2)
{
return t1 + t2;
}
}
public static class ArithmeticExtensions
{
public static Number Add(this Number n1, Number n2)
{
Number n = new Number();
n.TValue += n1.TValue + n2.TValue;
return n;
}
public static Number Add(this Number n1, Polynomial p1)
{
Number n = new Number(n1.TValue);
foreach (int i in p1.TValue)
{
n.TValue += i;
}
return n;
}
public static Polynomial Add(this Polynomial p1, Polynomial p2)
{
Polynomial p;
if (p1.TValue.Count == p2.TValue.Count)
{
p = new Polynomial(p1.TValue.ToArray());
for (int i = 0; i < p.TValue.Count; i++)
{
p.TValue[i] += p2.TValue[i];
}
} else if (p1.TValue.Count < p2.TValue.Count)
{
p = new Polynomial(p2.TValue.ToArray());
for (int i = 0; i < p1.TValue.Count; i++)
{
p.TValue[i] += p1.TValue[i];
}
}
else
{
p = new Polynomial(p1.TValue.ToArray());
for (int i = 0; i < p2.TValue.Count; i++)
{
p.TValue[i] += p2.TValue[i];
}
}
return p;
}
public static Polynomial Add(this Polynomial p1, Number n1)
{
Polynomial p = new Polynomial(p1.TValue.ToArray());
for (int i = 0; i < p.TValue.Count; i++)
{
p.TValue[i] += n1.TValue;
}
return p;
}
}
} Use example:
public void Teat()
{
Number n1, n2;
Polynomial p1, p2;
n1 = new Number(100);
n2 = new Number(200);
p1 = new Polynomial(1,2,3, 4, 5, 6);
p2 = new Polynomial(7,8,9);
var n3 = n1 + n2;
var p3 = p1 + p2;
var p4 = p1.Add(p2);
var p5 = p2.Add(p1);
var p6 = p1.Add(n1);
var n4 = n2.Add(p2);
}
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
modified 3-Apr-18 8:55am.
|
|
|
|
|
Is there a constraint one can add to the type parameter of a generic method to specify that the type implements certain extension methods? If not, I wouldn't think the extension methods would be accessible to the body of the method which, barring some completely different way of structuring things, is something I think I need to be able to do. A sketch of my current solution, where the point of jumping through these structural hoops is to support Exponentiate and ExtendedGCD:
interface IArithmetic<T>
{
T GetAdditiveIdentity();
T GetMultiplicativeIdentity();
T Minus(T n);
T Times(T n);
}
struct Division<T>
{
public T Quotient;
public T Remainder;
}
interface IDivisible<T> : IArithmetic<T>
{
Division<T> EuclideanDivideBy(T divisor);
}
abstract class Number : IArithmetic<Number>
{
...
}
class Integer : Number, IDivisible<Integer>
{
...
}
class Polynomial : IDivisible<Polynomial>
{
...
}
static T Exponentiate<T>(T expBase, Integer exponent) where T : IArithmetic<T>
{
T output = expBase.GetMultiplicativeIdentity();
T baseToAPowerOfTwo = expBase;
Integer two = new Integer(2);
while (exponent.Sign > 0)
{
Division<Integer> division = exponent.EuclideanDivideBy(two);
if (division.Remainder == One)
output = output.Times(baseToAPowerOfTwo);
baseToAPowerOfTwo = baseToAPowerOfTwo.Times(baseToAPowerOfTwo);
exponent = division.Quotient;
}
return output;
}
struct ExtendedGCDInfo<T>
{
public T GCD;
public T ACoefficient;
public T BCoefficient;
public T AOverGCD;
public T BOverGCD;
}
static ExtendedGCDInfo<T> ExtendedGCD<T>(T a, T b) where T : IDivisible<T>
{
ExtendedGCDInfo<T> output = new ExtendedGCDInfo<T>();
output.ACoefficient = a.GetAdditiveIdentity();
output.BCoefficient = a.GetMultiplicativeIdentity();
output.BOverGCD = a.GetMultiplicativeIdentity();
output.AOverGCD = a.GetAdditiveIdentity();
while (!a.Equals(a.GetAdditiveIdentity()))
{
Division<T> division = b.EuclideanDivideBy(a);
T m = output.ACoefficient.Minus(output.BOverGCD.Times(division.Quotient));
T n = output.BCoefficient.Minus(output.AOverGCD.Times(division.Quotient));
b = a;
a = division.Remainder;
output.ACoefficient = output.BOverGCD;
output.BCoefficient = output.AOverGCD;
output.BOverGCD = m;
output.AOverGCD = n;
}
output.GCD = b;
output.BOverGCD = a.GetAdditiveIdentity().Minus(output.BOverGCD);
return output;
}
The most troublesome thing about this approach is that GetAdditiveIdentity and GetMultiplicativeIdentity have to be called with respect to an instance, which isn't such a big deal here, but there's some new functionality for which it's seeming like I'll have to default construct an instance for the sole purpose of getting at the identities. It also seems a bit awkward that I have to define the methods in IArithmetic for Integers even though they're already defined for Numbers, and the functionality is identical, because the return values stipulated by the interface are different, but maybe stuff like that is inevitable no matter what I do.
|
|
|
|
|
Ooh...constructors don't require an instance to call, so instead of guaranteeing the presence of identities using an interface somehow, I could qualify the type parameters of Exponentiate and ExtendedGCD with new(), add parameterless constructors to Number/Integer/Polynomial that return their multiplicative inverses, and get an additive inverse where necessary by subtracting the multiplicative one from itself. Or...I could if Number weren't an abstract class. I don't think the abstractness of Number is negotiable...
|
|
|
|
|
1. E 2. D 3. D 4. B
5. A 6. C 7. E 8. B
9. D 10. C 11. D 12. A
13. A 14. D 15. D 16. E
17. A 18. E 19. A 20. D
A student must correctly answer 15 out of 20 questions to pass the exam.
|
|
|
|
|
We do not do your homework: it is set for a reason. It is there so that you think about what you have been told, and try to understand it. It is also there so that your tutor can identify areas where you are weak, and focus more attention on remedial action.
Try it yourself, you may find it is not as difficult as you think!
If you meet a specific problem, then please ask about that and we will do our best to help. But we aren't going to do it all for you!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
Hiya,
I am a complete beginner and need help with the loop function,
I have written my code but it doesnt run exactly as I need it to. Please help me!!
Florence needs help with C Sharp Programming as soon as possible. Florence wrote:
I am stuck on a basic c# calculator using the loop function, my loop function wont correctly loop.. please help!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Calculatorattemptone
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Calculator");
Console.WriteLine("***********************************************************");
Console.WriteLine("1 - Claculation");
Console.WriteLine("2 - Exit");
Console.Write("Please enter your option here: ");
bool incorrect = true;
while (incorrect)
{
string option = Console.ReadLine();
if (option != "1" || option != "2")
{
incorrect = true;
{
Console.WriteLine("Invalid option");
Console.WriteLine("1 - Claculation");
Console.WriteLine("2 - Exit");
Console.Write("Please enter your option here: ");
}
}
if (option == "2")
{
incorrect = false;
{
System.Environment.Exit(0);
}
}
if (option == "1")
{
incorrect = false;
{
Console.WriteLine("A - Addition");
Console.WriteLine("S - Subtraction");
Console.WriteLine("D - Division");
string equation = Console.ReadLine();
if (equation == "A")
{
equation = "1";
}
else if (equation == "S")
{
equation = "2";
}
else if (equation == "D")
{
equation = "3";
}
else
{
Console.WriteLine("ERROR: Unsupported Calculation");
}
Console.WriteLine("Enter your first number:");
int firstNumber = Int32.Parse(Console.ReadLine());
Console.WriteLine("Enter your second number:");
int ScndNumber = Int32.Parse(Console.ReadLine());
int result;
switch (equation)
{
case "1":
result = (firstNumber + ScndNumber);
Console.WriteLine("RESULT: " + result);
break;
case "2":
result = (firstNumber - ScndNumber);
Console.WriteLine("RESULT: " + result);
break;
case "3":
result = (firstNumber / ScndNumber);
Console.WriteLine("RESULT: " + result);
break;
default:
Console.WriteLine("Error Unsuported Calculation");
break;
}
Console.WriteLine("Press any key to continue....");
Console.ReadKey();
}
}
}
}
}
}
[edit]Code block added - OriginalGriff[/edit]
modified 1-Apr-18 1:56am.
|
|
|
|
|
Indent your code! It makes it so much more readable...I've edited your question and indented it for you.
Now, what's the problem?
You haven't told us anything about what is going wrong:
Quote: help with the loop function,
I have written my code but it doesnt run exactly as I need it to. Please help me!!
Florence needs help with C Sharp Programming as soon as possible. Florence wrote:
I am stuck on a basic c# calculator using the loop function, my loop function wont correctly loop.. please help!! Tells us nothing.
What does it do that you didn't expect, or not do that you did?
What do you do to make it do that?
What results do you get?
What have you tried to investigate the problem?
What does the debugger show you?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
if (option != "1" || option != "2")
{
incorrect = true;
The above statement means that your code will always stop at this point. If the option equals 1, then it is not equal to 2. And if it equals 2 then it is not equal to 1. You should be using the and operator (&& ), thus:
if (option != "1" && option != "2")
{
incorrect = true;
|
|
|
|
|
Nobody helped
modified 31-Mar-18 10:55am.
|
|
|
|
|
Somewhere in your code the object that your variable is referencing has had Dispose called on it, either explicitly or via a using block going out of scope. Start with line 27 of ObjectPool.cs and see what variables are being used, and backtrack to find out which are being Disposed and why.
We can't do that for you: we don't have your code, we don't have your data - and we can't access your HDD, see your screen or read your mind!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
Because youtube tutorials are generally written:
1) By people who have no idea how to make a video.
2) By people who have no idea how to teach, or even explain things.
and
3) By people who have working code, but mostly have no idea how it works or why.
At a guess - and that's all it's going to be, I'm not going near random youtube tutorials - he didn't show you something important or his code just plain doesn't work: Don't Hit Save - Welcome To The Tutorial[^] is timely ...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
|
The quality of the answers you get is directly dictated by the quality of the question you ask.
And knowing how to use the debugger probably would have headed off the question entirely.
|
|
|
|
|
Nobody helped? It's Easter Saturday and this is a volunteer support site. A bit of patience on your part would help.
This space for rent
|
|
|
|
|
Hello guys,
I'm making a small 3D platformer game with Unity, and I got some serious troubles making the player to walk on the rotating platforms, actually it turns out that it is absolutely impossible for me, I really tried everything, I've read probably all articles in the web about rotating platforms, parenting and so on, but nothing seems to help, even though the problem looks very simple.
What I'm doing is when the player jumps on the platform I make him a parent to that platform so he cam move with it, but in the moment I set him as a parent he turns at some degrees left or right(probably depending in the differences between the angle of the platform rotation and the angle of the player), here is a video that illustrates the problem:
err - YouTube[^]
I really have no idea why this happens and I'm so desperate nothing seems to work and if I can't fix it there is no point in continue making the game
Here is my code for parenting to the rotating platform:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
public class PlatformRide : MonoBehaviour
{
public GameObject _parent;
private GameObject _player = null;
void Start()
{
transform.gameObject.GetComponent<Collider>().isTrigger = true;
}
void LateUpdate()
{
if (!Globals.GamePaused)
{
_parent.transform.localRotation = transform.rotation;
}
}
void OnTriggerEnter(Collider col)
{
if (col.name == "CCLSSF_player")
{
_player = col.gameObject;
_player.transform.parent = _parent.transform;
}
}
void OnTriggerStay(Collider col)
{
if (col.name == "CCLSSF_player")
{
_player = col.gameObject;
_player.transform.parent = _parent.transform;
}
}
void OnTriggerExit(Collider col)
{
if (col.name == "CCLSSF_player")
{
_player.transform.parent = null;
_player = null;
}
}
}
I'm using the standard Unity FPS Controller, what could be wrong? Please help,
thank you in advance.
Even though I'm an artist throughout the years spent in coding I started to see that the programming is actually the real art .
|
|
|
|
|
If it works similar to WinForms, then the player would be confined to moving within that platform, not on top of it. I'd try adding some invisible container (Panel?) above the platform, same length as the platfrom, and a bit taller than the player. Next, set that as the parent.
Not sure if that would help, but the terms you're using gives me hope that it'll work similar
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
Thank you Eddy, yes I did it in a similar way you described, fortunately last night when I was scrolling down Google results(again....) I found this article:
Preserving the players rotation on rotating platforms : Unity3D[^]
The user there experienced the exact same problem as mine and he managed to solve it by changing the 'localRotation' to 'rotation' in the MouseLook.cs class from the standard Unity FPS controller, here is the code for the fix(this is the last if... statement from LookRotation void:
if (clampVerticalRotation)
m_CameraTargetRot = ClampRotationAroundXAxis(m_CameraTargetRot);
if (smooth)
{
character.localRotation = Quaternion.Slerp(character.localRotation, m_CharacterTargetRot,
smoothTime * Time.deltaTime);
camera.localRotation = Quaternion.Slerp(camera.localRotation, m_CameraTargetRot,
smoothTime * Time.deltaTime);
}
else
{
character.rotation = m_CharacterTargetRot;
camera.localRotation = m_CameraTargetRot;
}
I'm sooo very glad I found this solution it saved my *ss I'm sharing it, so anyone who have similar problem might benefit.
Even though I'm an artist throughout the years spent in coding I started to see that the programming is actually the real art .
|
|
|
|
|