AOC第2天 - 岩石剪刀
#初学者 #编程 #go #adventofcode

岩石剪刀ð§»â

Question

精灵开始在海滩上建立营地。为了确定谁的帐篷最接近零食存储,已经进行了巨大的岩石剪刀锦标赛。

上帝的描述总是纯金...现在让我们直接进去。

我们获得了一个字符串,我们的“策略指南”代表岩石,纸,剪刀变成决定。
字符串分为两列,第一个代表第一个玩家的决定,第二个列的决定。
例如:

A Y
B X
C Z

我们也被告知以下内容:
适用于播放器1- a =岩石,b =纸,c =剪刀
对于玩家2 -x =岩石,y =纸,z =剪刀
我们还获得了结果表的分数表,例如我们做出的决定,例如胜利为6分,选择纸张是2分,等等...

...

喜欢以前的问题,我们将从分析我们的输入

开始

解析

我们可以(看看我在那里做什么?),有几个选择可以代表我们的游戏

func parse(raw string) [][]string {
    chunks := strings.Split(string(raw), "\n")
    pairs := make([][]string, len(chunks))
    for i := range pairs {
        pairs[i] = strings.Split(chunks[i], " ")
    }

    return pairs
}
// example output
// [ [A, Y], [B, X], [C, Z] ]

make函数在我们的数组

的特定,指定的大小中分配了一段记忆

第1部分

如果我们完全按照策略指南中的指示,我们被要求提供总分。
让我们考虑一下,有几种方法可以解决这个问题,我们可以使用一堆if语句或一些精美的模式匹配,因为GO没有模式匹配,我不想写一吨if0陈述我们将采用混合方法。
我们将创建3个不同的映射:

  1. 代表我们选择的要点,例如岩石,纸或剪刀
  2. 获胜状态,这意味着如果我们选择X,其他玩家需要选择什么才能赢得我们
  3. 领带状态,与.2基本相同
scores := map[string]int{
    "X": 1,
    "Y": 2,
    "Z": 3,
}

// If I choose X(Rock) I need him to choose C(scissors) in order to win
win := map[string]string{
    "X": "C", 
    "Y": "A",
    "Z": "B",
}

tie := map[string]string{
    "X": "A",
    "Y": "B",
    "Z": "C",
}

我们没有考虑到失去状态,因为它的本质上是no-op(0分)

在这些地图上构建和我们的解析逻辑上,我们现在可以使用以下代码来解决第一部分

func part1(raw []byte) int {

    pairs := parse(string(raw))

    // X Rock, Y Paper, Z Scissors
    scores := map[string]int{
        "X": 1,
        "Y": 2,
        "Z": 3,
    }

    win := map[string]string{
        "X": "C",
        "Y": "A",
        "Z": "B",
    }

    tie := map[string]string{
        "X": "A",
        "Y": "B",
        "Z": "C",
    }

    score := 0
    for _, pair := range pairs {
        his := pair[0]
        my := pair[1]
        score += scores[my]
        if win[my] == his {
            score += WINNING_POINTS
        }

        if tie[my] == his {
            score += TIE_POINTS
        }

    }
    return score

}
// output for part 1 based on the example is
// 15 -> (8 + 1 + 6)

在每次循环迭代时,我们首先根据我们的选择添加点score += scores[my],然后检查his Move是否是根据我们的玩家选择所需的,以获胜或获得平局,如果是,我们将必要的点添加到我们的总得分。

第2部分

在第二部分中,偷偷摸摸的精灵开了一点。
代替我们的列代表我们的动作,它代表了x =输,y = tie和z = win的转弯结果,我们需要相应地选择我们的选择。
例如,让我们看一下第一个转弯A Y,这对的新含义是“玩家一选择的摇滚,游戏以平局结束”,我们可以创建新的映射,新映射将在播放器1之间选择和选择播放器2需要做出某种状态,例如获胜,输,领带等...
由于它与第1部分非常相似,因此我们将直接跳下并将第2部分视为一个整体

func part2(raw []byte) int {

    var pairs = parse(string(raw))

    // X Lose, Y Tie, Z Win
    scores := map[string]int{
        "X": 1,
        "Y": 2,
        "Z": 3,
    }

    win := map[string]string{
        "C": "X",
        "A": "Y",
        "B": "Z",
    }

    tie := map[string]string{
        "A": "X",
        "B": "Y",
        "C": "Z",
    }

    lose := map[string]string{
        "A": "Z",
        "B": "X",
        "C": "Y",
    }
    score := 0

    for _, pair := range pairs {
        hisMove := pair[0]
        myMove := pair[1]

                // we lose
        if myMove == "X" {
            score += scores[lose[hisMove]]
        }
                // we end in a tie
        if myMove == "Y" {
            score += TIE_POINTS
            score += scores[tie[hisMove]]
        }
                // we win
        if myMove == "Z" {
            score += WINNING_POINTS
            score += scores[win[hisMove]]
        }
    }
    return score
}

对于每个所需状态,我们检查基于玩家2选择需要执行的操作,然后将其传递给scores Map。

就是这样,我们都用纸,岩石,剪刀来完成,我必须承认,我认为这不会如此混乱ð€£

您可以找到完整的代码here
感谢您的阅读!