package main

import (
	"cmp"
	"fmt"
	"slices"
	"sort"
)

// Siswa menjadi contoh struct dengan dua field yang akan dibandingkan.
type Siswa struct {
	Nama  string
	Umur  int
	Nilai float64
}

func main() {
	// slices.Sort untuk tipe ordered: angka dan string.
	angka := []int{50, 10, 40, 20, 30}
	slices.Sort(angka)
	fmt.Println("terurut  :", angka)
	fmt.Println("sorted   :", slices.IsSorted(angka))

	// BinarySearch mencari nilai pada slice yang sudah terurut.
	posisi, ketemu := slices.BinarySearch(angka, 40)
	fmt.Println("cari 40  :", posisi, ketemu)
	_, ketemu = slices.BinarySearch(angka, 35)
	fmt.Println("cari 35  :", ketemu)

	// Contains dan Index memeriksa keanggotaan dan posisi.
	fmt.Println("ada 30   :", slices.Contains(angka, 30))
	fmt.Println("indeks 30:", slices.Index(angka, 30))

	// Clone menyalin slice sehingga pengurutan tidak mengubah aslinya.
	salinan := slices.Clone(angka)
	slices.Reverse(salinan)
	fmt.Println("asli     :", angka)
	fmt.Println("salinan  :", salinan)

	// SortFunc memakai comparator dari package cmp.
	siswa := []Siswa{
		{"Budi", 20, 3.4},
		{"Siti", 22, 3.9},
		{"Andi", 20, 3.1},
	}
	slices.SortFunc(siswa, func(a, b Siswa) int {
		return cmp.Compare(a.Nilai, b.Nilai)
	})
	fmt.Println("nilai    :", siswa)

	// SortStableFunc dengan dua kunci: umur naik, lalu nilai turun.
	slices.SortStableFunc(siswa, func(a, b Siswa) int {
		if c := cmp.Compare(a.Umur, b.Umur); c != 0 {
			return c
		}
		return cmp.Compare(b.Nilai, a.Nilai)
	})
	fmt.Println("2 kunci  :", siswa)

	// Package sort lama tetap tersedia untuk kode yang sudah ada.
	legacy := []string{"jeruk", "apel", "mangga"}
	sort.Strings(legacy)
	fmt.Println("legacy   :", legacy)
}
