Перша жаба 🐸


44

"Перша жаба" - це дивна тварина, яка стрибає між цілими числами, поки не прибуде 3 або 19 ...


Ваша програма повинна прийняти ціле число nяк вхід і вивести результат наведеного нижче алгоритму ( 3або 19).

Для заданого цілого числа n >= 2:

  1. Нехай fбуде положення жаби. Спочатку встановленоn
  2. якщо f = 3або f = 19: жаба перестає стрибати - зупиніть програму та виведіть f.
  3. якщо fце просто: жаба стрибає в положення 2×f-1. Поверніться до кроку 2.
  4. якщо fскладений: нехай dбуде fнайбільшим простим дільником. Жаба стрибає на позицію f-d. Поверніться до кроку 2.

Приклади:

Приклад із n = 5:

5 > 9 > 6 > 3 stop

Програма повинна вивести 3.

Ще один приклад n = 23:

23 > 45 > 40 > 35 > 28 > 21 > 14 > 7 > 13 > 25 > 20 > 15 > 10 > 5 > 9 > 6 > 3 stop

Знову ж таки, програма повинна вивести 3.

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

10 => 3
74 => 19
94 => 3
417 => 3
991 => 19
9983 => 19

Ви можете припустити 1 < n < 1000000(я перевірив, чи закінчується програма на ці значення).


3
3 петля - [3 5 9 6 3], а 19 петля - [19 37 73 145 116 87 58 29 57 38 19]
Арно

8
Холодна варіація Collatz.
Артур

3
Якщо ми не можемо довести, що жаба завжди доходить, 3або 19ми можемо змінити пункт 2. в алгоритмі, щоб сказати, що якщо жаба вступила в який-небудь цикл (зіткнулася з позицією, яку вона бачила раніше), вона припиняє стрибки і повертає найменшу член цієї петлі.
Джеппе Стіг Нільсен

4
@PyRulez Якщо досягти цього, ви, ймовірно, повинні сказати ОП.
mbomb007

3
@KeyuGan Можливо, це було б непогано розмістити інформацію про Math.SE.
mbomb007

Відповіді:



12

C (gcc),  87  65 байт

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);n=~16&n-3?f(n-k?:n+n-1):n;}

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

Пояснення:

i,k;
f(n)
{
    for (i=n; i>1;)              // Loop until `k` is prime (the largest positive
                                 // `i` inequal to `k` that divides `k` is 1).
        for (k=i; k%--i;);       // Find the largest factor `k`

    n =                          // Returning like this is undefined behaviour,
                                 // but happens to work with gcc. This can be
                                 // replaced with `return` at the cost of 4 bytes.

        ~16&n-3                  // If `n` is 3 or 19, this expression equals 0 and
                                 // the algorithm halts. Otherwise the function
                                 // calls itself to perform the next iteration.

        ? f(n-k ?: n+n-1)        // If `n-k` is non-zero, n is not prime.
                                 // In this case call `f` with the value of `n-k`.
                                 // (Omitting the second `n-k` between `?` and `:`
                                 // is a gcc extension)
                                 // Otherwise call `f` with `2*n-1`.

        : n;                     // All done, `n` is returned.
}

Портативна версія (72 байти):

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);return~16&n-3?f(n-k?n-k:n+n-1):n;}

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

З більш відповідними назвами змінних:

f,r;o(g){for(f=g;f>1;)for(r=f;r%--f;);g=~16&g-3?o(g-r?:g+g-1):g;}

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


5
Повністю любите гру зі словом жаба та вашими змінними. +1.
rayryeng

10

Сітківка , 63 62 байт

Завдяки Нілу за збереження 1 байта.

{`^(11+)(?<!^\2+(11+))(?=\1+$)

^(?!(11+)\1+$|111$|1{19}$)1
$_

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

Введення та вихід уніар (тестовий набір для зручності використовує десятковий). Це рішення стає надзвичайно повільним для більшого введення. У 9983тестових прикладах таймаута на TIO.

Пояснення

Через {, обидва етапи програми просто запускаються в циклі, поки вони більше не впливають на рядок. Ми чергуємо композиційні композиції, що обробляють ступінь, і етапи обробки сценічної обробки. Це дозволяє нам уникати фактичних умов (яких насправді не існує у сітківки). Якщо поточне значення є неправильним видом для сцени, етап просто нічого не робить.

^(11+)(?<!^\2+(11+))(?=\1+$)

Це обробляє композити. Ми співставляємо потенційного дільника (11+), але потім перевіряємо, чи не він є складовим (?<!^\2+(11+)), тому ми розглядаємо лише основні фактори. У зв'язку з жадібністю +цього пріоритет є найбільшим фактором. Потім ми перевіряємо , що цей потенціал дільник є фактичним дільником, намагаючись відповідати іншої частини рядка з повторенням цього, (?=\1+$). Цей дільник просто видаляється з рядка, тобто ви віднімаєте щось в одинарному.

^(?!(11+)\1+$|111$|1{19}$)1
$_

Це обробляє праймери, крім 3 та 19 . Негативний підказник гарантує, що вхід не складений, не 3 і не 19 . Тоді ми узгоджуємо сингл 1і замінюємо його на весь рядок. Це одинарна форма обчислення n - 1 + n , що, звичайно, 2n-1 .

Щойно ми потрапили в 3 або 19 , жоден етап не може відповідати рядку, і він більше не буде змінений.


1
Це не 1$'те саме, що $_?
Ніл

4
@Neil Так ......
Мартін Ендер

8

Лушпиння , 15 байт

Ω€p57§|o←DṠ-o→p

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

Пояснення

Ω€p57§|o←DṠ-o→p  Implicit input n.
Ω                Do this to n until
 €p57            you get a prime factor of 57 (which are 3 and 19):
            o→p   Take last element of the prime factors of n
          Ṡ-      and subtract it from n,
     §|           or if this gives 0 (so n is prime),
       o←D        double and decrement n.

8

Желе , 12 байт

_ÆfṂoḤ’$µÐḶṂ

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

Як це працює

_ÆfṂoḤ’$µÐḶṂ  Maink link. Argument: n

        µ     Combine the links to the left into a chain.
         ÐḶ   Repeatedly call the chain monadically until the results are no longer
              unique. Yield the loop, i.e., the first occurrence of the first
              repeated integer, up to and excluding the repetition.
              Let's call the argument of the chain k.
_Æf             Subtract all prime factors of k from k.
   Ṃ            Take the minimum of the differences. This yields 0 iff k is prime.
     Ḥ’$        Compute 2k-1.
    o           Take the logical OR of the results.
              The result is now a rotation of either [3, 5, 9, 6] or
              [19, 37, 73, 145, 116, 87, 58, 29, 57, 38].
          Ṃ   Take the minimum, yielding either 3 or 19.

7

Мова Вольфрама (Mathematica) , 6566 68 байт

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • -1 байт, дякую Міші Лаврову!
  • -2 байти, дякую Мартіну!

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

Натхненний наконечник . В основному, це просто відтворює алгоритм.

//.є RepeatedReplaceі /;є Condition. Отже, код замінить i_(одну кількість) на If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i], доки не i!=3&&!=19оцінить True.

Орієнтир:

орієнтир


3
цікавий факт: цей код не працює для більшої кількості, наприклад, 10000000010тому щоmaximum number of iterations is 2^16 (= 65536)
J42161217

1
Трохи коротший спосіб перевірити 3 та 19 рік#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
Міша Лавров

@MishaLavrov, але результат неправильний?
Кейу Ган

@KeyuGan Для мене обидві функції дають абсолютно однаковий результат для цілих чисел 1 до 1000.
Міша Лавров

1
Можливо, проблема, яку ви маєте, - це недруковані символи, вставлені під час копіювання та вставлення з коментарів, що іноді трапляється.
Міша Лавров

6

05AB1E , 19 18 17 байт

[ÐƵηfså#pi·<ëDfθ-

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

Пояснення

[      #            # loop until
 Ð   så             # a copy of the current value is contained in
  Ƶηf               # the unique prime factors of 171
        pi          # if the current value is prime
          ·<        # double and decrement
            ë   -   # else subtract
             Dfθ    # the largest prime factor of a copy of the current value

4
+1 за те, що у вихідному коді є справжня жаба
Арно,

За 57991 більше 1 хвилини
RosLuP

@RosLuP: Вам краще працювати в режимі офлайн дуже довгі тестові справи;)
Emigna

5

JavaScript (ES6), 73 71 69 байт

f=n=>57%n?f(n-(g=(k,d=1)=>++d<k?k%d?g(k,d):g(k/d):d<n?d:1-n)(n)):n%38

Тестові справи

Відформатовано та прокоментовано

f = n =>                 // given n
  57 % n ?               // if n is neither 3, 19 or 57 (and assuming that n is > 1):
    f(                   //   do a recursive call to f() with:
      n -                //     n minus
      (g = (k, d = 1) => //     the result of the recursive function g():
        ++d < k ?        //       increment d; if d is less than k:
          k % d ?        //         if d is not a divisor of k:
            g(k, d)      //           recursive call to g() with k and d unchanged
          :              //         else:
            g(k / d)     //           recursive call to g() with k = k / d, d = 1
        :                //       else, d is now the highest prime divisor of n:
          d < n ?        //         if d is less than n:
            d            //           n is composite: return d, which results in f(n - d)
          :              //         else:
            1 - n        //           n is prime: return 1 - n, which results in f(2n - 1)
      )(n)               //     initial call to g()
    )                    //   end of recursive call to f()
  :                      // else:
    n % 38               //   return n % 38 (gives 19 as expected if n = 57)

1
Розумний, використовуючи 57%nта n%38замість цього n==3|n==19. Збережено 1 байт у моїй відповіді на Java , тому дякую!
Kevin Cruijssen

У вхід ideone 57991 генерують prog.js: 2: 26 InternalError: занадто багато рекурсії
RosLuP

У tio f = n => 57% n? F (n- (g = (k, d = 1) => ++ d <k? K% d? G (k, d): g (k / d) : d <n? d: 1-n) (n)): n% 38 print (f (57991)) генерує стоп-програму не виводиться, мені здається
RosLuP

1
@RosLuP Це завдання з гольф-кодом без особливих обмежень. Поточний консенсус полягає в тому, що обмеження швидкості чи пам’яті (наприклад, розмір стека викликів) можна не враховувати, якщо в питанні прямо не зазначено інше. Я вважаю цілком зрозумілим, що обмеження 1000000 є лише інформативним, оскільки послідовність не була перевірена поза цим. Між іншим, ваше 70-байтне рішення ідеально чудово і, ймовірно, більш релевантне, ніж версія 93-байтових для кодового гольфу.
Арнольд


4

Пітон 2 , 110 105 103 101 байт

-2 байти завдяки @Lynn

f=lambda n,i=2,k=0:i/n and(n*(n&~16==3)or f((2*i-1,k-i)[k>0]))or n%i and f(n,i+1,k)or f(n/i,2,k or n)

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


Python 2 , 116 112 105 байт

f=lambda n,i=2:i/n*i or n%i and f(n,i+1)or f(n/i)
n=input()
while~16&n-3:n=[2*n-1,n-f(n)][f(n)<n]
print n

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


1
…n*(n&~16==3)or…економить 2 байти.
Лінн

Для введення 57991 sys.setrecursionlimit (20000)
RosLuP

4

MATL , 22 21 байт

Дякуємо @Giuseppe за видалення 1 байта!

`tZp?Eq}tYfX>-]tI19h-

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

`           % Do...while
  t         %   Duplicate. Takes (implicit) input the first time
  Zp        %   Is it prime? 
  ?         %   If so
    Eq      %     Times 2, minus 1
  }         %   Else
    t       %     Duplicate
    YfX>-   %     Prime divisors, maximum, subtract
  ]         %   End
  t         %   Duplicate
  I19h      %   Push array [3 19]
  -         %   Subtract, element-wise. The result is truthy if and only if
            %   it doesn't contain any zero
            % End (implicit). Next iteraton if top of the stack is truthy
            % Display (implicit)

4

Haskell - 154 байти

f 3=3
f 19=19
f n
 |(c==[1])=f$2*n-1
 |True=f$n-head c
 where c=z n;v b=reverse[x|x<-[1..(b-1)],b`rem`x==0];z j=case v j of[1]->[1];s->filter((==[1]).v)$s

Напевно, тут відсутні деякі хитрощі, це моя перша спроба хескелл-гольфу.


Привіт і ласкаво просимо на сайт. Вам не потрібні нові рядки та пробіли для шаблонів шаблонів. Ви можете також використовувати 1>0для Trueбільшості часу , але часто це може бути краще використовувати присвоювання, наприклад c<-z n.
Пшеничний майстер

1
[x|x<-[b-1,b-2..1],rem b x==0]також коротке, ніж reverse[x|x<-[1..(b-1)],bрем x==0].
Пшеничний майстер

2
І останнє, якщо ви хочете обговорити гольф з хескеллом, ви можете приєднатися до нас у "Monads and Men" .
Пшеничний майстер

3

Нейм , 17 16 байт

ͻY𝐏𝕚÷D𝐌Ξᚫ<#D𝐏𝐠𝕊

Пояснення:

ͻ                   Start infinite loop
 D                  Duplicate
  Y                 Push 57
   𝐏                Prime factors: [3 19]
     𝕚              If the second-to-top of stack is in the list
      ÷             Break the loop
       D            Duplicate
        𝐌Ξᚫ<       If prime, double and decrement
            #D𝐏𝐠𝕊   Otherwise, subtract the largest prime factor

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



3

Java 8, 140 135 134 94 байт

n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;t/=m=f);return n%38;}

-5 байт перетворення рекурсивного методу Java 7 в Java 8 лямбда з циклом.
-1 байт неявних завдяки @Arnauld JavaScript відповіді «s шляху зміни n!=3&n!=19і return n;до 57%n>0і return n%38;.
Я думаю, що слід якось поєднати дві петлі і перевірити, чи nє простим, і отримати це найбільший основний фактор одночасно, але я не можу це зрозуміти (поки). Тож це буде початкова версія наразі.
-40 колосальних байтів завдяки @Nevay, роблячи те, що я не міг робити: комбінуючи петлі, щоб перевірити наявність праймерів та найбільшого основного фактора одразу.

Пояснення:

Спробуйте тут (виконується навіть 999999за 1 секунду).

n->{                  // Method with integer as both parameter and return-type
  for(int f,          //  Flag-integer
          t,          //  Temp-integer
          m=1;        //  Max prime factor integer, starting at 0
      57%n>0;         //  Loop (1) as long as `n` is not 3, not 19 and not 57:
      n=f>n?          //    After every iteration: if `f` is larger than `n`:
         2*n-1        //     Change `n` to `2*n-1`
        :             //    Else:
         n-m)         //     Change `n` to `n-m`
    for(t=n,          //   Reset `t` to `n`
        f=1;          //   Reset `f` to 1
        f++<t;)       //   Inner loop (2) from 2 to `t` (inclusive)
      for(;t%f<1;     //    Inner loop (3) as long as `t` is divisible by `f`
        t/=m=f;       //     Set `m` to `f`, and set `t` to `t/f`
      );              //    End of inner loop (3)
                      //   End of inner loop (2) (implicit / single-line body)
                      //  End of loop (1) (implicit / single-line body)
  return n%38;        //  Return `n%38`, which is now either 3 or 19
}                     // End of method

1
На 1 символу не вистачає поліглоту C # :(
Ян Х.

@IanH. Так, зазвичай так: n=>замість n->. А іноді і малі / великі дзвінки. ;)
Кевін Круїссен

1
94 байт:n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;)t/=m=f;return n%38;}
Невай

@Nevay Дякую! Я просто знав, що можна поєднувати петлі, але не міг це зрозуміти. Завдяки вам збереглися колосальні 40 байт!
Кевін Кройсейсен

3

Баш, 73 байти

((57%$1))&&$0 $[(x=$1-`factor $1|sed 's/.* //'`)?x:2*$1-1]||echo $[$1%38]

Спробуйте в Інтернеті! Трохи модифікований для роботи над TIO.

Рекурсивно викликає власний файл сценарію за допомогою $0, який не працює в TIO, тому що його слід виконувати як./filename.sh . Приймає введення як аргумент командного рядка.

Використовується той самий модульний трюк, що і відповідь @ J Arnauld .

Випробування

$ for t in 5 23 10 74 94 417 991 9983;{ echo -n "$t -> "; ./prime-frog.sh $t; }
5 -> 3
23 -> 3
10 -> 3
74 -> 19
94 -> 3
417 -> 3
991 -> 19
9983 -> 19


1

Pyth , 19 байт

.W!/P57H?P_ZtyZ-ZeP

Перевірте всі тестові випадки!

Відповідь Хуска надихнула мене зберегти 2 байти ( ,3 19до P57).

Як це працює

.W! / P57H? P_ZtyZ-ZeP - Повна програма.

.W - функціональний час. У той час як A (значення) є правдою, значення = B (значення). Повертає останнє значення.
    P57 - Прості коефіцієнти 57 ([3, 19]).
   / H - Порахуйте виникнення поточного значення.
  ! - Логічний НЕ. 0 -> Truthy, все інше -> Falsy.
        ? P_Z - Якщо поточне значення є простим, то:
            tyZ - подвоєння поточного значення, декремент.
               -ZeP - В іншому випадку відніміть від себе максимальний простий коефіцієнт поточного значення.
                     - Друкувати неявно.

1

PowerShell , 150 126 байт

for($n="$args";57%$n){$a=$n;$d=for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}};if($n-in$d){$n+=$n-1}else{$n-=$d[-1]}}$n%38

Спробуйте в Інтернеті! (попередження: повільно для більшої кількості)

Ітеративний метод. У PowerShell немає вбудованих простих факторів , тому це запозичує код з моєї відповіді на Prime Factors Buddies .

По-перше, це наш forцикл. Налаштування встановлюється $nяк вхідне значення, а умовне зберігає цикл так довго, як 57%$nне дорівнює нулю (спасибі Арнольду за цей трюк). Всередині циклу ми спочатку отримуємо список простих факторів $a(встановлений у $n). Це код, запозичений у Prime Factors Buddies. Якщо введення $aвже є простим, це повернеться просто $a(важливо пізніше). Це (можливо, просто $a) зберігається в $d.

Далі - if/ elseумовний. З ifбоку, ми перевіряємо, чи $nє -in $d. Якщо це так, це означає, що $nце прем'єр, тому ми беремо $n=2*$n-1або $n+=$n-1. В іншому випадку він складений, тому нам потрібно знайти найбільший основний фактор. Це означає, що нам потрібно взяти останній [-1]з $dі відняти це з $nс $n-=. Це працює, тому що ми розбираємося, 2і тому останній елемент $dвже буде найбільшим.

Після того, як ми закінчилися циклічно, ми просто розмістимо $n%38(знову ж таки, дякую Арноульду) на конвеєр, і вихід неявний.


1

APL (Dyalog Unicode) , 113 90 59 байт

CY 'dfns'
g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵}
f←{⍵∊3 19:⍵⋄g ⍵}

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

TIO працює зі значеннями до ~ 3200. Тестований на моєму ПК для останнього тестового випадку. Для тестування на TIO просто додайте f valueвнизу коду. Більше не застосовується, завдяки @ Adám за те, що він вказав, що мій алгоритм перевірки первинності був дуже поганий і постачав мені заміну; також для економії 23 байтів.

Відредаговано, щоб виправити кількість байтів.

Як це працює

CY 'dfns'                      # Imports every Defined Function, which is shorter than importing just the function I used (pco).

g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵} 
g                              # define g as
   1pco ⍵:                      # if the argument ⍵ is prime
          f(2×⍵)-1              # Call f over 2×⍵-1
                  f            # else, call f over
                               # the first element of the
                      3pco     # list of prime factors of ⍵
                               # reversed

f←{⍵∊3 19:⍵⋄g ⍵}
f                              # Define f as
        :                      # if the argument ⍵
                               # is in
     3 19                       # the list [3, 19]
                               # return the argument ⍵
                               # else
            g                  # call g over the argument ⍵

1

Аксіома, 93 байти

h(n)==(repeat(n=3 or n=19 or n<2=>break;prime? n=>(n:=2*n-1);n:=n-last(factors(n)).factor);n)

тест:

(4) -> [[i,h(i)] for i in [10,74,94,417,991,9983]]
   (4)  [[10,3],[74,19],[94,3],[417,3],[991,19],[9983,19]]
                                                  Type: List List Integer

Було б функція 68 байтів

q x==(n<4=>3;n=19=>n;prime? n=>q(2*n-1);q(n-last(factors n).factor))

але для n = 57991 (якщо я добре пам’ятаю) це залишається зарезервований простір стека.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.