# PERTEMUAN 12 ----

# Fungsi Validasi Data Terurut
validasi_urut <- function(data) {
  if (any(is.na(data))) {
    stop("Data tidak boleh mengandung NA!")
  }

  if (is.unsorted(data)) {
    stop("Data harus terurut!")
  }
}


# Fungsi Jejak Binary Search
jejak_binary <- function(data, target) {
  validasi_urut(data)

  kiri <- 1
  kanan <- length(data)

  jejak <- data.frame(
    kiri = integer(),
    kanan = integer(),
    tengah = integer(),
    nilai_tengah = numeric()
  )

  while (kiri <= kanan) {
    tengah <- (kiri + kanan) %/% 2

    jejak <- rbind(jejak, data.frame(
      kiri = kiri,
      kanan = kanan,
      tengah = tengah,
      nilai_tengah = data[tengah]
    ))

    if (data[tengah] == target) {
      break
    } else if (data[tengah] < target) {
      kiri <- tengah + 1
    } else {
      kanan <- tengah - 1
    }
  }

  return(jejak)
}


# Fungsi Binary Search dengan Boolean
bin_boolean <- function(data, target) {
  validasi_urut(data)

  kiri <- 1
  kanan <- length(data)

  while (kiri <= kanan) {
    tengah <- (kiri + kanan) %/% 2

    if (data[tengah] == target) {
      return(tengah)
    } else if (data[tengah] < target) {
      kiri <- tengah + 1
    } else {
      kanan <- tengah - 1
    }
  }

  return(NA)
}


# Fungsi Binary Search Tanpa Boolean
bin_tanpa_boolean <- function(data, target) {
  validasi_urut(data)

  kiri <- 1
  kanan <- length(data)

  while (kiri <= kanan) {
    tengah <- (kiri + kanan) %/% 2

    if (data[tengah] == target) {
      return(tengah)
    } else if (data[tengah] < target) {
      kiri <- tengah + 1
    } else {
      kanan <- tengah - 1
    }
  }

  return(NA)
}


# Fungsi Binary Search Posisi Pertama
bin_pertama <- function(data, target) {
  validasi_urut(data)

  kiri <- 1
  kanan <- length(data)
  hasil <- NA

  while (kiri <= kanan) {
    tengah <- (kiri + kanan) %/% 2

    if (data[tengah] == target) {
      hasil <- tengah
      kanan <- tengah - 1
    } else if (data[tengah] < target) {
      kiri <- tengah + 1
    } else {
      kanan <- tengah - 1
    }
  }

  return(hasil)
}


# Fungsi Menghitung Kunjungan Sequential
kunjungan_sequential <- function(data, target) {
  if (any(is.na(data))) {
    stop("Data tidak boleh mengandung NA!")
  }

  jumlah <- 0

  for (i in seq_along(data)) {
    jumlah <- jumlah + 1

    if (data[i] == target) {
      return(jumlah)
    }
  }

  return(jumlah)
}
# 12A Jejak Binary Search

lat_urut <- seq(10, 100, by = 10)

hasil_12A <- jejak_binary(lat_urut, 80)

print(hasil_12A)
##   kiri kanan tengah nilai_tengah
## 1    1    10      5           50
## 2    6    10      8           80
cat("Target 80 ditemukan dalam", nrow(hasil_12A), "kunjungan.\n")
## Target 80 ditemukan dalam 2 kunjungan.
# 12B Kasus Batas Binary Search

cat("Target 10:\n")
## Target 10:
print(bin_boolean(lat_urut, 10))
## [1] 1
print(bin_tanpa_boolean(lat_urut, 10))
## [1] 1
cat("Target 100:\n")
## Target 100:
print(bin_boolean(lat_urut, 100))
## [1] 10
print(bin_tanpa_boolean(lat_urut, 100))
## [1] 10
cat("Target 105:\n")
## Target 105:
print(bin_boolean(lat_urut, 105))
## [1] NA
print(bin_tanpa_boolean(lat_urut, 105))
## [1] NA
# 12C Data Duplikat

lat_duplikat <- c(10, 20, 20, 20, 30)

cat("Binary dasar:\n")
## Binary dasar:
print(bin_boolean(lat_duplikat, 20))
## [1] 3
cat("Binary posisi pertama:\n")
## Binary posisi pertama:
print(bin_pertama(lat_duplikat, 20))
## [1] 2
# 12D Mencari Kode Produk 103

# Menggunakan objek produk_urut dan urutan
# yang sudah dibuat pada latihan atau modul sebelumnya.

if (exists("produk_urut") && exists("urutan")) {

  p <- bin_tanpa_boolean(produk_urut$kode, 103)

  if (!is.na(p)) {

    cat("Posisi terurut dan baris asli:\n")

    print(c(
      posisi_terurut = p,
      baris_asli = urutan[p]
    ))

    cat("Informasi produk:\n")

    print(produk_urut[p, , drop = FALSE])

  } else {
    cat("Kode 103 tidak ditemukan pada tabel produk.\n")
  }

} else {

  cat("Objek produk_urut dan urutan belum tersedia.\n")

  cat("Berdasarkan pembahasan modul:\n")
  cat("Posisi terurut: 3\n")
  cat("Baris asli: 4\n")
  cat("Nama produk: Minyak\n")
  cat("Stok: 30\n")

}
## Objek produk_urut dan urutan belum tersedia.
## Berdasarkan pembahasan modul:
## Posisi terurut: 3
## Baris asli: 4
## Nama produk: Minyak
## Stok: 30
# 12E Validasi Data Tidak Terurut

hasil_12E <- tryCatch(
  bin_boolean(c(30, 10, 20), 20),
  error = function(e) conditionMessage(e)
)

print(hasil_12E)
## [1] "Data harus terurut!"
# 12F Perbandingan Kunjungan

data_12F <- seq_len(1024)

hasil_12F <- c(
  sequential = kunjungan_sequential(data_12F, 1024),
  binary = nrow(jejak_binary(data_12F, 1024))
)

print(hasil_12F)
## sequential     binary 
##       1024         11