Kunci jawaban 07 Latihan Robot. Latihan 7.1 dan 7.2 dijalankan bersama kode proyek robot dari bukunya.

7.1 Mengukur Robot

function hitungLangkah(state, robot, memory) {
  for (let langkah = 0;; langkah++) {
    if (state.parcels.length == 0) return langkah;
    let aksi = robot(state, memory);
    state = state.move(aksi.direction);
    memory = aksi.memory;
  }
}
 
function compareRobots(robot1, memory1, robot2, memory2) {
  let total1 = 0, total2 = 0;
  for (let i = 0; i < 100; i++) {
    let state = VillageState.random();
    total1 += hitungLangkah(state, robot1, memory1);
    total2 += hitungLangkah(state, robot2, memory2);
  }
  console.log(`Robot 1: ${total1 / 100} langkah per tugas`);
  console.log(`Robot 2: ${total2 / 100} langkah per tugas`);
}

Kenapa: hitungLangkah sama seperti runRobot tapi mengembalikan angka, bukan mencetak. Karena VillageState immutable, state yang sama bisa diberikan ke dua robot berturut-turut tanpa khawatir robot pertama merusaknya — inilah manfaat nyata desain immutable dari babnya.

→ Soal: 07 Latihan Robot > 7.1 Mengukur Robot

7.2 Efisiensi Robot

function robotHemat({place, parcels}, route) {
  if (route.length == 0) {
    let rute = parcels.map(parcel => {
      if (parcel.place != place) {
        return {route: findRoute(roadGraph, place, parcel.place),
                ambil: true};
      } else {
        return {route: findRoute(roadGraph, place, parcel.address),
                ambil: false};
      }
    });
    function skor({route, ambil}) {
      return (ambil ? 0.5 : 0) - route.length;
    }
    route = rute.reduce((a, b) => skor(a) > skor(b) ? a : b).route;
  }
  return {direction: route[0], memory: route.slice(1)};
}

Kenapa: map bikin satu kandidat rute per paket. skor mengubah tiap kandidat jadi angka: makin pendek makin tinggi (- route.length), plus bonus 0.5 kalau rutenya menuju pengambilan — cukup buat memenangkan seri tapi gak cukup mengalahkan rute yang beneran lebih pendek. reduce memilih skor tertinggi, pola yang sama dengan mencari yang terbesar di 05 Fungsi Tingkat Tinggi > Merangkum dengan reduce.

→ Soal: 07 Latihan Robot > 7.2 Efisiensi Robot

7.3 Group Persisten

class PGroup {
  #members;
  constructor(members) {
    this.#members = members;
  }
  add(nilai) {
    if (this.has(nilai)) return this;
    return new PGroup(this.#members.concat([nilai]));
  }
  delete(nilai) {
    if (!this.has(nilai)) return this;
    return new PGroup(this.#members.filter(m => m !== nilai));
  }
  has(nilai) {
    return this.#members.includes(nilai);
  }
  static empty = new PGroup([]);
}

Kenapa: array #members tak pernah diubah; add/delete selalu bikin PGroup baru dengan concat/filter. Keduanya mengembalikan this kalau tak ada yang berubah (hemat, gak bikin objek identik). PGroup.empty adalah properti static berupa nilai. Cukup satu empty karena semua group kosong identik dan instance-nya immutable — kamu bisa bikin banyak group berbeda darinya tanpa memengaruhinya.

→ Soal: 07 Latihan Robot > 7.3 Group Persisten