Bạn bị lạc chưa


31

Nhiệm vụ của bạn là triển khai chuỗi số nguyên A130826 :

một n là số nguyên dương nhỏ nhất mà một n - n là toàn bộ một bội số của 3 và gấp đôi so với số lượng các ước của (một n - n) / 3 cung cấp cho các n thứ hạn trong sự khác biệt đầu tiên của chuỗi sản xuất bởi các Flavius Josephus sàng.

Mất chưa? Chà, thật ra thì khá dễ.

Các Flavius Josephus sàng định nghĩa một chuỗi số nguyên như sau.

  1. Bắt đầu với chuỗi các số nguyên dương và đặt k = 2 .

  2. Xóa mọi số nguyên thứ k của chuỗi, bắt đầu bằng số thứ k .

  3. Tăng k và quay lại bước 2.

f n là số nguyên thứ n (1 chỉ mục) không bao giờ bị xóa.

Nếu - như thường lệ - σ 0 (k) biểu thị số ước số dương của số nguyên k , chúng ta có thể định nghĩa a n là số nguyên dương nhỏ nhất sao cho 0 ((a n - n) / 3) = f n + 1 - f n .

Thử thách

Viết một chương trình hoặc chức năng mà phải mất một số nguyên dương n như là đầu vào và in hoặc trả về một n .

Luật tiêu chuẩn được áp dụng. Có thể mã ngắn nhất giành chiến thắng!

Ví dụ làm việc

Nếu chúng tôi loại bỏ mọi phần tử thứ hai của các số nguyên dương, chúng tôi sẽ bị bỏ lại

 1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 ...

Sau khi loại bỏ mọi yếu tố thứ ba của phần còn lại, chúng tôi nhận được

 1  3  7  9 13 15 19 21 25 27 31 33 37 39 ...

Bây giờ, loại bỏ mọi thứ tư, rồi thứ năm, rồi yếu tố thứ sáu giúp chúng ta

 1  3  7 13 15 19 25 27 31 37 39 ...
 1  3  7 13 19 25 27 31 39 ...
 1  3  7 13 19 27 31 39 ...
 1  3  7 13 19 27 39 ...

Hàng cuối cùng hiển thị các điều khoản f 1 đến f 7 .

Sự khác biệt của các yếu tố liên tiếp của các điều khoản này là

 2  4  6  6  8 12

Chia những khác biệt về phía trước cho 2 , chúng ta nhận được

 1  2  3  3  4  6 

Đây là số lượng mục tiêu ước tính.

  • 4 là số nguyên đầu tiên k sao cho σ 0 ((k - 1) / 3) = 1 . Trong thực tế, σ 0 (1) = 1 .
  • 8 là số nguyên đầu tiên k sao cho σ 0 ((k - 2) / 3) = 2 . Trong thực tế, σ 0 (2) = 2 .
  • 15 là số nguyên đầu tiên k sao cho σ 0 ((k - 3) / 3) = 3 . Trong thực tế, σ 0 (4) = 3 .
  • 16 là số nguyên đầu tiên k sao cho σ 0 ((k - 4) / 3) = 3 . Trong thực tế, σ 0 (4) = 3 .
  • 23 là số nguyên đầu tiên k sao cho σ 0 ((k - 5) / 3) = 4 . Trong thực tế, σ 0 (6) = 4 .
  • 42 là số nguyên đầu tiên k sao cho σ 0 ((k - 6) / 3) = 6 . Trong thực tế, σ 0 (12) = 6 .

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

   n     a(n)

   1        4
   2        8
   3       15
   4       16
   5       23
   6       42
   7       55
   8      200
   9       81
  10       46
  11      119
  12      192
  13      205
  14   196622
  15    12303
  16       88
  17      449
  18      558
  19      127
  20     1748
  21   786453
  22       58
  23     2183
  24     3096
  25     1105
  26   786458
  27 12582939
  28      568
  29     2189
  30     2730

14
Từ khóa trên OEIS: câm ("một chuỗi không quan trọng").
orlp

15
Câm? Nó có thể cứu thế giới!
Dennis

3
Đó là cách chơi chữ ...
Mego

Câu trả lời:


7

Thạch, 30 29 27 25 byte

Đã lưu 2 byte nhờ @Dennis thông báo cho tôi Ædvà 2 byte khác để kết hợp hai chuỗi.

RUð÷‘Ċ×µ/
‘Ç_ÇH0Æd=¥1#×3+

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

Đây có lẽ là niềm vui nhất tôi từng có với Jelly. Tôi bắt đầu từ dòng thứ hai, tính toán f n từ n bằng cách sử dụng công thức trên OEIS, và khá đẹp.

Giải trình

Liên kết RUð ÷ 'Ċ × từ / Trình trợ giúp để tính F n . Luận điểm: n
R Nhận số [1..n]
 Đảo ngược
        / Giảm bằng "làm tròn đến 2 bội số tiếp theo":
   Chia cho số tiếp theo
    'Tăng để bỏ qua nhiều
     Trần (làm tròn)
      × Nhân với số tiếp theo

'_ÇH0Æd = 1 # × 3 + Liên kết chính. Luận điểm: n
'Tăng n
 Tính F n + 1 
   Ç Tính F n
  _ Trừ
    H chia cho 2
     0 1 # Bắt đầu từ 0, tìm ứng cử viên đầu tiên cho (a n -n) / 3
                   thỏa mãn ...
      Æd 0 ((a n -n) / 3)
        = = (F n + 1 -F n ) / 2
            × 3 Nhân 3 để biến (a n -n) / 3 thành n -n
              + Thêm n để biến n -n thành n

3

Python 2 , 121 119 118 byte

n=input();r=range(1,4**n);d=s,=r*1,
for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,
print d.index(s[n]-s[n-1])*3+n

Thời gian chạy nên xấp xỉ O (16 n ) với mức sử dụng bộ nhớ O (4 n ) . Thay thế 4**nbằng 5<<n- mà tôi nghĩ là đủ - sẽ cải thiện đáng kể điều này, nhưng tôi không tin rằng nó hoạt động với các giá trị lớn tùy ý của n .

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

Hành vi tiệm cận và giới hạn trên của một n

Xác định b n(a n - n) / 3 , tức là số nguyên dương nhỏ nhất k sao cho σ 0 (k) = ½ (f n + 1 - f n ) .

Như đã lưu ý trên trang OEIS, f n ~ πn 2 , vì vậy f n + 1 - f n ~ ¼π (n + 1) 2 - ¼πn 2 = ¼π (2n + 1) ~ ½πn .

Bằng cách này, (f n + 1 - f n ) ~ ¼πn . Nếu số thực tế là một số nguyên tố p , số nguyên dương nhỏ nhất có ước số p2 p - 1 , do đó b n có thể được xấp xỉ bằng 2 c n , trong đó c n ~ nπn .

Do đó b n <4 n sẽ giữ cho n đủ lớn và với 2 ¼πn <2 n << (2 n ) 2 = 4 n , tôi tự tin không có phản ứng mẫu.

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

n=input();r=range(1,4**n);d=s,=r*1,

Điều này thiết lập một vài tài liệu tham khảo cho quá trình lặp lại của chúng tôi.

  • n là đầu vào của người dùng: một số nguyên dương.

  • r là danh sách [1, ..., 4 n - 1] .

  • s là bản sao của r .

    Lặp đi lặp lại danh sách một lần với r*1tạo ra một bản sao cạn, vì vậy thay đổi s sẽ không sửa đổi r .

  • d được khởi tạo là tuple (s) .

    Giá trị đầu tiên này không quan trọng. Tất cả những người khác sẽ giữ số lượng chia của số nguyên dương.

for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,

Với mỗi số nguyên k từ 1 đến 4 n - 1 , chúng tôi thực hiện như sau.

  • del s[k::k+1]tận dụng mọi (k + 1) thứ nguyên trong s - bắt đầu với (k + 1) thứ - và xóa mà lát từ s .

    Đây là một cách đơn giản để lưu trữ một khoảng ban đầu của sàng Flavius ​​Josephus trong s . Nó sẽ tính toán nhiều hơn các điều khoản ban đầu n + 1 cần thiết , nhưng sử dụng một forvòng lặp duy nhất để cập nhật cả sd sẽ tiết kiệm một số byte.

  • d+=sum(k%j<1for j in r)*2,đếm có bao nhiêu yếu tố của r chia k đồng đều và gắn thêm 0 (k) để d .

    d được khởi tạo là một tuple đơn, 0 (k) được lưu trữ tại chỉ mục k .

print d.index(s[n]-s[n-1])*3+n

Điều này tìm thấy chỉ số đầu tiên của f n + 1 - f n trong d , là k nhỏ nhất sao cho 0 (k) = f n + 1 - f n , sau đó tính a n3k + 1 và in kết quả.


2

Java 8, 336 , 305 , 303 , 287 , 283 279 byte

57 byte bị xóa nhờ Kritixi Lithos

Chơi gôn

class f{static int g(int s,int N){return s<1?N+1:g(s-1,N+N/s);}static int h(int k){int u=0,t=1,i;for(;u!=(g(k,k)-g(k,k-1))/2;t++)for(i=1,u=0;i<=t;)if(t%i++<1)u++;return 3*t-3+k;}public static void main(String[]a){System.out.print(h(new java.util.Scanner(System.in).nextInt()));}}

Ung dung

class f {
    static int g(int s,int N){return s < 1 ? N + 1 : g(s - 1, N + N / s);}

    static int h(int k) {
        int u = 0, t = 1, i;
        // get the first number with v divisors
        while(u != (g(k, k) - g(k, k - 1))/2){
            u = 0;
            for (i = 1; i <= t; i++)
                if (t % i < 1) u++;
            t++;
        }
        // 3*(t-1)+k = 3*t+k-3
        return 3 * t + k - 3;
    }

    public static void main(String[] a) {
        System.out.print(h(new java.util.Scanner(System.in).nextInt()));
    }
}

Tôi nghĩ rằng phân tích các đối số dòng lệnh là một intngắn hơn so với sử dụng java.util.Scanner. Nhưng ngay cả khi bạn đang sử dụng Máy quét, bạn có thể thực hiện System.out.print(h(new java.util.Scanner().nextInt()))và xóa dòng trước đó
Kritixi Lithos

@KritixiLithos thx, đang sửa chữa ngay bây giờ ...
Bobas_Pett

Bên trong int h(), bạn có thể thay đổi nó thành int v = (g(k,k)-g(k,k-1))/2,u = 0,t = 1;. Bạn có thể thay đổi câu lệnh if (nằm trong vòng lặp for của bạn) từ if(t%i==0)thànhif(t%i<1)
Kritixi Lithos

Ngoài ra, bạn có thể thay đổi chức năng của mình gđể quay lại bằng cách sử dụng các toán tử tạm thời giống như return s==0?N+1:g(s-1,N+N/2)-ish
Kritixi Lithos

2
@KritixiLithos lol vào thời điểm này bạn chỉ nên đăng bài này dưới dạng giải pháp riêng của bạn
Bobas_Pett

1

Toán học, 130 116 106 103 byte

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[Tr[2+0Divisors@k]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

hoặc là

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[2DivisorSum[k,1&]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

Cuối cùng, nó gần giống với mã Jelly của @ Pietu1998 ...

Giải trình

Catch@

Catchbất cứ điều gì là Throw-ed (ném).

Do[ ... ,{k,∞}]

Vòng lặp vô hạn; kbắt đầu từ 1và tăng mỗi lần lặp.

f= ...

Chỉ định f:

Reverse@Range@#

Tìm {1, 2, ... , n}. Đảo ngược nó lại.

#2⌈#/#2+1⌉&

Hàm xuất trần (n1 / n2 + 1) * n2

f= ... ~Fold~ ... &

Chỉ định f một hàm áp dụng đệ quy hàm trên cho danh sách từ hai bước trên, sử dụng mỗi đầu ra làm đầu vào đầu tiên và từng thành phần của danh sách làm đầu vào thứ hai. "Đầu ra" ban đầu (đầu vào đầu tiên) là thành phần đầu tiên của danh sách.

Tr[2+0Divisors@k]==f[#+1]-f@#

Kiểm tra xem hai lần số ước của k có bằng f (n + 1) - f (n) không.

If[ ... ,Throw@k]

Nếu điều kiện là True, Throwgiá trị củak . Nếu không, tiếp tục lặp.

3 ... +#&

Nhân sản lượng với 3 và thêm n.

Phiên bản 130 byte

Catch@Do[s=#+1;a=k-#;If[3∣a&&2DivisorSigma[0,a/3]==Differences[Nest[i=1;Drop[#,++i;;;;i]&,Range[s^2],s]][[#]],Throw@k],{k,∞}]&

1

Perl 6 , 154 149 136 107 byte

->\n{n+3*first ->\o{([-] ->\m{m??&?BLOCK(m-1).rotor(m+0=>1).flat!!1..*}(n)[n,n-1])/2==grep o%%*,1..o},^Inf}

Ung dung:

-> \n {                    # Anonymous sub taking argument n
  n + 3 * first -> \o {    # n plus thrice the first integer satisfying:
    (                      #
      [-]                  #
      -> \m {              # Compute nth sieve iteration:
        m                  # If m is nonzero,
          ?? &?BLOCK(m-1).rotor(m+0=>1).flat # then recurse and remove every (m+1)-th element;
          !! 1..*          # the base case is all of the positive integers
      }                    #
      (n)                  # Get the nth sieve
      [n,n-1]              # Get the difference between the nth and (n-1)th elements (via the [-] reduction operator above)
    ) / 2                  # and divide by 2;
    ==                     # We want the number that equals
    grep o %% *, 1..o      # the number of divisors of o.
  }
  ,^Inf
}

1

05AB1E ,35 34 39 byte

1Qi4ë[N3*¹+NÑg·¹D>‚vyy<LRvy/>îy*}}‚Æ(Q#

Có vẻ khủng khiếp, hiệu suất thời gian chạy cũng vậy. Phải mất vài giây cho đầu vào mang lại giá trị nhỏ. Đừng thử các số như 14; cuối cùng nó sẽ tìm thấy kết quả nhưng nó sẽ mất nhiều thời gian.

Giải trình

Nó hoạt động như 2 chương trình được gọi là tuần tự. Người đầu tiên tính F n + 1 - F n và điều thứ hai xác định một n dựa trên định nghĩa của nó, sử dụng một cách tiếp cận bruteforce.

F n + 1 - F n được ước tính cho mỗi lần lặp mặc dù nó là bất biến vòng lặp. Nó làm cho thời gian mã không hiệu quả, nhưng nó làm cho mã ngắn hơn.

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


Tôi không chắc là tôi hiểu. Tại sao nó không thể tính được sàng trên 65.536?
Dennis

Nó xuất phát từ thực tế là nó tạo ra tất cả các số nguyên trong khoảng từ 0 đến 65536 ( žHL) và sau đó lọc ra các giá trị không thỏa mãn các ràng buộc sàng. Tôi nghĩ rằng phần đầu tiên của chương trình này nên được viết lại hoàn toàn với một cách tiếp cận hoàn toàn khác để làm cho nó có thể chơi được.
Osable

Trừ khi có những hạn chế (như số nguyên chiều rộng cố định) ngăn bạn làm như vậy, các câu trả lời dự kiến ​​sẽ hoạt động cho bất kỳ đầu vào nào, với đủ thời gian và bộ nhớ.
Dennis

Đó là lý do tại sao tôi nghĩ ra một thuật toán sàng khác. Nó có thể chơi được nhưng tôi không tìm thấy tốt hơn trong 05AB1E. Tuy nhiên, có một ví dụ về given enough time and memory, vì tôi đã thấy một số câu trả lời cho các câu hỏi khác chạy chậm đến mức gần như không thể nói liệu họ có tạo ra đầu ra đúng hay không. Vì lý do này, tôi đặt tính toán sàng qua vòng lặp và nó tiêu tốn của tôi 2 byte.
Osable

Không cần phải làm cho mã của bạn hiệu quả. Bạn có thể thực hiện việc chơi golf / chậm trong bài nộp của mình và bao gồm bài nhanh hơn / dài hơn như một ghi chú bên lề. Tôi sợ rằng tôi phải nhấn mạnh vào giới hạn động, ngay cả khi nó tốn một byte.
Dennis
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.