Skip to content

Instantly share code, notes, and snippets.

@film42
Last active August 29, 2015 14:01
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 film42/5838a9b0ea979e5e8889 to your computer and use it in GitHub Desktop.
Save film42/5838a9b0ea979e5e8889 to your computer and use it in GitHub Desktop.
Project Euler #11
(ns euler.euler-11
(:require [clojure.string :as s]))
(def grid-data
"Open data from file"
(slurp "files/11.txt"))
(defn- get-grid
"Get the matrix from the slurped text. Break on new lines, then split and parse for Ints"
[]
(let [rows (s/split-lines grid-data)
colls (map #(s/split % #" ") rows)]
(for [c colls]
(map #(java.lang.Integer/parseInt %) c))))
(def grid (get-grid))
(defn- mnth
"Get an item within the matrix given some row and col indicies"
[matrix row col]
(nth (nth matrix row) col))
(defn- dcount
"Get the count of possible diagonal slices: count + (count - 1)"
[matrix] ;; diag count
(+ (count matrix) (dec (count matrix))))
(defn- col
"Get a column in the matrix given some col number"
[matrix col]
(for [c matrix]
(nth c col)))
(defn- diag-right
"Super ugly. This returns a diag slice that descends to the right."
[matrix slice]
(if (< slice (count matrix))
;; First half (col starts 0)
(let [start (- (count matrix) (inc slice))]
(loop [i start
col 0
acc '()]
(if (= (count matrix) i)
acc
(recur
(inc i)
(inc col)
(conj acc (mnth matrix i col))))))
;; Second half (row starts at 0)
(let [start (- (inc slice) (count matrix))]
(loop [i start
row 0
acc '()]
(if (= (count matrix) i)
acc
(recur
(inc i)
(inc row)
(conj acc (mnth matrix row i)))))) ))
(defn- diag-left
"Returns a diag slice that descends to the left. Note, we just flip and use the right diag"
[matrix slice]
(let [m (map reverse matrix)]
(diag-right m slice)))
(defn- process
"Given any list, vec, etc. Find the max product it contains of 4 adjacent numbers.
This method is used heavily. All subproblems use this function."
[row]
(loop [acc row
sub-result 0]
(let [curr (reduce * (take 4 acc))
t (rest acc)]
(if (empty? acc)
sub-result
(recur t (max sub-result curr))))))
(defn max-product
"A large max reducer. Check the max from each valid direction and return the result."
[matrix]
(let [side-max (apply max (map process matrix))
up-max (apply max (for [i (range (count matrix))]
(process (col matrix i))))
r-diag (apply max (for [i (range (dcount matrix))]
(process (diag-right matrix i))))
l-diag (apply max (for [i (range (dcount matrix))]
(process (diag-left matrix i))))]
;; This is the end
(max side-max up-max r-diag l-diag)))
;; RUNNER
(defn -main [& args]
(println (max-product grid)))
"Elapsed time: 16.785 msecs"
70,600,674
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment