Великодушные числа


24

Учитывая положительное целое число в качестве входных данных, определите, является ли оно великодушным числом.

Великодушное число - это число, такое, что любая вставка +знака между любыми двумя цифрами в основании 10 приводит к выражению простого целого числа.

Например, 40427 великодушно, потому что

4+0427  = 431  is prime
40+427  = 467  is prime
404+27  = 431  is prime
4042+7  = 4049 is prime

Выход

Вы должны вывести два разных значения: одно, когда вход великодушный, и другое, когда вход не велик.

счет

Целью этого конкурса будет сделать размер исходного кода, написанного для решения этой задачи, в байтах, как можно меньше.

Тестовые случаи

1       -> True
2       -> True
4       -> True
10      -> False
98      -> True
101     -> True
109     -> False
819     -> False
4063    -> True
40427   -> True
2000221 -> True

OEIS 253996


Меня просто смущает определение задачи, как 1 и 2 являются даже допустимыми входными данными. Не говоря уже о том, что 1со знаком плюс, вставленным между любыми двумя символами (без вставки), можно получить только результат 1, который сам не является простым.
Волшебная урна осьминога

4
@MagicOctopusUrn Плюс должен быть вставлен между двумя цифрами, таким образом , так 1и 2не две цифры множества выражений пуст. Все члены пустого множества простые. Кроме того, ни один из них не является, но это помимо смысла. Это немного сбивает с толку, я дам вам это, но я думаю, что это имеет больше смысла, чем альтернативы.
Пшеничный волшебник

Ответы:


8

05AB1E , 10 байтов

Код

η¨¹.s¨R+pP

Использует кодировку 05AB1E . Попробуйте онлайн! или проверьте все контрольные примеры!

объяснение

η¨             # Take the prefixes of the input and remove the last element
  ¹.s¨         # Take the suffixes of the input and remove the last element
      R        # Reverse the array of suffixes
       +       # Vectorized addition
        p      # Check if each element is prime
         P     # Product of the array

Как это работает для 1 - 9. Произведение пустого набора равно 1? Зачем?
Волшебная Урна Осьминога

@MagicOctopusUrn Пустой товар всегда равен 1.
Adnan

@MagicOctopusUrn Взятие товара начинается с 1умножения его на каждый предмет в наборе, так что ...
ETHproductions

1
Ах, математически имеет смысл. Угадайте, как и как sumна []это эквивалентно 0, с помощью индукции собственности при реализации была довольно умна.
Волшебная Урна Осьминога

@jontro Да, в UTF-8 это 14 байтов. Однако 05AB1E использует кодовую страницу 05AB1E , где это 10 байтов.
Аднан

7

C (gcc) , 8384 85 83 84 86 75 111 байтов

Все оптимизации отключены и только на GCC 32-bit.

-1 байт благодаря @ceilingcat

+ несколько байтов для 1дела.

+ несколько байтов для многоразовых функций.

i,j,r,s;f(a){for(i=10,r=1;a/i;i*=10)for(s=a%i+a/i,r*=s-1,j=2;j<s;)r*=s%j++>0;a=!r;}

Принимает ввод как целое число. Верните 1 для ложных случаев, 0 для истинных случаев.

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

Смотрите мой другой ответ для кода Mathematica (55 байт).


Это должно быть два отдельных ответа. Кроме того , решение Mathematica дает неверные результаты 1, 98и 4063.
ngenisis

6

Сетчатка , 38 байт

\B
$`$*_$'$*_
S`\d
G`^_$|^(__+)\1+$
^$

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

Принты 1для великодушных номеров и 0прочее.

объяснение

\B
$`$*_$'$*_

Мы начинаем с сопоставления каждой позиции между двумя цифрами (позициями, которые не являются границами слов) и вставляем как префикс, так и суффикс этого совпадения в унарной форме, используя _в качестве унарной цифры. Таким образом, вместо того, чтобы вставлять +s, мы напрямую вставляем туда унарный результат суммы.

S`\d

Теперь мы разбиваем строку вокруг цифр, так что каждая сумма идет своей строкой, и мы избавляемся от этих цифр (также будет пустая начальная и конечная строки, но это не важно).

G`^_$|^(__+)\1+$

Это стандартное регулярное выражение для сопоставления не простых чисел в унарных. Использование Gстадии повторения здесь означает, что мы просто сохраняем все строки, содержащие положительные не простые числа (отбрасывая пустые строки).

^$

Наконец, мы проверяем, является ли строка пустой. Если вход был великодушным, предыдущий этап отбросит все строки (потому что все они были простыми числами), и это дает нам 1. В противном случае, если какая-либо строка не была простой, она останется в строке, и регулярное выражение завершится неудачно, давая 0.


4

Python 2 , 82 79 78 байт

f=lambda n,d=10:n<d or d/n<all((n/d+n%d)%k*f(n,10*d)for k in range(2,n/d+n%d))

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

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

Альтернативная версия, 79 байт

f=lambda n,d=10:n<d or f(n,10*d)>d/n<all((n/d+n%d)%k for k in range(2,n/d+n%d))

Ускоряется за счет одного байта.

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


3

Умное использование d!
Эрик Outgolfer

@EriktheOutgolfer это третий вариант, который я попробовал, после «все разделы -> фильтр для длины 2» и «J, неправда, разделить каждый»
Leaky Nun

3

Java 8, 175 171 94 88 байт

n->{long d=10,r=0,i,t;for(;d<=n;d*=10,r|=t-i)for(t=n/d+n%d,i=1;t%++i%t>0;);return r==0;}

-77 благодаря @PeterTaylor , используя арифметику (вместо String with .substring) и избавляясь от отдельного метода, чтобы проверить, является ли целое число простым числом.
-6 байт, используя метод первичной проверки @SaraJ, так что убедитесь, что проголосовали за нее!

Попробуй это здесь.

Объяснение:

n->{                  // Method with long as both parameter and return-type
  long d=10,r=0,i,t;  //  Some temp longs
  for(;d<=n           //  Loop as long as `d` is below or equal to input `n`
                      //  (inclusive instead of exclusive due to special case 10)
      ;               //    After every iteration:
       d*=10,         //     Multiple `d` by 10
       r|=t-i)        //     and Bitwise-OR `r` with `t-i`
    for(t=n/d+n%d,    //   Set `t` to `n` integer-divided by `d` plus `n` modulo-`d`
        i=1;          //   Set `i` to 1
        t%++i%t>0;);  //   Inner oop as long as `t` modulo `i+1` modulo `t` is not 0 yet
                      //   (after we've first increased `i` by 1 with `++i`)
                      //   (if `t` equals `i` afterwards, it means `t` is a prime)
  return r==0;}       //  Return if `r` is still 0

1
Я думаю, что есть как минимум два способа сократить это: во-первых, заменить цикл на pрекурсию; во-вторых, накапливайте результаты таким образом, что главной функции требуется только один returnоператор, делая значение Sentinel из pbe -1и используя &для проверки, что все возвращаемые значения являются -1.
Питер Тейлор

1
На самом деле, главное - не использовать строки.
Питер Тейлор

n->{for(long d=10,m=1;d<n;d*=10)m|=p(n/d+n%d,2)-2;return m>0;}long p(long n,int i){return i<n?p(n%i<1?1:n,i+1):n;}
Питер Тейлор

@PeterTaylor Спасибо за предложения! Что касается предложенной вами функции в конце, вы уверены, что она правильная? Я сейчас даю неверные результаты , если не делаю что-то не так.
Кевин Круйссен

1
Хорошо, d<=nчтобы справиться 10. Переполнение стека не является проблемой (спецификация не дает диапазона ввода, который должен быть обработан), но может быть исправлено и может быть получена большая экономия путем возврата к циклу и вставке .
Питер Тейлор

2

Pyth , 14 байт

.AmP_ssMcQ]dtU

Попробуйте онлайн! Будет отображаться, Trueесли число великодушно, в Falseпротивном случае. Принимает число в виде строки.

Пояснения

.AmP_ssMcQ]dtU

              Q    # Implicit input Q
            tU     # Generate the range [1, 2, ..., len(Q)-1]
  m                # For each index d in the above range...
        cQ]d       # Split Q at index d
      sM           # Convert the two parts to integers
     s             # Sum
   P_              # Check it is a prime
.A                 # ...end for. Check all elements are True

2

Python 2 , 104 102 98 96 103 байт

  • Спасибо @Wheat Wizard за 2 байта: сделан iполностью анонимным, так как вызывается только один раз.
  • Спасибо @Hyperneutrino за 4 байта: более умный способ получения чисел из основного числа вместо нарезки
  • @Hyperneutrino сохранил еще 2 байта: x-1только xдля проверки первичной проверки.
  • Исправлен сбой для случая x=10, добавив, таким образом, 7 байт, благодаря @Dennis и @Wheat Wizard за его обнаружение: моя ранняя версия считала 1 простым числом
lambda x:all((lambda x:x>1and all(x%j for j in range(2,x)))(x/10**j+x%10**j)for j in range(1,len(`x`)))

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



Круто, спасибо @HyperNeutrino
officialaimm

1
96 байт : вам не нужно x-1в конце диапазона; Ассортимент эксклюзив справа.
HyperNeutrino

1
Это терпит неудачу в течение 10 (новый контрольный пример).
Деннис

1
Это терпит неудачу в течение 10. Я также полагаю, что 10 - единственное число, для которого это терпит неудачу.
Пшеничный волшебник

2

Japt , 24 16 байт

Это было в значительной степени сотрудничество между @Shaggy, @ETHproduction и мной.

¬£[YîU UtY]xÃÅej

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

Принимает ввод в виде строки.


Г! Почти идентичный альтернативному решению, над которым я работал! Вот 22 байта, которые у меня были до сих пор. РЕДАКТИРОВАТЬ: Получил до 20 байтов , комбинируя вещи из обоих.
Лохматый

@ Шэгги Довольно забавно, я сейчас работаю над своим редактированием ... Это шокирующе похоже на ваше: ethproductions.github.io/japt/…
Оливер

Подсказка: xавтоматически преобразует элементы в массиве в числа ;-)
ETHproductions

Да, вот куда я тоже пойду, @ETHproductions: 16 байтов .
Лохматый

Кроме того, XîUэто гений. Я думаю, что U¯Xработает на ту же длину, но все же
ETHproductions

2

Пип , 25 24 байта

$&0N_%,_=1M$+(a^@_)M1,#a

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

объяснение

aэто первый аргумент командной строки. 1,#aгенерирует диапазон, содержащий числа 1через len(a)-1. Для этого мы сопоставляем лямбда-функцию:

$+(a^@_)
   a^@_   Split a at this index
$+(    )  Fold the resulting 2-element list on +

Далее мы сопоставляем другую лямбда-функцию 0N_%,_=1, которая проверяет на простоту. Я взял это из этого ответа ; Вы можете прочитать объяснение там. Наконец, мы складываем список по логическому AND ( $&). Результат1 если все суммы были простыми,0 если таковые не были.

Пример, с вводом 4063:

                    1,#a   [1; 2; 3]
           $+(a^@_)M       [67; 103; 409]
  0N_%,_=1M                [1; 1; 1]
$&                         1

2

CJam , 22 байта

r:L,({)_L<i\L>i+mp!},!

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

Выводит положительное целое число для правды, ноль для фальсификации.

-1 благодаря умному трюку Питера Тейлора .
-3 благодаря другому совету Питера Тейлора.


0&!короче1+:*
Питер Тейлор

@PeterTaylor Ох, это умно ... вы злоупотребили фактом, который !возвращает логическое значение, и использовали пересечение множеств с ложным значением, 0так что вы можете делать 0&!в 3 вместо 1&!!...
Эрик Outgolfer

Вы можете сохранить еще 3 байта, присвоив входные данные переменной, что упрощает работу со стеком, и ,вместо оператора используется оператор фильтра f.
Питер Тейлор

PS Я не вижу никаких злоупотреблений при использовании !для преобразования в логическое значение: это было стандартным в GolfScript и стандартным в CJam. И 1&!!было бы неправильно: 0&!это очевидный тест, потому что требование полностью, а не существует.
Питер Тейлор

@PeterTaylor Это не то, что я имел в виду ...: P
Эрик Outgolfer

2

Japt , 23 байта

Принимает ввод в виде строки.

Черт возьми; избитый ударом по более короткой альтернативе, над которой я работал.

£i+Ýe@OxXr"%+0+"'+)j

Попробуй это


@ETHproductions, нет, ты был прав; оригинальная версия была неправильной; только проверка на великодушные простые числа . ¬£i+YÄÃe@OxX j
Лохматый

Я знал, что не
сошел с

1
Сбой 4063(должен быть истиной, ложь). Хитрость заключается в том, что JS считает, что ведущий 0означает, что вы хотите восьмеричный ...
ETHproductions

Хммм ... Хорошо, думаю, у меня есть альтернатива - потребуется несколько минут, чтобы проверить это и сыграть в гольф.
Лохматый

Я думаю, что сейчас произойдет сбой в некоторых случаях, которые содержат два 0, за которыми следуют две другие цифры ... ( 40043например) Просто добавьте +после, 0чтобы исправить это.
ETHproductions

2

Mathematica, 75 байт

And@@Table[PrimeQ@ToExpression@StringInsert[#,"+",n],{n,2,StringLength@#}]&

Functionкоторый ожидает String. PrimeQ@ToExpression@StringInsert[#,"+",n]Возвращает, дает ли вставка +после nцифры th простое число. Table[...,{n,2,StringLength@#}]дает список этих значений в виде nдиапазонов от 2длины строки. Затем мы берем Andкаждый из элементов этого списка. Удобно, если StringLength@#<2, то Table[...]есть пустой список, для которогоAnd@@{}==True


2

Математика, 55 50 45 49 50 54 62 байтов

Кажется, я должен опубликовать это отдельно.

+6 байт для длины кода переизмерено.

+5 байт благодаря ngenisis.

And@@(qPrimeQ[#~Mod~q+⌊#/q⌋])@Rest@PowerRange@#&

Принимает входные данные как целое число и возвращает обычные Trueи False. В промежутке между Юникодом 0xF4A1, коротки дляFunction[,] . Длина кода измеряется по размеру файла (UTF-8 без спецификации), прокомментируйте, если он указан неверно.

PowerRange[x]возвращает 1, 10, 100 ... не больше, чем xвведено в Mathematica 10.


2

Простой английский 4,204 341 315 251 241 240 байт

(Повторно) включил тестирование простоты в библиотеку простого английского языка, переместив 3863 байта в библиотеку простого английского. Удалил 26 байт пустого пространства. Сохранено 64 байта путем сокращения локальных переменных. Сохранено 10 байт за счет сокращения интерфейса. Согласно предложению РосЛюП , 1 байт был сохранен путем изменения инициализации и приращения m.

To decide if a n number is g:
Put 1 in a m number.
Loop.
Multiply the m by 10.
If the m is greater than the n, say yes.
Divide the n by the m giving a q quotient and a r remainder.
Add the q to the r.
If the r is not prime, say no.
Repeat.

Неуправляемая версия финального кода:

To decide if a number is magnanimous:
  Put 1 in another number.
  Loop.
    Multiply the other number by 10.
    If the other number is greater than the number, say yes.
    Divide the number by the other number giving a quotient and a remainder.
    Add the quotient to the remainder.
    If the remainder is not prime, say no.
  Repeat.

Примечания. Среда IDE на простом английском языке доступна по адресу github.com/Folds/english . IDE работает в Windows. Компилируется в 32-битный код x86.

Osmosian Order «s динамическая вилка равнинных Английский уже в проверки простоты версии 4700, но он использовал очень неэффективный алгоритм (по состоянию на январь-июнь 2017 года). В версиях 4001-4011 динамического разветвления сайта GitHub пропущено тестирование первичности. Версия 4013 динамического разветвления сайта GitHub включает тестирование первичности. Код для тестирования первичности был разработан как часть предыдущих версий этого ответа.


1

Perl 6 , 58 байт

{?(10,10* *...^*>$_).map({$_ div$^a+$_%$^a}).all.is-prime}

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

10, 10 * * ...^ * > $_является геометрической последовательностью, кратной десяти, взятой до единицы перед элементом, который превышает входной параметр $_. Затем мы просто проверяем, что для каждой степени десяти сумма входного параметра, взятого div и mod, равна простому.


1

Haskell, 114 110 байт

p x=[x]==[i|i<-[2..x],x`mod`i<1]
i!x|i<1=0<1|0<1=p(uncurry(+)$divMod x$10^i)&&(i-1)!x
f x=(length(show x)-1)!x

Разгромленный с объяснением:

-- Check if x is a prime number
p x = [x] == [i | i<-[2..x], x`mod`i < 1]
-- Checks all pairs of numbers a '+' can be put in between
i ! x | i<1 = 0<1                                -- Single-digit numbers are always truthy
      | 0<1 = p (uncurry (+) $ divMod x $ 10^i)  -- Does x split at i digits from right sum up to a prime?
           && (i-1) ! x                          -- If so, check next pair
-- Start (!) with the number of digits in x minus one
f x = (length (show x)-1) ! x

Если вы используете в p x=[x]==[i|i<-[2..x],x`mod`i<1]качестве основной проверки, вы можете сохранить 2 байта.
Пшеничный волшебник

Вы также можете использовать divMod x$10^iвместоx`divMod`(10^i)
Wheat Wizard

@WheatWizard: я знал, что основной тест еще можно улучшить. ;) Благодарность!
Сиракуза

1

Аксиома, 88 байт

f(n:PI):Boolean==(i:=10;repeat(q:=n quo i;q=0 or ~prime?(q+n rem i)=>break;i:=i*10);q=0)

тест и результаты

(10) -> [[i,f(i)]  for i in [1,2,4,10,98,101,109,819,4063,40427,2000221,999999999999999999999999999999999999999999999]]
   (10)
   [[1,true], [2,true], [4,true], [10,false], [98,true], [101,true],
    [109,false], [819,false], [4063,true], [40427,true], [2000221,true],
    [999999999999999999999999999999999999999999999 ,false]]



0

С накоплением , 51 байт

[tostr:#'1-~>splitat tr['+',' '#`#~prime]map 1,all]

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

Это функция. Он работает путем преобразования своего аргумента в string ( tostr), дублирования его и получения его length ( :#'), вычитая 1 ( 1-), делая диапазон от 1 до этого числа ( ~>). Стек выглядит примерно так, для ввода 40427:

('40427' (1 2 3 4))

Мы выполняем векторизацию splitat, в результате чего следующий массив оказывается на вершине стека:

(('4' '40' '404' '4042') ('0427' '427' '27' '7'))

Транспонируя это с tr, мы получаем:

(('4' '0427') ('40' '427') ('404' '27') ('4042' '7'))

Затем мы отображаем функцию ['+',' '## ~ prime] (withmap`). Эта функция делает:

['+',' '#`#~prime]
 '+',                concatenate a plus sign (string)    `('4' '0427' '+')
     ' '#`           join by spaces                      `'4 0427 +'`
          #~         evaluate                            `431`
            prime    check primality                     `1`

Затем, после карты, мы объединяем 1. Это так как allвозвращает undefпустой список.


0

JavaScript (ES6), 70 байт

P=(n,x=2)=>n%x?P(n,x+1):n==x
f=(n,i=10)=>i>n||P((n/i|0)+n%i)&f(n,i*10)

Сбой в последнем случае в моем браузере из-за ошибки "слишком много рекурсии" при расчете P(200023). Надеюсь, это не сделает его недействительным.


0

QBIC , 38 байт

_L;|[a-1|q=q*µ!_sA,b|!+!_sA,b+1,a|!}?q

объяснение

_L |     Create a variable a and set it to the length of
  ;      the input string (A$)
[a-1|    FOR b = 1 to a-1
q=q*     multiply q by
 µ       -1 if prime, 0 if not, of
  !        a cast of 
   _s       a substring of
     A,       A$
     b        from index 1 to index b (only one index is given, so that is assumed to be the req. length from 1)
      |!   to number
 +         plus
 !         a cast of
  _s         a substring of
    A,         A$
    b+1        from index b+1
    ,a         for the length of a (does not error if it exceeds the end of the string)
      |!   to number
 }       NEXT 
 ?q      PRINT q, which is eitrher -1 or 1 for all-prime sums, or 0 otherwise

0

CJam (21 байт)

r:R,({RiA@)#md+mp!},!

Интернет демо , онлайн набор тестов

рассечение

r:R       e# Take a token of input and assign it to R
,(        e# Take the length of R minus one
{         e# Filter i = 0 to (length of R minus two)
  Ri      e#   Push R as an integer value
  A@)#    e#   Push 10 to the power of (i + 1)
  md      e#   divmod
  +mp!    e#   Add, primality test, negate result
},        e# The result of the filter is a list of splits which give a non-prime
!         e# Negate result, giving 0 for false and 1 for true


0

APL (NARS), символы 35, байты 70

{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}

тест:

  f←{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}
  f¨1 2 4 10 98 101 109 819 4063 40427 2000221
1 1 1 0 1 1 0 0 1 1 1 

Это был бы перевод в APL с поста algo здесь.

{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}
 0≥k←¯1+≢⍕⍵:1⋄  assign to k the length as array of argument return 1 if that is <=0
 ∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k
              m←10*⍳k  m is the array pow(10,1..k)
           ⌊⍵÷m       the array of quotient of argumet with m
          +           sum 
     (m∣⍵)            with array of remander
   0π                 build the binary array of "are prime each"
 ∧/                   and that array

0

PHP, 100 байт

for(;++$k<strlen($a=$argn);$x+=$i==1)for($i=$n=substr($a,$k)+$b.=$a[$k-1];--$i&&$n%$i;);echo$x+2>$k;

печатает, 1если вход великодушный, пустой вывод, если нет. Запустите как трубу с -nRили попробуйте онлайн .


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.