0

Daily Challenge #0

Cześć. Postanowiłem zrobić lekką gimnastykę mózgu wieczorami i zapisałem się na Daily Coding Problem. Od dzisiaj postaram się każdego dnia rozwiązywać zadanie dostarczane dla subskrybentów.

Zadania są raczej łatwe i po rozwiązaniu pierwszego odnoszę wrażenie, że nie zostały dopasowane do języków wysokiego poziomu. Mimo to, chcę się „pobawić”. 😉

Swoimi poczynaniami będę się dzielić we wpisach. Kod dostępny jest również na GitHubie.

Wpis ten należy do cyklu Daily Challenge. W cyklu tym rozwiązuję każdego dnia nowe zadanie. Zadanie te traktuję w taki sposób, jakbym dostał je na rozmowie kwalifikacyjnej i miał coś wymyślić. Implementuję pierwszą myśl jaka przyjdzie mi do głowy. Nie musi być ona (zazwyczaj nie będzie) najlepszym rozwiązaniem. Chodzi po prostu o zabawę i sprawdzenie jakbym sobie poradził z podobnym wyzwaniem. Zaimplementowane rozwiązanie nie jest z reguły tłumaczone, jeżeli masz pytania możesz je zadawać w komentarzach. Wszystkie zadania udostępniane są subskrybentom Daily Coding Problem.

Zadanie

Treść dzisiejszego zadania została zaproponowana przez Ubera i brzmi następująco:

Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i. For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected output would be [2, 3, 6]. Follow-up: what if you can’t use division?

Banał. Dobra, zaczynamy!

Testy

Oczywiście na początku napisałem testy sprawdzające (do zaproponowanych przykładów dodałem jeden „wrażliwy”). Kod przedstawia się następująco:

[TestMethod]
public void DailyChallenge_0()
{
    DailyChallenge0 dc = new DailyChallenge0();
    int[] inputA = new int[] { 1, 2, 3, 4, 5 };
    int[] inputB = new int[] { 3, 2, 1 };
    int[] inputC = new int[] { 3, 2, 0 };
    int[] outputA = dc.Proceed(inputA);
    int[] outputB = dc.Proceed(inputB);
    int[] outputC = dc.Proceed(inputC);
    Test(new int[] { 120, 60, 40, 30, 24 }, outputA);
    Test(new int[] { 2, 3, 6 }, outputB);
    Test(new int[] { 0, 0, 6 }, outputC);
}
 
private void Test(int[] tableA, int[] tableB)
{
    Assert.AreEqual(tableA.Length, tableB.Length);
    for (int i = 0; i < tableA.Length; ++i)
    {
        Assert.AreEqual(tableA[i], tableB[i]);
    }
}

Implementacja #0

Na początku łatwiejszy wariant. Użyłem jednak tego dzielenia, którego zabronili.

public int[] Proceed(int[] input)
{
    int[] result = new int[input.Length];
    for (int index = 0; index < input.Length; ++index)
    {
        result[index] = Product(input) / input[index];
    }
    return result;
}
 
private int Product(IEnumerable<int> ints)
{
    int result = 1;
    foreach (int i in ints)
    {
        result *= i;
    }
    return result;
}

Kod działa dla przykładów podanych w treści zadania, jednak nie działa dla mojego przypadku. Trzeba to jednak poprawić.

Implementacja #1

W takim razie zastosowałem się do zaleceń i wywaliłem dzielenie. Wygląda to teraz tak:

public int[] Proceed(int[] input)
{
    int[] result = new int[input.Length];
    for (int index = 0; index < input.Length; ++index)
    {
        int pivot = 0;
        result[index] = Product(input.Where(x => pivot++ != index));
    }
    return result;
}
 
private int Product(IEnumerable<int> ints)
{
    int result = 1;
    foreach (int i in ints)
    {
        result *= i;
    }
    return result;
}

Ta implementacja zdaje wszystkie testy.

Mission Complete

Zadanie banalne, czas realizacji to koło 2-3 min (pisanie tych durnych tablic do testów trochę zajmuje).

Zadania przedstawione w ramach tego cyklu można pewnie zaimplementować na kilka sposobów. Mój może nie być najlepszy, jednak moim celem jest napisać kod tak jakbym miał na to kilka minut na rozmowie kwalifikacyjnej. Ma po prostu robić swoje. Optymalizacja to już czysta przyjemność.

Pozdro!

Patryk Bogdański

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.