Apakah itu dalam set Cantor?


20

Tantangan

Untuk tantangan ini, Anda harus menentukan apakah angka yang diberikan ada dalam set Cantor. Jadi pertama-tama, mari kita tentukan set Cantor.

Pertama, mulailah dengan angka antara 0 dan 1. Angka apa pun di luar rentang ini tidak dalam set Penyedia. Sekarang, mari kita bagi angka menjadi tiga bagian yang sama: [0,1 / 3], [1 / 3,2 / 3], [2/3, 1]. Angka apa pun yang tidak di dalam rentang bagian pertama dan terakhir tidak ada dalam set Penyedia. Sekarang, Anda ulangi proses ini untuk segmen [0,1 / 3] dan [2/3, 1]. Kemudian Anda ulangi apa yang tersisa. Anda terus melakukan ini selamanya. Pada akhirnya, semua angka yang tersisa berada di set Cantor. Berikut adalah diagram dari enam iterasi pertama:

Diagram penyanyi


Memasukkan

Dua bilangan bulat xdan y.
0 < y < 2^15
0 <= x <= y
Penyebut umum terbesar dari xdan yadalah 1, kecuali x == 0.


Keluaran

Jujur jika x/yada dalam set Penyedia .
Falsy jika x/ytidak dalam set Cantor.


Contohnya

Sekarang, mari kita lihat beberapa contoh angka yang ada di set Cantor.

1/3 -> true  

Itu ada di batas, dan batas tidak pernah dihapus.

1/4 -> true  

1/4tidak pernah di sepertiga tengah segmen, meskipun tidak pernah di perbatasan juga. Jika Anda mengikuti jalannya, Anda akan benar-benar menemukan bahwa itu bergantian antara berada di pertiga bagian pertama dan terakhir.

1/13 -> true  

1/13 bergantian antara bagian pertama, pertama, dan terakhir.

1/5 -> false

1/5 jatuh ke blok kosong pertama dari baris ketiga dalam diagram di atas, antara 1/9 dan 2/9.

Kasus uji lainnya:

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

Anda dapat mencoba nomor lain dengan cuplikan ini:


Objektif

Orang dengan byte terkecil menang.


Apakah kami dijamin inputnya tidak (0,0)? Apakah fraksi diberikan dalam bentuk paling sederhana?
xnor

1
@xnatau lihat rentang yang diberikan untuk y. Saya akan mengatakan bahwa fraksi ini dalam bentuk yang paling sederhana kecualix == 0
TheNumberOne

Beberapa test case di mana x! = 1 akan baik. Juga, cuplikan Anda mengatakan 1/3 tidak ada dalam set pemberi.
xnor

@ xnor Ditambahkan dan diperbaiki;)
TheNumberOne

6
Pelayan dapatkah ditemukan?
mbomb007

Jawaban:


13

Mathematica, 54 byte

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

Fungsi yang tidak disebutkan namanya mengambil sebagian kecil x/ysebagai input, di mana y > 0dan 0 ≤ x ≤ y, dan mengembalikan Trueatau False.

Bilangan real antara 0 dan 1 ada di Cantor yang diatur tepat ketika tidak ada digit dalam ekspansi basis-3 yang sama dengan 1; pengecualian adalah bahwa fraksi yang penyebutnya berkekuatan 3 (yang ekspansi basis-3nya diakhiri) dibiarkan berakhir dalam angka 1.

RealDigits[#,3][[1]]memberikan semua digit pada ekspansi basis-3 dari input fraksional #, dalam bentuk seperti {1, 0, 2, {0, 1, 0, 2}}: daftar terakhir adalah bagian periodik dari ekspansi, sedangkan bilangan bulat sebelumnya adalah digit sebelum periodisitas dimulai. Jika ekspansi base-3 periodik segera, outputnya seperti {{0, 1, 0, 2}}; jika ekspansi basis-3 berakhir, bentuknya seperti {1, 0, 2}.

Jadi kami ingin memeriksa, menggunakan ~FreeQ~1, apakah daftar itu bebas 1atau tidak. Namun, karena penghentian ekspansi hal, kami ingin menghapus elemen terakhir dari daftar jika sama 1; itulah yang If[Last@#===1,Most@#,#]berhasil. ( ===Diperlukan untuk membandingkan daftar potensial dengan 1: ==sendirian tetap tidak dievaluasi dalam situasi itu.)


4
Saya terkejut bahwa Mathematica tidak memiliki IsCantorNumbertetapi memiliki fungsi untuk menentukan sesuatu adalah kambing .
Brain Guider

3
Ya, saya tidak tahu, yang muncul lebih banyak dalam kehidupan nyata: kambing atau fraktal? ;)
Greg Martin

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

Aturan seperti itu juga akan menghapus trailing 1di bagian periodik, yang mengarah pada jawaban yang salah. Misalnya, ekspansi basis-3 dari 7/8 adalah .21212121 ...., atau {{2,1}}; tetapi aturan yang disarankan akan mengubahnya menjadi {{2}}, yang bebas dari 1tetapi tidak seharusnya.
Greg Martin

Sentuh. Bagaimana dengan #==0||FreeQ[RealDigits[#,3]/.{{x___,1},_}:>{x},1]&? Jika itu berakhir dan bukan nol RealDigits[#,3]akan menjadi bentuk {{__Integer},-1}dan jika itu berulang akan menjadi bentuk {{___Integer,{__Integer}},-1}, kan? Saya sedang menggunakan ponsel sehingga sulit untuk menguji sekarang. Jika ini berhasil, gunakan notasi infiks untuk RealDigitsmungkin berfungsi juga.
ngenisis

9

C (gcc) , 61 59 58 byte

f(x,y,i){for(i=y;i--&&x<y;)x=(y-x<x?y-x:x)*3;return x<=y;}

Mengeksploitasi simetri set Cantor. Istirahat setelah yiterasi untuk menghindari infinite loop.

Cobalah online!


7

Jelly , 22 17 16 15 byte

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

Mencetak 3 untuk truey, tidak ada untuk falsy.

Cobalah online!

Latar Belakang

Properti terkenal dari set Cantor adalah bahwa ia mengandung angka-angka antara 0 dan 1 yang dapat ditulis tanpa 1 dalam ekspansi terner mereka.

Perhatikan bahwa beberapa angka - tepatnya tepi kanan dari interval tertutup yang terlibat dalam konstruksi himpunan - dapat ditulis dengan satu (trailing) 1 atau dengan jumlah trailing 2 yang tak terbatas . Sebagai contoh, 1 = 1 3 = 0,22222 ... 3 dan 1/3 = 0,1 3 = 0,022222 ... 3 , sama seperti 0,5 10 = 0,499999 ... 10 .

Untuk menghindari casing khusus tepi kanan, kita dapat memeriksa 1 adalah ekspansi desimal terpendek di kedua x / y dan 1 - x / y = (y - x) / y , di mana x / y adalah tepi kanan jika (y - x) / y adalah tepi kiri. Jika setidaknya salah satu dari mereka mengandung angka 1 , x / y adalah milik set Cantor.

Bagaimana itu bekerja

,ạµ%⁹×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].

3adalah true+1 yang benar .
Magic Octopus Mm

3

JavaScript (ES6), 65 67

Edit 2 byte disimpan thx @ Lukas

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

Kurang golf

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
}

Uji

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


Saya pikir Anda dapat mengganti n=n%d*3dengan q=n/d|0dan kemudian mengganti z[n]denganz[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

Gunakan dengan mencari di penyebut pertama dan pembilang kedua. Bentuk standar adalah satu byte lebih panjang:

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

Penjelasan

Jika sebagian kecil tidak ada dalam set Penyedia, itu harus jatuh ke salah satu bagian tengah di beberapa titik; oleh karena itu, perwakilannya dalam basis 3 harus berisi angka 1 diikuti pada titik tertentu dengan angka bukan nol. Begitulah cara kerjanya:

  • z melacak apakah kami telah menemukan 1.
  • q adalah digit saat ini di basis 3.
  • !z|!qbenar jika zsalah (kami belum menemukan 1) atau qsalah (digit saat ini adalah 0).

Jika nberjalan ke nol sebelum kami menemukan angka bukan nol di suatu tempat setelah angka 1, fraksi ada di set Penyedia dan kami kembali 1.


2

Utilitas Bash + GNU, 62 byte

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

Cobalah online!

Berikan dua argumen integer dengan arg1 <= arg2 dan 0 <arg2.

Output dikembalikan dalam kode keluar (0 untuk palsu, 1 untuk kebenaran), sebagaimana diizinkan oleh metode I / O PPCG .

Saya menduga regex dapat di-golf lebih jauh, bahkan mungkin menghilangkan perintah tr yang mendukung penggunaan grep -z, tetapi ini adalah yang terpendek yang dapat saya lakukan. (Sayangnya, grep -z tidak kompatibel dengan grep -P, dan opsi -P untuk mendapatkan reg-style perl diperlukan untuk sintaks?!).

Program dan keluaran Testbed:

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

Penjelasan

bagian dc (argumennya adalah x dan 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.

tr dan grep bagian:

Masalah kecil adalah bahwa, meskipun dc menangani bilangan bulat besar yang sewenang-wenang, ketika dc mencetak angka besar, ia akan memecahnya menjadi garis-garis 69-karakter, dengan setiap baris kecuali akhir yang terakhir dengan garis miring terbalik, dan dengan baris baru setelah setiap baris.

Perintah tr menghapus sembarang garis miring terbalik dan baris baru. Ini hanya menyisakan satu baris.

Perintah grep kemudian menggunakan reg-style perl (opsi -P, yang merupakan ekstensi GNU). Regex cocok jika baris berisi 1 tidak diikuti oleh setidaknya y 0 atau paling tidak y 2 yang kemudian mengakhiri string.

Inilah yang diperlukan untuk mengidentifikasi x / y sebagai tidak berada dalam set Cantor, karena bagian berulang dari representasi basis-3 dari bilangan rasional x / y dapat dilihat sebagai mulai dari digit # y + 1 setelah titik ternary , dan paling lama y digit.


1

CJam (19 byte)

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

Test suite online

Ini adalah blok anonim (fungsi) yang mengambil dua argumen pada stack dan daun 0atau 1pada stack. Ia bekerja dengan basis mengubah pecahan x/ymenjadi digit ybasis 3dan mengembalikan true jika mereka tidak mengandung 1atau hanya 1merupakan bagian dari akhiran 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

Pyth , 14 byte

gu*3hS,G-QGQE0

Berdasarkan solusi C saya. ypada baris input pertama, xkedua.

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

Jika x/yberada dalam set Cantor, xtetap di antara 0dan y. Kalau tidak, xmenjadi lebih besar dari ypada satu titik, kemudian menyimpang ke infinity negatif dalam iterasi yang tersisa.

Cobalah online!


0

Batch, 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%

Menguji y-1basis 3 digit pertama x/y. iadalah jumlah digit yang diuji. nadalah nilai selanjutnya dari x. jbenar jika nmencapai nol (karena ekspansi berakhir) atau kami telah menguji y-1digit tanpa menemukan a 1. fbernilai true jika jbenar atau jika digit berikutnya adalah a 1, pada titik mana kita menghentikan perulangan dan keluaran j.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.