package main
import (
"errors"
"fmt"
"sort"
"strconv"
"strings"
)
// Struct Klasemen menyimpan data poin setiap klub
type Klasemen struct {
poin map[string]int
urutanKlub []string
}
// NewKlasemen sebagai constructor untuk menerima daftar klub
func NewKlasemen(klubKlub []string) *Klasemen {
k := &Klasemen{
poin: make(map[string]int),
}
for _, nama := range klubKlub {
k.poin[nama] = 0
k.urutanKlub = append(k.urutanKlub, nama)
}
return k
}
// function parseSkor untuk mengubah string skor seperti "1:0" menjadi dua angka integer
func parseSkor(skor string) (int, int, error) {
bagian := strings.Split(skor, ":")
if len(bagian) != 2 {
return 0, 0, errors.New("format skor tidak validd, gunakan format 'angka:angka'")
}
skorKandang, err := strconv.Atoi(strings.TrimSpace(bagian[0]))
if err != nil {
return 0, 0, errors.New("skor kandang bukan angka yang valid")
}
skorTandang, err := strconv.Atoi(strings.TrimSpace(bagian[1]))
if err != nil {
return 0, 0, errors.New("skor tandang bukan angka yang valid")
}
return skorKandang, skorTandang, nil
}
// function catatPermainan untuk mencatat hasil pertandingan dan menghitung poin
func (k *Klasemen) catatPermainan(klubKandang, klubTandang, skor string) error {
skorKandang, skorTandang, err := parseSkor(skor)
if err != nil {
return err
}
switch {
case skorKandang > skorTandang:
k.poin[klubKandang] += 3
case skorKandang < skorTandang:
k.poin[klubTandang] += 3
default: // seri
k.poin[klubKandang] += 1
k.poin[klubTandang] += 1
}
return nil
}
// struct pasanganKlub digunakan untuk menjaga urutan klub+poin saat di-sort
type pasanganKlub struct {
nama string
poin int
}
// function cetakKlasemen mengembalikan daftar klub terurut dari poin tertinggi ke terendah
func (k *Klasemen) cetakKlasemen() []pasanganKlub {
var hasil []pasanganKlub
for _, nama := range k.urutanKlub {
hasil = append(hasil, pasanganKlub{nama: nama, poin: k.poin[nama]})
}
sort.SliceStable(hasil, func(i, j int) bool {
return hasil[i].poin > hasil[j].poin
})
return hasil
}
// function ambilPeringkat untuk mengembalikan nama klub di posisi tertentu (1 = teratas)
func (k *Klasemen) ambilPeringkat(nomorPeringkat int) (string, error) {
klasemen := k.cetakKlasemen()
if nomorPeringkat < 1 || nomorPeringkat > len(klasemen) {
return "", fmt.Errorf("peringkat %d tidak ditemukan", nomorPeringkat)
}
return klasemen[nomorPeringkat-1].nama, nil
}
func main() {
klasemen := NewKlasemen([]string{
"Persija Jakarta",
"Persib Bandung",
"Arema FC",
"Persebaya Surabaya",
})
klasemen.catatPermainan("Persija Jakarta", "Persib Bandung", "2:1")
klasemen.catatPermainan("Arema FC", "Persebaya Surabaya", "2:0")
klasemen.catatPermainan("Persib Bandung", "Arema FC", "3:3")
klasemen.catatPermainan("Persebaya Surabaya", "Persija Jakarta", "1:2")
klasemen.catatPermainan("Persija Jakarta", "Arema FC", "2:3")
klasemen.catatPermainan("Persib Bandung", "Persebaya Surabaya", "4:2")
fmt.Println("Klasemen akhir:")
for _, pasangan := range klasemen.cetakKlasemen() {
fmt.Printf("%s -> %d\n", pasangan.nama, pasangan.poin)
}
peringkat1, err := klasemen.ambilPeringkat(1)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Peringkat 1:", peringkat1)
}
}
cGFja2FnZSBtYWluCgppbXBvcnQgKAoJImVycm9ycyIKCSJmbXQiCgkic29ydCIKCSJzdHJjb252IgoJInN0cmluZ3MiCikKCi8vIFN0cnVjdCBLbGFzZW1lbiBtZW55aW1wYW4gZGF0YSBwb2luIHNldGlhcCBrbHViCnR5cGUgS2xhc2VtZW4gc3RydWN0IHsKCXBvaW4gICAgICAgbWFwW3N0cmluZ11pbnQKCXVydXRhbktsdWIgW11zdHJpbmcKfQoKLy8gTmV3S2xhc2VtZW4gc2ViYWdhaSBjb25zdHJ1Y3RvciB1bnR1ayBtZW5lcmltYSBkYWZ0YXIga2x1YgpmdW5jIE5ld0tsYXNlbWVuKGtsdWJLbHViIFtdc3RyaW5nKSAqS2xhc2VtZW4gewoJayA6PSAmS2xhc2VtZW57CgkJcG9pbjogbWFrZShtYXBbc3RyaW5nXWludCksCgl9Cglmb3IgXywgbmFtYSA6PSByYW5nZSBrbHViS2x1YiB7CgkJay5wb2luW25hbWFdID0gMAoJCWsudXJ1dGFuS2x1YiA9IGFwcGVuZChrLnVydXRhbktsdWIsIG5hbWEpCgl9CglyZXR1cm4gawp9CgovLyBmdW5jdGlvbiBwYXJzZVNrb3IgdW50dWsgbWVuZ3ViYWggc3RyaW5nIHNrb3Igc2VwZXJ0aSAiMTowIiBtZW5qYWRpIGR1YSBhbmdrYSBpbnRlZ2VyCmZ1bmMgcGFyc2VTa29yKHNrb3Igc3RyaW5nKSAoaW50LCBpbnQsIGVycm9yKSB7CgliYWdpYW4gOj0gc3RyaW5ncy5TcGxpdChza29yLCAiOiIpCglpZiBsZW4oYmFnaWFuKSAhPSAyIHsKCQlyZXR1cm4gMCwgMCwgZXJyb3JzLk5ldygiZm9ybWF0IHNrb3IgdGlkYWsgdmFsaWRkLCBndW5ha2FuIGZvcm1hdCAnYW5na2E6YW5na2EnIikKCX0KCglza29yS2FuZGFuZywgZXJyIDo9IHN0cmNvbnYuQXRvaShzdHJpbmdzLlRyaW1TcGFjZShiYWdpYW5bMF0pKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIDAsIGVycm9ycy5OZXcoInNrb3Iga2FuZGFuZyBidWthbiBhbmdrYSB5YW5nIHZhbGlkIikKCX0KCglza29yVGFuZGFuZywgZXJyIDo9IHN0cmNvbnYuQXRvaShzdHJpbmdzLlRyaW1TcGFjZShiYWdpYW5bMV0pKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIDAsIGVycm9ycy5OZXcoInNrb3IgdGFuZGFuZyBidWthbiBhbmdrYSB5YW5nIHZhbGlkIikKCX0KCglyZXR1cm4gc2tvckthbmRhbmcsIHNrb3JUYW5kYW5nLCBuaWwKfQoKLy8gZnVuY3Rpb24gY2F0YXRQZXJtYWluYW4gdW50dWsgbWVuY2F0YXQgaGFzaWwgcGVydGFuZGluZ2FuIGRhbiBtZW5naGl0dW5nIHBvaW4KZnVuYyAoayAqS2xhc2VtZW4pIGNhdGF0UGVybWFpbmFuKGtsdWJLYW5kYW5nLCBrbHViVGFuZGFuZywgc2tvciBzdHJpbmcpIGVycm9yIHsKCXNrb3JLYW5kYW5nLCBza29yVGFuZGFuZywgZXJyIDo9IHBhcnNlU2tvcihza29yKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXN3aXRjaCB7CgljYXNlIHNrb3JLYW5kYW5nID4gc2tvclRhbmRhbmc6CgkJay5wb2luW2tsdWJLYW5kYW5nXSArPSAzCgljYXNlIHNrb3JLYW5kYW5nIDwgc2tvclRhbmRhbmc6CgkJay5wb2luW2tsdWJUYW5kYW5nXSArPSAzCglkZWZhdWx0OiAvLyBzZXJpCgkJay5wb2luW2tsdWJLYW5kYW5nXSArPSAxCgkJay5wb2luW2tsdWJUYW5kYW5nXSArPSAxCgl9CgoJcmV0dXJuIG5pbAp9CgovLyBzdHJ1Y3QgcGFzYW5nYW5LbHViIGRpZ3VuYWthbiB1bnR1ayBtZW5qYWdhIHVydXRhbiBrbHViK3BvaW4gc2FhdCBkaS1zb3J0CnR5cGUgcGFzYW5nYW5LbHViIHN0cnVjdCB7CgluYW1hIHN0cmluZwoJcG9pbiBpbnQKfQoKLy8gZnVuY3Rpb24gY2V0YWtLbGFzZW1lbiBtZW5nZW1iYWxpa2FuIGRhZnRhciBrbHViIHRlcnVydXQgZGFyaSBwb2luIHRlcnRpbmdnaSBrZSB0ZXJlbmRhaApmdW5jIChrICpLbGFzZW1lbikgY2V0YWtLbGFzZW1lbigpIFtdcGFzYW5nYW5LbHViIHsKCXZhciBoYXNpbCBbXXBhc2FuZ2FuS2x1YgoJZm9yIF8sIG5hbWEgOj0gcmFuZ2Ugay51cnV0YW5LbHViIHsKCQloYXNpbCA9IGFwcGVuZChoYXNpbCwgcGFzYW5nYW5LbHVie25hbWE6IG5hbWEsIHBvaW46IGsucG9pbltuYW1hXX0pCgl9CgoJc29ydC5TbGljZVN0YWJsZShoYXNpbCwgZnVuYyhpLCBqIGludCkgYm9vbCB7CgkJcmV0dXJuIGhhc2lsW2ldLnBvaW4gPiBoYXNpbFtqXS5wb2luCgl9KQoKCXJldHVybiBoYXNpbAp9CgovLyBmdW5jdGlvbiBhbWJpbFBlcmluZ2thdCB1bnR1ayBtZW5nZW1iYWxpa2FuIG5hbWEga2x1YiBkaSBwb3Npc2kgdGVydGVudHUgKDEgPSB0ZXJhdGFzKQpmdW5jIChrICpLbGFzZW1lbikgYW1iaWxQZXJpbmdrYXQobm9tb3JQZXJpbmdrYXQgaW50KSAoc3RyaW5nLCBlcnJvcikgewoJa2xhc2VtZW4gOj0gay5jZXRha0tsYXNlbWVuKCkKCglpZiBub21vclBlcmluZ2thdCA8IDEgfHwgbm9tb3JQZXJpbmdrYXQgPiBsZW4oa2xhc2VtZW4pIHsKCQlyZXR1cm4gIiIsIGZtdC5FcnJvcmYoInBlcmluZ2thdCAlZCB0aWRhayBkaXRlbXVrYW4iLCBub21vclBlcmluZ2thdCkKCX0KCglyZXR1cm4ga2xhc2VtZW5bbm9tb3JQZXJpbmdrYXQtMV0ubmFtYSwgbmlsCn0KCmZ1bmMgbWFpbigpIHsKCWtsYXNlbWVuIDo9IE5ld0tsYXNlbWVuKFtdc3RyaW5newoJCSJQZXJzaWphIEpha2FydGEiLAoJCSJQZXJzaWIgQmFuZHVuZyIsCgkJIkFyZW1hIEZDIiwKCQkiUGVyc2ViYXlhIFN1cmFiYXlhIiwKCX0pCgoJa2xhc2VtZW4uY2F0YXRQZXJtYWluYW4oIlBlcnNpamEgSmFrYXJ0YSIsICJQZXJzaWIgQmFuZHVuZyIsICIyOjEiKQoJa2xhc2VtZW4uY2F0YXRQZXJtYWluYW4oIkFyZW1hIEZDIiwgIlBlcnNlYmF5YSBTdXJhYmF5YSIsICIyOjAiKQoJa2xhc2VtZW4uY2F0YXRQZXJtYWluYW4oIlBlcnNpYiBCYW5kdW5nIiwgIkFyZW1hIEZDIiwgIjM6MyIpCglrbGFzZW1lbi5jYXRhdFBlcm1haW5hbigiUGVyc2ViYXlhIFN1cmFiYXlhIiwgIlBlcnNpamEgSmFrYXJ0YSIsICIxOjIiKQoJa2xhc2VtZW4uY2F0YXRQZXJtYWluYW4oIlBlcnNpamEgSmFrYXJ0YSIsICJBcmVtYSBGQyIsICIyOjMiKQoJa2xhc2VtZW4uY2F0YXRQZXJtYWluYW4oIlBlcnNpYiBCYW5kdW5nIiwgIlBlcnNlYmF5YSBTdXJhYmF5YSIsICI0OjIiKQoKCWZtdC5QcmludGxuKCJLbGFzZW1lbiBha2hpcjoiKQoJZm9yIF8sIHBhc2FuZ2FuIDo9IHJhbmdlIGtsYXNlbWVuLmNldGFrS2xhc2VtZW4oKSB7CgkJZm10LlByaW50ZigiJXMgLT4gJWRcbiIsIHBhc2FuZ2FuLm5hbWEsIHBhc2FuZ2FuLnBvaW4pCgl9CgoJcGVyaW5na2F0MSwgZXJyIDo9IGtsYXNlbWVuLmFtYmlsUGVyaW5na2F0KDEpCglpZiBlcnIgIT0gbmlsIHsKCQlmbXQuUHJpbnRsbigiRXJyb3I6IiwgZXJyKQoJfSBlbHNlIHsKCQlmbXQuUHJpbnRsbigiUGVyaW5na2F0IDE6IiwgcGVyaW5na2F0MSkKCX0KfQ==