Avatar of artemkorsakov

artemkorsakov's solution

to Largest Series Product in the Go Track

Published at Feb 26 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 go test from within the exercise directory.

If the test suite contains benchmarks, you can run these with the --bench and --benchmem flags:

go test -v --bench . --benchmem

Keep in mind that each reviewer will run benchmarks on a different machine, with different specs, so the results from these benchmark tests may vary.

Further information

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

Source

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

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

cases_test.go

package lsproduct

// Source: exercism/problem-specifications
// Commit: 85da7a5 largest-series-product: testdata to have standard error indicators (#1331)
// Problem Specifications Version: 1.2.0

var tests = []struct {
	digits  string
	span    int
	product int64
	ok      bool
	error   string
}{
	{"29", 2, 18, true, ""},
	{"0123456789", 2, 72, true, ""},
	{"576802143", 2, 48, true, ""},
	{"0123456789", 3, 504, true, ""},
	{"1027839564", 3, 270, true, ""},
	{"0123456789", 5, 15120, true, ""},
	{"73167176531330624919225119674426574742355349194934", 6, 23520, true, ""},
	{"0000", 2, 0, true, ""},
	{"99099", 3, 0, true, ""},
	{"123", 4, -1, false, "span must be smaller than string length"},
	{"", 0, 1, true, ""},
	{"123", 0, 1, true, ""},
	{"", 1, -1, false, "span must be smaller than string length"},
	{"1234a5", 2, -1, false, "digits input must only contain digits"},
	{"12345", -1, -1, false, "span must be greater than zero"},
}

largest_series_product_test.go

package lsproduct

import "testing"

func TestLargestSeriesProduct(t *testing.T) {
	for _, test := range tests {
		p, err := LargestSeriesProduct(test.digits, test.span)
		if test.ok {
			// we do not expect error
			if err != nil {
				t.Fatalf("LargestSeriesProduct(%s, %d) returned error %q.  "+
					"Error not expected.",
					test.digits, test.span, err)
			}

			if int64(p) != test.product {
				t.Fatalf("LargestSeriesProduct(%s, %d) = %d, want %d",
					test.digits, test.span, p, test.product)
			}
		} else { // expect error
			// check if err is of error type
			var _ error = err

			// we expect error
			if err == nil {
				t.Fatalf("LargestSeriesProduct(%s, %d) = %d, %v."+
					"  Expected error got nil",
					test.digits, test.span, p, err)
			}
		}
	}
}

func BenchmarkLargestSeriesProduct(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, test := range tests {
			LargestSeriesProduct(test.digits, test.span)
		}
	}
}
package lsproduct

import (
	"errors"
	"regexp"
)

var reg, _ = regexp.Compile("^\\d*$")

// LargestSeriesProduct calculates the largest product for a contiguous substring of digits of length span.
func LargestSeriesProduct(digits string, span int) (int, error) {
	if len(digits) < span {
		return -1, errors.New("span must be smaller than string length")
	}
	if span < 0 {
		return -1, errors.New("span must be greater than zero")
	}
	if !reg.MatchString(digits) {
		return -1, errors.New("digits input must only contain digits")
	}

	max := 0
	for i := 0; i <= len(digits)-span; i++ {
		mul := GetProduct(digits, span, i)
		if mul > max {
			max = mul
		}
	}

	return max, nil
}

// GetProduct calculates the product for a contiguous substring of digits of length span from a given index.
func GetProduct(digits string, span int, index int) int {
	res := 1
	for i := 0; i < span; i++ {
		res = res * (int(digits[index+i]) - '0')
	}
	return res
}

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?