<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Munene Ndereba</title>
    <description>The latest articles on DEV Community by Munene Ndereba (@munenendereba).</description>
    <link>https://dev.to/munenendereba</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1169926%2Fea05c379-876a-4219-9fdf-adbf70639980.png</url>
      <title>DEV Community: Munene Ndereba</title>
      <link>https://dev.to/munenendereba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/munenendereba"/>
    <language>en</language>
    <item>
      <title>Solving the Baseball Game in Go</title>
      <dc:creator>Munene Ndereba</dc:creator>
      <pubDate>Mon, 11 Mar 2024 17:20:27 +0000</pubDate>
      <link>https://dev.to/munenendereba/solving-the-baseball-game-in-go-4hej</link>
      <guid>https://dev.to/munenendereba/solving-the-baseball-game-in-go-4hej</guid>
      <description>&lt;p&gt;Below is an interpretation of how to solve the Baseball Game Challenge in Go. Below are the instructions:&lt;/p&gt;

&lt;p&gt;You are keeping score for a baseball game with strange rules. The game consists of several rounds, where the scores of past rounds may affect future rounds' scores.&lt;br&gt;
At the beginning of the game, you start with an empty record. You are given a list of strings ops, where ops[i] is the ith operation you must apply to the record and is one of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An integer x - Record a new score of x.&lt;/li&gt;
&lt;li&gt;"+" - Record a new score that is the sum of the previous two scores. It is guaranteed there will always be two previous scores.&lt;/li&gt;
&lt;li&gt;"D" - Record a new score that is double the previous score. It is guaranteed there will always be a previous score.&lt;/li&gt;
&lt;li&gt;"C" - Invalidate the previous score, removing it from the record. It is guaranteed there will always be a previous score.
Return the sum of all the scores on the record.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is how I solved the challenge in Go. Below are the test cases to help us check our answer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Given input as &lt;code&gt;{"1"}&lt;/code&gt; should return &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Input: &lt;code&gt;{"5", "2", "C", "D", "+"}&lt;/code&gt;. Output: &lt;code&gt;30&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Input: &lt;code&gt;{"5", "-2", "4", "C", "D", "9", "+", "+"}&lt;/code&gt;. Output: &lt;code&gt;27&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the &lt;code&gt;main.go&lt;/code&gt; file, we create a function that takes a string slice as a parameter and returns an int representing the sum of the resulting slice of scores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

func main(){

}

func CalculatePoints(ops []string) int {
    var res int = 0

    return res
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, we need to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loop through the slice&lt;/li&gt;
&lt;li&gt;For every operator, perform the necessary operation&lt;/li&gt;
&lt;li&gt;Append the result to a new slice of numbers&lt;/li&gt;
&lt;li&gt;From the resulting slice of numbers, return their sum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take the first step. We declare a new slice to hold our numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers := []int{}

for i, op := range ops {
    switch op {

        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We check for each condition and then append the result to the numbers as shown below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the operator is a &lt;code&gt;+&lt;/code&gt;, the position will be held by a number that is the result of adding the previous two numbers&lt;/li&gt;
&lt;li&gt;If the operator is a &lt;code&gt;D&lt;/code&gt;, we will double the previous number&lt;/li&gt;
&lt;li&gt;The default expectation is that this is a normal number which we will append to the list
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case "+":
    numbers = append(numbers, numbers[i-1]+numbers[i-2])
case "D":
    numbers = append(numbers, numbers[i-1]*2)
default:
    num, _ := strconv.Atoi(op)
    numbers = append(numbers, num)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that there is one condition missing. But for the three other conditions, this should work. Given an input for instance: &lt;code&gt;{"5", "2", "D", "+"}&lt;/code&gt;, we get expect &lt;code&gt;17&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's add the loop to sum, so we can test with the sample above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for _, num := range numbers {
    res += num
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;main&lt;/strong&gt; function, let's call our function with the above sample. Running the code with &lt;code&gt;go run .&lt;/code&gt; should give &lt;code&gt;17&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    ops := []string{"5", "2", "D", "+"}
    fmt.Println(CalculatePoints(ops))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now consider the unimplemented condition where we have &lt;code&gt;C&lt;/code&gt;, which should delete the previous number from the slice. Given the following sample &lt;code&gt;{"5", "2", "C", "D", "+"}&lt;/code&gt;, we expect the output slice of numbers to look like this &lt;code&gt;{5, 10, 15}&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, add the number 5 to the slice, resulting in &lt;code&gt;{5}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add 2, resulting in &lt;code&gt;{5, 2}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;"C" means we remove the previous number, hence, our slice now looks like &lt;code&gt;{5}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;"D" means we double the previous number, resulting in &lt;code&gt;{5, 10}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;"+" means we add the previous two numbers, resulting in &lt;code&gt;{5, 10, 15}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The sum of the elements in the resulting slice would give &lt;code&gt;30&lt;/code&gt;
Now, note that the operation "C" actually reduces the length of the numbers slice, so that while the &lt;code&gt;ops&lt;/code&gt; slice has &lt;code&gt;len&lt;/code&gt; of 5, our slice of &lt;code&gt;numbers&lt;/code&gt; has only 3. This means that the result of "C" actually deletes its own position, as well as the previous position, reducing the length by 2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the updated function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers := []int{}
removed, j := 0, 0

for i, op := range ops {
    j = i - removed
    switch op {
    case "+":
        numbers = append(numbers, numbers[j-1]+numbers[j-2])
    case "D":
        numbers = append(numbers, numbers[j-1]*2)
    case "C":
        numbers = numbers[:j-1]
        removed += 2
    default:
        num, _ := strconv.Atoi(op)
        numbers = append(numbers, num)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We add two int variables &lt;code&gt;removed&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; initialized to &lt;code&gt;0&lt;/code&gt;. &lt;code&gt;removed&lt;/code&gt; will hold how many positions have been removed by the "C" operation. For every "C" operation, two positions are removed from the &lt;code&gt;numbers&lt;/code&gt; slice. &lt;code&gt;j&lt;/code&gt; holds the current position of the numbers slice. The value of &lt;code&gt;j&lt;/code&gt; is the result of subtracting the current value of &lt;code&gt;i&lt;/code&gt; with the number of positions &lt;code&gt;removed&lt;/code&gt;. If no position has been &lt;code&gt;removed&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; will have the same value.&lt;/p&gt;

&lt;p&gt;Note that the other &lt;code&gt;case&lt;/code&gt;s have also been updated to now use &lt;code&gt;j&lt;/code&gt;, otherwise we would have an &lt;code&gt;out of bounds index&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;Testing with the test cases now gives the correct results. The full code file &lt;code&gt;main.go&lt;/code&gt; now looks like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "strconv"
)

func CalculatePoints(ops []string) int {
    var res int = 0

    numbers := []int{}
    removed, j := 0, 0

    for i, op := range ops {
        j = i - removed
        switch op {
        case "+":
            numbers = append(numbers, numbers[j-1]+numbers[j-2])
        case "D":
            numbers = append(numbers, numbers[j-1]*2)
        case "C":
            numbers = numbers[:j-1]
            removed += 2
        default:
            num, _ := strconv.Atoi(op)
            numbers = append(numbers, num)
        }
    }

    for _, num := range numbers {
        res += num
    }

    return res
}

func main() {
    ops := []string{"5", "2", "C", "D", "+"}
    fmt.Println(CalculatePoints(ops))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add some tests. Create a file called &lt;code&gt;main_test.go&lt;/code&gt; and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "fmt"
    "testing"
)

func TestCalculatePoints(t *testing.T) {
    var tests = []struct {
        ops []string
        sum int
    }{
        {[]string{"5", "2", "C", "D", "+"}, 30},
        {[]string{"1"}, 1},
        {[]string{"5", "-2", "4", "C", "D", "9", "+", "+"}, 27},
    }

    for i, test := range tests {
        ops := test.ops
        sum := test.sum

        testname := fmt.Sprintf("running test %d", i)

        t.Run(testname, func(t *testing.T) {
            res := CalculatePoints(ops)

            if res != sum {
                t.Errorf(`Calculate Points(%s), expected result to be %d, got %d`, ops, sum, res)
            }
        })

    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To execute the tests, run the following: &lt;code&gt;go test -v .&lt;/code&gt; All the tests should pass.&lt;/p&gt;

&lt;p&gt;The full source of the solution can be found on GitHub &lt;a href="https://github.com/munenendereba/baseball-game-go"&gt;Baseball Game&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for reading. Leave a comment on any optimizations you suggest. Let's go!&lt;/p&gt;

</description>
      <category>go</category>
      <category>algorithms</category>
      <category>interview</category>
      <category>challenges</category>
    </item>
  </channel>
</rss>
