<?php

class Kamus
{

    private $daftar = array();

    public function __construct()
    {
        $this->daftar = array();
    }

    public function tambah($kata, array $sinonim)
    {
        // Kata utama tetap didaftarkan walau array sinonimnya kosong.
        $this->daftarkanKata($kata);

        foreach ($sinonim as $pasangan) {
            $this->daftarkanKata($pasangan);

            // Relasi dua arah: kunci agar ambilSinonim('gigantic')
            // mengembalikan array berisi 'huge'.
            $this->buatRelasi($kata, $pasangan);
            $this->buatRelasi($pasangan, $kata);
        }
    }

    public function ambilSinonim($kata)
    {
        if (!array_key_exists($kata, $this->daftar)) {
            return null;
        }

        return $this->daftar[$kata];
    }

    private function daftarkanKata($kata)
    {
        if (!array_key_exists($kata, $this->daftar)) {
            $this->daftar[$kata] = array();
        }
    }

    private function buatRelasi($dari, $ke)
    {
        if ($dari === $ke) {
            return; // sebuah kata bukan sinonim bagi dirinya sendiri
        }

        if (!in_array($ke, $this->daftar[$dari], true)) {
            $this->daftar[$dari][] = $ke;
        }
    }
}


/* ===================== PENGUJIAN ===================== */

function cetak($label, $hasil)
{
    echo str_pad($label, 28) . ' => '
        . ($hasil === null ? 'null' : json_encode($hasil)) . PHP_EOL;
}

$kamus = new Kamus();
$kamus->tambah('big',  array('large', 'great'));
$kamus->tambah('big',  array('huge', 'fat'));
$kamus->tambah('huge', array('enormous', 'gigantic'));

cetak("ambilSinonim('big')",      $kamus->ambilSinonim('big'));
cetak("ambilSinonim('huge')",     $kamus->ambilSinonim('huge'));
cetak("ambilSinonim('gigantic')", $kamus->ambilSinonim('gigantic'));
cetak("ambilSinonim('colossal')", $kamus->ambilSinonim('colossal'));

echo PHP_EOL . "--- Kasus tepi tambahan ---" . PHP_EOL;

$kamus->tambah('big', array('large', 'big'));   // duplikat + self-loop
cetak("ambilSinonim('big') [ulang]", $kamus->ambilSinonim('big'));

$kamus->tambah('solo', array());                 // kata tanpa sinonim
cetak("ambilSinonim('solo')", $kamus->ambilSinonim('solo'));
cetak("ambilSinonim('fat')",  $kamus->ambilSinonim('fat'));