(ns sleeping-barber
  (:require [clojure.core.async :as async :refer [<! <!! >! go]]
            [clojure.core.async.timeout :refer [timeout]]))

(defn sleep-millis [min max]
  (+ min (rand-int (- max min))))

(defn wait-for-customer []
  (Thread/sleep (sleep-millis 10 30)))

(defn haircut []
  (Thread/sleep 20))

(defn customer [barber-chair waiting-room]
  (go
    (wait-for-customer)
    (if (not (async/put! waiting-room :customer))
      (println "No chair available. Customer leaves.")
      (do
        (async/<! barber-chair) ; Wait for barber chair to be available
        (println "Customer sits in the barber chair.")
        (async/>! barber-chair :customer) ; Signal the barber
        (println "Barber starts giving a haircut.")
        (haircut)
        (println "Haircut finished. Customer leaves.")
        (recur barber-chair waiting-room)))))

(defn barber [barber-chair waiting-room]
  (go-loop []
    (let [customer (async/<! waiting-room)]
      (if (= customer :customer)
        (do
          (println "Barber wakes up and starts giving a haircut.")
          (haircut)
          (println "Haircut finished. Barber goes back to sleep.")
          (async/>! barber-chair :chair)
          (recur))
        (recur))))

(defn simulate-haircuts []
  (let [barber-chair (async/chan)
        waiting-room (async/chan 3)]
    (async/go
      (barber barber-chair waiting-room))
    (doseq [i (range 10)]
      (customer barber-chair waiting-room))
    (println "Simulation completed."))
  ;; Wait for the simulation to complete
  (Thread/sleep 10000))

(simulate-haircuts)

Embed on website

To embed this program on your website, copy the following code and paste it into your website's HTML: