Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active December 11, 2020 17:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericnormand/1524630ea3d4cadb84c588a19fccea89 to your computer and use it in GitHub Desktop.
Save ericnormand/1524630ea3d4cadb84c588a19fccea89 to your computer and use it in GitHub Desktop.

Powers in range

Let's say you have an inclusive range of integers [a, b]. You also have an exponent n. What numbers k^n (integer k raised to the nth power) occur in that range? Write a function that takes a, b, and n and returns the numbers k^n.

Examples

;; n = 2, [a, b] = [49, 65]
(powers-in-range 2 49 65) ;=> [49 64] ;; that is, 7^2 and 8^2
;; n = 3, [a, b] = [1, 27]
(powers-in-range 3 1 27) ;=> [1 8 27] ;; 1^3, 2^3, and 3^3
;; n = 10, [a, b] = [1, 5]
(powers-in-range 10 1 5) ;=> [1] ;; 1^10

Thanks to this site for the challenge idea where it is considered Hard level in Python.

Email submissions to eric@purelyfunctional.tv before August 15, 2020. You can discuss the submissions in the comments below.

(ns tst.demo.core
(:use tupelo.core tupelo.test))
(defn powers-in-range
[exponent low high]
(let [exp-inv (/ 1.0 exponent)
root-low (Math/round (Math/pow (double low) exp-inv))
root-high (Math/round (Math/pow (double high) exp-inv))
in-interval? (fn [val] (<= low val high))
results (keep-if in-interval?
(mapv #(int (Math/pow % exponent)) (thru root-low root-high)))]
results))
(dotest
(is= (powers-in-range 2 49 65) [49 64])
(is= (powers-in-range 3 1 27) [1 8 27])
(is= (powers-in-range 10 1 5) [1]))
(defn powers-in-range [n a b]
(->> (range)
(map #(int(Math/pow % n)))
(drop-while #(< % a))
(take-while #(<= % b))))
(defn powers-in-range [n a b]
(->> (range (Math/ceil (Math/pow a (/ n)))
(inc (Math/floor (Math/pow b (/ n)))))
(map #(long (Math/pow % n)))))
(defn powers-in-range [n a b]
(second (partition-by #(<= a % b) (map #(apply * (repeat n %)) (range)))))
(ns clojure-challenge.issue-391)
(defn exp [x n]
(reduce * (repeat n x)))
(defn powers-in-range [n min max]
(->> (range)
(map #(exp % n))
(drop-while #(> min %))
(take-while #(>= max %))))
(defn powers-in-range-rec
([n min max]
(powers-in-range-rec n min max [] 1))
([n min max col x]
(let [power (exp x n)]
(cond
(> power max) col
(>= power min) (recur n min max (conj col power) (inc x))
:else (recur n min max col (inc x))))))
(defn powers-in-range [exp lo hi]
(let [root (fn [exp n] (Math/pow n (/ 1 exp)))
pow (fn [exp n] (reduce * (repeat exp n)))
n0 (int (Math/floor (root exp lo)))]
(->> (iterate inc n0)
(map (partial pow exp))
(drop-while #(< % lo))
(take-while #(<= % hi)))))
(defn powers-in-range [n a b]
(when (or (not (pos? n))
(not= n (int n)))
(throw (ex-info "Only positive, integer n's allowed" {:n n})))
(let [nth-root (fn [n x]
(Math/round
(Math/pow x (/ 1.0 n))))]
(->> (range (nth-root n a)
(inc (nth-root n b)))
(map (comp int #(Math/pow % n)))
(filter (partial <= a))
(filter (partial >= b)))))
(defn powers-in-range [n a b]
(let [k-guess (->> n (/ 1) (Math/pow a) Math/floor long)
powers (map #(long (Math/pow % n)) (iterate inc k-guess))]
(->> powers (drop-while #(< % a)) (take-while #(<= % b)))))
(defn- pow [i p]
(int (Math/pow i p)))
(defn- log [i base]
(int (quot (Math/log i) (Math/log base))))
(defn powers-in-range [power minimum maximum]
(let [start (log minimum power)
->pow #(pow % power)]
(into [] (->>
(iterate inc start)
(map ->pow)
(drop-while #(< % minimum))
(take-while #(<= % maximum))))))
(defn powers-in-range
[n a b]
(let [k-min (int (Math/floor (Math/pow (max a 0) (/ 1. n))))
k-max (int (Math/ceil (Math/pow b (/ 1. n))))
k-range (range k-min (inc k-max))
kn-range (map #(int (Math/pow % n)) k-range) ; k^n
kn-filtered (vec (filter #(<= a % b) kn-range))]
kn-filtered))
(comment
(powers-in-range 2 49 65) ; => [49 64]
(powers-in-range 3 1 27) ; => [1 8 27]
(powers-in-range 10 1 5) ; => [1]
:_)
@ninjure
Copy link

ninjure commented Aug 17, 2020

(defn powers-in-range [n a b]
  (let [[start end] (sort [a b])
        nth-pow (fn [x n] (reduce * (repeat n x)))]
    (->> (range)
         (map #(nth-pow % n))
         (drop-while #(< % start))
         (take-while #(<= % end)))))

it is not so complicated if we can assume that the variables a, b, and n take only positive integers.

@KingCode
Copy link

(defn powers-in-range [n lo hi]
  (let  [pow (fn [base] (->> (iterate #(* base %) 1) (drop n) first))]
    (->> (range) 
         (drop-while #(> lo (pow %)))
         (take-while #(>= hi (pow %)))
         (mapv #(pow %)))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment