add genericsum task

This commit is contained in:
Pavel 2022-04-06 15:52:32 +03:00
parent 7658844998
commit c572019eed
5 changed files with 254 additions and 11 deletions

10
genericsum/README.md Normal file
View file

@ -0,0 +1,10 @@
# genericsum
Реализуйте несколько небольших функций с дженериками.
* `Min` - минимум из 2 переменных
* `SortSlice` - сортировка слайса inplace
* `MapsEqual` - равенство 2 мап. Значения мап сравниваются через обычный оператор =
* `SliceContains` - содержит ли слайс заданный элемент
* `MergeChans` - сделать из нескольких каналов один. При отправке значения в любой из входных каналов, его можно получить в выходном канале. Необходимо закрыть созданный канал, когда все входные каналы будут закрыты - это единственный корректный вариант завершения работы.
* `IsHermitianMatrix` - проверка, является ли квадратная матрица эрмитовой. Подсказка: достаточно проверить, что транспонированная комплексно сопряженная матрица равна исходной матрице

31
genericsum/genericsum.go Normal file
View file

@ -0,0 +1,31 @@
//go:build !solution
package genericsum
func Min(a, b int) int {
panic("implement me")
}
func SortSlice(a []int) {
panic("implement me")
}
func MapsEqual(a, b map[int]int) bool {
panic("implement me")
}
func SliceContains(s []int, v int) bool {
panic("implement me")
}
func MergeChans(chs ...<-chan int) <-chan int {
panic("implement me")
}
func MergeChans(chs ...<-chan int) <-chan int {
panic("implement me")
}
func IsHermitianMatrix(m [][]int) bool {
panic("implement me")
}

View file

@ -0,0 +1,203 @@
package genericsum
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
)
func TestMin(t *testing.T) {
assert.Equal(t, 10, Min(10, 20))
assert.Equal(t, -10, Min(20, -10))
assert.Equal(t, 1.0, Min(1.0, 2.0))
assert.Equal(t, int64(10), Min(int64(10), 20))
assert.Equal(t, "abc", Min("def", "abc"))
type myString string
assert.Equal(t, myString("abc"), Min(myString("def"), myString("abc")))
}
func TestSortSlice(t *testing.T) {
t.Run("ints", func(t *testing.T) {
inputs, expected := []int{3, 6, 2, 4, 5, 1}, []int{1, 2, 3, 4, 5, 6}
SortSlice(inputs)
assert.Equal(t, expected, inputs)
})
t.Run("ints64", func(t *testing.T) {
inputs, expected := []int64{3, 6, 2, 4, 5, 1}, []int64{1, 2, 3, 4, 5, 6}
SortSlice(inputs)
assert.Equal(t, expected, inputs)
})
t.Run("strings", func(t *testing.T) {
inputs, expected := []string{"d", "b", "ab", "a"}, []string{"a", "ab", "b", "d"}
SortSlice(inputs)
assert.Equal(t, expected, inputs)
})
type myStringSlice []string
t.Run("strings custom type", func(t *testing.T) {
inputs, expected := myStringSlice([]string{"d", "b", "ab", "a"}), myStringSlice([]string{"a", "ab", "b", "d"})
SortSlice(inputs)
assert.Equal(t, expected, inputs)
})
}
func TestMapsEqual(t *testing.T) {
assert.True(t, MapsEqual(map[string]string{"1": "3", "2": "4"}, map[string]string{"2": "4", "1": "3"}))
var i int
assert.False(t, MapsEqual(map[string]*int{"1": &i, "2": nil}, map[string]*int{"1": &i}))
assert.False(t, MapsEqual(map[string]*int{"1": &i}, map[string]*int{"1": &i, "2": nil}))
assert.False(t, MapsEqual(map[string]*int{"1": new(int)}, map[string]*int{"1": new(int)}),
"different pointers")
type k struct {
i int
s string
}
assert.True(t, MapsEqual(map[k]k{k{10, "abc"}: {20, "def"}}, map[k]k{k{10, "abc"}: {20, "def"}}))
type myMap map[int]int
assert.True(t, MapsEqual(myMap(nil), myMap(nil)), "type aliases must also be ok")
}
func TestSliceContains(t *testing.T) {
assert.True(t, SliceContains([]int{5, 9, 12}, 5))
assert.False(t, SliceContains([]int{5, 9, 12}, 7))
type k struct{ i, j int }
assert.True(t, SliceContains([]k{{1, 2}, {5, 7}, {9, 12}}, k{5, 7}))
type mySlice []k
assert.True(t, SliceContains(mySlice{{1, 2}, {5, 7}, {9, 12}}, k{5, 7}))
}
func TestMergeChansTypes(t *testing.T) {
t.Run("floats", func(t *testing.T) {
defer goleak.VerifyNone(t)
chans := make([]chan float64, 5)
chanArgs := make([]<-chan float64, 5)
for i := range chans {
chans[i] = make(chan float64, 1)
chanArgs[i] = chans[i]
}
ch := MergeChans(chanArgs...)
for _, ch := range chans {
close(ch)
}
for range ch {
}
})
t.Run("structs", func(t *testing.T) {
defer goleak.VerifyNone(t)
type tp struct{}
chans := make([]chan tp, 5)
chanArgs := make([]<-chan tp, 5)
for i := range chans {
chans[i] = make(chan tp, 1)
chanArgs[i] = chans[i]
}
ch := MergeChans(chanArgs...)
for _, ch := range chans {
close(ch)
}
for range ch {
}
})
}
func TestMergeChans(t *testing.T) {
defer goleak.VerifyNone(t)
const numChans = 10
chans := make([]chan int, numChans)
chanArgs := make([]<-chan int, numChans)
for i := range chans {
chans[i] = make(chan int, 1)
chanArgs[i] = chans[i]
}
ch := MergeChans(chanArgs...)
chans[5] <- 10
assert.Equal(t, 10, <-ch)
chans[1] <- 5
assert.Equal(t, 5, <-ch)
const numIter = 1000
receivedNumbers := make([]bool, numIter)
go func() {
for i := 0; i < numIter; i++ {
chans[i%numChans] <- i
}
for _, ch := range chans {
close(ch)
}
}()
// don't ever deadlock
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
var receivedNum int
Loop:
for {
select {
case v, ok := <-ch:
if !ok {
break Loop
}
require.True(t, v >= 0 && v < len(receivedNumbers), "invalid received number", v)
require.False(t, receivedNumbers[v], "shouldn't receive number twice", v)
receivedNumbers[v] = true
receivedNum++
case <-ctx.Done():
require.FailNow(t, "timeouted")
}
}
assert.Equal(t, numIter, receivedNum)
}
func TestIsHermitianMatrix(t *testing.T) {
assert.True(t, IsHermitianMatrix([][]int{
{1, 7, 9},
{7, 2, 12},
{9, 12, 19},
}))
assert.False(t, IsHermitianMatrix([][]int{
{1, 12, 8},
{3, 4, 7},
{8, 7, 11},
}))
assert.True(t, IsHermitianMatrix([][]complex64{
{1, 3 + 2i},
{3 - 2i, 4},
}))
assert.True(t, IsHermitianMatrix([][]complex128{
{1, 3 + 2i, 9 - 1i},
{3 - 2i, 5, 7 - 3i},
{9 + 1i, 7 + 3i, 19},
}))
assert.False(t, IsHermitianMatrix([][]complex64{
{1 + 1i, 3 + 2i},
{3 - 2i, 4},
}))
}

5
go.mod
View file

@ -26,6 +26,7 @@ require (
github.com/testcontainers/testcontainers-go v0.9.0
go.uber.org/goleak v1.0.0
go.uber.org/zap v1.14.0
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f
golang.org/x/perf v0.0.0-20191209155426-36b577b0eb03
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
@ -78,9 +79,9 @@ require (
go.uber.org/atomic v1.5.0 // indirect
go.uber.org/multierr v1.3.0 // indirect
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/lint v0.0.0-20190930215403-16217165b5de // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a // indirect

16
go.sum
View file

@ -48,7 +48,6 @@ github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwj
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -203,7 +202,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
@ -219,7 +217,6 @@ github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye47
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
@ -234,7 +231,6 @@ github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCM
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.3.0 h1:l8JvKrby3RI7Kg3bYEeU9TA4vqC38QDpFCfcrC7KuN0=
github.com/jackc/pgtype v1.3.0/go.mod h1:b0JqxHvPmljG+HQ5IsvQ0yqeSi4nGcDTVjFoiLDb0Ik=
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
@ -401,7 +397,6 @@ github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -435,13 +430,16 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb h1:pC9Okm6BVmxEw76PUu0XUbOTQ92JX11hfvqTjAV3qxM=
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -457,8 +455,8 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 h1:LQmS1nU0twXLA96Kt7U9qtHJEbBk3z6Q0V4UXjZkpr4=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -526,9 +524,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=