Project Euler #68 wrong answer for simple algorithm - clojure

So I'm attempting problem 68 in Project Euler. I came up with a simple algorithm. However, my submission comes up wrong. Do note that the algorithm works correctly for the 3-case. Please help me understand what I'm doing wrong. I've been stuck with this for some time now.
; https://projecteuler.net/problem=68
(ns eul
(:require [clojure.math.combinatorics :as combo]))
; Try the 3-case first to see if correct.
; a
; \
; b
; / \
; e - c - d
; /
; f
(->> (combo/permutations (range 1 7))
(filter (fn [[a b c d e f]] (and (= (+ a b c) (+ d c e) (+ f e b))
(< a d)
(< a f))))
(map (fn [[a b c d e f]] (->> [a b c d c e f e b]
(map str)
(apply str))))
(map #(Integer/parseInt %))
(sort >)
(first))
; a
; |
; b -- e - d
; | \
; | g
; | / \
; j - c -- i f
; /
; h
(->> (combo/permutations (range 1 11))
(filter (fn [[a b c d e f g h i j]] (and (= (+ a b c) (+ d e b) (+ f g e) (+ h i g) (+ j c i))
(< a d) (< a f) (< a h) (< a j))))
(map (fn [[a b c d e f g h i j]] (->> [a b c d e b f g e h i g j c i]
(map str)
(apply str))))
(filter #(= (.length %) 16))
(map biginteger)
(sort >)
(first))

It turned out that the arrangement of the vars were wrong in the second case. The problem statement did not match.

Related

Run length encoding of sequences

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.

if I have the public and private keys of an rsa key, how do I calculate seeds p and q?

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.

Sequentially nest vectors/list in Clojure?

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])))

how to apply a two-arg function to a sequence?

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])

Project Euler #9 (Pythagorean triplets) in Clojure

My answer to this problem feels too much like these solutions in C.
Does anyone have any advice to make this more lispy?
(use 'clojure.test)
(:import 'java.lang.Math)
(with-test
(defn find-triplet-product
([target] (find-triplet-product 1 1 target))
([a b target]
(let [c (Math/sqrt (+ (* a a) (* b b)))]
(let [sum (+ a b c)]
(cond
(> a target) "ERROR"
(= sum target) (reduce * (list a b (int c)))
(> sum target) (recur (inc a) 1 target)
(< sum target) (recur a (inc b) target))))))
(is (= (find-triplet-product 1000) 31875000)))
The clojure-euluer-project has several programs for you to reference.
I personally used this algorithm(which I found described here):
(defn generate-triple [n]
(loop [m (inc n)]
(let [a (- (* m m) (* n n))
b (* 2 (* m n)) c (+ (* m m) (* n n)) sum (+ a b c)]
(if (>= sum 1000)
[a b c sum]
(recur (inc m))))))
Seems to me much less complicated :-)