I have a sequence:
[a b c ...]
And a function (f x y). I want to get this:
(f c (f b (f a 1)))
Etc.. How to do this?
Reduce, with a small adaptation:
(reduce #(f %2 %1) 1 [a b c])
(reduce (fn [acc x] (f x acc)) 1 [a b c d])
Related
So I am trying to solve this problem, and this is the code I have come up with:
First I have a pack function, receives a list and groups same elements into a vector.
(defn pack [lst]
(def a [])
(def vect [])
(cond
(empty? lst)
lst
:else
(loop [i 0]
(def r (get lst i))
(def t (get lst (+ i 1)))
(if (= r t)
(def vect (conj vect r))
)
(if (not= r t)
(and (def vect (conj vect r)) (and (def a (conj a vect)) (def vect [])))
)
(if (= i (- (count lst) 1))
a
(recur (inc i))
)
))
)
for example if I have this vector:
(def tes '[a a a a b c c a a d e e e e])
pack function will return this:
[[a a a a] [b] [c c] [a a] [d] [e e e e]]
Then I tried doing the "encode" part of the problem with this code:
(def v1 [])
(def v2 [])
(conj v2 (conj v1 (count (get (pack tes) 0)) (get (get (pack tes) 0) 0)))
And it returned what I wanted, a vector "v2" with a vector "v1" that has the "encoded" item.
[[4 a]]
So now I try to make the function:
(defn encode [lst]
(loop [index 0 limit (count (pack lst)) v1 [] v2[]]
(if (= index limit)
lst
(conj v2 (conj v1 (count (get (pack tes) index)) (get (get (pack tes) index) index)))
)
(recur (inc index) limit v1 v2)
)
)
(encode tes)
but I get this error:
2021/03/07 00:00:21 got exception from server /usr/local/bin/lein: line 152:
28 Killed "$LEIN_JAVA_CMD" "${BOOTCLASSPATH[#]}" -Dfile.encoding=UTF-8 -Dmaven.wagon.http.ssl.easy=false -Dmaven.wagon.rto=10000 $LEIN_JVM_OPTS
-Dleiningen.original.pwd="$ORIGINAL_PWD" -Dleiningen.script="$0" -classpath "$CLASSPATH" clojure.main -m leiningen.core.main "$#"
2021/03/07 01:42:20 error reading from server EOF
Any way to fix my code or to solve the problem more efficiently but still return a vector?
juxt can be used in the pack function:
(defn pack [xs]
(map (juxt count first) (partition-by identity xs)))
(defn unpack [xs]
(mapcat #(apply repeat %) xs))
Don't use def inside function, because it creates global
variable. Use let instead.
Don't use multiple if in row, there is cond.
Format your code better- for example, put all parentheses on the end together on one line.
Here is more efficient solution:
(defn pack [lst]
(letfn [(pack-help [lst]
(if (empty? lst) '()
(let [elem (first lst)]
(cons (vec (take-while #(= % elem) lst))
(pack-help (drop-while #(= % elem) lst))))))]
(vec (pack-help lst))))
(defn pack-with-count [lst]
(mapv #(vector (count %) (first %))
(pack lst)))
(defn unpack [packed-lst]
(into [] (apply concat packed-lst)))
(pack '[a a a a b c c a a d e e e e])
(pack-with-count '[a a a a b c c a a d e e e e])
(unpack '[[a a a a] [b] [c c] [a a] [d] [e e e e]])
As a rule, whenever you reach for loop/recur, there are some pieces of the standard library which will allow you to get the desired effect using higher-order functions. You avoid needing to implement the wiring and can just concentrate on your intent.
(def tes '[a a a a b c c a a d e e e e])
(partition-by identity tes)
; => ((a a a a) (b) (c c) (a a) (d) (e e e e))
(map (juxt count first) *1)
; => ([4 a] [1 b] [2 c] [2 a] [1 d] [4 e])
(mapcat #(apply repeat %) *1)
; => (a a a a b c c a a d e e e e)
Here *1 is just the REPL shorthand for "previous result" - if you need to compose these into functions, this will be replaced with your argument.
If you really need vectors rather than sequences for the outer collection at each stage, you can wrap with vec (to convert the lazy sequence to a vector), or use mapv instead of map.
Finally - the error message you are getting from lein is a syntax error rather than a logic or code problem. Clojure generally flags an unexpected EOF if there aren't enough closing parens.
(println "because we left them open like this -"
Consider working inside a REPL within an IDE, or if that isn't possible then using a text editor that matches parens for you.
One of my favorite ways to test the power of a language I'm learning is to try and implement various fixed-point combinators. Since I'm learning Clojure (though I'm not new to lisps), I did the same for it.
First, a little "testable" code, factorial:
(def !'
"un-fixed factorial function"
(fn [f]
(fn [n]
(if (zero? n)
1
(* n (f (dec n)))))))
(defn !
"factorial"
[n]
(if (zero? n)
1
(apply * (map inc (range n)))))
For any combinator c I implement, I want to verify that ((c !') n) is equal to (! n).
We start with the traditional Y:
(defn Y
"pure lazy Y combinator => stack overflow"
[f]
(let [A (fn [x] (f (x x)))]
(A A)))
But of course Clojure is not nearly so lazy as that, so we pivot to Z:
(defn Z
"strict fixed-point combinator"
[f]
(let [A (fn [x] (f (fn [v] ((x x) v))))]
(A A)))
And indeed, it holds that (= ((Z !') n) (! n)).
Now comes my issue: I cannot get either of U or the Turing combinator (theta-v) to work correctly. I suspect with U it's a language limit, while with theta-v I'm more inclined to believe it's a misread of Wikipedia's notation:
(defn U
"the U combinator => broken???"
[f]
(f f))
(defn theta-v
"Turing fixed-point combinator by-value"
[f]
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
A sample REPL experience:
((U !') 5)
;=> Execution error (ClassCastException) at fix/!'$fn (fix.clj:55).
;=> fix$_BANG__SINGLEQUOTE_$fn__180 cannot be cast to java.lang.Number
((theta-v !') 5)
;=> Execution error (ClassCastException) at fix/theta-v$A$fn (fix.clj:36).
;=> java.lang.Long cannot be cast to clojure.lang.IFn
Can anyone explain
Why these implementations of U and theta-v are not working; and
How to fix them?
Your definition of theta-v is wrong for two reasons. The first is pretty obvious: you accept f as a parameter and then ignore it. A more faithful translation would be to use def style, as you have for your other functions:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
The second reason is a bit sneakier: you translated λz.xxyz to (fn [z] ((x x) y) z), remembering that lisps need more parentheses to denote function calls that are implicit in lambda-calculus notation. However, you missed one set: just as x x y z would have meant "evaluate x twice, then y once, then finally return z", what you wrote means "evaluate ((x x) y), then throw away that result and return z". Adding the extra set of parentheses yields a working theta-v:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] (((x x) y) z)))))]
(A A)))
and we can demonstrate that it works by calculating some factorials:
user> (map (theta-v !') (range 10))
(1 1 2 6 24 120 720 5040 40320 362880)
As for U: to use the U combinator, functions being combined must change how they self-call, meaning you would need to rewrite !' as well:
(def U [f] (f f))
(def ! (U (fn [f]
(fn [n]
(if (zero? n)
1
(* n ((f f) (dec n))))))))
Note that I have changed (f (dec n)) to ((f f) (dec n)).
This is a repeat of this question: Calculate primes p and q from private exponent (d), public exponent (e) and the modulus (n)
I'm just explicitly stating the problem and asking for a solution - hopefully in clojure:
public key (n):
8251765078168273332294927113607583143463818063169334570141974734622347615608759376136539680924724436167734207457819985975399290886224386172465730576481018297063
private key (d):
3208816897586377860956958931447720469523710321495803767643746679156057326148423456475670861779003305999429436586281847824835615918694834568426186408938023979073
exponent (e): 65537
and I want to get the seeds: p and q
p: 87270901711217520502010198833502882703085386146216514793775433152756453168234183
q: 87270901711217520502010198833502882703085386146216514793775433152756453168234183
To get n and d in the first place is not too hard:
(defn egcd [a b]
(if (= a 0)
[b, 0, 1]
(let [[g y x] (egcd (mod b a) a)]
[g (- x (* y (quot b a))) y])))
(defn modinv [a m]
(let [[g y x] (egcd a m)]
(if (not= 1 g)
(throw (Exception. "Modular Inverse Does Not Exist"))
y)))
(def n (* p q))
(def d (modinv e (* (dec p) (dec q)))
Now I require a reverse transform.
The algorithm Thomas Pornin posted in response to the question you link to works perfectly. Transcribed into Clojure, it looks like this:
;; using math.numeric-tower 0.0.4
(require '[clojure.math.numeric-tower :as num])
(defn find-ks [e d n]
(let [m (num/round (/ (*' e d) n))]
((juxt dec' identity inc') m)))
(defn phi-of-n [e d k]
(/ (dec' (*' e d)) k))
(defn p-and-q [p+q pq]
[(/ (+' p+q (num/sqrt (-' (*' p+q p+q) (*' 4 pq)))) 2)
(/ (-' p+q (num/sqrt (-' (*' p+q p+q) (*' 4 pq)))) 2)])
(defn verify [n p q]
(== n (*' p q)))
(defn solve [e d n]
(first
(for [k (find-ks e d n)
:let [phi (phi-of-n e d k)
p+q (inc' (-' n phi))
[p q] (p-and-q p+q n)]
:when (verify n p q)]
[p q])))
Applying this to your e, d and n we get
(solve 65537N 3208816897586377860956958931447720469523710321495803767643746679156057326148423456475670861779003305999429436586281847824835615918694834568426186408938023979073N 8251765078168273332294927113607583143463818063169334570141974734622347615608759376136539680924724436167734207457819985975399290886224386172465730576481018297063N)
;= [94553452712951836476229946322137980113539561829760409872047377997530344849179361N
87270901711217520502010198833502882703085386146216514793775433152756453168234183N]
You posted the same number as p and q, by the way -- the second one in the result vector above -- but it's easy to verify that these are the correct numbers by using the pair to rederive n and d.
For example, the extended euclidean algorithm (quoted from wiki):
function extended_gcd(a, b)
x := 0 lastx := 1
y := 1 lasty := 0
while b ≠ 0
quotient := a div b
(a, b) := (b, a mod b)
(x, lastx) := (lastx - quotient*x, x)
(y, lasty) := (lasty - quotient*y, y)
return (lastx, lasty)
which I tried and got:
(defn extended-gcd
[a b]
(loop [a a b b x 0 y 1 lx 1 ly 0]
(if (zero? b)
[lx ly]
(recur b (mod a b)
(- lx (* (int (/ a b)) x))
(- ly (* (int (/ a b)) y))
x y))))
I guess I could find a way to translate loops that deal with sequence. But how about this one? How do I write it in clojure way? something with map, reduce, etc. rather than loop recur.
For the extended Euclidean algorithm you can use a simple recursion, which makes a function look quite elegant:
(defn extended-gcd [a b]
(if (zero? b) [1 0]
(let [[q r] [(quot a b) (rem a b)]
[s t] (extended-gcd b r)]
[t (- s (* q t))])))
Let's try it:
user=> (extended-gcd 120 23)
[-9 47]
Not all problems need to be solved by using map/reduce/sequence. I would argue that the above is just as Clojure way as a "(reduce + [1 2 3 4 5])" type of an answer you are looking for.
For this kind of problem iterate is often a good alternative to using loop. In this case it leads to a fairly transparent translation of the source algorithm:
(defn extended-gcd [a b]
(->> {:a a, :b b, :x 0, :y 1, :lx 1, :ly 0}
(iterate
(fn [{keys [a b x y lx ly]}]
(let [q (quot a b)]
{:a b, :b (mod a b), :x (- lx (* q x)), :lx x, :y (- ly (* q y)), :ly y})))
(drop-while #(not= 0 (:b %)))
first
((juxt :lx :ly))))
That said, using loop is a Clojure way too -- admonitions to avoid it, I believe, are meant to encourage use of higher-level constructs where they're more appropriate.
How could I convert this:
[a b c d e]
or this:
(e d c b a) ;(rseq [a b c d e])
to this:
[a[b[c[d[e]]]]]
I've been wracking my brain and I feel like there is a simple solution! :-\
Ultimately I want to do this:
[a b c d e]
[a b c x y]
[a b c d j k]
as this:
{a {b {c {d {e}
{j {k}}
{x {y}}}}
Which I think conj will help with
(Update: added answer to the new question added in the edit below the answer to the original question.)
I've actually answered this very question in #clojure recently.
Here are two approaches: f is pretty much the spec directly transformed into code, which however creates a seq -- (next xs) -- which immediately gets poured into a new vector at each step; g is a much better version which only allocates objects which will actually occur in the output, plus a vector and the seq links to traverse it:
;; [1 2 3] -> [1 [2 [3]]]
;; naive, quadratic:
(defn f [xs]
(if (next xs)
[(first xs) (vec (f (next xs)))]
(vec xs)))
;; only allocates output + 1 vector + a linear number of seq links,
;; linear overall:
(defn g [v]
(reduce (fn [acc x]
[x acc])
[(peek v)]
(rseq (pop v))))
NB. I'm overlooking the usual logarithmic factors arising from vector operations (so this is soft-O complexity).
As for producing a nested map, the above isn't particularly useful. Here's one approach:
(defn h
([v]
(h nil v))
([m v]
(assoc-in m v nil)))
(h [1 2 3 4])
;= {1 {2 {3 {4 nil}}}}
(def data
'[[a b c d e]
[a b c x y]
[a b c d j k]])
(reduce h {} data)
;= {a {b {c {x {y nil}, d {j {k nil}, e nil}}}}}
I'm using nil as a "terminator", since {y} (as currently found in the answer text) is not a well-formed literal. true might be a more convenient choice if you plan to call these maps as functions to check for presence of keys.
Simpler solution here (using destructuring and non-tail recursion):
http://ideone.com/qchXZC
(defn wrap
([[a & as]]
(if-let [[b & cs] as]
[a (wrap as)]
[a])))