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

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

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`)))

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

officialaimm
источник
1
98 байт
HyperNeutrino
Круто, спасибо @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
DLosc
источник
2

CJam , 22 байта

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

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

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

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

Эрик Outgolfer
источник
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

ngenisis
источник
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]]
РосЛУП
источник
1

Perl 6 , 35 байт

{m:ex/^(.+)(.+)$/.all.sum.is-prime}

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

Объяснение:

{                                 }     # Anonymous code block that
 m:ex/^        $/                         # Match all
       (.+)(.+)                           # Splits of the input number
                 .all                     # Are all of them
                     .sum                   # When summed
                         .is-prime          # Prime?
Джо Кинг
источник
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). Надеюсь, это не сделает его недействительным.

ETHproductions
источник
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
steenbergh
источник
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

Pyth, 15 14 байтов

.AmP_svcz]dtUz

Тестирование

Сохраненный байт с использованием новейшего изменения Pyth.

isaacg
источник
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
RosLuP
источник
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или попробуйте онлайн .

Titus
источник