Ếch nguyên tố


44

"Ếch chính" là một loài động vật kỳ lạ nhảy giữa các số nguyên, cho đến khi nó đến vào ngày 3 hoặc 19 ...


Chương trình của bạn nên chấp nhận một số nguyên nlàm đầu vào và đầu ra kết quả của thuật toán bên dưới ( 3hoặc 19).

Đối với một số nguyên cho trước n >= 2:

  1. Hãy flà vị trí của ếch. Ban đầu nó được đặt thànhn
  2. if f = 3hoặc f = 19: ếch dừng nhảy - tạm dừng chương trình và đầu ra f.
  3. nếu flà số nguyên tố: con ếch nhảy đến vị trí 2×f-1. Quay trở lại bước 2.
  4. if flà hợp số: hãy dfước số nguyên tố lớn nhất. Con ếch nhảy đến vị trí f-d. Quay trở lại bước 2.

Ví dụ:

Một ví dụ với n = 5:

5 > 9 > 6 > 3 stop

Chương trình nên xuất 3.

Một ví dụ khác với n = 23:

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

Một lần nữa, chương trình nên xuất ra 3.

Các trường hợp thử nghiệm:

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

Bạn có thể giả sử 1 < n < 1000000(tôi đã kiểm tra kết thúc chương trình cho các giá trị này).


3
3 vòng là [3 5 9 6 3] và 19 vòng là [19 37 73 145 116 87 58 29 57 38 19]
Arnaud

8
Biến thể Collatz mát mẻ.
Arthur

3
Nếu chúng ta không thể chứng minh rằng con ếch luôn đến 3hoặc 19, chúng ta có thể thay đổi mục 2. trong thuật toán để nói rằng nếu con ếch đã đi vào bất kỳ vòng lặp nào (gặp phải một vị trí mà nó đã thấy trước đó), thì nó sẽ ngừng nhảy và trả về giá trị nhỏ nhất thành viên của vòng lặp đó.
Jeppe Stig Nielsen

4
@PyRulez Nếu đạt được điều đó, có lẽ bạn nên nói với OP.
mbomb007

3
@KeyuGan Có lẽ đây sẽ là một điều tốt để đăng trên Math.SE.
mbomb007

Câu trả lời:



12

C (gcc),  87  65 byte

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;}

Hãy thử trực tuyến!

Giải trình:

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.
}

Phiên bản di động (72 byte):

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;}

Hãy thử trực tuyến!

Với tên biến thích hợp hơ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;}

Hãy thử trực tuyến!


5
Hoàn toàn thích chơi với từ ếch và các biến của bạn. +1.
rayryeng - Phục hồi Monica

10

Võng mạc , 63 62 byte

Cảm ơn Neil vì đã tiết kiệm 1 byte.

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

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

Hãy thử trực tuyến!

Đầu vào và đầu ra trong unary (bộ kiểm tra sử dụng thập phân để thuận tiện). Giải pháp này trở nên cực kỳ chậm đối với đầu vào lớn hơn. Các 9983trường hợp thử nghiệm hết thời gian trên TIO.

Giải trình

Do {, cả hai giai đoạn của chương trình chỉ đơn giản là chạy trong một vòng lặp cho đến khi chúng không còn ảnh hưởng đến chuỗi. Chúng tôi xen kẽ giữa một vật liệu xử lý giai đoạn và một số nguyên tố xử lý giai đoạn. Điều đó cho phép chúng tôi tránh một điều kiện thực tế (không thực sự tồn tại trong Retina). Nếu giá trị hiện tại là loại sai cho giai đoạn, thì giai đoạn đơn giản là không làm gì cả.

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

Quá trình này vật liệu tổng hợp. Chúng tôi kết hợp một ước số tiềm năng với (11+), nhưng sau đó chúng tôi kiểm tra xem nó không phải là kết hợp với (?<!^\2+(11+)), vì vậy chúng tôi chỉ xem xét các yếu tố chính. Do sự tham lam của +, điều này ưu tiên yếu tố lớn nhất. Sau đó, chúng tôi kiểm tra rằng ước số tiềm năng này là một ước số thực tế bằng cách cố gắng khớp phần còn lại của chuỗi với sự lặp lại của nó , (?=\1+$). Số chia này chỉ đơn giản là loại bỏ khỏi chuỗi, đó là cách bạn trừ đi một cái gì đó trong unary.

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

Điều này xử lý các số nguyên tố, ngoại trừ 319 . Giao diện phủ định đảm bảo rằng đầu vào không phải là hỗn hợp, không phải 3 và không phải 19 . Sau đó, chúng tôi khớp một đơn 1và thay thế nó bằng toàn bộ chuỗi. Đây là một dạng đơn tính của điện toán n - 1 + n , tất nhiên là 2n-1 .

Khi chúng tôi đạt 3 hoặc 19 , không giai đoạn nào có thể khớp với chuỗi và nó sẽ không còn được thay đổi.


1
Không 1$'giống như $_?
Neil

4
@Neil Có ......
Martin Ender

8

Husk , 15 byte

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

Hãy thử trực tuyến!

Giải trình

Ω€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

Thạch , 12 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

_Æ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

Ngôn ngữ Wolfram (Mathicala) , 6566 68 byte

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • -1 byte, nhờ Misha Lavrov!
  • -2 byte, cảm ơn Martin!

Hãy thử trực tuyến!

Lấy cảm hứng từ đầu . Về cơ bản, nó chỉ tạo lại thuật toán.

//.RepeatedReplace/;Condition. Vì vậy, mã sẽ thay thế i_(một số lượng duy nhất) bằng If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i], cho đến khi i!=3&&!=19đánh giá True.

Điểm chuẩn:

điểm chuẩn


3
sự thật thú vị: mã này sẽ không hoạt động với số lượng lớn hơn 10000000010maximum number of iterations is 2^16 (= 65536)
J42161217

1
Một cách ngắn hơn để kiểm tra 3 và 19 là#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
Misha Lavrov

@MishaLavrov nhưng kết quả không chính xác?
Keyu Gan

@KeyuGan Đối với tôi, hai hàm cho kết quả chính xác giống nhau cho các số nguyên từ 1 đến 1000.
Misha Lavrov

1
Có thể vấn đề bạn gặp phải là các ký tự không thể in được chèn khi bạn sao chép và dán từ các nhận xét, điều này đôi khi xảy ra.
Misha Lavrov

6

05AB1E , 19 18 17 byte

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

Hãy thử trực tuyến!

Giải trình

[      #            # 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 để có một con ếch thực sự trong mã nguồn của bạn
Arnaud

Trong 57991 hơn 1 phút
RosLuP

@RosLuP: Tốt hơn hết là bạn nên chạy các trường hợp thử nghiệm dài ngoại tuyến;)
Emigna

5

JavaScript (ES6), 73 71 69 byte

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

Các trường hợp thử nghiệm

Định dạng và nhận xét

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
Thông minh, sử dụng 57%nn%38thay vì n==3|n==19. Đã lưu 1 byte trong câu trả lời Java của tôi , vì vậy cảm ơn!
Kevin Cruijssen

Trong ideone 57991, tạo prog.js: 2: 26 InternalError: quá nhiều đệ quy
RosLuP

Trong 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)) tạo ra chương trình dừng không xuất, đối với tôi
RosLuP

1
@RosLuP Đây là một thử thách chơi gôn mà không có bất kỳ ràng buộc cụ thể nào. Sự đồng thuận hiện tại là giới hạn tốc độ hoặc bộ nhớ (như kích thước ngăn xếp cuộc gọi) có thể bị bỏ qua trừ khi có quy định rõ ràng khác trong câu hỏi. Tôi chấp nhận rằng giới hạn 1000000 chỉ là thông tin vì trình tự không được kiểm tra vượt quá. Ngẫu nhiên, giải pháp 70 byte của bạn là hoàn toàn tốt và có lẽ phù hợp hơn phiên bản 93 byte cho một thử thách golf-code.
Arnauld



4

MATL , 22 21 byte

Cảm ơn @Giuseppe đã xóa 1 byte!

`tZp?Eq}tYfX>-]tI19h-

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

`           % 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 byte

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

Có lẽ thiếu một số thủ thuật golf ở đây, đây là nỗ lực đầu tiên của tôi tại haskell golf.


Xin Chào và Chào Mừng đến với trang. Bạn không cần các dòng mới và không gian cho các mẫu bảo vệ. Bạn cũng có thể sử dụng 1>0trong Truehầu hết các lần nhưng thường thì tốt hơn là sử dụng một bài tập chẳng hạn c<-z n.
Thuật sĩ lúa mì

1
[x|x<-[b-1,b-2..1],rem b x==0]cũng ngắn hơn reverse[x|x<-[1..(b-1)],brem x==0].
Thuật sĩ lúa mì

2
Và một điều cuối cùng, nếu bạn muốn thảo luận về môn đánh gôn haskell, bạn có thể tham gia cùng chúng tôi trong Of Monads and Men .
Thuật sĩ lúa mì

3

Neim , 17 16 byte

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

Giải trình:

ͻ                   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

Hãy thử trực tuyến!


3

R + số , 102 99 byte

function(n){while(!n%in%c(3,19))n="if"(isPrime(n),2*n-1,n-max(primeFactors(n)))
n}
library(numbers)

Hãy thử trực tuyến!

R không được biết đến với các bản dựng ngắn và thậm chí các gói cũng tuân theo!


3

Java 8, 140 135 134 94 byte

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 byte chuyển đổi phương thức đệ quy Java 7 sang lambda Java 8 với vòng lặp.
-1 byte ẩn nhờ câu trả lời JavaScript của @Arnauld bằng cách thay đổi n!=3&n!=19return n;thành 57%n>0return n%38;.
Tôi nghĩ rằng bằng cách nào đó có thể kết hợp hai vòng lặp và kiểm tra xem có phải nlà số nguyên tố hay không và có được hệ số nguyên tố lớn nhất cùng một lúc hay không, nhưng tôi chưa thể tìm ra (chưa). Vì vậy, đây sẽ là phiên bản ban đầu.
-40 số byte nhờ vào @Nevay, bằng cách làm những gì tôi không thể làm: kết hợp các vòng lặp để kiểm tra các số nguyên tố và thừa số nguyên tố lớn nhất cùng một lúc.

Giải trình:

Hãy thử ở đây (thực hiện ngay cả 999999trong dưới 1 giây).

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 ký tự ngắn là một polyglot C # :(
Ian H.

@IanH. Hehe, vâng, đó thường là trường hợp: n=>thay vì n->. Và đôi khi các cuộc gọi viết thường / viết hoa. ;)
Kevin Cruijssen

1
94 byte: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

@Nevay Cảm ơn! Tôi chỉ biết rằng có thể kết hợp các vòng lặp, nhưng không thể tìm ra. Một con số khổng lồ 40 byte được lưu nhờ vào bạn!
Kevin Cruijssen

3

Bash, 73 byte

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

Hãy thử trực tuyến! Sửa đổi một chút để làm việc trên TIO.

Gọi đệ quy tệp script riêng của nó bằng cách sử dụng $0, tệp này không hoạt động trong TIO vì nó phải được chạy dưới dạng./filename.sh . Chấp nhận đầu vào là đối số dòng lệnh.

Sử dụng thủ thuật mô đun tương tự như câu trả lời JS của @ Arnauld .

Các trường hợp thử nghiệm

$ 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

Bình thường , 19 byte

.W!/P57H?P_ZtyZ-ZeP

Xác nhận tất cả các trường hợp thử nghiệm!

Các câu trả lời trấu cảm hứng cho tôi để tiết kiệm 2 byte ( ,3 19để P57).

Làm thế nào điều này hoạt động

.W! / P57H? P_ZtyZ-ZeP - Chương trình đầy đủ.

.W - Chức năng trong khi. Trong khi A (giá trị) là trung thực, giá trị = B (giá trị). Trả về giá trị cuối cùng.
    P57 - Các yếu tố chính của 57 ([3, 19]).
   / H - Đếm số lần xuất hiện của giá trị hiện tại.
  ! - Logic KHÔNG. 0 -> Sự thật, bất cứ điều gì khác -> Falsy.
        ? P_Z - Nếu giá trị hiện tại là số nguyên tố, thì:
            tyZ - Nhân đôi giá trị hiện tại, giảm dần.
               -ZeP - Khác, trừ hệ số nguyên tố cực đại của giá trị hiện tại từ chính nó.
                     - In ngầm.

1

PowerShell , 150 126 byte

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

Hãy thử trực tuyến! (cảnh báo: chậm cho số lớn hơn)

Phương pháp lặp. PowerShell không có bất kỳ yếu tố tích hợp nguyên tố chính nào, vì vậy, mã này mượn mã từ câu trả lời của tôi trên Prime Factors Buddies .

Đầu tiên là forvòng lặp của chúng tôi . Thiết lập được đặt $nthành giá trị đầu vào và điều kiện giữ cho vòng lặp tiếp tục miễn 57%$nlà khác không (nhờ Arnauld cho thủ thuật đó). Trong vòng lặp, trước tiên chúng ta có một danh sách các thừa số nguyên tố của $a(được đặt thành $n). Đây là mã được mượn từ Prime Factors Buddies. Nếu đầu vào $alà số nguyên tố, điều này sẽ trả về $a(quan trọng sau). Điều đó (có khả năng chỉ $a) được lưu trữ vào $d.

Tiếp theo là một if/ có elseđiều kiện. Về ifphần, chúng tôi kiểm tra xem $n-in $d. Nếu có, điều đó có nghĩa $nlà nguyên tố, vì vậy chúng tôi lấy $n=2*$n-1hoặc $n+=$n-1. Mặt khác, nó là hợp số, vì vậy chúng ta cần tìm ra thừa số nguyên tố lớn nhất. Điều đó có nghĩa chúng ta cần phải thực hiện tác phẩm mới nhất [-1]của $dvà trừ rằng từ $nvới $n-=. Điều này hoạt động bởi vì chúng tôi lặp lại từ 2đó và do đó, yếu tố cuối cùng $dđã là lớn nhất.

Khi chúng tôi thực hiện xong vòng lặp, chúng tôi chỉ đặt $n%38(một lần nữa, cảm ơn Arnauld) trên đường ống dẫn và đầu ra là ẩn.


1

APL (Dyalog Unicode) , 113 90 59 byte

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

Hãy thử trực tuyến!

TIO hoạt động với giá trị lên tới ~ 3200. Đã thử nghiệm trên PC của tôi cho trường hợp thử nghiệm cuối cùng. Để kiểm tra trên TIO, chỉ cần thêm f valuevào dưới cùng của mã. Không áp dụng nữa, cảm ơn @ Adám đã chỉ ra rằng thuật toán kiểm tra tính nguyên thủy của tôi thực sự xấu và cung cấp cho tôi một sự thay thế; cũng để lưu 23 byte.

Đã chỉnh sửa để sửa số byte.

Làm thế nào nó hoạt động

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

Tiên đề, 93 byte

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)

kiểm tra:

(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

Sẽ có chức năng 68 byte

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

nhưng với n = 57991 (nếu tôi nhớ rõ), nó sẽ vượt ra khỏi không gian ngăn xếp dành riêng.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.