Это черепаха премьер?


28

Как мы все знаем, это черепахи все время вниз . Но неужели это тоже простые числа?

Число считается «черепашьим-простым», если оно удовлетворяет следующим условиям:

1) It is prime.
2) It is possible to remove a single digit leaving a prime number.
3) Step 2 can be repeated until left with a single digit prime.

Например, 239это «черепаха-премьер», так как она может быть уменьшена до 23одного 2или 3обоих, оба из которых являются простыми. Это также может быть уменьшено до того 29времени 2. 151не простое число черепахи, так как оно сводится к 15(не простое), 51(не простое) или 11. 11прост, но может только уменьшить 1, чего нет.

Учитывая положительное целое число, определите, является ли оно «черепашьей вершиной». Ваш вывод может быть в любой форме, при условии, что он дает одинаковый вывод для любого истинного или ложного значения.

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

input -> output
1     -> false
2     -> true
17    -> true
19    -> false
239   -> true
389   -> false

счет

Это , поэтому выигрывает самый короткий ответ на каждом языке!



@MagicOctopusUrn WOW
Кейу Ган


3
Можем ли мы принять ввод в виде списка цифр?
полностью человек

1
Ваши условия говорят, что все однозначные простые числа не являются простыми числами черепахи. Условие 2 не выполняется: невозможно удалить цифру и все равно оставить простое число, поскольку удаление единственной цифры ничего не оставляет.
HVD

Ответы:


6

Желе , 16 байт

DŒPḊṖLÐṀḌ߀¬Ȧ<ÆP

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

Как это работает

DŒPḊṖLÐṀḌ߀¬Ȧ<ÆP  Main link. Argument: n

D                 Decimal; convert n to base 10.
 ŒP               Powerset; get all sub-arrays of n's decimal digits.
   Ḋ              Dequeue; remove the first sub-array (empty array).
    Ṗ             Pop; remove the last sub-array (all of n's digits).
     LÐṀ          Maximal by length; keep those of the remaining subarrays that
                  have maximal length. This keep exactly those sub-arrays that have
                  one (and only one) digit removed. If n < 10, this yields an empty
                  array. Without Ḋ, it would yield [[]] instead.
        Ḍ         Undecimal; turn the generated digit arrays into integers.
         ߀       Recursively map the main link over the generated integers.
           ¬      Negate; map 1 to 0 and 0 to 1.
            Ȧ     Any and all; yield 0 if the array is empty (n < 10) or any of the
                  recursive calls returned 1 (mapped to 0). If all calls returned
                  0, this will yield 1.
              ÆP  Test n for primality, yielding 1 for primes, 0 otherwise.
             <    Test if the result to the left is less than the result to the
                  right. This is possible only if the left result is 0 (n < 10 or
                  removing a digit results in a turtle prime) and the right result
                  is 1 (n itself is prime).

Больше волшебного желе! Чувак, этот материал распространяется повсюду ...
Caird Coinheringaahing

7

Haskell , 104 102 99 98 97 95 91 байт

p x=product[2..x-1]^2`mod`x>0
f[]=1>0
f x|y<-zip[0..]x=or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

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

объяснение

Сначала мы создали тест на простоту

p x=product[2..x-1]^2`mod`x>0

Это использует теорему Вильсона, чтобы определить первичность входных данных.

Затем мы объявляем базовый случай, который будет утверждать, что пустая строка является правдивой.

f[]=1>0

Теперь мы определяем фактическую функцию

f x|y<-zip[0..]x=or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

Мы используем шаблон охранник привязку zip[0..]xк y, потому что мы должны использовать его в два раза ниже. Затем мы утверждаем, что ответ

or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

[[snd b|b<-y,b/=a]|a<-y]все числа, которые являются цифрой, удалены из нашего ввода. Итак, мы утверждаем, что хотя бы одно из этих чисел является правдоподобным f. Чтобы гарантировать, что составные числа ложны, мы добавляем prime$read x. Если число не простое, список станет пустым, а anyпустой список будет ложным.


1
−2 байта: any f[[or[f[
Андерс Касеорг

1
−4 байта: [b|(i,b)<-y,i/=a]|(a,_)<-y[snd b|b<-y,b/=a]|a<-y
Андерс Касеорг

6

R, 124 122 120 113 95 93 106 105 байт

 g=pryr::f(`if`(gmp::isprime(sum(x*10^((l<-sum(x|1)-1):0))),any(!l,sapply(0:l+1,function(z)g(x[-z]))),!1))

Который оценивает функцию:

function (x) 
if (gmp::isprime(sum(x * 10^((l <- sum(x | 1) - 1):0)))) any(!l, 
    sapply(0:l + 1, function(z) g(x[-z]))) else !1

Рекурсивное решение. Вводит в виде списка цифр.

Имеет 2 логических утверждения:

  1. Является ли xпремьер при соединении?

  2. Является ли любое из следующего TRUE:

    1. Длина не равна xнулю? Это наше последнее условие прекращения.

    2. Является ли f TRUEдля любого подмножества x?

Первое утверждение гарантирует, что мы продолжаем работать только с простыми числами. Второй выполняет рекурсию.

Сохранено два байта благодаря @Giuseppe.

Мне пришлось вернуть некоторые из моих гольфов из-за ошибки, когда я случайно тестировал предыдущее определение функции.

R, 98 байт, неконкурентный

Как я уже упоминал в комментариях, я сделал пакет . Так как задача предшествует этому, это не конкурирует, но я хотел продемонстрировать это немного. Пока немного, но мы туда доберемся.

g=pryr::f(`if`(gmp::isprime(RG::C(x)),any(!(l<-sum(x|1)-1),sapply(0:l+1,function(z)g(x[-z]))),!1))

C() является первой функцией в пакете и заботится о соединении цифр в число.


Некоторые из этих операций (глядя на тебя sum(x*10^(((l<-sum(x|1))-1):0))) ооочень многословны. Я действительно думаю о создании пакета для гольфа R.
JAD

это было бы моим решением, но я не мог обернуть голову вокруг sapply... Также я думаю, что вы можете захотеть сделать, f=pryr::f(...)иначе вам нужно использовать fв sapply.
Джузеппе

1
@ Giuseppe Однобуквенные имена для всего: D Почему бы не назвать пакет gили что-то?
JAD

1
@Giuseppe Создан старт для пакета: p Взгляните: github.com/JarkoDubbeldam/RG
JAD

1
@JarkoDubbeldam прекрасно. Я уверен, что будущие проблемы покажут, какие дополнительные функции необходимо добавить. Манипулирование строками велико: что-то для el(strsplit(x,''))экономии тонны байтов.
BLT

5

Желе , 19 байт

DJḟЀ`ịDḌḟ0߀¬Ȧ¬aÆP

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

Как это работает

DJḟЀ`ịDḌḟ0߀¬Ȧ¬aÆP                input:239

D                    decimal         [2,3,9]
 J                   range@length    [1,2,3]
  ḟЀ`               filter out each [[2,3],[1,3],[1,2]]
      ịD             index&decimal   [[3,9],[2,9],[2,3]]
        Ḍ            undecimal       [39,29,23]
         ḟ0          filter out 0    [39,29,23]
           ߀        this@each       [1,1,1]
             ¬       logical not     [0,0,0]
              Ȧ      any and all     0
               ¬     logical not     1
                aÆP  and&is_prime    1

Рекурсия без базового случая ftw.


3

Желе , 27 26 байт

DµœcL’$Ḍµ€FÆPÐf
×⁵WÇÐĿFṪ<8

Монадическая ссылка, берущая и возвращающая целые числа ( 1для черепахи 0иначе).

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

Как?

DµœcL’$Ḍµ€FÆPÐf  Link 1: primes by digit removal: list of numbers  e.g. [19790]
D                cast to decimal list (vectorises)                      [[1,9,7,9,0]]
 µ      µ€       monadic chain for €ach:
      $            last two links as a monad:
    L                length                                             5
     ’               decrement                                          4
  œc             combinations without replacement                       [[1,9,7,9],[1,9,7,0],[1,9,9,0],[1,7,9,0],[9,7,9,0]]
       Ḍ         cast from decimal list (vectorises)                    [1979,1970,1990,1790,9790]
          F      flatten (from a list of lists form the for €ach to a single list)
             Ðf  filter keep if:
           ÆP      is prime?

×⁵WÇÐĿFṪ<8  Main Link: number, n             e.g. 1979
 ⁵          literal 10
×           multiply                              19790
              (this is so the first number is tested as prime too)
  W         wrap in a list                        [19790]
    ÐĿ      loop, collecting results (including the input×10) while change still occurs:
   Ç          call the last (1) link as a monad   [[19790],[1979],[197,199,179],[19,17,97,19,19,17,19,79],[7,7,7,7],[]]
      F     flatten                               [19790,1979,197,199,179,19,17,97,19,19,17,19,79,7,7,7,7]
       Ṫ    tail                                  7
        <8  less than 8?                          1
              (if a single digit prime was reached this will be 1
               otherwise it will be 0
               e.g. an input of 4 yields 40 at the end which is not <8)

1
Интересно увидеть два существенно разных ответа желе. Давайте посмотрим, кто может сократить их меньше.
Лорд Фаркваад

2

Рубин , 72 57 + 8 = 80 65 байт

Использует -rprimeфлаг. -15 байт от гистократа!

f=->n{n==''||n.to_i.prime?&!n.scan(/./){f[$`+$']&&break}}

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


Вы можете заменить &&!!на просто &, это приведёт результат к логическому значению. Ваш рекурсивный вызов также может стать немного короче, если использовать перлизмы:!n.scan(/./){f[$`+$']&&break}}
гистократ

@histocrat Ах да, я забыл, что мне не нужно логическое короткое замыкание для последней части из-за начального условия. Вы знаете, почему n.scanтрюк работает так, как работает?
Value Ink

1
Да, две глобальные переменные там установлены в строку слева и справа от самого последнего совпадения, поэтому их объединение дает строку минус один символ. Поскольку нам нужно состояние в каждой точке итерации, мы не можем делать ничего подобного .scan.find, но мы можем вручную выйти из цикла при успешном выполнении. Если мы ломаем , scanвозвращаем nil, в противном случае он возвращает строку, которая всегда верна.
гистократ

2

Java, 220 байт

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

Golfed:

boolean t(String n){int l=n.length();if(f(x->{for(int i=2;i<x;)if(x%i++==0)return 1<0;return x>1;},new Integer(n)))if(l<2)return 1>0;else for(int i=0;i<l;)if(t(n.substring(0,i)+n.substring(++i,l)))return 1>0;return 1<0;}

Ungolfed:

  boolean t(String n) {
    int l = n.length();
    if (f(x -> {
      for (int i = 2; i < x;) {
        if (x % i++ == 0) {
          return 1 < 0;
        }
      }
      return x > 1;
    } , new Integer(n))) {
      if (l < 2) {
        return 1 > 0;
      }
      else {
        for (int i = 0; i < l;) {
          if (t(n.substring(0, i) + n.substring(++i, l))) {
            return 1 > 0;
          }
        }
      }
    }
    return 1 < 0;
  }

Не обращайте внимания на мой предыдущий комментарий. Но вы можете boolean t(String n){int l=n.length(),x=new Integer(n),i;for(i=2;i<x;x=x%i++<1?0:x);if(x>1)if(l<2)return 1>0;else for(i=0;i<l;)if(t(n.substring(0,i)+n.substring(++i,l)))return 1>0;return 1<0;}
Кевин Круйссен,

Вы можете сохранить несколько байтов, возвращая 1 и 0 вместо true и false.
Невай

@Nevay Это будет работать в C ++, но не в Java. Целые числа не могут быть неявно преобразованы в логические значения.

1
Не уверен, но откуда f?
Роман Греф

В вопросе говорится, что любое значение может быть использовано для истинного / ложного; единственное место, где вам нужен логический результат метода, - это последнее условие if (где вы можете добавить >0преобразование int в логическое значение), которое должно сохранить 2 * 2 + 1 * 4 = 8 байт в версии Кевина Круйссена.
Nevay

1

05AB1E , 28 27 байт

Итеративное решение.

¸[D0èg2‹#εæ¨D€gZQÏDpÏ}˜]p1å

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

объяснение

¸                              # wrap input in a list
 [                             # start a loop
  D0èg2‹#                      # if the length of the first element is less than 2, break
         ε                     # apply to each element in the list
          æ                    # compute powerset
           ¨                   # remove last element (the full number)
            D€gZQÏ             # keep only the elements whose length is the max length
                  DpÏ          # keep only primes
                     }         # end apply
                      ˜        # flatten list
                       ]       # end loop
                        p1å    # is any element in the resulting list prime

1

Python 2 , 132 124 119 байтов

-8 Спасибо @WheatWizard

-5 Благодаря @LeakyNun

p=lambda i:i>1and all(i%v for v in range(2,i))
f=lambda n:n<'0'or any(f(n[:i]+n[i+1:])for i in range(len(n)))*p(int(n))

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

Ничего не могу придумать, чтобы отточить это без какой-то встроенной первичной проверки. Принимает число в виде строки (я предполагал, что это, учитывая, что OP разрешил список цифр, но если нет, то +14 байт для другой лямбды), и рекурсивно вычисляет черепаху каждого «взбалтыванного» числа.



Я думаю, что f=lambda n,i=0:n==''or p(int(n))and i<len(n)and(f(n[:i]+n[i+1:])or f(n,i+1))сохраняет байт. Кто-то с лучшими навыками игры в гольф Python, вероятно, может сократить это дальше.
Нил

@Neil, он действительно сохраняет байт, но формулировка «один и тот же вывод для любого значения truey или falsey» не позволяет мне принять его, так как ввод 1 возвращает 0 вместо False, как и в других случаях (из-за проверки простоты -8) , Если OP допускает разные (хотя и синонимичные) выходы, я бы изменил его.
Арнольд Палмер

1
Извините, мое предыдущее предложение недействительно. 119 байт
Утренняя монахиня

1

C #, 355 байт

namespace System{using B=Numerics.BigInteger;class A{static void Main(){Console.WriteLine(D(Console.ReadLine()));}static bool P(B x){if(x<2)return 1<0;B r=1;for(int i=1;i<=x-1;i++)r*=i;return(r+1)%x==0;}static bool D(string x){if(x.Length==0)return 1>0;bool b;if(b=P(B.Parse(x))){var n=1<0;for(int i=0;i<x.Length;i++)n|=D(x.Remove(i,1));b&=n;}return b;}}}

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

Мой первый кодовый гольф, так что я надеюсь, что все сделал правильно. Я не мог придумать, как сделать его еще меньше (кроме использования int вместо BigInteger, но я сделал это так, чтобы оно работало для всех предоставленных тестовых случаев). Во всяком случае, здесь то же самое правильно отформатирован:

namespace System
{
    using B = Numerics.BigInteger;
    class A
    {
        static void Main()
        {
            Console.WriteLine(D(Console.ReadLine()));
        }

        static bool P(B x)
        {
            if (x < 2)
                return 1<0;
            B r = 1;
            for (int i = 1; i <= x - 1; i++)
                r *= i;
            return (r + 1) % x == 0;
        }

        static bool D(string x)
        {
            if (x.Length == 0)
                return 1>0;
            bool b;
            if (b = P(B.Parse(x)))
            {
                var n = 1<0;
                for (int i = 0; i < x.Length; i++)
                    n |= D(x.Remove(i, 1));
                b &= n;
            }
            return b;
        }
    }
}


0

PHP , 164 байта

function t($n){for($i=1;++$i<$n;)if($n%$i<1)return 0;if($n<10)return $n>1;foreach($r=str_split($n)as$k=>$v){$q=$r;array_splice($q,$k,1);$z|=t(join($q));}return $z;}

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

Начинается с проверки числа на первичность, затем проходит по цифрам в виде массива, вытаскивает каждую из них, соединяет остальные вместе и рекурсивно передает их через функцию. Каждая ссылка вниз выполняет логическое ИЛИ с нижними путями, возвращая только trueесли существует хотя бы один путь из всех простых чисел.


0

Javascript 167 байт

n=>{a=[];for(i=1;i++<=n;)a.every(x=>i%x)?a.push(i):0;b=k=>(s=''+k,a.indexOf(k)>-1&&(k<10||[...s].some((x,i)=>(r=[...s],r.splice(i,1),b(~~(r.join('')))))));return b(n)}

объяснение

n=>{
    a=[];                             // create array to store primes in
    for(i=1;i++<=n;)                  // iterate from 2 to n
        a.every(x=>i%x)?a.push(i):0;  // if i % x is truthy for all x in a,
                                      // then i is prime
    b=k=>(                            // function to test is k is turtle prime
        s=''+k,                       // convert k to a string
        a.indexOf(k)>-1 && (          // if k is prime and
            k<10 ||                   // k is a single digit or
            [...s].some((x,i)=>(      // iterate over the digits of k
                                      // and check to see if, by removing each
                                      // any of the resulting numbers is turtle prime
                                      // ... is spread operator
                                      // [...s] converts string s to an array of characters 
                r=[...s],             // convert s to an array again,
                                      // importantly, this cannot be the same array
                                      // we created above, as we need to
                r.splice(i,1),        // splice out the ith element of the array
                b(~~(r.join('')))     // join the array to a string, convert to int,
                                      // and check if this number is turtle prime
                                      // ~ is bitwise negate, implicitly converts to int first before negating
                                      // ~~ negates the negation, getting us the int
            ))
        )
    );
    return b(n)
}

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