2
\$\begingroup\$

Example input :

A) 1, 2

B) 2, 8

C) 7, 8

Required Result : 8, 10

The output from the program with this input should be A + C.

Few notes :

  1. We can only combine 2 sets.
  2. There must always be exactly one pair (or a single set) which sums up to the specified result.
  3. Input will always be in this format x,y.

Set

internal class Set
{
    protected bool Equals(Set other)
    {
        return Number01 == other.Number01 && Number02 == other.Number02;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Set) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (Number01*397) ^ Number02;
        }
    }

    public int Number01 { get; }
    public int Number02 { get; }

    public Set(int number01, int number02)
    {
        Number01 = number01;
        Number02 = number02;
    }

    public static Set operator +(Set set1, Set set2)
    {
        return new Set(set1.Number01 + set2.Number01, set1.Number02 + set2.Number02);
    }
}

Static void Main

    static void Main(string[] args)
    {
        Console.Write("Length : ");
        int inputLength = int.Parse(Console.ReadLine());
        string[] inputSets = new string[inputLength];
        Set[] sets = new Set[inputLength];

        for (int i = 0; i < inputLength; i++)
        {
            Console.Write($"Enter set #{i + 1} : ");
            inputSets[i] = Console.ReadLine();
        }

        Console.Write("Enter the expected result : ");
        string[] answer = Console.ReadLine().Split(',');
        Set requiredResult = new Set(int.Parse(answer[0]), int.Parse(answer[1]));

        for (int i = 0; i < inputSets.Length; i++)
        {
            string[] numbersFromSet = inputSets[i].Split(',');
            sets[i] = new Set(int.Parse(numbersFromSet[0]), int.Parse(numbersFromSet[1]));
        }

        foreach (Set set in sets)
        {
            if (Equals(set, requiredResult))
            {
                Console.WriteLine("First set : " + set.Number01 + " " + set.Number02);
                Console.WriteLine("Result : " + requiredResult.Number01 + " " + requiredResult.Number02);
                Console.ReadKey();
                return;
            }
        }

        for (int i = 0; i < sets.Length; i++)
        {
            for (int j = i + 1; j < sets.Length; j++)
            {
                if (Equals(sets[i] + sets[j], requiredResult))
                {
                    Console.WriteLine("First set : " + sets[i].Number01 + " " + sets[i].Number02);
                    Console.WriteLine("Second set : " + sets[j].Number01 + " " + sets[j].Number02);
                    Console.WriteLine("Result : " + requiredResult.Number01 + " " + requiredResult.Number02);
                    Console.ReadKey();
                    return;
                }
            }
        }
        Console.ReadKey();
    }
\$\endgroup\$
  • \$\begingroup\$ You use the Equals method in Main in some ifs like if (Equals(set, requiredResult)). Did you forget to post this one? \$\endgroup\$ – t3chb0t Dec 19 '16 at 11:31
  • \$\begingroup\$ No error checking in split or int.Parse. Ask for desired result first and if you don't allow negative can throw some out. If you are only going to return the first you can check against prior as it is entered. Can use HS to eliminate duplicates. Rather than add and compare. subtract once and look for specific. \$\endgroup\$ – paparazzo Dec 19 '16 at 12:20
2
\$\begingroup\$

I usually don't like the Tuple but in this case it looks like a perfect example where I think you'd be much better off if you used one instead of the Set (that I'd name Pair).

The Tuple already can do all the equality stuff so you don't need to write it yourself or you can derive your class from the Tuple so that is supports the + operator.

class Pair : Tuple<int, int>
{
    public Pair(int item1, int item2) : base(item1, item2) {}

    public static Pair operator +(Pair left, Pair right)
    {
        return new Pair(left.Item1 + right.Item1, left.Item2 + right.Item2);
    }
}

Example:

var pair1 = new Pair(1, 2);
var pair2 = new Pair(1, 2);
var pair3 = new Pair(1, 3);

(pair1.Equals(pair2)).Dump(); // True
(pair1.Equals(pair3)).Dump(); // False
\$\endgroup\$
1
\$\begingroup\$

if (Equals(set, requiredResult))

As @t3chb0t points out, you're calling Equals rather than [set object].Equals in Main. In effect you are saying this.Equals(set, requiredResult), this being the class containing Main. The object class implements Equals, and all classes inherit from object, so what you're ultimately calling is object.Equals. In other words, you've gone to the trouble of overriding Equals in your Set class but you're not using it. This will lead to unexpected results given you expect equality to be determined by the content of the properties, rather than by reference (which is what object.Equals will do for classes).

Another issue is you override Equals but don't override the equality operators. This means that set1.Equals(set2) will return a different result than set1 == set2, which is surely undesirable.

\$\endgroup\$
  • \$\begingroup\$ Thank you for pointing out the fact that i didnt overload the != & == operators but since im not using them i decided they will just take more space. I picked t3chb0t's answer because using his approach not only that it shortens the code but also does all the work i might need in the future. \$\endgroup\$ – Denis Dec 19 '16 at 12:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.