Функция Кармайкла не увеличивает k

Для любого числа функция Кармайкла возвращает 0 независимо от входных данных n.

function gcd(a, b)
  if b == 0 then
    return a
  else
    return (gcd(b,a%b))
  end
end

function carmichael(n)
  coprimes = {}
  for i = 1,n-1 do
    if gcd(i,n) == 1 then
      table.insert(coprimes,i)
    end
  end
  k = 0
  while true do
    for counter = 1,#coprimes do
      coprime = coprimes[counter]
      if (coprime^k)%n ~= 1 then
        break
      else
        return k
      end
      k = k+1
    end
  end
end

input = io.read()

print(carmichael(tonumber(input)))

Если coprime = 1, то (coprime^k)%n равно 1, поэтому оно переходит в часть else и просто return k

qrsngky 05.06.2024 12:23

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

Overo3 05.06.2024 12:28

Что ты хочешь сделать с k? Каков ожидаемый результат camichael(n)?

qrsngky 05.06.2024 12:30

Ожидаемый результат — это число Кармайкла n, по сути, наименьшее число из набора действительных целых чисел, которое имеет свойство a^m = 1 (mod n), справедливое для каждого целого числа, взаимно простого с n здесь

Overo3 05.06.2024 12:33

Прочтите stackoverflow.com/questions/47761383/proper-carmichael-funct‌​ion, а затем примените то, чему вас там учит, в контексте Lua?

Mike 'Pomax' Kamermans 05.06.2024 14:14

Один из возможных способов — не «возвращаться после одного совпадения», а использовать переменную, чтобы проверить, не прервался ли цикл. Если он выходит за пределы цикла for без нарушения, то все взаимно простые числа удовлетворяют условию, в противном случае переход к следующему k. Однако я думаю о другой проблеме, а именно о том, превышает ли coprime^k максимальное целое число в Lua.

qrsngky 05.06.2024 14:57

@Mike'Pomax'Kamermans единственный ответ на этот вопрос - это не "правильная" функция Кармайкла, поскольку она не гарантирует, что все взаимно простые числа соответствуют условию a^m%n=1, только один, что приводит к выводу функции всегда быть 0

Overo3 05.06.2024 15:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я исправил код, добавив проверку, чтобы убедиться, что цикл не был нарушен, и изменил проверку, чтобы убедиться, что все взаимно простые числа соответствуют условию, используя k, и изменил значение присваивания k с 0 на 1, чтобы coprime^k%n не всегда вычислялось. до 1, потому что все числа в степени 0 дают 1. Модифицированный код:

function carmichael(n)
  coprimes = {}
  for i = 1,n-1 do
    if gcd(i,n) == 1 then
      table.insert(coprimes,i)
    end
  end
  totient = #coprimes
  k = 1
  while k <= totient do
    notcarmichael = false
    for counter = 1,#coprimes do
      coprime = coprimes[counter]
      if (coprime^k)%n ~= 1 then
        notcarmichael = true
        break
      end
    end
    if not notcarmichael then
      return k
    else
      k = k+1
    end
  end
  return totient
end

Должно быть хорошо для меньших чисел, но если coprime^k приведет к очень большому числу, это может привести к странному поведению. Чтобы понять, что я имею в виду под «очень большим», попробуйте unsafe_int = 2^53; print(unsafe_int == unsafe_int+1), который печатает true. Все, что больше значения 9007199254740991 ссылка

qrsngky 06.06.2024 03:42

Другие вопросы по теме