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


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.