Clojure - Создание функции без делителей - PullRequest
0 голосов
/ 09 ноября 2018

Я действительно изо всех сил пытаюсь сделать эту одну функцию. Функция выглядит следующим образом

Написать функцию с именем no-divisors? который принимает вход n. Функция должна возвращать true, если ни одно из чисел от 2 до √? не делит n, и false в противном случае. Функция должна использовать как вашу функцию get-divisors, так и ваши делители? функция. Подсказка: вам, вероятно, понадобится обернуть деления? функция в анонимной функции, так что вы можете передать значение n.

Это моя get-divisors функция:

(defn get-divisors [n]
  (str (range 2 (inc (Math/floor (Math/sqrt n))))))

Это моя divides? функция:

(defn divide [a b]
  (zero? (mod a b)))

Я попытался создать метод, чтобы попытаться выполнить это задание, однако, к счастью.

Вот что я пытался:

(defn no-divisors [n] 
  divide(n (get-divisors n)))

И я получил вывод:

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn  user/x (form-init5516475059937019181.clj:16)`

У меня есть идея, которой я хотел бы поделиться, как я мог бы создать эту задачу, однако, поскольку я впервые использую Clojure, я не слишком уверен в том, чтобы реализовать эту функцию или, если это вообще возможно. Мне очень жаль, что у меня смешанный синтаксис, просто я никогда не использовал Clojure до этого момента, но вот мой черновик / проект:

(defn no-divisors [n]
  resultsArray = []
    def results((get-divisors n))
    for results in get-divisors
      resultsArray.append(results)

      for i=results[0]; i< results.count; i++ 
        divide(n i)
)

Возможно, я на правильном пути или, возможно (скорее всего), совершенно не прав. Я благодарен и благодарен за любую помощь, которую я могу получить. Еще одно замечание: обе мои функции get-divisors и divides? работают безупречно.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Вы должны проверить свою работу по ходу дела. Давайте посмотрим на вашу get-divisors функцию:

(defn get-divisors [n]
  (str (range 2 (inc (Math/floor (Math/sqrt n))))))

Давайте попробуем:

=> (get-divisors 20)
"(2 3 4)"

Это строка символов, а не набор цифр, который должен быть. Снимите разрушительный str вызов:

(defn get-divisors [n]
  (range 2 (inc (Math/floor (Math/sqrt n)))))

Теперь

=> (get-divisors 20)
(2 3 4)

Хорошо. И крайний случай, просто чтобы убедиться:

=> (get-divisors 16)
(2 3 4)

Хорошо, снова! Мы можем использовать эту функцию с некоторой уверенностью.

Теперь мы хотим выяснить, верно ли что-то для нет этой коллекции. Для этого есть удобная функция not-any?. Например,

=> (not-any? even? (range 1 100 2))
true

Что мы хотим определить, так это то, что ни один из потенциальных делителей n не делит n. Таким образом, форма функции может быть ...

0 голосов
/ 10 ноября 2018

Во-первых, вы не можете просто поместить круглые скобки в коде, как на других языках. Они означают что-то конкретное в Clojure (и других шутках) при оценке кода, а именно первое, что в списке есть глагол; функция для вызова. Вложенные скобки означают повторные обращения к результату функции. Поэтому, если у вас есть функция alice, которая возвращает функцию, например, так (оставайтесь со мной, я пытаюсь объяснить ошибку, которую вы получаете;)):

(defn alice []
  (fn [] :bob))

тогда вы можете назвать это так

(alice) ;; => #function[user/alice/fn--6930]

и он вернет функцию, которую вы создали внутри, и вы можете вызвать эту анонимную функцию следующим образом:

((alice)) ;; => :bob

чтобы получить результат этой функции. Извините, если это немного необычно, но у паренов есть смысл, и это причина ошибки, которую вы получаете:

ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn

Это означает, что вы пытаетесь вызвать номер как функцию. clojure.lang.IFn - это способ Clojure сказать «то, что я ожидал, было чем-то, что я мог бы назвать функцией». К java.lang.Long означает среднее число Clojure. ClassCastException означает, что я видел одно, а ожидал другого. На самом деле, эта ошибка пытается сказать, что вы написали открытый код ( и добавили что-то с именем числа, а не функции. Это похоже на то, что вы написали divide(n (get-divisors n)) вместо (divide n (get-divisors n)), потому что при оценке divide(n (get-divisors n)) он сначала пытается оценить divide и обнаруживает, что это функция, но не пытается ее вызвать. Затем он смотрит на следующую форму (n (get-divisors n)) и пытается спросить, что такое n, и находит его число, которое нельзя вызвать как функцию. Имеет смысл?

В вашем псевдокоде у вас есть массив, к которому вы добавляете данные для сбора результатов, в то же время повторяя цикл для построения результатов. Это очень обязательный способ решения проблемы, а не то, как Clojure пытается побудить вас решать проблемы. Clojure стремится учиться более ориентированному на данные способу решения проблемы. Один из способов думать о проблеме - это то, как она сформулирована на английском языке. Получив число n, возьмите все числа, меньшие его квадратного корня, и проверьте, делятся ли они на n. Если этот список пуст, верните true, иначе верните false. В Clojure вы могли бы написать:

(defn divide? [a b]
  (zero? (mod a b)))

(defn no-divisors? [n]
  (->> (range 2 n)
       (take-while #(< (* % %) n))
       (filter (partial divide? n))
       empty?))

Здесь мы используем макрос ->>, чтобы взять ленивую последовательность чисел от 2 до n, затем ограничиваем эту последовательность, используя take-while, только теми, у которых квадрат числа меньше n , Затем мы проверяем, что каждый делится на n, используя функцию divide?, и, наконец, спрашиваем, является ли список empty?. Поскольку последовательности Clojure являются ленивыми, никаких реальных вычислений не происходит, пока мы не попытаемся оценить результат, используя empty?, который остановится, когда он достигнет элемента в последовательности. Это делает его более эффективным, чем обход всего списка для больших значений n.

Надеюсь, это поможет.

P.S. Я не уверен, что ваша реализация get-divisors совершенно правильная.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...