Немного премьер-пира


20

(Случайно вдохновленный /mathpro//q/339890 )
(Связанный: 1 , 2 )

Учитывая входной список различных простых чисел (например, [2, 5, 7]) и целое число n, выведите все натуральные числа, строго меньшие, чем те, nкоторые содержат только эти простые числа в качестве делителей. Для ввода [2, 5, 7]и n=15это означает вывод [2, 4, 5, 7, 8, 10, 14].

Дальнейшие примеры

[list] n | output

[2, 5, 7] 15 | [2, 4, 5, 7, 8, 10, 14]
[2, 5, 7] 14 | [2, 4, 5, 7, 8, 10]
[2] 3 | [2]
[2] 9 | [2, 4, 8]
[103, 101, 97] 10000 | [97, 101, 103, 9409, 9797, 9991]
[97, 101, 103] 104 | [97, 101, 103]

Правила и разъяснения

  • Входной список гарантированно не пустой, но может быть только одним элементом
  • Вы можете предположить, что входной список предварительно отсортирован любым удобным способом
  • n всегда будет больше, чем самый большой элемент в списке ввода
  • Так как, например, 2**0 = 1вы можете при желании включить 1в свой список вывода
  • Ввод и вывод может быть дан любым удобным способом
  • Вы можете распечатать результат в STDOUT или вернуть его как результат функции
  • Либо полная программа или функция приемлемы
  • Если применимо, вы можете предположить, что целые числа ввода / вывода вписываются в родной intдиапазон вашего языка
  • Стандартные лазейки запрещены
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах)

Можем ли мы выводить в любом порядке?
— xnor

@xnor Да, вывод в любом порядке.
— AdmBorkBork

Извините ... Просто чтобы быть абсолютно уверенным: «которые содержат только те простые числа как делители» означает «которые содержат только по крайней мере одно из этих простых чисел как простые делители»?
— AZTECCO

Вы должны были проинформировать существующие решения об изменении спецификации, чтобы разрешить 1вывод.
— Лохматый

@AZTECCO Верно. Но, например, если ваш список [2, 3, 7]вы не можете использовать 5.
— AdmBorkBork

Ответы:



5

05AB1E , 6 байтов

<LʒfåP

Принимает целое число в качестве первого ввода, список как второй. Включает дополнительный 1в выходной.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

<       # Decrease the (implicit) input by 1
 L      # Create a list in the range [1,input-1]
  ʒ     # Filter it by:
   f    #  Get all prime factors of the current number (without duplicates)
    å   #  Check for each if its in the (implicit) input-list
     P  #  And check if this is truthy for all
        # (after the filter, the result is output implicitly)

Два 6 байт альтернативы , предоставляемые @Grimy :

GNfåP–

Попробуйте онлайн.

G       # Loop `N` in the range [1, (implicit) input):
 Nf     #  Get all prime factors of `N` (without duplicates)
   å    #  Check for each if its in the (implicit) input-list
    P   #  And check if this is truthy for all
     –  #  If it is, output the current `N` with trailing newline

Этот очень медленный ( [2,5,7], 15тестовый тайм-аут уже истек), но менее похож на два других подхода:

sиPÑʒ›

В отличие от двух других программ, приведенных выше, в качестве первого ввода принимается список, а во втором - целое число. 1Тем не менее, он включает в себя и дополнительный вывод.

Попробуйте онлайн.

s       # Swap so the stack is now [list-input, integer-input]
 и      # Repeat the list (flattened) the integer amount of times
        #  i.e. [2,5] and 10 → [2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5,2,5]
  P     # Take the product of this list
        #  → 10000000000
   Ñ    # Get all divisors of this integer
        # (the bottleneck for larger integers in this approach)
        #  → [1,2,4,5,8,10,16,20,25,32,40,50,64,80,100,125,128,160,200,250,256,320,400,500,512,625,640,800,1000,1024,1250,1280,1600,2000,2500,2560,3125,3200,4000,5000,5120,6250,6400,8000,10000,12500,12800,15625,16000,20000,25000,25600,31250,32000,40000,50000,62500,64000,78125,80000,100000,125000,128000,156250,160000,200000,250000,312500,320000,390625,400000,500000,625000,640000,781250,800000,1000000,1250000,1562500,1600000,1953125,2000000,2500000,3125000,3200000,3906250,4000000,5000000,6250000,7812500,8000000,9765625,10000000,12500000,15625000,16000000,19531250,20000000,25000000,31250000,39062500,40000000,50000000,62500000,78125000,80000000,100000000,125000000,156250000,200000000,250000000,312500000,400000000,500000000,625000000,1000000000,1250000000,2000000000,2500000000,5000000000,10000000000]
    ʒ   # Filter these divisors:
     ›  #  And only keep those where the (implicit) input-integer is larger than the divisor
        #  → [1,2,4,5,8]
        # (after the filter, the result is output implicitly)

1
Альтернатива 7: sиPѦʒ›. Я думал, что у меня есть 6, но, кажется, нет никакого способа использовать s/ I/¹
— Grimmy

@Grimy Хорошая альтернатива, но для ее исполнения требуется много времени. Для первого теста нужно найти все делители 4747561509943000000000000000. ;)
— Кевин Круйссен

1
Для вертикального вывода:GNfåP–
— Grimmy

4

JavaScript (ES6),  64 ... 52  50 байт

Принимает входной сигнал , как , (n)(primes)где штрихи представляют собой набор. Выходы путем изменения набора.

n=>g=(s,q=1)=>{for(p of s)(p*=q)<n&&g(s.add(p),p)}

Попробуйте онлайн!

комментарии

n =>              // n = maximum value
g = (             // g is a recursive function taking:
  s,              //   s = set of primes
  q = 1           //   q = current product, initialized to 1
) => {            //
  for(p of s)     // for each value p in s:
    (p *= q)      //   multiply p by q
    < n &&        //   if the result is less than n:
      g(          //     do a recursive call:
        s.add(p), //       with p added to the set
        p         //       with q = p
      )           //     end of recursive call
}                 //

4

Python 3 , 68 65 байт

f=lambda s,n,c=1:n//c*s and f(s,n,s[0]*c)+f(s[1:],n,c)or[c][:c<n]

Попробуйте онлайн!

-3 байта благодаря @xnor

Функция принимает простую последовательность и целое число n в качестве входных данных. Вывод представляет собой список, который включает 1.

Ungolfed:

def f(s, n, c=1):
    if not c < n:
       return []
    elif not s:
       return [c]
    else:
       return f(s,n,s[0]*c) + f(s[1:],n,c)

Попробуйте онлайн!


Это какой-то аккуратный код короткого замыкания у вас есть. Похоже, вы можете объединить первые два условия как c*s<n*s. Изменить: n//c*sкороче.
— xnor

@xnor Спасибо за улучшение. Ваш подход также хорош.
— Джоэл


3

Haskell , 39 байт

l%n=[k|k<-[2..n-1],mod(product l^k)k<1]

Попробуйте онлайн!

Проверяет, kделится ли делится только на простые числа l, проверяя, делится ли произведение lна высокую степень k.


3

Python 2 , 65 байт

lambda l,n:[k for k in range(2,n)if reduce(int.__mul__,l)**n%k<1]

Попробуйте онлайн!

Проверяет, kделится ли делится только на простые числа l, проверяя, делится ли произведение lна высокую степень k.

Если lможно рассматривать как список строк eval("*".join(l)) сохраняет 3 байт над reduce(int.__mul__,l)и может быть использован в Python 3 , который испытывает недостаток reduce.

Python 3 , 64 байта

def f(l,n,P=1):
 for x in l:P*=x
 n-=1;P**n%n or print(n);f(l,n)

Попробуйте онлайн!

Функция печатает в обратном порядке и завершается с ошибкой.

Приведенное ниже рекурсивное решение было бы короче, если бы оно nбыло включено в список. Я также пытался рекурсивно вычислять продукт l, но это было дольше.

62 байта (нерабочий)

f=lambda l,n:n*[f]and[n][reduce(int.__mul__,l)**n%n:]+f(l,n-1)

Попробуйте онлайн!


1

Gaia , 10 байт

…@e⟪ḍ‡⁻!⟫⁇

Попробуйте онлайн!

Раньше я никогда не использовал ‡монаду, это очень полезно для работы со стеком.

…		| push [0..n-1]
@e		| push list of primes
  ⟪    ⟫⁇	| filter [0..n-1] for where the following predicate is true:
   ḍ‡		| the list of prime factors
     ⁻		| minus the list of primes
      !		| is empty


1

Желе , 7 байт

ṖÆffƑ¥Ƈ

Попробуйте онлайн!

Диадическая ссылка, принимающая исключительную верхнюю границу в качестве левого аргумента и список простых чисел в качестве правого. Возвращает список, который включает 1, а также числа, состоящие только из предоставленных простых чисел.

Альтернатива 7 будет ṖÆfḟ¥Ðḟ




0

Это включает 1в вывод, что это не должно. Я тоже начал с k e!øVмоего решения, но мне понадобилось 2 дополнительных байта для фильтрации 0& 1.
— лохматый

Since, e.g., 2**0 = 1, you can optionally include 1 in your output list
— Воплощение Невежества

Что было не было частью оригинальной спецификации.
— Лохматый


0

Сетчатка 0.8.2 , 64 байта

\d+
$*
\G1
$.`,$`;
+`,(1+)(\1)*(?=;.* \1\b)
,1$#2$*
!`\d+(?=,1;)

Попробуйте онлайн!Список включает меньшие тестовые случаи ( 10000время ожидания из-за всех длинных строк). Принимает входные данные в порядке n f1 f2 f3...(факторы не должны быть простыми, но они должны быть взаимно простыми). Выход включает в себя 1. Объяснение:

\d+
$*

Преобразовать в одинарный.

\G1
$.`,$`;

Создайте список от 0 до n-1, как десятичный, так и унарный.

+`,(1+)(\1)*(?=;.* \1\b)
,1$#2$*

Повторно делите одинарное на любые доступные факторы.

!`\d+(?=,1;)

Выведите десятичные числа, до которых унарное число было уменьшено 1.


0

Pyth , 10 байт

f!-PThQtUe

Попробуйте онлайн!

Принимает вход как [[primes...], n]

        Ue  # range(0, Q[-1])  (Q is the input, implicit)
       t    #                [1:] -> range(1, Q[-1]), tUe == PSe
f           # filter that on the condition: lambda T:
   PT       # prime_divisors(T)
  -  hQ     #                   - Q[0]
 !          # logical negation (![] == True)


0

Древесный уголь , 22 20 байт

IΦ…²η⬤…·²ι∨﹪ιλ⊙θ¬﹪λν

Попробуйте онлайн! Ссылка на подробную версию кода. Слишком медленно для большого тестового случая. Объяснение:

 Φ                      Filter on
  …                     Range from
   ²                    Literal `2` to
    η                   Input limit
     ⬤                  Where all values
      …·                Inclusive range from
        ²               Literal `2` to
         ι              Filter value
          ∨             Either
             λ          Inner value
           ﹪            Is not a divisor of
            ι           Filter value
              ⊙         Or any of
               θ        Input primes
                   ν    Current prime
                ¬﹪      Is a divisor of
                  λ     Inner value
I                       Cast to string for implicit print

Предыдущий более быстрый 22-байтовый ответ:

⊞υ¹FυF×ιθF›‹κη№υκ⊞υκIυ

Попробуйте онлайн! Ссылка на подробную версию кода. Выход включает в себя 1. Объяснение:

⊞υ¹

Нажмите 1на предопределенный пустой список.

Fυ

Цикл по списку, включая любые элементы, добавленные к нему во время цикла.

F×ιθ

Умножьте текущий элемент на каждое простое число и переберите продукты.

F›‹κη№υκ

Проверьте, является ли продукт новым значением.

⊞υκ

Если это так, то нажмите его в список.

Iυ

Распечатайте список.


0

C (лязг) , 115 байт

#define f(n,l,z){int j,i,k,x[n]={};for(i=x[1]=1;i<n;printf(x[i]+"\0%d ",i++))for(j=z;j--;k<n?x[k]=x[i]:0)k=i*l[j];}

Попробуйте онлайн!

Сито из раствора на основе эратосфена.

(Включает 1 в выходной)

Благодаря предложению @ceilingcat: printf (x [i] + "\ 0% d", i ++) вместо x [i] && printf ("% d", i), i ++, я полагаю, он сдвигает указатель литерала, но не не нашел никакой документации, если кто-то может дать мне некоторое понимание, это будет приветствоваться.


Спасибо, но .. как это работает?
— AZTECCO

1
Если x[i]==1 затем строка "%d ". Если x[i]==0затем строка "". Строки C завершаются нулем, поэтому явный нулевой символ завершает строку. Этот хак также злоупотребляет некоторым неопределенным поведением в clang, связанным с i++.
— потолок кошка
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.