第六届字节跳动青训营第二课 | 豆包MarsCode AI 刷题

45 阅读9分钟

打点计数器的区间合并

问题描述

小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。

例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。


测试样例

样例1:

输入:inputArray = [[1, 4], [7, 10], [3, 5]]
输出:9

样例2:

输入:inputArray = [[1, 2], [6, 10], [11, 15]]
输出:12

样例3:

输入:inputArray = [[1, 3], [2, 6], [8, 10]]
输出:9

:::success 用map

:::

def solution(inputArray):
    # Please write your code here
    m = {}
    count = 0
    for array in inputArray:
        for i in range(array[0], array[1]+1):
            if not m.get(i):
                m[i] = True
                count += 1
    #print(count)
    return count

if __name__ == "__main__":
    #  You can add more test cases here
    testArray1 = [[1,4], [7, 10], [3, 5]]
    testArray2 = [[1,2], [6, 10], [11, 15]]

    print(solution(testArray1) == 9 )
    print(solution(testArray2) == 12 )

叠盘子排序

问题描述

小M有一个独特的方式来收拾家中的盘子。每次用餐后,他会将盘子按照他们的序号顺序叠放。盘子的序号都是唯一的整数,并且在收拾前就是递增的。小M的叠放规则是,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。需要编写程序帮助小M确定盘子的叠放方式。

例如,输入的盘子序号是 [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],按照小M的规则,连续递增序列 -3, -2, -1 可以叠在一起表示为 -3--1,而 18, 19, 20 可以叠在一起表示为 18-20。不满足连续递增至少3个的,如 2, 10, 15, 16 都应单独列出。


输入参数

  • plates: 一个整数数组,表示盘子的序号
  • n: 盘子总数

测试样例

样例1:

输入:plates = [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20], n = 10
输出:"-3--1,2,10,15,16,18-20"

样例2:

输入:plates = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20], n = 20
输出:"-6,-3-1,3-5,7-11,14,15,17-20"

样例3:

输入:plates = [1, 2, 7, 8, 9, 10, 11, 19], n = 8
输出:"1,2,7-11,19"

:::success 水题,遍历模拟

:::

def solution(plates: list[int], n: int) -> str:
    # Please write your code here
    count = 1
    res = ""
    for i in range(n+1):
        if i == 0:
            continue
        if i < n and plates[i] == plates[i-1]+1:
            count += 1
        else:
            if count >= 3:
                j = i - count
                if j == 0 :
                    res += str(plates[j]) + '-' + str(plates[i-1])
                else:
                    res += ',' + str(plates[j]) + '-' + str(plates[i-1])
            else:
                j = i - count
                while j <= i-1:
                    # print("hh")
                    if j == 0:
                        res += str(plates[j])
                    else:
                        res += ',' + str(plates[j])
                    j += 1
            count = 1
    
    #print(res)
    return res


if __name__ == "__main__":
    #  You can add more test cases here
    print(solution([-3, -2, -1, 2, 10, 15, 16, 18, 19, 20], 10) == "-3--1,2,10,15,16,18-20" )
    print(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20], 20) == "-6,-3-1,3-5,7-11,14,15,17-20")
    print(solution([1, 2, 7, 8, 9, 10, 11, 19], 8) == "1,2,7-11,19")

分组飞行棋棋子

问题描述

小M和小F在玩飞行棋。游戏结束后,他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子,每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组,每组恰好5个,并且组内棋子的序号相同。小M希望知道是否可以按照这种方式对棋子进行分组。

例如,假设棋子序号为 [1, 2, 3, 4, 5],虽然只有5个棋子,但由于序号不同,因此不能形成有效的分组。如果序号是 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2],则可以形成两个有效分组,因此输出为 True


测试样例

样例1:

输入:nums = [1, 2, 3, 4, 5]
输出:"False"

样例2:

输入:nums = [1, 1, 1, 1, 2, 1, 2, 2, 2, 2]
输出:"True"

样例3:

输入:nums = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
输出:"True"

样例4:

输入:nums = [7, 7, 7, 8, 8, 8, 8, 8, 7, 7]
输出:"True"

样例5:

输入:nums = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
输出:"False"

:::success map

:::

def solution(nums: list[int]) -> str:
    # Please write your code here
    m = {}
    for n in nums:
        if m.get(n):
            m[n] += 1
        else:
            m[n] = 1
    for v in m.values():
        if v % 5 != 0:
            return "False"
    return "True"

if __name__ == "__main__":
    #  You can add more test cases here
    print(solution([1, 3, 4, 5, 6, 5, 4]) == "False" )
    print(solution([1, 1, 1, 1, 2, 1, 2, 2, 2, 2]) == "True")
    print(solution([11, 45, 49, 37, 45, 38, 3, 47, 35, 49, 26, 16, 24, 4, 45, 39, 28, 26, 14, 22, 4, 49, 18, 4, 4, 26, 47, 14, 1, 21, 9, 26, 17, 12, 44, 28, 24, 24, 10, 31, 33, 32, 23, 41, 41, 19, 17, 24, 28, 46, 28, 4, 18, 23, 48, 45, 7, 21, 12, 40, 2, 19, 19, 28, 32, 6, 27, 43, 6, 18, 8, 27, 9, 6, 6, 31, 37, 15, 26, 20, 43, 3, 14, 40, 20]) == "False")

最佳人选

问题描述

某特种部队采用了一套性格密码机制来筛选执行特定任务的最佳士兵,该机制的规则如下:

  1. 每个人的性格可以通过 M 个维度来描述,每个维度分为 A, B, C, D, E 五种类型。
  2. 同一维度内,字母距离越近,性格类型差异越小,匹配程度越高。比如,A 和 B 的差异为 1,A 和 D 的差异为 3
  3. 其中 AEBDCEBE 为不相容性格类型,差异值设为无穷大(无法匹配)。
  4. 如果某一维度存在不相容性格类型,则表示两个士兵性格完全不匹配。
  5. 对于符合匹配条件的士兵,差异值总和越小表示匹配程度越高。

现在,有一个重要的机密任务,要求找到最匹配该任务所需性格密码的士兵。你需要编写一个算法,帮助部队找到符合条件的最佳人选。

  • m 表示性格密码的维度。
  • n 表示备选特种兵的数量。
  • target 是代表任务的性格密码。
  • array 是一个包含 n 个元素的列表,每个元素为 M 位的性格密码。

测试样例

样例1:

输入:m = 6, n = 3, target = "ABCDEA", array = ["AAAAAA", "BBBBBB", "ABDDEB"]
输出:'ABDDEB'

样例2:

输入:m = 5, n = 4, target = "ABCED", array = ["ABCDE", "BCDEA", "ABDCE", "EDCBA"]
输出:'ABCDE'

样例3:

输入:m = 4, n = 4, target = "AEBC", array = ["ACDC", "BBDC", "EBCB", "BBBB"]
输出:'None'

:::success 遍历判断

:::

import re


def solution(m, n, target, array):
    # Edit your code here
    INF = 0x3f3f3f3f3f3f3f
    dis_max = INF
    index = -1
    res = ""
    for j in range(n):
        p = array[j]
        count = 0
        flag = True
        for i in range(m):
            if target[i] == "E" and (p[i] == "A" or p[i] == "B" or p[i] == "C"):
                # print(j)
                flag = False
                break
            elif p[i] == "E" and (target[i] == "A" or target[i] == "B" or target[i] == "C"):
                # print(j)
                flag = False
                break
            elif (p[i] == "B" and target[i] == "D") or (p[i] == "D" and target[i] == "B"):
                flag = False
                break
            else:
                count += abs(ord(p[i]) - ord(target[i]))
        if flag:
            # print(j)
            if count < dis_max:
                dis_max = count
                res = array[j]
            elif count == dis_max:
                res += " " + array[j]

    
    if res == "":
        return 'None'
    else:
        # print(array[index])
        return res

    return None


if __name__ == "__main__":
    # Add your test cases here
    # matrix = [
    #     "AAAAAA", "BBBBBB", "ABDDEB"
    # ]
    # print(solution(6, 3, "ABCDEA", matrix) == "ABDDEB")
    matrix = [
        "ABCDE","BCDEA","ABDCE","EDCBA"
    ]
    print(solution(5, 4, "ABCED", matrix) == "ABCDE")

Go语言入门-工程实践

  • 并发:多线程程序在一个核的cpu上运行
  • 并行:多线程程序在多个核的cpu上运行
  • Go 可以充分发挥多核优势,高效运行

Goroutine

  • 协程:用户态,轻量级线程,栈 KB 级别
  • 线程:内核态,线程跑多个协程,栈 MB 级别

CSP

提倡通过通信共享内存而不是通过共享内存而实现通信

Channel

  • 有缓冲通道 make(chan int, 2)
  • 无缓冲通道 make(chan int, 2)

依赖管理

Go 依赖管理演进

GOPATH -> Go Vender -> Go Module

Go Module

通过 go.mod 文件管理依赖包版本

通过 go get/go mod 指令工具管理依赖包

依赖管理三要素

  1. 配置文件,描述依赖 go.mod
  2. 中心仓库管理依赖库 proxy
  3. 本地工具 go get/mod

依赖分发-回源

  • 无法保证构建稳定性 - 增加/修改/删除软件版本
  • 无法保证依赖可用性 - 删除软件
  • 增加第三方压力 - 代码托管平台负载问题

依赖分发-Proxy

依赖分发-变量GOPROXY

GOPROXY="proxy1.cn, proxy2.cn, direct"

服务站点URL列表,“direct”表示源站

测试

  • 回归测试
  • 集成测试
  • 单元测试
  • 从上到下,覆盖率逐层变大,成本却逐层降低

规则

  • 所有测试文件以 _test.go结尾
  • func TestXxx(*testing.T)
  • 初始化逻辑放到 TestMain 中
  • 一般覆盖率:50%-60%, 较高覆盖率80%+
  • 测试分之相互独立,全面覆盖。
  • 测试单元粒度足够,函数单一职责。

func ReadFirstLine() string {
    open, err := os.Open("log")
    defer open.Close()
    if err != nil {
        return ""
    }
    scanner := bufio.NewScanner(open)
    for scanner.Scan() {
        return scanner.Text()
    }
    return ""
}
func ProcessFirstLine() string {
    line := ReadFirstLine()
    destLine := strings.ReplaceAll(line, "11", "00")
    return destLine
}
//func TestProcessFirstLine(t *testing.T) {
//	firstLine := ProcessFirstLine()
//	assert.Equal(t, "line00", firstLine)
//}

func TestProcessFirstLineWithMock(t *testing.T) {
	monkey.Patch(ReadFirstLine, func() string {
		return "line110"
	})
	defer monkey.Unpatch(ReadFirstLine)
	line := ProcessFirstLine()
	assert.Equal(t, "line000", line)

}
package benchmark

import (
	"github.com/bytedance/gopkg/lang/fastrand"
	"math/rand"
)

var ServerIndex [10]int

func InitServerIndex() {
	for i := 0; i < 10; i++ {
		ServerIndex[i] = i + 100
	}
}

func Select() int {
	return ServerIndex[rand.Intn(10)]
}
func FastSelect() int {
	return ServerIndex[fastrand.Intn(10)]
}
import "testing"

func BenchmarkSelect(b *testing.B) {
	InitServerIndex()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		Select()
	}
}
func BenchmarkSelectParallel(b *testing.B) {
	InitServerIndex()
	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			Select()
		}
	})
}
func BenchmarkFastSelectParallel(b *testing.B) {
	InitServerIndex()
	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			FastSelect()
		}
	})
}

需求描述

社区话题页面

展示话题(标题,文字描述)和回帖列表

暂不考虑前端

话题和回帖数据用文件存储

分层结构

  • 数据层:数据Model, 外部数据的增删改查
  • 逻辑层:业务Entity, 处理核心业务逻辑输出
  • 视图层:视图view, 处理和外部的交互逻辑