Có phải trong bộ Cantor?


20

Các thách thức

Đối với thử thách này, bạn phải xác định xem một số đã cho có nằm trong tập hợp Cantor hay không. Vì vậy, trước tiên, hãy xác định bộ Cantor.

Đầu tiên, bắt đầu với các số từ 0 đến 1. Bất kỳ số nào nằm ngoài phạm vi này không nằm trong tập hợp Cantor. Bây giờ, hãy chia các số thành ba phần bằng nhau: [0,1 / 3], [1 / 3,2 / 3], [2/3, 1]. Bất kỳ số nào không nằm trong phạm vi của phần đầu tiên và phần cuối không nằm trong tập hợp Cantor. Bây giờ, bạn lặp lại quy trình này cho các phân đoạn [0,1 / 3] và [2/3, 1]. Sau đó, bạn lặp lại về những gì còn sót lại. Bạn cứ làm điều này mãi mãi. Cuối cùng, tất cả các số còn lại đều nằm trong tập hợp Cantor. Đây là sơ đồ của sáu lần lặp đầu tiên:

Sơ đồ Cantor


Đầu vào

Hai số nguyên xy.
0 < y < 2^15
0 <= x <= y
Mẫu số chung lớn nhất của xylà 1, trừ khi x == 0.


Đầu ra

Sự thật nếu x/ylà trong bộ Cantor.
Falsy nếu x/ykhông có trong bộ Cantor.


Ví dụ

Bây giờ, hãy xem một số ví dụ về các số trong tập hợp Cantor.

1/3 -> true  

Đó là trên một ranh giới, và ranh giới không bao giờ được gỡ bỏ.

1/4 -> true  

1/4không bao giờ nằm ​​ở một phần ba giữa của một phân khúc, mặc dù nó cũng không bao giờ nằm ​​trên ranh giới. Nếu bạn đi theo con đường của nó, bạn thực sự sẽ thấy rằng nó xen kẽ giữa việc ở một phần ba đầu tiên và cuối cùng của một phần.

1/13 -> true  

1/13 xen kẽ giữa các phần đầu tiên, đầu tiên và cuối cùng.

1/5 -> false

1/5 rơi vào khối trống đầu tiên của hàng thứ ba trong sơ đồ trên, giữa 1/9 và 2/9.

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

0/4 -> true
3/10 -> true
3/4 -> true
10/13 -> true
1/1 -> true
12/19 -> false
5/17 -> false
3/5 -> false
1/7 -> false
1/2 -> false

Bạn có thể thử các số khác với đoạn trích này:


Mục tiêu

Người có ít byte nhất sẽ thắng.


Chúng tôi có đảm bảo rằng đầu vào không (0,0) không? Là phần được đưa ra ở dạng đơn giản nhất?
xnor

1
@xnor nhìn vào phạm vi được đưa ra cho y. Tôi sẽ nói rằng phân số ở dạng đơn giản nhất trừ khix == 0
TheNumberOne

Một số trường hợp thử nghiệm trong đó x! = 1 sẽ tốt. Ngoài ra, đoạn trích của bạn nói rằng 1/3 không có trong bộ cantor.
xnor

@xnor Đã thêm và sửa;)
TheNumberOne

6
Cantor nó có thể được tìm thấy?
mbomb007

Câu trả lời:


13

Toán học, 54 byte

If[Last@#===1,Most@#,#]&@RealDigits[#,3][[1]]~FreeQ~1&

Hàm không tên lấy một phân số x/ylàm đầu vào, ở đâu y > 00 ≤ x ≤ yvà trả về Truehoặc False.

Một số thực nằm trong khoảng từ 0 đến 1 nằm trong Cantor được đặt chính xác khi không có chữ số nào trong phần mở rộng cơ sở 3 của nó bằng 1; ngoại lệ là một phân số có mẫu số là lũy thừa 3 (do đó việc mở rộng cơ sở 3 do đó chấm dứt) được phép kết thúc bằng 1.

RealDigits[#,3][[1]]đưa ra tất cả các chữ số trong khai triển cơ sở 3 của đầu vào phân số #, dưới dạng như {1, 0, 2, {0, 1, 0, 2}}: danh sách cuối cùng là phần định kỳ của khai triển, trong khi các số nguyên trước đó là các chữ số trước khi bắt đầu định kỳ. Nếu việc mở rộng cơ sở 3 là định kỳ ngay lập tức, đầu ra sẽ như thế nào {{0, 1, 0, 2}}; nếu việc mở rộng cơ sở-3 chấm dứt, hình thức sẽ như thế nào {1, 0, 2}.

Vì vậy, chúng tôi muốn kiểm tra, sử dụng ~FreeQ~1, xem danh sách có miễn phí 1hay không. Tuy nhiên, vì điều mở rộng kết thúc, chúng tôi muốn xóa phần tử cuối cùng của danh sách nếu nó bằng 1; đó là những gì If[Last@#===1,Most@#,#]đạt được. (Điều ===cần thiết để so sánh một danh sách tiềm năng với 1: ==một mình vẫn chưa được đánh giá trong tình huống đó.)


4
Tôi ngạc nhiên rằng Mathicala không có IsCantorNumbernhưng có một chức năng để xác định là một cái gì đó là một con dê .
Brain Guider

3
Chà, tôi không biết, thứ xuất hiện nhiều hơn trong cuộc sống thực: dê hay fractals? ;)
Greg Martin

FreeQ[RealDigits[#,3][[1]]/.{{x___,1}}:>{x},1]&
ngenisis

Một quy tắc như vậy cũng sẽ loại bỏ các dấu 1trong phần định kỳ, dẫn đến câu trả lời không chính xác. Ví dụ: bản mở rộng cơ sở 3 của 7/8 là .21212121 ...., hoặc {{2,1}}; nhưng quy tắc được đề xuất sẽ thay đổi điều đó thành {{2}}, không có 1s nhưng không nên.
Greg Martin

Touché. Thế còn #==0||FreeQ[RealDigits[#,3]/.{{x___,1},_}:>{x},1]&? Nếu nó chấm dứt và nonzero RealDigits[#,3]sẽ có dạng {{__Integer},-1}và nếu nó lặp lại thì nó sẽ có dạng {{___Integer,{__Integer}},-1}, phải không? Tôi đang sử dụng điện thoại di động nên rất khó để kiểm tra ngay bây giờ. Nếu điều này hoạt động, sử dụng ký hiệu infix cho cũng RealDigitscó thể hoạt động.
ngenisis


7

Thạch , 22 17 16 15 byte

,ạµ%⁹×3µÐĿ:⁹Ḅ3ḟ

In 3 cho sự thật, không có gì cho giả.

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

Lý lịch

Một thuộc tính nổi tiếng của tập hợp Cantor là nó chứa chính xác các số đó từ 0 đến 1 có thể được viết mà không cần 1 trong phần mở rộng về phía sau của chúng.

Lưu ý rằng một số số - chính xác là các cạnh phải của các khoảng đóng có liên quan đến cấu trúc của tập hợp - có thể được viết bằng một dấu ( 1 ) duy nhất hoặc với số lượng vô hạn của 2 dấu . Ví dụ: 1 = 1 3 = 0,222222 31/3 = 0,1 3 = 0,0222222 3 , chỉ bằng 0,5 10 = 0,499999 trộm 10 .

Để tránh vỏ đặc biệt cho các cạnh phải, chúng ta có thể kiểm tra 1 'là phần mở rộng thập phân ngắn nhất trong cả x / y1 - x / y = (y - x) / y , trong đó x / y là cạnh phải (y - x) / y là cạnh trái. Nếu ít nhất một trong số chúng không chứa 1 , thì x / y thuộc về bộ Cantor.

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

,ạµ%⁹×3µÐĿ:⁹Ḅ3ḟ  Main link. Left argument: x. Right argument: y

 ạ               Absolute difference; yield y - x.
,                Pair; yield [x, y - x].
       µ         Begin a new, monadic chain with argument [a, b] := [x, y - x].
  µ     ÐĿ       Repeatedly execute the links in between until the results are no
                 longer unique, updating a and b after each execution. Return the
                 array of all unique results.
   %⁹              Compute [a % y, b % y].
     ×3            Compute [3(a % y), 3(b % y)].
                 This yields all unique dividends of the long division of x by y in
                 base 3.
          :⁹     Divide all dividends by y to get the corresponding ternary digits.
            Ḅ    Unbinary; turn [1, 1] into 3, other pairs into other numbers.
             3ḟ  Remove all occurrences of the resulting numbers from [3], leaving
                 an empty array if and only if one pair [a, b] is equal to [1, 1].

3true+1 thực sự .
Bạch tuộc ma thuật Urn

3

JavaScript (ES6), 65 67

Chỉnh sửa 2 byte đã lưu thx @Luke

n=>d=>(z=>{for(q=0;~-q*n*!z[n];n=n%d*3)z[n]=1,q=n/d|0})([])|q!=1|!n

Ít chơi gôn

n=>d=>{
  z = []; // to check for repeating partial result -> periodic number
  for(q = 0; q != 1 && n != 0 && !z[n]; )
    z[n] = 1,
    q = n / d | 0,
    n = n % d * 3
  return q!=1 | n==0
}

Kiểm tra

f=
n=>d=>(z=>{for(q=0;~-q*n*!z[n=n%d*3];q=n/d|0)z[n]=1})([])|q!=1|!n
  

console.log(
'Truthy: 1/3 1/4 1/13 0/4 3/10 3/4 10/13 1/1\nFalsey: 1/5 12/19 5/17 3/5 1/7 1/2'.replace(/(\d+).(\d+)/g,(a,x,y)=>a+':'+f(x)(y))
)  


Tôi nghĩ bạn có thể thay thế n=n%d*3bằng q=n/d|0và sau đó thay thế z[n]bằngz[n=n%d*3]
Luke

2

JavaScript (ES6), 55 byte

y=>f=(x,z,n=~y,q=x/y|0)=>n?!z|!q&&f(x%y*3,z|q==1,n+1):1

Sử dụng bằng cách curry trong mẫu số đầu tiên và tử số thứ hai. Các hình thức tiêu chuẩn là một byte dài hơn:

f=(x,y,z,n=~y,q=x/y|0)=>n?!z|!q&&f(x%y*3,y,z|q==1,n+1):1

Giải trình

Nếu một phần không nằm trong tập hợp Cantor, nó phải rơi vào một trong các phần giữa tại một số điểm; do đó, biểu diễn của nó trong cơ sở 3 phải chứa 1 theo sau tại một số bằng một chữ số khác không. Đó là cách nó hoạt động:

  • z theo dõi xem chúng tôi đã tìm thấy 1.
  • q là chữ số hiện tại trong cơ sở 3.
  • !z|!qlà đúng nếu zlà sai (chúng tôi không tìm thấy 1) hoặc qsai (chữ số hiện tại là 0).

Nếu nchạy xuống 0 trước khi chúng ta tìm thấy một chữ số khác không ở đâu đó sau 1, phân số nằm trong tập hợp Cantor và chúng ta quay trở lại 1.


2

Tiện ích Bash + GNU, 62 byte

dc -e3o9d$2^$1*$2/p|tr -cd 012|grep -P "1(?!(0{$2,}|2{$2,})$)"

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

Truyền cho nó hai đối số nguyên với arg1 <= arg2 và 0 <arg2.

Đầu ra được trả về trong mã thoát (0 cho sai, 1 cho trung thực), như được cho phép bởi các phương thức I / O của PPCG .

Tôi nghi ngờ regex có thể được chơi gôn hơn nữa, thậm chí có thể loại bỏ lệnh tr có lợi cho việc sử dụng grep -z, nhưng đây là lần ngắn nhất tôi có thể nghĩ ra. (Thật không may, grep -z không tương thích với grep -P và tùy chọn -P để có được các biểu thức kiểu perl được yêu cầu cho cú pháp ?!).

Chương trình thử nghiệm và đầu ra:

for x in '1 3' '1 4' '1 13' '1 5' '0 4' '3 10' '3 4' '10 13' '1 1' '12 19' '5 17' '3 5' '1 7' '1 2'
  do
    printf %-6s "$x "
    ./cantor $x >/dev/null && echo F || echo T
  done

1 3   T
1 4   T
1 13  T
1 5   F
0 4   T
3 10  T
3 4   T
10 13 T
1 1   T
12 19 F
5 17  F
3 5   F
1 7   F
1 2   F

Giải trình

phần dc (các đối số là x và y):

3o     Set output base to 3.
9      Push 9 on the stack.
d      Duplicate the top of the stack. (The extra 9 on the stack isn't actually used, but I need some delimiter in the code here so that the 9 doesn't run into the number coming up next.  If I used a space as a no-op, then I'd need to quote it for the shell, adding an extra character.)
$2^    Raise 9 to the y power. This number in base 3 is 1 followed by 2y 0's.
$1*$2/ Multiply the base-3 number 10....0 (with 2y 0's in it) by x and then divide by y (truncating). This computes 2y digits (after an implied ternary point) of x/y.  That's enough digits so that the repeating part of the rational number is there at least twice.
p      Print the result, piping it to tr.

phần tr và grep:

Một vấn đề nhỏ là, mặc dù dc xử lý các số nguyên lớn tùy ý, nhưng khi dc in một số lượng lớn, nó sẽ chia nó thành các dòng 69 ký tự, với mỗi dòng ngoại trừ kết thúc cuối cùng bằng dấu gạch chéo ngược và với dòng mới sau mỗi dòng.

Lệnh tr xóa bất kỳ dấu gạch chéo ngược và dòng mới. Điều này chỉ để lại một dòng duy nhất.

Sau đó, lệnh grep sử dụng biểu thức chính quy theo kiểu perl (tùy chọn -P, là phần mở rộng GNU). Regex khớp với nếu dòng chứa 1 không được theo sau bởi ít nhất là y 0 hoặc ít nhất là y 2 sau đó kết thúc chuỗi.

Đây chính xác là những gì cần thiết để xác định x / y là không có trong tập hợp Cantor, bởi vì phần lặp lại của biểu diễn cơ sở 3 của số hữu tỷ x / y có thể được xem là bắt đầu từ chữ số # y + 1 sau điểm thứ ba và dài tối đa y chữ số.


1

CJam (19 byte)

{_@3@#*\/3b0-W<1&!}

Bộ kiểm tra trực tuyến

Đây là một khối ẩn danh (hàm) có hai đối số trên ngăn xếp và rời khỏi 0hoặc 1trên ngăn xếp. Nó hoạt động bằng cách chuyển đổi phân số x/ythành các chữ số ycơ bản 3và trả về iff thực mà chúng không chứa 1hoặc chỉ 1là một phần của hậu tố 1 0 0 0 ....

{            e# Begin a block
  _@3@#*\/3b e#   Base conversion
   0-W<      e#   Remove all zeros and the final non-zero digit
   1&!       e#   True iff no 1s are left
}

1

Bình thường , 14 byte

gu*3hS,G-QGQE0

Dựa trên giải pháp C của tôi. ytrên dòng đầu tiên, xtrên thứ hai.

                Q = y
 u         QE   G = x
                loop y times
  *3                x = 3 *
    hS,G                min(x,
        -QG                 y-x)
g            0  return x >= 0

Nếu x/ynằm trong bộ Cantor, hãy xở giữa 0y. Mặt khác, xtrở nên lớn hơn ytại một điểm, sau đó chuyển hướng sang vô cực âm trong các lần lặp còn lại.

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


0

Mẻ, 91 byte

@set/ai=%3+1,n=%1*3%%%2,f=%1*3/%2%%2,f^|=j=!((%2-i)*n)
@if %f%==0 %0 %n% %2 %i%
@echo %j%

Kiểm tra y-13 chữ số cơ sở đầu tiên của x/y. ilà số chữ số được kiểm tra. nlà giá trị tiếp theo của x. jlà đúng nếu nđạt đến 0 (vì quá trình mở rộng chấm dứt) hoặc chúng tôi đã kiểm tra các y-1chữ số mà không tìm thấy a 1. flà đúng nếu jlà đúng hoặc nếu chữ số tiếp theo là a 1, tại điểm này chúng ta dừng lặp và đầu ra j.

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.