Cantor setinde mi?


20

Meydan okuma

Bu zorluk için, verilen bir sayının Cantor setinde olup olmadığını belirlemeniz gerekir. Önce Cantor setini tanımlayalım.

İlk olarak, 0 ile 1 arasındaki sayılarla başlayın. Bu aralığın dışındaki sayılar Cantor kümesinde değildir. Şimdi sayıları üç eşit parçaya bölelim: [0,1 / 3], [1 / 3,2 / 3], [2/3, 1]. İlk ve son parça aralıklarında olmayan sayılar Cantor setinde değildir. Şimdi bu işlemi [0,1 / 3] ve [2/3, 1] segmentleri için tekrar edersiniz. Sonra artık ne olduğunu tekrarlayın. Bunu sonsuza dek yapmaya devam ediyorsun. Sonunda, kalan tüm sayılar Cantor kümesinde bulunur. İlk altı iterasyonun bir şeması:

Kantor diyagramı


Giriş

İki tamsayı xve y.
0 < y < 2^15
0 <= x <= y
En büyük ortak paydası xve ysürece 1'dir x == 0.


Çıktı

x/yCantor setindeyse doğrudur . Cantor setinde değilse
Falsy x/y.


Örnekler

Şimdi, Cantor setindeki sayıların bazı örneklerine bakalım.

1/3 -> true  

Bu bir sınır üzerindedir ve sınırlar asla kaldırılmaz.

1/4 -> true  

1/4hiçbir zaman bir segmentin orta üçte birinde değildir, ancak hiçbir zaman sınırda değildir. Onun yolunu izlerseniz, aslında bir bölümün ilk ve son üçte birinde olmak arasında değiştiğini göreceksiniz.

1/13 -> true  

1/13 ilk, ilk ve son bölümler arasında geçiş yapar.

1/5 -> false

1/5 1/9 ve 2/9 arasında, yukarıdaki diyagramda üçüncü sıranın ilk boş bloğuna düşer.

Diğer test örnekleri:

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

Bu snippet ile diğer numaraları deneyebilirsiniz:


Amaç

En az bayt olan kişi kazanır.


Girişin (0,0) olmadığı garanti ediliyor mu? Kesir en basit biçimde mi veriliyor?
xnor

1
@xnor, y için verilen aralığa bakın. Ben kesir basit form sürece olduğunu söylemek için gidiyorumx == 0
TheNumberOne

X! = 1'in iyi olduğu bazı test durumları. Ayrıca, snippet'iniz 1/3'ün hazine kümesinde olmadığını söylüyor.
xnor

@xnor Eklendi ve düzeltildi;)
TheNumberOne

6
Cantor bulunabilir mi?
mbomb007

Yanıtlar:


13

Mathematica, 54 bayt

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

Bir fraksiyonu alınarak Adsız fonksiyonu x/ygirdi olarak y > 0ve 0 ≤ x ≤ y, ve geri Trueya da False.

0 ile 1 arasındaki gerçek bir sayı, tabanındaki 3 genişlemesindeki rakamlardan hiçbiri 1'e eşit olmadığında, Cantor kümesinde tam olarak bulunur; istisna, paydası 3 gücü olan (taban-3 genişlemesi bu nedenle sona eren) bir fraksiyonun 1'de bitmesine izin verilmesidir.

RealDigits[#,3][[1]]kesirli girdinin base-3 genişlemesindeki tüm basamakları aşağıdaki #gibi verir {1, 0, 2, {0, 1, 0, 2}}: son liste genişlemenin periyodik kısmıdır, önceki tamsayılar periyodiklik başlamadan önceki basamaklardır. Base-3 genişlemesi hemen periyodikse, çıktı aşağıdaki gibidir {{0, 1, 0, 2}}; base-3 genişlemesi sona ererse, form benzerdir {1, 0, 2}.

Bu yüzden ~FreeQ~1listenin 1s olup olmadığını kontrol etmek istiyoruz . Ancak, sona eren genişletme işlemi nedeniyle, listenin eşit olması durumunda listenin son öğesini silmek istiyoruz 1; bu ne If[Last@#===1,Most@#,#]yapar. ( ===Potansiyel bir listeyi karşılaştırmak için gereklidir 1: ==tek başına bu durumda değerlendirilmemiş kalır.)


4
Mathematica'nın IsCantorNumberbir şeyin keçi olduğunu belirleme işlevine sahip olmasına şaşırdım .
Brain Guider

3
Peki, gerçek hayatta daha fazla ortaya çıkan bilmiyorum: keçi mi, fraktal mı? ;)
Greg Martin

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

Böyle bir kural ayrıca 1periyodik kısımdaki sonları siler, bu da yanlış cevaplara yol açar. Örneğin, 7/8 baz-3 genişlemesi .21212121 ...., veya {{2,1}}; ancak önerilen kural {{2}}, 1s içermeyen ancak olmamalı olanı olarak değiştirir.
Greg Martin

Touché. Nasıl #==0||FreeQ[RealDigits[#,3]/.{{x___,1},_}:>{x},1]&? Eğer sonlandırılıyorsa ve sıfırdan farklı bir RealDigits[#,3]formda {{__Integer},-1}olacaksa ve tekrar ederse formda olacak {{___Integer,{__Integer}},-1}, değil mi? Cep telefonuyum, bu yüzden şu anda test etmek zor. Bu işe yararsa, için infix gösterimini kullanmak RealDigitsda işe yarayabilir.
ngenisis

9

C (gcc) , 61 59 58 bayt

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

Cantor kümesinin simetrisini kullanır. ySonsuz bir döngüden kaçınmak için yinelemelerden sonra kırılır.

Çevrimiçi deneyin!


7

Jöle , 22 17 16 15 bayt

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

3 doğruluk için, baskı için hiçbir şey yazdırmaz.

Çevrimiçi deneyin!

Arka fon

Cantor kümesinin iyi bilinen bir özelliği, üçlü genişlemelerinde 1 'ler olmadan yazılabilen 0 ve 1 arasındaki sayıları tam olarak içermesidir .

Bazı sayıların - setin yapısında yer alan kapalı aralıkların tam olarak sağ kenarları - tek bir (sondaki) 1 veya sonsuz miktarda sondaki 2 ' ile yazılabileceğini unutmayın . Örneğin, 1 = 1 3 = 0.22222… 3 ve 1/3 = 0.1 3 = 0.022222… 3 , tıpkı 0.5 10 = 0.499999… 10 gibi .

Biz özel mahfazası doğru kenarları kontrol edebilir önlemek için , 1 s' kısa ondalık hem de genişleme x / y ve - (X-Y) / y x / y = 1 - , x / y , bir sağ kenar IFF olan (y - x) / y sol kenardır. Bunlardan en az biri 1 ' içermiyorsa , x / y Cantor kümesine aittir.

Nasıl çalışır

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

3gerçek true+1.
Sihirli Ahtapot Urn

3

JavaScript (ES6), 65 67

Düzenleme 2 kaydedilen thx @Luke bayt

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

Daha az 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
}

Ölçek

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


Ben değiştirmek düşünüyorum n=n%d*3ile q=n/d|0ve daha sonra değiştirmek z[n]ilez[n=n%d*3]
Luke

2

JavaScript (ES6), 55 bayt

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

Önce paydada, sonra da payda körükleyerek kullanın. Standart form bir bayt daha uzundur:

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

açıklama

Cantor setinde bir fraksiyon yoksa, bir noktada orta bölümlerden birine düşmelidir; bu nedenle, taban 3'teki temsili bir 1 ve ardından bir noktada sıfır olmayan bir rakam içermelidir. Bu böyle çalışır:

  • z 1 bulup bulmadığımızı takip eder.
  • q taban 3'teki geçerli rakamdır.
  • !z|!qzfalse ( doğruysa (1 qbulmadık )) veya false (geçerli basamak 0'dır) ise doğrudur .

n1'den sonra bir yerde sıfır olmayan bir rakam bulmadan önce sıfıra düşerse , kesir Cantor kümesinde olur ve geri döneriz 1.


2

Bash + GNU yardımcı programları, 62 bayt

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

Çevrimiçi deneyin!

Arg1 <= arg2 ve 0 <arg2 ile iki tamsayı argümanını iletin.

Çıkış, PPCG I / O yöntemlerinin izin verdiği şekilde çıkış kodunda (falsy için 0, doğruluk için 1) döndürülür .

Ben regex daha da golf olabilir şüpheli, hatta hatta grep -z kullanmak lehine tr komut ortadan kaldırılması, ama bu gelip mümkün olan en kısa. (Ne yazık ki, grep -z, grep -P ile uyumsuzdur ve?! Sözdizimi için perl stili normal ifadeleri almak için -P seçeneği gereklidir.)

Test edilmiş program ve çıktı:

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

açıklama

dc bölümü (bağımsız değişkenler x ve y'dir):

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 ve grep kısmı:

Küçük bir sorun, dc keyfi olarak büyük tamsayıları işlemesine rağmen, dc çok sayıda yazdırdığında, son satır hariç her satır bir ters eğik çizgi ve her satırdan sonra bir yeni satır ile 69 karakterlik satırlara böler.

Tr komutu ters eğik çizgileri ve yeni satırları siler. Bu sadece tek bir satır bırakıyor.

Daha sonra grep komutu perl-tarzı regex (GNU uzantısı olan -P seçeneği) kullanır. Satır 1'den sonra gelmeyen en az y 0 veya en az y 2 içeriyorsa regex eşleşir ve dizeyi bitirir.

Bu x / y'yi Cantor setinde olmadığı olarak tanımlamak için gereken şeydir, çünkü x / y rasyonel sayısının base-3 temsili tekrarlayan kısmı üçlü noktadan sonra # y + 1 rakamından başlayarak görülebilir. ve en fazla y basamak uzunluğundadır.


1

CJam (19 bayt)

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

Çevrimiçi test takımı

Bu, yığın ve yapraklar üzerinde 0veya yığın üzerinde iki bağımsız değişken alan anonim bir bloktur (işlev) 1. Bu fraksiyon dönüştürme baz ile çalışır x/yiçine ytaban 3hiçbir ihtiva IFF basamak ve doğru döndüren 1veya sadece 1bir ekinin bir parçasıdır 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 bayt

gu*3hS,G-QGQE0

C çözümüme dayanarak. yilk giriş satırında, xikinci giriş satırında .

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

Eğer x/yCantor kümesi içinde olduğunu xarasındaki kalır 0ve y. Aksi takdirde, bir noktadan xdaha büyük olur y, daha sonra kalan iterasyonlarda negatif sonsuza ayrılır.

Çevrimiçi deneyin!


0

Toplu, 91 bayt

@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%

İlk y-1basamağın 3 basamağını test eder x/y. itest edilen basamak sayısıdır. nsonraki değeri x. sıfıra ulaştığında jdoğrudur n(genişleme sona erdiğinden) veya y-1rakamları a bulmadan test ettik 1. ftrue ise jveya sonraki basamak a ise 1, döngü ve çıktıyı durdurduğumuzda doğrudur j.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.