Cantorセット内ですか?


20

チャレンジ

この課題では、特定の番号がカンターセットに含まれているかどうかを判断する必要があります。最初に、Cantorセットを定義しましょう。

最初に、0〜1の数字から始めます。この範囲外の数字は、Cantorセットには含まれません。ここで、数字を3つの等しい部分に分割しましょう:[0,1 / 3]、[1 / 3,2 / 3]、[2/3、1]。最初と最後の部分の範囲内にない数値は、カンターセットに含まれません。ここで、セグメント[0,1 / 3]および[2/3、1]に対してこのプロセスを繰り返します。それから残り物を繰り返します。あなたはこれを永遠にやり続けます。最終的に、残りのすべての番号はカンターセットに含まれます。以下に、最初の6つの反復の図を示します。

カントール図


入力

2つの整数xy
0 < y < 2^15
0 <= x <= y
最大公約数xyしない限り、1ですx == 0


出力

x/yCantorセットにある場合は真実です。カントールセットにない
場合x/yは偽。


次に、Cantorセットに含まれる数値の例を見てみましょう。

1/3 -> true  

それは境界上にあり、境界は削除されません。

1/4 -> true  

1/4セグメントの中央の3分の1にあることはありませんが、どちらの境界にもあることはありません。そのパスをたどると、実際にはセクションの最初と最後の3分の1にあることがわかります。

1/13 -> true  

1/13 最初のセクション、最初のセクション、最後のセクションを交互に切り替えます。

1/5 -> false

1/5 上の図の3行目の1/9から2/9までの最初の空のブロックに分類されます。

その他のテストケース:

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

このスニペットで他の番号を試すことができます:


目的

バイトが最も少ない人が勝ちます。


入力が(0,0)でないことが保証されていますか?分数は最も単純な形で与えられていますか?
-xnor

1
@xnorは、yに指定された範囲を調べます。x == 0
-TheNumberOne

x!= 1のテストケースが良いでしょう。また、スニペットは、1/3がカンターセットにないことを示しています。
-xnor

@xnorが追加および修正されました;)
TheNumberOne

6
カントールはそれを見つけることができますか?
mbomb007

回答:


13

Mathematica、54バイト

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

名前のない関数は、分数x/yを入力として、where y > 0および0 ≤ x ≤ yを返し、Trueor を返しFalseます。

0から1の間の実数は、その基数3展開の数字が1に等しくない場合に正確にCantorセットにあります。例外は、分母が3の累乗である分数(したがって、基数3の展開が終了する)が1で終わることを許可されることです。

RealDigits[#,3][[1]]最後のリストは拡張の周期部分であり、整数は事前に周期性が始まる前の数字であるのに対し、小数入力の基数3の拡張のすべての数字を次の#ような形式で与え{1, 0, 2, {0, 1, 0, 2}}ます。base-3展開がすぐに周期的である場合、出力は次のようになり{{0, 1, 0, 2}}ます。base-3展開が終了する場合、形式は次のようになり{1, 0, 2}ます。

その~FreeQ~1ため、リストに1s がないかどうかをチェックします。ただし、展開が終了するため、リストの最後の要素が等しい場合は削除し1ます。それがIf[Last@#===1,Most@#,#]達成することです。(===潜在的なリストと1:を比較するために必要なのは==、その状況では単独で評価されないままです。)


4
MathematicaにはヤギIsCantorNumberはないが、それ何かを決定する機能があることに驚いた。
ブレインガイダー

3
実は、ヤギとフラクタルのどちらがより現実的なのでしょうか?;)
グレッグマーティン

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

このようなルールは1、周期部分の末尾のs も除去し、誤った答えを導きます。たとえば、7/8のベース3展開は.21212121 ....または{{2,1}};です。しかし、提案されたルールはそれを{{2}}に変更し1ます。
グレッグマーティン

Touché。どう#==0||FreeQ[RealDigits[#,3]/.{{x___,1},_}:>{x},1]&?終了し、ゼロ以外RealDigits[#,3]の形式の{{__Integer},-1}場合、繰り返しの場合、形式になり{{___Integer,{__Integer}},-1}ますか?私はモバイルですので、今はテストするのが難しいです。これが機能する場合、インフィックス表記法を使用しRealDigitsても同様に機能する可能性があります。
ngenisis


7

ゼリー22 17 16 15バイト

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

プリント3 truthy、falsyのため何のために。

オンラインでお試しください!

バックグラウンド

Cantorセットのよく知られた特性は、3進展開で1なしで記述できる0から1までの数字を正確に含むことです。

いくつかの数値(正確にはセットの構築に含まれる閉じた間隔の右端)は、単一の(末尾)1または無限の末尾2で書き込むことができます。たとえば、1 = 1 3 = 0.22222… 3および1/3 = 0.1 3 = 0.022222… 3で0.5 10 = 0.499999… 10と同じです

右端の特別なケースを避けるために、1がx / y1-x / y =(y-x)/ yの両方で最も短い10進展開であるかどうかをチェックできます。ここでx / yは右端iffです。(y-x)/ yは左端です。それらの少なくとも一つが全く含まれていない場合には1のが、X / Yは、カントール集合に属しています。

使い方

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

3真のtrue+1です。
魔法のタコUr

3

JavaScript(ES6)、65 67

2バイト保存された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

少ないゴルフ

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
}

テスト

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


私はあなたが交換することができると思うn=n%d*3q=n/d|0、次に置き換えるz[n]z[n=n%d*3]
ルーク

2

JavaScript(ES6)、55バイト

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

最初に分母を、次に分子をカリー化して使用します。標準形式は1バイト長くなります。

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

説明

分数がカンターセットに含まれていない場合、ある時点で中間セクションのいずれかに分類する必要があります。したがって、基数3の表現には、1の後にゼロ以外の数字が続く必要があります。それがこれの仕組みです:

  • z 1が見つかったかどうかを追跡します。
  • q は、基数3の現在の数字です。
  • !z|!qzfalse(1が見つからない)またはqfalse(現在の桁が0)の場合、trueです。

場合はnゼロに流れ落ちるが、我々は1の後に非ゼロ桁のどこかを見つける前に、端数はカントール集合であり、我々は返します1


2

Bash + GNUユーティリティ、62バイト

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

オンラインでお試しください!

arg1 <= arg2および0 <arg2の2つの整数引数を渡します。

出力は、PPCG I / Oメソッドで許可されているように、終了コード(偽の場合は0、真実の場合は1)で返されます

grep -zを使用してtrコマンドを削除することもできますが、これは私が考え出した中で最短です。(残念ながら、grep -zはgrep -Pと互換性がなく、?!構文にはperlスタイルの正規表現を取得する-Pオプションが必要です。)

テストベッドプログラムと出力:

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

説明

dc部分(引数はxおよび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およびgrep部分:

マイナーな問題は、dcは任意の大きな整数を処理しますが、dcが大きな数を出力するとき、それを69文字の行に分割し、最後の行を除く各行がバックスラッシュで終わり、各行の後に改行があるということです。

trコマンドは、バックスラッシュと改行を削除します。これにより、1行だけになります。

grepコマンドは、perlスタイルの正規表現(GNU拡張である-Pオプション)を使用します。行に1が含まれ、その後に少なくともy 0または少なくともy 2が続かない場合、正規表現は一致し、文字列が終了します。

これは、有理数x / yの基数3表現の繰り返し部分が3進小数点の後の数字#y + 1から始まると見なせるため、Cantorセットにないとしてx / yを識別するために必要なものです。 、最大でy桁の長さです。


1

CJam(19バイト)

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

オンラインテストスイート

これは、スタック上で2つの引数を取り、スタック上0またはスタック上で残す匿名ブロック(関数)1です。それは分数x/yy3数桁に基数変換し、それらが含まない11接尾語の一部のみである場合に真を返すことで動作します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バイト

gu*3hS,G-QGQE0

私のCソリューションに基づいています。y最初の入力行、x2番目の行。

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

x/yがCantorセット内にある場合x0との間に留まりますy。そうでなければ、ある点xよりも大きくなりy、残りの反復で負の無限大に発散します。

オンラインでお試しください!


0

バッチ、91バイト

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

の最初のy-13桁をテストしx/yます。iテストされた桁数です。nの次の値ですx。(展開が終了するため)ゼロに達した場合、またはを見つけずに数字をテストしたj場合はtrueです。がtrueの場合、または次の数字がa である場合、true になり、その時点でループと出力を停止します。ny-11fj1j

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.