ALGORITMA BFS

 Seorang penjelajah harus menemukan jalan dari S G di sebuah peta penuh dinding dan menuju jalan berbiaya. Dengan bantuan algoritma BFS yang memeriksa semua kemungkinan jalur secara teratur, penjelajahan berhasil menemukan rute paling murah. Setelah menghitung semua kemungkinan, biaya minimum untuk sampai ke tujuan adalah 7.

Code 

import java.util.*;

public class PetaBFS {
    static char[][] peta = {
            {'S', '1', '1', '9', '1'},
            {'1', '2', '1', '1', '1'},
            {'1', '9', '2', '9', '1'},
            {'1', '1', '2', '1', '1'},
            {'1', '1', '1', '2', 'G'}
    };

    static int n = 5, m = 5;
    static int[][] dist = new int[n][m];
    static int[] dx = {1, -1, 0, 0};
    static int[] dy = {0, 0, 1, -1};

    public static void main(String[] args) {
        for (int[] row : dist) Arrays.fill(row, Integer.MAX_VALUE);

        bfs(0, 0); // mulai dari S

        System.out.println("Biaya minimum: " + dist[4][4]);
    }

    static void bfs(int sx, int sy) {
        Queue<int[]> q = new LinkedList<>();
        dist[sx][sy] = 0;
        q.add(new int[]{sx, sy});

        while (!q.isEmpty()) {
            int[] cur = q.poll();
            int x = cur[0], y = cur[1];

            for (int k = 0; k < 4; k++) {
                int nx = x + dx[k], ny = y + dy[k];
                if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
                if (peta[nx][ny] == '9') continue; // tembok

                int tambah = (peta[nx][ny] == 'S' || peta[nx][ny] == 'G') ? 0 : (peta[nx][ny] - '0');
                int newCost = dist[x][y] + tambah;

                if (newCost < dist[nx][ny]) {
                    dist[nx][ny] = newCost;
                    q.add(new int[]{nx, ny});
                }
            }
        }
    }
}


Output



Algorima DFS

 Di sebuah peta berbentuk persegi 5x5, terdapat seorang petualang yang memulai perjalanan dari titik awal yang ditandai dengan huruf S. Tujuan utamanya adalah mencapai titik G yang terletak di sudut lain dari peta.

Namun, perjalanan tidaklah mudah. Setiap langkah di peta memiliki biaya perjalanan. Angka yang tertera di setiap kotak adalah beban yang harus ditanggung oleh sang petualang ketika melangkah ke sana. Ada juga jalur berbahaya yang ditandai dengan angka 9, tempat terlarang yang tidak bisa dilewati sama sekali.

Sang petualang tidak bisa sembarangan berjalan. Ia hanya boleh bergerak ke atas, bawah, kiri, atau kanan, selangkah demi selangkah. Untuk menghindari kebingungan dan jebakan, ia menandai jalur yang sudah dikunjunginya agar tidak mengulanginya.

Dengan tekad yang kuat, ia menyusuri setiap kemungkinan jalan melalui DFS (Depth First Search)—sebuah strategi di mana ia berani masuk ke satu jalur hingga akhir, sebelum kembali dan mencoba jalur lain. Setiap kali mencapai Goal (G), ia mencatat total biaya perjalanan yang sudah ditempuh. Dari semua kemungkinan jalur yang ada, ia hanya akan memilih perjalanan dengan biaya minimum.

Akhirnya, setelah mencoba berbagai kemungkinan jalan, sang petualang menemukan jawaban: berapa biaya paling kecil untuk mencapai tujuan dari Start ke Goal. Itulah hasil yang ditampilkan di akhir program.


code

package com.example.belajar1;

import java.util.ArrayList;

public class PetaDFS {
    static char[][] peta = {
            {'S', '1', '1', '9', '1'},
            {'1', '2', '1', '1', '1'},
            {'1', '9', '2', '9', '1'},
            {'1', '1', '2', '1', '1'},
            {'1', '1', '1', '2', 'G'}
    };

    static int min = Integer.MAX_VALUE;
    static boolean[][] kunjungi = new boolean[5][5];

    public static void main(String[] args) {
        dfs(0, 0, 0);

        System.out.println("Biaya minimum: " + min);
    }

    private static void dfs(int i, int j, int biaya) {
        if (i < 0 || i >= 5 || j < 0 || j >= 5 || peta[i][j] == '9' || kunjungi[i][j]) return;

        if (peta[i][j] == 'G') {
            min = Math.min(min, biaya);
            return;
        }

        int nilai = (peta[i][j] == 'S') ? 0 : (peta[i][j] - '0');
        kunjungi[i][j] = true;

        dfs(i + 1, j, biaya + nilai); // bawah
        dfs(i - 1, j, biaya + nilai); // atas
        dfs(i, j + 1, biaya + nilai); // kanan
        dfs(i, j - 1, biaya + nilai); // kiri

        kunjungi[i][j] = false;
    }
}

Output



GREEDY

 



Bayangkan kamu sedang berada di sebuah peta kotak-kotak 5x5. Setiap kotak punya angka tertentu. Angka itu menunjukkan biaya yang harus dibayar kalau kamu ingin melewatinya. Ada juga beberapa kotak dengan angka 9, yang artinya ada rintangan dan kamu tidak bisa lewat di situ.

Tugasmu adalah berangkat dari pojok kiri atas (0,0) dan harus sampai ke pojok kanan bawah (4,4). Kamu ingin mencari jalan dengan biaya sekecil mungkin, tapi kamu memakai strategi Greedy.

Strategi Greedy itu seperti orang yang selalu bilang:
"Ambil saja pilihan yang paling murah sekarang, nanti urusan berikutnya belakangan."

Bagaimana langkahnya?
1. Kamu mulai dari kotak awal (0,0) dengan biaya 0.
2. Dari sini ada beberapa pilihan jalan. Kamu melihat semua tetangga, lalu langsung memilih kotak dengan angka paling kecil.
3. Setelah berpindah, kamu ulangi lagi langkah tadi: lihat tetangga, pilih yang paling kecil.
4. Kamu terus melakukannya sampai akhirnya tiba di tujuan (4,4).

Apa hasilnya?
- Jalur yang kamu lalui adalah:
  (0,0) → (0,1) → (0,2) → (1,2) → (1,3) → (1,4) → (2,4) → (3,4) → (4,4)
- Total biaya perjalananmu adalah 10.


Walaupun mungkin ada jalur lain yang sebenarnya lebih murah, dengan strategi Greedy kamu berhasil menemukan jalan yang valid dan bisa sampai tujuan. Greedy memang selalu memilih langkah terbaik saat itu, sehingga jalur akhirnya wajar saja jika tidak selalu paling optimal.



code: 

import java.util.*;

public class greedy {
    static int N = 5;
    static int[][] grid = {
        {0, 1, 1, 9, 1},
        {1, 2, 1, 1, 1},
        {1, 9, 2, 9, 1},
        {1, 1, 2, 1, 1},
        {1, 1, 2, 1, 0} // Goal dianggap biaya 0
    };

   
    static int[] dx = {0, 1, 0, -1};
    static int[] dy = {1, 0, -1, 0};

    static class Node {
        int x, y, cost;
        Node(int x, int y, int cost) {
            this.x = x; this.y = y; this.cost = cost;
        }
    }

    public static void greedySearch(int startX, int startY, int goalX, int goalY) {
        boolean[][] visited = new boolean[N][N];
        List<String> path = new ArrayList<>();
        int totalCost = 0;

        int x = startX, y = startY;
        path.add("(" + x + "," + y + ")");

        while (!(x == goalX && y == goalY)) {
            visited[x][y] = true;

            Node nextNode = null;

            // cari tetangga dengan biaya terkecil (ikuti prioritas arah)
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];

                if (nx >= 0 && nx < N && ny >= 0 && ny < N &&
                    !visited[nx][ny] && grid[nx][ny] != 9) {

                    if (nextNode == null || grid[nx][ny] < nextNode.cost) {
                        nextNode = new Node(nx, ny, grid[nx][ny]);
                    }
                }
            }

            if (nextNode == null) {
                System.out.println("Greedy gagal: jalur buntu!");
                System.out.println("Jalur yang ditempuh: " + path);
                System.out.println("Total biaya: " + totalCost);
                return;
            }

            x = nextNode.x;
            y = nextNode.y;
            totalCost += nextNode.cost;
            path.add("(" + x + "," + y + ")");
        }

        System.out.println("Greedy berhasil!");
        System.out.println("Jalur: " + path);
        System.out.println("Total biaya: " + totalCost);
    }

    public static void main(String[] args) {
        greedySearch(0, 0, 4, 4);
    }
}



Output :





Tugas 2 IMK

Code awal 

<!DOCTYPE html>

<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Kalkulator</title>
  <style>
    /* reset dasar */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* global style */
    html {
      height: 100%;
      background: white;
      background: radial-gradient(circle, white 10%, #eee);
    }

    body {
      font: 16px arial;
    }

    /* container kalkulator */
    #kalkulator {
      width: 325px;
      height: 300px;
      margin: 20px auto;
      padding: 20px 20px 10px;
      background: linear-gradient(#baffc9, #a0ffb5);
      box-shadow: 0 4px 0 #64bf77, 0 10px 15px rgba(0,0,0,0.2);
      border-radius: 5px;
    }

    /* bagian atas (tombol C dan layar) */
    .atas {
      overflow: hidden;
      padding-right: 6px;
    }

    .tombol {
      width: 66px;
      height: 36px;
      float: left;
      background: #ffb3ba;
      color: white;
      border-radius: 3px;
      text-align: center;
      line-height: 35px;
      box-shadow: 0 4px 0 #df8c94;
      margin: 0 5px 11px 0;
      position: relative;
      top: 0;
      user-select: none;
      cursor: pointer;
      transition: 0.2s ease;
    }

    .layar {
      width: 208px;
      height: 40px;
      background: rgba(0,0,0,0.2);
      float: right;
      text-align: right;
      line-height: 40px;
      padding: 0 10px;
      box-shadow: inset 0px 4px rgba(0, 0, 0, 0.2);
      border-radius: 3px;
      font-size: 1.1em;
      color: white;
      letter-spacing: 1px;
      text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
      overflow: hidden;
    }

    /* bagian bawah */
    .bawah {
      overflow: hidden;
      margin-top: 15px;
    }

    .tombol.angka {
      background: white;
      box-shadow: 0 4px 0 rgba(0,0,0,0.2);
      color: #999;
    }

    .tombol.operator {
      background: #ffdfba;
      box-shadow: 0 4px 0 #dea768;
      color: #dea768;
      font-size: 1.4em;
    }

    .tombol.hitung {
      background: #ffffba;
      box-shadow: 0 4px 0 #bebe47;
      color: #bebe47;
      font-size: 1.4em;
    }

    .tombol:hover {
      filter: brightness(0.95);
    }

    .tombol:active {
      box-shadow: 0 0 0;
      top: 4px;
    }
  </style>
</head>
<body>

<div id="kalkulator">
  <div class="atas">
    <div class="tombol" id="clear">C</div>
    <div class="layar" id="layar"></div>
  </div>
 
  <div class="bawah">
    <span class="tombol angka">7</span>
    <span class="tombol angka">8</span>
    <span class="tombol angka">9</span>
    <span class="tombol operator">/</span>
   
    <span class="tombol angka">4</span>
    <span class="tombol angka">5</span>
    <span class="tombol angka">6</span>
    <span class="tombol operator">*</span>
   
    <span class="tombol angka">1</span>
    <span class="tombol angka">2</span>
    <span class="tombol angka">3</span>
    <span class="tombol operator">-</span>
   
    <span class="tombol angka">0</span>
    <span class="tombol angka">.</span>
    <span class="tombol hitung">=</span>
    <span class="tombol operator">+</span>
  </div>
</div>

<script>
  const layar = document.getElementById("layar");
  const tombol = document.querySelectorAll(".tombol");

  tombol.forEach(btn => {
    btn.addEventListener("click", () => {
      const nilai = btn.textContent;

      if (btn.id === "clear") {
        layar.textContent = "";
      }
      else if (btn.classList.contains("hitung")) {
        try {
          let hasil = eval(layar.textContent);

          // handling jika hasil tidak terdefinisi atau infinity
          if (hasil === Infinity || isNaN(hasil)) {
            layar.textContent = "Error";
          } else {
            layar.textContent = hasil;
          }
        } catch (error) {
          layar.textContent = "Error";
        }
      }
      else {
        layar.textContent += nilai;
      }
    });
  });
</script>

</body>
</html>


Analisis dilakukan terhadap aspek kemudahan penggunaan (usability).   

Kelebihan:

·       Konsistensi tombol – tombol angka dan operator jelas

·       Feedback instan – input langsung muncul di layar.

·       Tombol tambahan ± dan ⌫ – memudahkan koreksi input.

·       Estetika lebih baik – dark mode nyaman di mata.

·       Tampilan responsif – tombol besar, cocok untuk mobile.

  Kekurangan:

·       Belum ada riwayat perhitungan (history).

·       Masih terbatas pada operasi dasar (+ - * /).

·       Tidak ada persentase (%) atau akar kuadrat (√).

Di sini masih ada sedikit kekurangannya


Redesign Interface

Redesign dilakukan untuk meningkatkan kenyamanan pengguna (user experience).

      Perubahan yang dilakukan:

·       Dark Mode – tampilan gelap untuk kenyamanan mata.

·       Warna tombol berbeda – angka abu gelap, operator oranye, C merah, = kuning.

·       Ukuran tombol lebih besar – lebih mudah digunakan di mobile.

·       Grid Layout – tombol lebih rapi dan proporsional.

·       Tambahan usability – tombol ± dan ⌫.

Analisis Error & Iterasi

Analisis dilakukan dengan menguji input salah dan melihat bagaimana aplikasi merespons.

       Hasil uji coba:

·       Input 10/0 → muncul 'Error'.

·       Input salah (misalnya 5++2) → muncul 'Error'.

·       Input besar tetap diproses, tampilan dipotong jika terlalu panjang.

·       Input kosong lalu tekan '=' → tetap kosong, tidak error.

    Perbaikan:

·       Menambahkan try...catch untuk error handling.

·       Menampilkan 'Error' saat input tidak valid.

·       Menambahkan ± dan ⌫ untuk memudahkan koreksi.


code setelah di lakukan perbaikan


<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Kalkulator Redesign</title>
  <style>
    * {margin:0; padding:0; box-sizing:border-box;}
    body {
      font: 16px Arial;
      background: #121212;
      color: white;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
    }

    #kalkulator {
      width: 340px;
      background: #1e1e1e;
      padding: 20px;
      border-radius: 10px;
      box-shadow: 0 4px 15px rgba(0,0,0,0.6);
    }

    .atas {
      display: flex;
      justify-content: space-between;
      margin-bottom: 15px;
    }

    .layar {
      flex: 1;
      height: 50px;
      background: #333;
      border-radius: 5px;
      text-align: right;
      line-height: 50px;
      padding: 0 10px;
      font-size: 1.3em;
      color: #fff;
      overflow: hidden;
    }

    .bawah {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 10px;
    }

    .tombol {
      height: 60px;
      border-radius: 8px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      font-size: 1.2em;
      transition: 0.2s;
      user-select: none;
    }

    .tombol:hover {
      filter: brightness(1.2);
    }

    .angka {background: #444;}
    .operator {background: #ff7043; color:white; font-weight: bold;}
    .hitung {background: #fdd835; color:#333; font-weight: bold;}
    .clear {background: #e53935; color:white;}
    .back {background: #757575; color:white;}
  </style>
</head>
<body>

<div id="kalkulator">
  <div class="atas">
    <div class="layar" id="layar"></div>
  </div>
  <div class="bawah">
    <div class="tombol clear">C</div>
    <div class="tombol back"></div>
    <div class="tombol operator">±</div>
    <div class="tombol operator">/</div>

    <div class="tombol angka">7</div>
    <div class="tombol angka">8</div>
    <div class="tombol angka">9</div>
    <div class="tombol operator">*</div>

    <div class="tombol angka">4</div>
    <div class="tombol angka">5</div>
    <div class="tombol angka">6</div>
    <div class="tombol operator">-</div>

    <div class="tombol angka">1</div>
    <div class="tombol angka">2</div>
    <div class="tombol angka">3</div>
    <div class="tombol operator">+</div>

    <div class="tombol angka">0</div>
    <div class="tombol angka">.</div>
    <div class="tombol hitung">=</div>
  </div>
</div>

<script>
  const layar = document.getElementById("layar");
  const tombol = document.querySelectorAll(".tombol");

  tombol.forEach(btn => {
    btn.addEventListener("click", () => {
      const nilai = btn.textContent;

      if (btn.classList.contains("clear")) {
        layar.textContent = "";
      }
      else if (btn.classList.contains("back")) {
        layar.textContent = layar.textContent.slice(0, -1);
      }
      else if (nilai === "±") {
        if (layar.textContent) {
          layar.textContent = String(-parseFloat(layar.textContent));
        }
      }
      else if (btn.classList.contains("hitung")) {
        try {
          let hasil = eval(layar.textContent);

          if (hasil === Infinity || isNaN(hasil)) {
            layar.textContent = "Error";
          } else {
            layar.textContent = hasil;
          }
        } catch (error) {
          layar.textContent = "Error";
        }
      }
      else {
        layar.textContent += nilai;
      }
    });
  });
</script>

</body>
</html>




Tugas 1 IMK

 

Masalah yang sering terjadi pada lampu merah:

  1. Kesalahan hitung mundur 

  2. Sering mati/error tidak berfungsi.

  3. Waktu tidak seimbang karena ada jalur yang terlalu lama, ada yang sebentar.

  4. Posisinya terhalang pohon atau papan iklan.

  5. Kurang informatif (tidak ada petunjuk tambahan).

  6. Tidak ramah pejalan kaki (tidak ada suara/tombol khusus penyeberangan).

Solusi:

  • Menggunakan sistem sensor lalu lintas otomatis agar waktu lampu menyesuaikan jumlah kendaraan.

  • Menggunakan energi cadangan (UPS/panel surya) agar tidak mati saat listrik padam.

  • Pemasangan lampu merah lebih tinggi dan horizontal agar terlihat jelas.

  • Menambahkan layar LED informasi (arah, estimasi waktu, simbol pejalan kaki).

  • Menambahkan tombol dan suara khusus untuk pejalan kaki.

Desain lampu merah baru:

          1. Penghitung Waktu Mundur Digital yang Akurat

  • Alasan:

    • Memberikan kepastian waktu kepada pengemudi dan pejalan kaki.

    • Mengurangi stres dan potensi pelanggaran lalu lintas karena pengguna tahu berapa lama harus menunggu.

    • Membantu pengemudi melaju secara aman dan efisien saat lampu akan berubah.

    2.Sensor Lalu Lintas Otomatis

    Alasan:

    • Waktu nyala lampu dapat disesuaikan dengan kepadatan kendaraan di setiap arah.

    • Mengurangi kemacetan pada jalur yang lebih padat, dan tidak membuang waktu pada jalur yang kosong.

    • Lebih adaptif dan hemat energi dibandingkan sistem statistik.

    3. Layar LED Tambahan (Informasi Arah & Status)

    Alasan:

    • Menampilkan informasi seperti arah tujuan (misal: “Belok kiri langsung jalan”), status lampu, atau himbauan keselamatan.

    • Berguna bagi pengemudi asing atau pengemudi baru yang membutuhkan arah yang jelas.

    • Bisa menampilkan peringatan darurat atau perubahan arus lalu lintas secara real-time.

    4. Pembicara untuk Suara Penyeberangan

    Alasan:

    • Membantu pejalan kaki tunanetra atau orang tua saat persimpangan.

    • Memberikan sinyal suara saat aman ke perbatasan.

    • Menambah aspek inklusif dan ramah disabilitas dalam desain kota.

    5. Tombol Penyeberangan Pejalan Kaki

    Alasan:

    • Memberikan kendali pada pejalan kaki untuk meminta waktu penyeberangan.

    • Menghindari penyeberangan sembarangan karena pejalan kaki tahu kapan lampu akan menyala.

    • Mengintegrasikan hak pengguna jalan secara adil, bukan hanya untuk kendaraan.



    Lokasi pemasangan: Di perempatan, lampu dipasang lebih tinggi agar terlihat jelas.

  • Dengan posisi horizontal di atas jalan, lampu lebih terlihat dan tidak terhalang pohon/baliho.

  • Timer digital & sensor lalu lintas membuat arus kendaraan lebih adil dan lancar.

  • Panel LED dan suara menjadikannya ramah untuk pejalan kaki dan lebih informatif.

  • Sistem energi cadangan menjamin lampu tetap berfungsi saat listrik padam.