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.