Avatar of Alexpud

Alexpud's solution

to Largest Series Product in the C# Track

Published at Oct 02 2019 · 0 comments
Instructions
Test suite
Solution

Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.

For example, for the input '1027839564', the largest product for a series of 3 digits is 270 (9 * 5 * 6), and the largest product for a series of 5 digits is 7560 (7 * 8 * 3 * 9 * 5).

Note that these series are only required to occupy adjacent positions in the input; the digits need not be numerically consecutive.

For the input '73167176531330624919225119674426574742355349194934', the largest product for a series of 6 digits is 23520.

Running the tests

To run the tests, run the command dotnet test from within the exercise directory.

Initially, only the first test will be enabled. This is to encourage you to solve the exercise one step at a time. Once you get the first test passing, remove the Skip property from the next test and work on getting that test passing. Once none of the tests are skipped and they are all passing, you can submit your solution using exercism submit LargestSeriesProduct.cs

Further information

For more detailed information about the C# track, including how to get help if you're having trouble, please visit the exercism.io C# language page.

Source

A variation on Problem 8 at Project Euler http://projecteuler.net/problem=8

LargestSeriesProductTest.cs

// This file was auto-generated based on version 1.2.0 of the canonical data.

using System;
using Xunit;

public class LargestSeriesProductTest
{
    [Fact]
    public void Finds_the_largest_product_if_span_equals_length()
    {
        Assert.Equal(18, LargestSeriesProduct.GetLargestProduct("29", 2));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_find_the_largest_product_of_2_with_numbers_in_order()
    {
        Assert.Equal(72, LargestSeriesProduct.GetLargestProduct("0123456789", 2));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_find_the_largest_product_of_2()
    {
        Assert.Equal(48, LargestSeriesProduct.GetLargestProduct("576802143", 2));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_find_the_largest_product_of_3_with_numbers_in_order()
    {
        Assert.Equal(504, LargestSeriesProduct.GetLargestProduct("0123456789", 3));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_find_the_largest_product_of_3()
    {
        Assert.Equal(270, LargestSeriesProduct.GetLargestProduct("1027839564", 3));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_find_the_largest_product_of_5_with_numbers_in_order()
    {
        Assert.Equal(15120, LargestSeriesProduct.GetLargestProduct("0123456789", 5));
    }

    [Fact(Skip = "Remove to run test")]
    public void Can_get_the_largest_product_of_a_big_number()
    {
        Assert.Equal(23520, LargestSeriesProduct.GetLargestProduct("73167176531330624919225119674426574742355349194934", 6));
    }

    [Fact(Skip = "Remove to run test")]
    public void Reports_zero_if_the_only_digits_are_zero()
    {
        Assert.Equal(0, LargestSeriesProduct.GetLargestProduct("0000", 2));
    }

    [Fact(Skip = "Remove to run test")]
    public void Reports_zero_if_all_spans_include_zero()
    {
        Assert.Equal(0, LargestSeriesProduct.GetLargestProduct("99099", 3));
    }

    [Fact(Skip = "Remove to run test")]
    public void Rejects_span_longer_than_string_length()
    {
        Assert.Throws<ArgumentException>(() => LargestSeriesProduct.GetLargestProduct("123", 4));
    }

    [Fact(Skip = "Remove to run test")]
    public void Reports_1_for_empty_string_and_empty_product_0_span_()
    {
        Assert.Equal(1, LargestSeriesProduct.GetLargestProduct("", 0));
    }

    [Fact(Skip = "Remove to run test")]
    public void Reports_1_for_nonempty_string_and_empty_product_0_span_()
    {
        Assert.Equal(1, LargestSeriesProduct.GetLargestProduct("123", 0));
    }

    [Fact(Skip = "Remove to run test")]
    public void Rejects_empty_string_and_nonzero_span()
    {
        Assert.Throws<ArgumentException>(() => LargestSeriesProduct.GetLargestProduct("", 1));
    }

    [Fact(Skip = "Remove to run test")]
    public void Rejects_invalid_character_in_digits()
    {
        Assert.Throws<ArgumentException>(() => LargestSeriesProduct.GetLargestProduct("1234a5", 2));
    }

    [Fact(Skip = "Remove to run test")]
    public void Rejects_negative_span()
    {
        Assert.Throws<ArgumentException>(() => LargestSeriesProduct.GetLargestProduct("12345", -1));
    }
}
using System;

public static class LargestSeriesProduct
{
    public static long GetLargestProduct(string digits, int span)
    {
        if (span == 0)
        {
            return 1;
        }

        ThrowIfInvalidInputs(digits, span);

        long largestProduct = 0;
        long currentSpanProduct = 1;
        for (int i = 0; i <= digits.Length - span; i++)
        {
            currentSpanProduct = 1;
            for (int j = i; j <= i + (span - 1); j++)
            {
                var digit = (long)char.GetNumericValue(digits[j]);
                ThrowIfInvalidDigit(digit);
                currentSpanProduct *= digit;
            }
            largestProduct = currentSpanProduct > largestProduct ? currentSpanProduct : largestProduct;
        }
        return largestProduct;
    }

    private static void ThrowIfInvalidDigit(long digit)
    {
        if (digit < 0)
        {
            throw new ArgumentException("Can't have non digit characters");
        }
    }

    private static void ThrowIfInvalidInputs(string digits, int span)
    {
        if (string.IsNullOrWhiteSpace(digits))
        {
            throw new ArgumentException("Digits can't be null or empty");
        }

        if (span < 0)
        {
            throw new ArgumentException("Span can't be negative");
        }

        if (digits.Length < span)
        {
            throw new ArgumentException("Span can't be larger than the digits");
        }
    }
}

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?