I've pasted the code on this page in an IDE and it works. The problem is that when I replace the definition of target-data with this vector of pairs* it gives me this error**.
(vector [[1 2]
[2 3]
[3 4]
[4 5]] ) ; *
UnsupportedOperationException nth not supported on this type: core$vector clojure.lang.RT.nthFrom (RT.java:857) **
What should I do to use my own target-data?
UPDATED FULL CODE:
(ns evolvefn.core)
;(def target-data
; (map #(vector % (+ (* % %) % 1))
; (range -1.0 1.0 0.1)))
;; We'll use input (x) values ranging from -1.0 to 1.0 in increments
;; of 0.1, and we'll generate the target [x y] pairs algorithmically.
;; If you want to evolve a function to fit your own data then you could
;; just paste a vector of pairs into the definition of target-data instead.
(def target-data
(vec[1 2]
[2 3]
[3 4]
[4 5]))
;; An individual will be an expression made of functions +, -, *, and
;; pd (protected division), along with terminals x and randomly chosen
;; constants between -5.0 and 5.0. Note that for this problem the
;; presence of the constants actually makes it much harder, but that
;; may not be the case for other problems.
(defn random-function
[]
(rand-nth '(+ - * pd)))
(defn random-terminal
[]
(rand-nth (list 'x (- (rand 10) 5))))
(defn random-code
[depth]
(if (or (zero? depth)
(zero? (rand-int 2)))
(random-terminal)
(list (random-function)
(random-code (dec depth))
(random-code (dec depth)))))
;; And we have to define pd (protected division):
(defn pd
"Protected division; returns 0 if the denominator is zero."
[num denom]
(if (zero? denom)
0
(/ num denom)))
;; We can now evaluate the error of an individual by creating a function
;; built around the individual, calling it on all of the x values, and
;; adding up all of the differences between the results and the
;; corresponding y values.
(defn error
[individual]
(let [value-function (eval (list 'fn '[x] individual))]
(reduce + (map (fn [[x y]]
(Math/abs
(- (value-function x) y)))
target-data))))
;; We can now generate and evaluate random small programs, as with:
;; (let [i (random-code 3)] (println (error i) "from individual" i))
;; To help write mutation and crossover functions we'll write a utility
;; function that injects something into an expression and another that
;; extracts something from an expression.
(defn codesize [c]
(if (seq? c)
(count (flatten c))
1))
(defn inject
"Returns a copy of individual i with new inserted randomly somwhere within it (replacing something else)."
[new i]
(if (seq? i)
(if (zero? (rand-int (count (flatten i))))
new
(if (< (rand)
(/ (codesize (nth i 1))
(- (codesize i) 1)))
(list (nth i 0) (inject new (nth i 1)) (nth i 2))
(list (nth i 0) (nth i 1) (inject new (nth i 2)))))
new))
(defn extract
"Returns a random subexpression of individual i."
[i]
(if (seq? i)
(if (zero? (rand-int (count (flatten i))))
i
(if (< (rand) (/ (codesize (nth i 1))
(- (codesize i)) 1))
(extract (nth i 1))
(extract (nth i 2))))
i))
;; Now the mutate and crossover functions are easy to write:
(defn mutate
[i]
(inject (random-code 2) i))
(defn crossover
[i j]
(inject (extract j) i))
;; We can see some mutations with:
;; (let [i (random-code 2)] (println (mutate i) "from individual" i))
;; and crossovers with:
;; (let [i (random-code 2) j (random-code 2)]
;; (println (crossover i j) "from" i "and" j))
;; We'll also want a way to sort a populaty by error that doesn't require
;; lots of error re-computation:
(defn sort-by-error
[population]
(vec (map second
(sort (fn [[err1 ind1] [err2 ind2]] (< err1 err2))
(map #(vector (error %) %) population)))))
;; Finally, we'll define a function to select an individual from a sorted
;; population using tournaments of a given size.
(defn select
[population tournament-size]
(let [size (count population)]
(nth population
(apply min (repeatedly tournament-size #(rand-int size))))))
;; Now we can evolve a solution by starting with a random population and
;; repeatedly sorting, checking for a solution, and producing a new
;; population.
(defn evolve
[popsize]
(println "Starting evolution...")
(loop [generation 0
population (sort-by-error (repeatedly popsize #(random-code 2)))]
(let [best (first population)
best-error (error best)]
(println "======================")
(println "Generation:" generation)
(println "Best error:" best-error)
(println "Best program:" best)
(println " Median error:" (error (nth population
(int (/ popsize 2)))))
(println " Average program size:"
(float (/ (reduce + (map count (map flatten population)))
(count population))))
(if (< best-error 0.1) ;; good enough to count as success
(println "Success:" best)
(recur
(inc generation)
(sort-by-error
(concat
(repeatedly (* 1/2 popsize) #(mutate (select population 7)))
(repeatedly (* 1/4 popsize) #(crossover (select population 7)
(select population 7)))
(repeatedly (* 1/4 popsize) #(select population 7)))))))))
;; Run it with a population of 1000:
(evolve 1000)
And the error is:
(evolve 1000)
Starting evolution...
IllegalArgumentException No matching method found: abs clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
evolvefn.core=>
Related
I want to implement this psuedo code in Clojure:
function(n)
B[0] <-- 1
for m <-- 1 to n do
B[m] <-- 0
for k <-- 0 to m - 1 do
B[m] <-- B[m] − binom(m+1, k) * B[k]
B[m] <-- B[m]/(m+1)
return B[n]
My first thought was to do something like this:
(defn foo [n]
(if (= n 0)
(int 1)
(for [k (range 0 (- n 1))]
(* (binom (+ n 1) k)
(foo k)))))
but now I'm stuck and I don't know how to continue. The nested loops confuse me a lot when I try to translate them to Clojure.
I'd really appreciate some help on how to write this code in Clojure, I feel a bit lost.
Thanks in advance!
Some algorithms are naturally imperative in nature. Don't be afraid to write imperative code if that is the easiest solution, rather than trying to "force fit" the algorithm into a functional style.
This algorithm could easily use a mutable atom to store the B array:
(defn factorial [x]
(reduce * (range 2 (inc x))))
(defn binom [n k]
(/ (factorial n)
(factorial k) (factorial (- n k))))
(defn bernoulli [n]
(let [B (atom (vec (repeat n 0)))] ; allocate B[0]..B[n-1] = zeros
(swap! B assoc 0 1) ; B[0] = 1
(doseq [m (range 1 (inc n))] ; 1..n
(swap! B assoc m 0) ; B[m] = 0
(doseq [k (range m)] ; 0..(m-1)
(swap! B #(assoc % m ; B[m] = ...
(-
(get % m) ; B[m]
(*
(binom (inc m) k)
(get % k)))))) ; B[k]
(swap! B update m ; B[m] = B[m] ...
#(/ % (inc m))))
(get #B n)))
(dotest
(dotimes [i 10]
(spyx [i (bernoulli i)])))
with result
[i (bernoulli i)] => [0 1]
[i (bernoulli i)] => [1 -1/2]
[i (bernoulli i)] => [2 1/6]
[i (bernoulli i)] => [3 0N]
[i (bernoulli i)] => [4 -1/30]
[i (bernoulli i)] => [5 0N]
[i (bernoulli i)] => [6 1/42]
[i (bernoulli i)] => [7 0N]
[i (bernoulli i)] => [8 -1/30]
[i (bernoulli i)] => [9 0N]
You could also use with-local-vars for some algorithms, or even drop down into a (mutable) Java array. You can see an example of that in this mutable Java matrix example
The given pseudocode computes the nth Bernoulli number. It uses all the previous Bernoulli numbers to compute the result. Much like the factorial function, this lends itself to a recursive algorithm which may be implemented with memoize to avoid re-computation of earlier numbers:
(def factorial
"Returns n!."
(memoize (fn [n]
(if (< 1 n)
(* n (factorial (dec n)))
1N))))
(def bernoulli
"Returns the nth Bernoulli number."
(memoize (fn [n]
(if (zero? n)
1
(let [n! (factorial n)
term #(/ (* n! (bernoulli %))
(factorial %)
(factorial (- n % -1)))
terms (map term (range n))]
(reduce - 0 terms))))))
(map bernoulli (range 9)) ; => (1 -1/2 1/6 0N -1/30 0N 1/42 0N -1/30)
The pseudo code uses plenty of in-place updates which makes it a bit hard to read. But essentially, the code computes a list of numbers where every number is computed from the previous numbers in the list. And then we pick one of the numbers in the list.
I would implement this algorithm like
(defn compute-next-B [B]
(let [m (count B)
m+1 (inc m)
terms (map-indexed (fn [k Bk] (- (* Bk (binom m+1 k)))) B)]
(conj B (/ (apply + terms) m+1))))
(defn foo [n]
(->> [1]
(iterate compute-next-B)
(drop n)
first
last))
The outer loop from the pseudo code is the lazy sequence produced by (iterate compute-next-B ...). The inner loop from the pseudo code is the iteration inside (apply + terms) on the lazy sequence terms.
I was trying to modify a vector of vector but ended up with lazy-seq inside. I am new to clojure. Can someone help me to get this correctly?
(require '[clojure.string :as str])
;;READ CUST.TXT
(def my_str(slurp "cust.txt"))
(defn esplit [x] (str/split x #"\|" ))
(def cust (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
;;func to print
(for [i cust] (do (println (str (subs (str i) 2 3) ": [" (subs (str i) 5 (count (str i)))))))
;;CODE TO SEARCH CUST
(defn cust_find [x] (for [i cust :when (= (first i) x )] (do (nth i 1))))
(type (cust_find "2"))
;;READ PROD.TXT
(def my_str(slurp "prod.txt"))
(def prod (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
;;func to print
(for [i prod] (do (println (str (subs (str i) 2 3) ": [" (subs (str i) 5 (count (str i)))))))
;;CODE TO SEARCH PROD
(defn prod_find [x y] (for [i prod :when (= (first i) x )] (nth i y)))
(prod_find "2" 1)
(def my_str(slurp "sales.txt"))
(def sales (vec (sort-by first (vec (map esplit (vec (str/split my_str #"\n")))))))
; (for [i (range(count sales))] (cust_find (nth (nth sales i) 1)))
; (defn fill_sales_1 [x]
; (assoc x 1
; (cust_find (nth x 1))))
; (def sales(map fill_sales_1 (sales)))
(def sales (vec (for [i (range(count sales))] (assoc (nth sales i) 1 (str (cust_find (nth (nth sales i) 1)))))))
; (for [i (range(count sales))] (assoc (nth sales i) 2 (str (prod_find (nth (nth sales i) 2) 1))))
(for [i sales] (println i))
When I print sales vector I get
[1 clojure.lang.LazySeq#10ae5ccd 1 3]
[2 clojure.lang.LazySeq#a5d0ddf9 2 3]
[3 clojure.lang.LazySeq#a5d0ddf9 1 1]
[4 clojure.lang.LazySeq#d80cb028 3 4]
If you need the text files I will upload them as well.
In Clojure, for and map, as well as other functions and macros working with sequences, generate a lazy sequence instead of a vector.
In the REPL, lazy sequences are usually fully computed when printing - to have it printed, it's enough to remove the str in your second to last line:
(def sales (vec (for [i (range(count sales))] (assoc (nth sales i) 1 (cust_find (nth (nth sales i) 1))))))
Just in case, note that your code can be prettified / simplified to convey the meaning better. For example, you are just iterating over a sequence of sales - you don't need to iterate over the indices and then get each item using nth:
(def sales
(vec (for [rec sales])
(assoc rec 1 (cust_find (nth rec 1)))))
Second, you can replace nth ... 1 with second - it will be easier to understand:
(def sales
(vec (for [rec sales])
(assoc rec 1 (cust_find (second rec))))
Or, alternatively, you can just use update instead of assoc:
(def sales
(vec (for [rec sales])
(update rec 1 cust_find)))
And, do you really need the outer vec here? You can do most of what you intend without it:
(def sales
(for [rec sales])
(update rec 1 cust_find))
Also, using underscores in Clojure function names is considered bad style: dashes (as in cust-find instead of cust_find) are easier to read and easier to type.
(for [i sales] (println (doall i)))
doall realizes a lazy sequence. Bare in mind that if the sequence is huge, you might not want to do this.
Still very new to Clojure and programming in general so forgive the stupid question.
The problem is:
Find n and k such that the sum of numbers up to n (exclusive) is equal to the sum of numbers from n+1 to k (inclusive).
My solution (which works fine) is to define the following functions:
(defn addd [x] (/ (* x (+ x 1)) 2))
(defn sum-to-n [n] (addd(- n 1)))
(defn sum-to-k [n=1 k=4] (- (addd k) (addd n)))
(defn is-right[n k]
(= (addd (- n 1)) (sum-to-k n k)))
And then run the following loop:
(loop [n 1 k 2]
(cond
(is-right n k) [n k]
(> (sum-to-k n k) (sum-to-n n) )(recur (inc n) k)
:else (recur n (inc k))))
This only returns one answer but if I manually set n and k I can get different values. However, I would like to define a function which returns a lazy sequence of all values so that:
(= [6 8] (take 1 make-seq))
How do I do this as efficiently as possible? I have tried various things but haven't had much luck.
Thanks
:Edit:
I think I came up with a better way of doing it, but its returning 'let should be a vector'. Clojure docs aren't much help...
Heres the new code:
(defn calc-n [n k]
(inc (+ (* 2 k) (* 3 n))))
(defn calc-k [n k]
(inc (+ (* 3 k)(* 4 n))))
(defn f
(let [n 4 k 6]
(recur (calc-n n k) (calc-k n k))))
(take 4 (f))
Yes, you can create a lazy-seq, so that the next iteration will take result of the previous iteration. Here is my suggestion:
(defn cal [n k]
(loop [n n k k]
(cond
(is-right n k) [n k]
(> (sum-to-k n k) (sum-to-n n) )(recur (inc n) k)
:else (recur n (inc k)))))
(defn make-seq [n k]
(if-let [[n1 k1] (cal n k)]
(cons [n1 k1]
(lazy-seq (make-seq (inc n1) (inc k1))))))
(take 5 (make-seq 1 2))
;;=> ([6 8] [35 49] [204 288] [1189 1681] [6930 9800])
just generating lazy seq of candidatess with iterate and then filtering them should probably be what you need:
(def pairs
(->> [1 2]
(iterate (fn [[n k]]
(if (< (sum-to-n n) (sum-n-to-k n k))
[(inc n) k]
[n (inc k)])))
(filter (partial apply is-right))))
user> (take 5 pairs)
;;=> ([6 8] [35 49] [204 288] [1189 1681] [6930 9800])
semantically it is just like manually generating a lazy-seq, and should be as efficient, but this one is probably more idiomatic
If you don't feel like "rolling your own", here is an alternate solution. I also cleaned up the algorithm a bit through renaming/reformating.
The main difference is that you treat your loop-recur as an infinite loop inside of the t/lazy-gen form. When you find a value you want to keep, you use the t/yield expression to create a lazy-sequence of outputs. This structure is the Clojure version of a generator function, just like in Python.
(ns tst.demo.core
(:use tupelo.test )
(:require [tupelo.core :as t] ))
(defn integrate-to [x]
(/ (* x (+ x 1)) 2))
(defn sum-to-n [n]
(integrate-to (- n 1)))
(defn sum-n-to-k [n k]
(- (integrate-to k) (integrate-to n)))
(defn sums-match[n k]
(= (sum-to-n n) (sum-n-to-k n k)))
(defn recur-gen []
(t/lazy-gen
(loop [n 1 k 2]
(when (sums-match n k)
(t/yield [n k]))
(if (< (sum-to-n n) (sum-n-to-k n k))
(recur (inc n) k)
(recur n (inc k))))))
with results:
-------------------------------
Clojure 1.10.1 Java 13
-------------------------------
(take 5 (recur-gen)) => ([6 8] [35 49] [204 288] [1189 1681] [6930 9800])
You can find all of the details in the Tupelo Library.
This first function probably has a better name from math, but I don't know math very well. I'd use inc (increment) instead of (+ ,,, 1), but that's just personal preference.
(defn addd [x]
(/ (* x (inc x)) 2))
I'll slightly clean up the spacing here and use the dec (decrement) function.
(defn sum-to-n [n]
(addd (dec n)))
(defn sum-n-to-k [n k]
(- (addd k) (addd n)))
In some languages predicates, functions that return booleans,
have names like is-odd or is-whatever. In clojure they're usually
called odd? or whatever?.
The question-mark is not syntax, it's just part of the name.
(defn matching-sums? [n k]
(= (addd (dec n)) (sum-n-to-k n k)))
The loop special form is kind of like an anonymous function
for recur to jump back to. If there's no loop form, recur jumps back
to the enclosing function.
Also, dunno what to call this so I'll just call it f.
(defn f [n k]
(cond
(matching-sums? n k) [n k]
(> (sum-n-to-k n k) (sum-to-n n)) (recur (inc n) k)
:else (recur n (inc k))))
(comment
(f 1 2) ;=> [6 8]
(f 7 9) ;=> [35 49]
)
Now, for your actual question. How to make a lazy sequence. You can use the lazy-seq macro, like in minhtuannguyen's answer, but there's an easier, higher level way. Use the iterate function. iterate takes a function and a value and returns an infinite sequence of the value followed by calling the function with the value, followed by calling the function on that value etc.
(defn make-seq [init]
(iterate (fn [n-and-k]
(let [n (first n-and-k)
k (second n-and-k)]
(f (inc n) (inc k))))
init))
(comment
(take 4 (make-seq [1 2])) ;=> ([1 2] [6 8] [35 49] [204 288])
)
That can be simplified a bit by using destructuring in the argument-vector of the anonymous function.
(defn make-seq [init]
(iterate (fn [[n k]]
(f (inc n) (inc k)))
init))
Edit:
About the repeated calculations in f.
By saving the result of the calculations using a let, you can avoid calculating addd multiple times for each number.
(defn f [n k]
(let [to-n (sum-to-n n)
n-to-k (sum-n-to-k n k)]
(cond
(= to-n n-to-k) [n k]
(> n-to-k to-n) (recur (inc n) k)
:else (recur n (inc k)))))
I'd like to create a hash-map that has n number of key-value pairs created in sets of 3 where the sets do not intersect, e.g. [(34 false) (35 false) (36 false)] && [(24 false) (25 false) (26 false)] -> {34 false 35 false 36 false 24 false 25 false 26 false}
EDIT:
To play/practice with Clojure, I'm attempting to implement an idiomatic version of the battleship board game. I decided to store the battleship coordinates in a hash-map where the keys are coordinates and the values are booleans indicating whether that section of the ship has been hit. The specific piece of code below is supposed to
Select an axis (horizontal or vertical)
Select a coordinate for the bow of the ship
"Build" the rest of the ship (3 coordinates in total) by increasing the x or y value accordingly, e.g. {"10" false "11" false "12" false}. Note the "10" translates into the second row of a matrix, first column.
Note: Before adding the ship to the hash-map of coordinates the new ship coordinates must be checked to ensure that an intersection does not exist. If it does, the ship must be "re-built."
To that end, I've created the code below. It has 2 issues:
Executing the function results in the following exception from the use of the 'acc' accumulator:
clojure.lang.LazySeq cannot be cast to clojure.lang.Associative
The result of the function is not a single hash-map, but rather a list of n hash-maps
Using idiomatic clojure, how can I achieve my goal?
(defn launch
[n]
(loop [cnt n acc {}]
(if (= cnt 0)
acc
(recur
(- cnt 1)
((fn []
(let [axis (rand-int 2)]
(if (= axis 0)
(let [x (rand-int 8) y (rand-int 10)]
(for [k (range 3)]
(assoc acc (str y (+ x k)) false)))
(let [x (rand-int 10) y (rand-int 8)]
(for [k (range 3)]
(assoc acc (str (+ y k) x) false)))))))))))
that's how i would rewrite it:
(defn create-key [axis-val i]
(if axis-val
(str (rand-int 10) (+ (rand-int 8) i))
(str (+ (rand-int 8) i) (rand-int 10))))
(defn launch [n]
(reduce (fn [acc axis]
(reduce #(assoc % (create-key axis %2) false)
acc
(range 3)))
{}
(repeatedly n #(zero? (rand-int 2)))))
in repl:
user> (launch 5)
{"40" false, "07" false, "19" false,
"46" false, "87" false, "47" false,
"41" false, "62" false, "86" false}
or (in case you don't like reduce):
(defn launch [n]
(zipmap (mapcat #(map (partial create-key %) (range 3))
(repeatedly n #(zero? (rand-int 2))))
(repeat false)))
the third variant is to use list comprehension to generate keys:
(defn launch [n]
(zipmap (for [_ (range n)
:let [axis (zero? (rand-int 2))]
i (range 3)]
(create-key axis i))
(repeat false)))
all three of them are idiomatic ones, i guess, so it's up to you to choose one, according to your own preferred programming style.
notice that the resulting keys are shuffled inside the map, because unsorted maps don't preserve order. If it is important, you should use sorted-map
What about your variant, the one generating error is this:
(for [k (range 3)] (assoc acc (str y (+ x k)) false))
it doesn't put all the keys to one map, rather it generates a seq of three items equalling (assoc acc k false):
(let [acc {}]
(for [k (range 3)] (assoc acc k false)))
;;=> ({0 false} {1 false} {2 false})
to do what you want, you use reduce:
(let [acc {}]
(reduce #(assoc %1 %2 false) acc (range 3)))
;;=> {0 false, 1 false, 2 false}
leetwinski has given a more concise answer, but I thought I would post this anyway, since I basically left your structure intact, and this may help you see the error a bit more clearly.
First, I am not sure why you were rebinding acc to the value of an anonymous function call. Your let will happily return a result; so, you should probably do some thinking about why you thought it was necessary to create an anonymous function.
Second, the problem is that for returns a lazy seq, and you are binding this to what you think is a map data structure. This explains why it works fine for cases 0 and 1, but when you use a value of 2 it fails.
Since I don't really fully understand what you're trying to accomplish, here is your original code, modified to work. Disclaimer--this is not really idiomatic and not how I would write it, but I'm posting because it may be helpful to see versus the original, since it actually works.
(defn launch
[n]
(loop [cnt n
acc {}]
(if (= cnt 0)
acc
(recur
(dec cnt)
(into acc
(let [axis (rand-int 2)]
(if (= axis 0)
(let [x (rand-int 8) y (rand-int 10)]
(map #(hash-map (str y (+ x %)) false) (range 3)))
(let [x (rand-int 10) y (rand-int 8)]
(map #(hash-map (str (+ y %) x) false) (range 3))))))))))
I have completed this problem on hackerrank and my solution passes most test cases but it is not fast enough for 4 out of the 11 test cases.
My solution looks like this:
(ns scratch.core
(require [clojure.string :as str :only (split-lines join split)]))
(defn ascii [char]
(int (.charAt (str char) 0)))
(defn process [text]
(let [parts (split-at (int (Math/floor (/ (count text) 2))) text)
left (first parts)
right (if (> (count (last parts)) (count (first parts)))
(rest (last parts))
(last parts))]
(reduce (fn [acc i]
(let [a (ascii (nth left i))
b (ascii (nth (reverse right) i))]
(if (> a b)
(+ acc (- a b))
(+ acc (- b a))))
) 0 (range (count left)))))
(defn print-result [[x & xs]]
(prn x)
(if (seq xs)
(recur xs)))
(let [input (slurp "/Users/paulcowan/Downloads/input10.txt")
inputs (str/split-lines input)
length (read-string (first inputs))
texts (rest inputs)]
(time (print-result (map process texts))))
Can anyone give me any advice about what I should look at to make this faster?
Would using recursion instead of reduce be faster or maybe this line is expensive:
right (if (> (count (last parts)) (count (first parts)))
(rest (last parts))
(last parts))
Because I am getting a count twice.
You are redundantly calling reverse on every iteration of the reduce:
user=> (let [c [1 2 3]
noisey-reverse #(doto (reverse %) println)]
(reduce (fn [acc e] (conj acc (noisey-reverse c) e))
[]
[:a :b :c]))
(3 2 1)
(3 2 1)
(3 2 1)
[(3 2 1) :a (3 2 1) :b (3 2 1) :c]
The reversed value could be calculated inside the containing let, and would then only need to be calculated once.
Also, due to the way your parts is defined, you are doing linear time lookups with each call to nth. It would be better to put parts in a vector and do indexed lookup. In fact you wouldn't need a reversed parts, and could do arithmetic based on the count of the vector to find the item to look up.