from typing import List, Set, Dict, Optional
class Kamus:
"""
Sistem kamus sinonim (thesaurus) dengan hubungan simetris.
"""
def __init__(self):
# Struktur data utama: Dict untuk pencarian O(1), Set untuk data unik & efisiensi.
self._data: Dict[str, Set[str]] = {}
def tambah(self, kata: str, sinonim: List[str]) -> None:
self._data.setdefault(kata, set()).update(sinonim)
for s in sinonim:
self._data.setdefault(s, set()).add(kata)
def ambil_sinonim(self, kata: str) -> Optional[List[str]]:
hasil_set = self._data.get(kata)
if hasil_set is not None:
return list(hasil_set)
return None
def main():
# Inisialisasi object dari class Kamus.
kamus = Kamus()
kamus.tambah('big', ['large', 'great'])
kamus.tambah('big', ['huge', 'fat'])
kamus.tambah('huge', ['enormous', 'gigantic'])
# Test case untuk kata 'big'.
hasil_big = kamus.ambil_sinonim('big')
print(sorted(hasil_big) if hasil_big else None)
# Test case untuk kata 'huge'.
hasil_huge = kamus.ambil_sinonim('huge')
print(sorted(hasil_huge) if hasil_huge else None)
# Test case untuk kata 'gigantic', menguji hubungan simetris dari 'huge'.
hasil_gigantic = kamus.ambil_sinonim('gigantic')
print(sorted(hasil_gigantic) if hasil_gigantic else None)
# Test case untuk kata yang tidak ada di dalam kamus.
hasil_colossal = kamus.ambil_sinonim('colossal')
print(sorted(hasil_colossal) if hasil_colossal else None)
# Standard entry point di Python.
if __name__ == "__main__":
main()
ZnJvbSB0eXBpbmcgaW1wb3J0IExpc3QsIFNldCwgRGljdCwgT3B0aW9uYWwKCmNsYXNzIEthbXVzOgogICAgIiIiCiAgICBTaXN0ZW0ga2FtdXMgc2lub25pbSAodGhlc2F1cnVzKSBkZW5nYW4gaHVidW5nYW4gc2ltZXRyaXMuCiAgICAiIiIKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICAgIyBTdHJ1a3R1ciBkYXRhIHV0YW1hOiBEaWN0IHVudHVrIHBlbmNhcmlhbiBPKDEpLCBTZXQgdW50dWsgZGF0YSB1bmlrICYgZWZpc2llbnNpLgogICAgICAgIHNlbGYuX2RhdGE6IERpY3Rbc3RyLCBTZXRbc3RyXV0gPSB7fQoKICAgIGRlZiB0YW1iYWgoc2VsZiwga2F0YTogc3RyLCBzaW5vbmltOiBMaXN0W3N0cl0pIC0+IE5vbmU6CiAgICAgICAgc2VsZi5fZGF0YS5zZXRkZWZhdWx0KGthdGEsIHNldCgpKS51cGRhdGUoc2lub25pbSkKICAgICAgICBmb3IgcyBpbiBzaW5vbmltOgogICAgICAgICAgICBzZWxmLl9kYXRhLnNldGRlZmF1bHQocywgc2V0KCkpLmFkZChrYXRhKQoKICAgIGRlZiBhbWJpbF9zaW5vbmltKHNlbGYsIGthdGE6IHN0cikgLT4gT3B0aW9uYWxbTGlzdFtzdHJdXToKICAgICAgICBoYXNpbF9zZXQgPSBzZWxmLl9kYXRhLmdldChrYXRhKQogICAgICAgIGlmIGhhc2lsX3NldCBpcyBub3QgTm9uZToKICAgICAgICAgICAgcmV0dXJuIGxpc3QoaGFzaWxfc2V0KQogICAgICAgIHJldHVybiBOb25lCgpkZWYgbWFpbigpOgogICAgIyBJbmlzaWFsaXNhc2kgb2JqZWN0IGRhcmkgY2xhc3MgS2FtdXMuCiAgICBrYW11cyA9IEthbXVzKCkKICAgIGthbXVzLnRhbWJhaCgnYmlnJywgWydsYXJnZScsICdncmVhdCddKQogICAga2FtdXMudGFtYmFoKCdiaWcnLCBbJ2h1Z2UnLCAnZmF0J10pCiAgICBrYW11cy50YW1iYWgoJ2h1Z2UnLCBbJ2Vub3Jtb3VzJywgJ2dpZ2FudGljJ10pCiAgICAKICAgICMgVGVzdCBjYXNlIHVudHVrIGthdGEgJ2JpZycuCiAgICBoYXNpbF9iaWcgPSBrYW11cy5hbWJpbF9zaW5vbmltKCdiaWcnKQogICAgcHJpbnQoc29ydGVkKGhhc2lsX2JpZykgaWYgaGFzaWxfYmlnIGVsc2UgTm9uZSkKICAgIAogICAgIyBUZXN0IGNhc2UgdW50dWsga2F0YSAnaHVnZScuCiAgICBoYXNpbF9odWdlID0ga2FtdXMuYW1iaWxfc2lub25pbSgnaHVnZScpCiAgICBwcmludChzb3J0ZWQoaGFzaWxfaHVnZSkgaWYgaGFzaWxfaHVnZSBlbHNlIE5vbmUpCgogICAgIyBUZXN0IGNhc2UgdW50dWsga2F0YSAnZ2lnYW50aWMnLCBtZW5ndWppIGh1YnVuZ2FuIHNpbWV0cmlzIGRhcmkgJ2h1Z2UnLgogICAgaGFzaWxfZ2lnYW50aWMgPSBrYW11cy5hbWJpbF9zaW5vbmltKCdnaWdhbnRpYycpCiAgICBwcmludChzb3J0ZWQoaGFzaWxfZ2lnYW50aWMpIGlmIGhhc2lsX2dpZ2FudGljIGVsc2UgTm9uZSkKCiAgICAjIFRlc3QgY2FzZSB1bnR1ayBrYXRhIHlhbmcgdGlkYWsgYWRhIGRpIGRhbGFtIGthbXVzLgogICAgaGFzaWxfY29sb3NzYWwgPSBrYW11cy5hbWJpbF9zaW5vbmltKCdjb2xvc3NhbCcpCiAgICBwcmludChzb3J0ZWQoaGFzaWxfY29sb3NzYWwpIGlmIGhhc2lsX2NvbG9zc2FsIGVsc2UgTm9uZSkKCiMgU3RhbmRhcmQgZW50cnkgcG9pbnQgZGkgUHl0aG9uLgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigp