Skip to content

Instantly share code, notes, and snippets.

@minikomi
Created August 15, 2023 02:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minikomi/372051ab85d5f576579bcaf4d558eb3c to your computer and use it in GitHub Desktop.
Save minikomi/372051ab85d5f576579bcaf4d558eb3c to your computer and use it in GitHub Desktop.
(ns co.poyo.wordleclj.core
(:require [clojure.java.io :as io]
[clojure.string :as str]))
(def word-list
(->> "wordle-answers-alphabetical.txt"
io/resource
slurp
str/split-lines
(map str/trim)
(map str/lower-case)))
(defn get-letter-freqs [strs]
(let [all-chars (reduce into [] strs)]
(->> all-chars
frequencies
(map (fn [[k v]] [k (/ v (count all-chars))]))
(into {}))))
(defn score-word [freqs w]
(apply + (map freqs (set w))))
(defn sort-by-score [words]
(sort-by (partial score-word (get-letter-freqs words)) > words))
(defn does-not-contain-black [black-chars-set word]
(every? #(not (black-chars-set %)) word))
(defn match-green [green-chars-positional word]
(if (empty? green-chars-positional) true
(every?
(fn [[idx c]]
(= (get word idx) c))
green-chars-positional)))
(defn not-match-positional-yellow [yellow-chars-positional word]
(every?
(fn [[idx c-set]]
(not (contains? c-set (get word idx))))
yellow-chars-positional))
(defn matches-seen-yellow [seen-yellow-chars-set word]
(if (empty? seen-yellow-chars-set) true
(let [w-set (set word)]
(every? #(w-set %) seen-yellow-chars-set))))
(defn filter-words [{:keys [black
green
yellow-pos
yellow-total]}
words]
(->> words
(filter (partial match-green green))
(filter (partial does-not-contain-black black))
(filter (partial not-match-positional-yellow yellow-pos))
(filter (partial matches-seen-yellow yellow-total))))
(map vector (range) [1 2 3] [:a :b: :c ])
(defn add-to-state [state [idx c result]]
(case result
:g (assoc-in state [:green idx] c)
:b (update state :black conj c)
:y (-> state
(update :yellow-total conj c)
(update-in [:yellow-pos idx] (fnil conj #{}) c))))
(defn update-state [state guess result]
(reduce add-to-state state (map vector (range) guess result)))
(defn solve []
(loop [words word-list state {:black #{} :yellow-pos {} :yellow-total #{} :green {}}]
(let [word (do (println "word:") (str/trim (read-line)))
answer (do (println "result:") (mapv (comp keyword str) (str/trim (read-line))))
new-state (update-state state word answer)
new-words (sort-by-score (filter-words new-state words))]
(println "Total remaining:" (count new-words))
(if (>= 1 (count new-words))
(println "finish:" new-words)
(do (println (take 10 new-words))
(recur new-words new-state))))))
(defn -main [& args] (solve))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment