Skip to content

Instantly share code, notes, and snippets.

@skuro
Last active August 14, 2019 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save skuro/477b6e875b1f28175df608260d6be8d5 to your computer and use it in GitHub Desktop.
Save skuro/477b6e875b1f28175df608260d6be8d5 to your computer and use it in GitHub Desktop.
Nonograms dojo
;; fork me and include your solution!
(ns nonograms.core
(:require [clojure.java.io :as io])
(:import (javax.imageio ImageIO)
(java.awt.image BufferedImage)
(java.awt Image)))
(defn read-image
"Reads an image"
[path]
(-> path
io/resource
ImageIO/read))
(defn size
"Returns a map of :width and :height of the image"
[^BufferedImage image]
{:height (.getHeight image)
:width (.getWidth image)})
(defn resize-image
"Calculates the total size of the grid"
[{:keys [target-height target-width]} image]
(let [scaled (.getScaledInstance image target-width target-height Image/SCALE_SMOOTH)
resized (BufferedImage. target-width target-height BufferedImage/TYPE_INT_ARGB)]
(doto (.createGraphics resized)
(.drawImage scaled 0 0 nil)
(.dispose))
resized))
(defn target-size
"Calculates the target size of an image"
[grid-x grid-y {:keys [height width]}]
(let [mod-y (mod height grid-y)
mod-x (mod width grid-x)
target-height (if (zero? mod-y)
height
(+ height (- grid-y (mod height grid-y))))
target-width (if (zero? mod-x)
width
(+ width (- grid-x (mod width grid-x))))]
{:target-height target-height
:target-width target-width}))
(defn square-bytes
"Extracts the bytes of the square at the given coordinates"
[{:keys [grid-x grid-y]}
{:keys [x y]}
image]
(let [{:keys [height width]} (size image)
square-w (/ width grid-x)
square-h (/ height grid-y)
sub-image (.getSubimage image
(* x square-w)
(* y square-h)
square-w
square-h)]
sub-image))
(defn white?
[image]
(let [{:keys [height width]} (size image)
pixels (for [x (range width)
y (range height)]
(.getRGB image x y))
zeros (filter zero? pixels)]
(< (count zeros) (/ (count pixels) 2))))
(defn pixel [p]
(if p
"■"
"□"))
(defn print-board [board]
(for [row board]
(println (map pixel row))))
(defn find-groupings
[partitions]
(->> partitions
(filter (comp true? first))
(map count)))
(defn find-row-groupings
[row]
(let [partitions (partition-by true? row)]
(find-groupings partitions)))
(defn main []
(let [image (read-image "lambda.png")
resized-image (resize-image (target-size 20 20 (size image)) image)
board (partition-all 20
(for [y (range 20)
x (range 20)]
(let [bs (square-bytes {:grid-x 20
:grid-y 20}
{:x x
:y y}
resized-image)]
(white? bs))))
transpose #(apply map vector %)
puzzle-rows (map find-row-groupings board)
puzzle-columns (map find-row-groupings (transpose board))]
{:puzzle-rows puzzle-rows
:puzzle-columns puzzle-columns}))
;; (print-board _b)
;; (□ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □)
;; (□ □ □ ■ ■ ■ ■ □ □ □ □ □ □ □ □ □ □ □ □ □)
;; (□ □ ■ ■ ■ ■ ■ ■ □ □ □ □ □ □ □ □ □ □ □ □)
;; (□ ■ ■ □ □ □ ■ ■ ■ □ □ □ □ □ □ □ □ □ □ □)
;; (□ ■ □ □ □ □ □ ■ ■ □ □ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ □ □ ■ ■ □ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ □ □ ■ ■ □ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ □ □ ■ ■ ■ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ □ □ ■ ■ ■ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ □ ■ ■ ■ ■ □ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ □ ■ ■ ■ ■ ■ ■ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ ■ ■ ■ ■ □ ■ ■ □ □ □ □ □ □ □ □)
;; (□ □ □ □ □ ■ ■ ■ ■ □ □ ■ □ □ □ □ □ □ □ □)
;; (□ □ □ □ ■ ■ ■ ■ □ □ □ ■ ■ □ □ □ □ □ □ □)
;; (□ □ □ ■ ■ ■ ■ □ □ □ □ ■ ■ □ □ □ □ □ □ □)
;; (□ □ ■ ■ ■ ■ □ □ □ □ □ □ ■ ■ □ □ □ □ □ ■)
;; (□ ■ ■ ■ ■ ■ □ □ □ □ □ □ ■ ■ ■ □ □ □ ■ ■)
;; (□ ■ ■ ■ ■ □ □ □ □ □ □ □ □ ■ ■ ■ ■ ■ ■ ■)
;; (■ ■ ■ ■ □ □ □ □ □ □ □ □ □ □ ■ ■ ■ ■ □ □)
;; (□ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment