Це черепаха?


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, чого немає.

Давши додатне ціле число, визначте, чи це "черепаха". Вихід може бути в будь-якій формі, якщо він дає однаковий результат для будь-якого значення truthy або falsey.

Тестові приклади:

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

Оцінка балів

Це , тому найкоротша відповідь на кожній мові виграє!



@MagicOctopusUrn WOW
Keyu Gan


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[
Anders Kaseorg

1
−4 байти: [b|(i,b)<-y,i/=a]|(a,_)<-y[snd b|b<-y,b/=a]|a<-y
Anders Kaseorg

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
Цікаво бачити дві суттєво різні відповіді желе. Подивимось, хто може скоротити їх менше.
Lord Farquaad

2

Ruby , 72 57 + 8 = 80 65 байт

Використовує -rprimeпрапор. -15 байт від істократа!

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

Спробуйте в Інтернеті!


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

@ так, я забув, що мені не потрібно було булевого короткого замикання для цієї останньої частини через початкові умови. Чи знаєте ви, чому n.scanфокус працює так, як це робиться?
Значення чорнила

1
Так, дві тамтешні глобальні змінні встановлені в рядку зліва та справа від останнього збігу, тому об'єднання їх дає вам рядок мінус один символ. Оскільки нам потрібна держава в кожній точці ітерації, ми нічого не можемо зробити .scan.find, але ми можемо вручну вирватися з циклу на успіх. Якщо ми порушимо, scanповернеться nil, інакше він поверне рядок, який завжди є правдою.
гістократ

2

Java, 220 байт

Спробуйте в Інтернеті!

Гольф:

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();
    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 замість істинних та неправдивих.
Невай

@Nevay Це працювало б на C ++, але не на Java. Цілі числа не можуть бути неявно перетворені в булеві.

1
Не впевнений, але звідки береться f?
Роман Ґраф

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

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

Спробуйте в Інтернеті!

Не можу придумати що-небудь, щоб відточити це без якоїсь вбудованої простої перевірки. Приймає число як рядок (я вважав, що це дано, якщо ОП дозволив перелік цифр, але якщо ні, то +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, він зберігає байт, але формулювання "той самий вихід для будь-якого значення truthy або falsey" заважає мені його приймати, оскільки введення 1 повертає 0 замість False, як і інші випадки (через перевірку первинності -8) . Якщо ОП дозволяє різні (хоча і синонімічні) виходи, я б змінив це.
Арнольд Палмер

1
На жаль, моя попередня пропозиція недійсна. 119 байт
Leaky Nun

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.