Liegt es im Cantor-Set?

20

Die Herausforderung

Für diese Herausforderung müssen Sie feststellen, ob eine bestimmte Nummer im Cantor-Set enthalten ist. Definieren wir zunächst die Cantor-Menge.

Beginnen Sie zunächst mit den Zahlen zwischen 0 und 1. Zahlen außerhalb dieses Bereichs sind nicht im Cantor-Set enthalten. Teilen wir nun die Zahlen in drei gleiche Teile: [0,1 / 3], [1 / 3,2 / 3], [2/3, 1]. Alle Zahlen, die nicht in den Bereichen des ersten und des letzten Parts liegen, sind nicht im Cantor-Set enthalten. Jetzt wiederholen Sie diesen Vorgang für die Segmente [0,1 / 3] und [2/3, 1]. Dann wiederholen Sie, was übrig bleibt. Du machst das immer weiter. Am Ende befinden sich alle verbleibenden Nummern im Cantor-Set. Hier ist ein Diagramm der ersten sechs Iterationen:

Kantorendiagramm


Eingang

Zwei Integer xund y.
0 < y < 2^15
0 <= x <= y
Der größte gemeinsame Nenner von xund yist 1, es sei denn x == 0.


Ausgabe

Die Wahrheit ist, wenn sie x/yim Cantor-Set enthalten ist.
Falsch, wenn x/ynicht im Cantor-Set.


Beispiele

Sehen wir uns nun einige Beispiele für Zahlen im Cantor-Set an.

1/3 -> true  

Es befindet sich an einer Grenze, und Grenzen werden niemals aufgehoben.

1/4 -> true  

1/4befindet sich nie im mittleren Drittel eines Segments, obwohl es sich auch nie an der Grenze befindet. Wenn Sie diesem Pfad folgen, werden Sie feststellen, dass er sich abwechselnd im ersten und letzten Drittel eines Abschnitts befindet.

1/13 -> true  

1/13 wechselt zwischen dem ersten, ersten und letzten Abschnitt.

1/5 -> false

1/5 fällt in den ersten leeren Block der dritten Zeile im obigen Diagramm zwischen 1/9 und 2/9.

Andere Testfälle:

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

Sie können mit diesem Snippet auch andere Nummern ausprobieren:


Zielsetzung

Die Person mit den wenigsten Bytes gewinnt.

Die Nummer eins
quelle
Sind wir garantiert, dass die Eingabe nicht (0,0) ist? Wird der Bruch in einfachster Form angegeben?
xnor
1
@xnur den für y angegebenen Bereich betrachten. Ich werde sagen, dass der Bruch in der einfachsten Form ist, es sei dennx == 0
TheNumberOne
Einige Testfälle mit x! = 1 wären gut. Außerdem steht in Ihrem Snippet, dass 1/3 nicht im Kantorsatz enthalten ist.
xnor
@xnor Hinzugefügt und behoben;)
TheNumberOne
6
Cantor kann es gefunden werden?
mbomb007

Antworten:

13

Mathematica, 54 Bytes

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

Unbenannte Funktion, die einen Bruch x/yals Eingabe verwendet, wo y > 0und 0 ≤ x ≤ yund zurück Trueoder False.

Eine reelle Zahl zwischen 0 und 1 wird im Cantor genau dann festgelegt, wenn keine der Ziffern in der Erweiterung zur Basis 3 gleich 1 ist. Die Ausnahme ist, dass ein Bruch, dessen Nenner eine Potenz von 3 ist (dessen Basis-3-Erweiterung daher endet), mit einer 1 enden darf.

RealDigits[#,3][[1]]Gibt alle Ziffern in der Basis-3-Erweiterung der gebrochenen Eingabe #in einer Form wie {1, 0, 2, {0, 1, 0, 2}}folgt an: Die letzte Liste ist der periodische Teil der Erweiterung, während die Ganzzahlen zuvor die Ziffern sind, bevor die Periodizität beginnt. Wenn die Basis-3-Erweiterung sofort periodisch ist, ist die Ausgabe ähnlich {{0, 1, 0, 2}}; Wenn die Base-3-Erweiterung beendet wird, ist die Form ähnlich{1, 0, 2} .

Wir wollen also überprüfen, ~FreeQ~1ob die Liste frei von 1s ist oder nicht. Aufgrund der abschließenden Erweiterung möchten wir jedoch das letzte Element der Liste löschen, wenn es gleich ist 1. das ist es, was If[Last@#===1,Most@#,#]erreicht. (Das ===wird benötigt, um eine potenzielle Liste zu vergleichen mit 1: ==allein bleibt in dieser Situation unbewertet.)

Greg Martin
quelle
4
Ich bin überrascht, dass Mathematica keine IsCantorNumberFunktion hat, um festzustellen, ob es sich bei etwas um eine Ziege handelt .
Brain Guider
3
Nun, ich weiß nicht, was im wirklichen Leben häufiger vorkommt: Ziegen oder Fraktale? ;)
Greg Martin
FreeQ[RealDigits[#,3][[1]]/.{{x___,1}}:>{x},1]&
Genisis
Eine solche Regel würde auch nachfolgende 1s im periodischen Teil entfernen, was zu falschen Antworten führt. Beispielsweise ist die Basis-3-Erweiterung von 7/8 .21212121 .... oder {{2,1}}; aber die vorgeschlagene Regel würde das ändern {{2}}, was frei von 1s ist, aber nicht sein sollte.
Greg Martin
Touché. Wie wäre es #==0||FreeQ[RealDigits[#,3]/.{{x___,1},_}:>{x},1]&? Wenn es beendet wird und nicht Null ist, RealDigits[#,3]wird es von der Form sein {{__Integer},-1}und wenn es wiederholt wird, wird es von der Form sein {{___Integer,{__Integer}},-1}, richtig? Ich bin auf dem Handy, daher ist es schwer, es gerade zu testen. Wenn dies funktioniert, funktioniert RealDigitsmöglicherweise auch die Verwendung der Infix-Notation für .
Genisis
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;}

Nutzt die Symmetrie des Cantor-Sets. Unterbricht nach yIterationen, um eine Endlosschleife zu vermeiden.

Probieren Sie es online!

nwellnhof
quelle
7

Jelly , 22 17 16 15 Bytes

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

Druckt 3 für wahr, nichts für falsch.

Probieren Sie es online!

Hintergrund

Eine bekannte Eigenschaft der Cantor-Menge ist, dass sie genau die Zahlen zwischen 0 und 1 enthält , die ohne 1 geschrieben werden können ‚s in ihrer ternären Expansion.

Beachten Sie, dass einige Zahlen - genau die rechten Kanten der geschlossenen Intervalle, die an der Konstruktion der Menge beteiligt sind - entweder mit einer einzelnen (nachgestellten) 1 oder mit einer unendlichen Anzahl von nachgestellten 2 geschrieben werden können . Zum Beispiel ist 1 = 1 3 = 0,22222… 3 und 1/3 = 0,1 3 = 0,022222… 3 , genauso wie 0,5 10 = 0,499999… 10 .

Um zu vermeiden, dass die rechten Kanten speziell umschlossen werden, können wir prüfen, ob 1 die kürzeste Dezimalexpansion in x / y und 1 - x / y = (y - x) / y ist , wobei x / y eine rechte Kante ist, wennf (y - x) / y ist eine linke Kante. Wenn mindestens eine von ihnen keine 1 enthält , gehört x / y zum Cantor-Set.

Wie es funktioniert

,ạµ%⁹×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].
Dennis
quelle
3ist die wahre true+1.
Magic Octopus Urn
3

JavaScript (ES6), 65 67

Bearbeite 2 Bytes gespeichert dank @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

Weniger golfen

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
}

Prüfung

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

edc65
quelle
Ich denke, Sie können ersetzen n=n%d*3durch q=n/d|0und dann ersetzen z[n]durchz[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

Verwenden Sie, indem Sie zuerst den Nenner und dann den Zähler eingeben. Die Standardform ist ein Byte länger:

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

Erläuterung

Wenn ein Bruch nicht im Cantor-Satz enthalten ist, muss er irgendwann in einen der mittleren Abschnitte fallen. Daher muss seine Darstellung in Basis 3 eine 1 enthalten, auf die irgendwann eine Ziffer ungleich Null folgt. So funktioniert das:

  • z Verfolgt, ob wir eine 1 gefunden haben.
  • q ist die aktuelle Ziffer in Basis 3.
  • !z|!qist wahr, wenn zfalsch (wir haben keine 1 gefunden) oder qfalsch (die aktuelle Ziffer ist 0).

Wenn nder Wert auf Null abfällt, bevor wir irgendwo nach einer 1 eine Ziffer ungleich Null finden, befindet sich der Bruch in der Cantor-Menge und wir kehren zurück 1.

ETHproductions
quelle
2

Bash + GNU-Dienstprogramme, 62 Bytes

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

Probieren Sie es online!

Übergeben Sie zwei ganzzahlige Argumente mit arg1 <= arg2 und 0 <arg2.

Die Ausgabe wird im Exit-Code (0 für falsch, 1 für wahr) zurückgegeben, wie dies in PPCG-E / A-Methoden zulässig ist .

Ich vermute, dass die Regex weiter verbessert werden kann, vielleicht sogar, indem der Befehl tr zugunsten der Verwendung von grep -z gestrichen wird, aber dies ist der kürzeste, den ich mir einfallen lassen konnte. (Leider ist grep -z nicht mit grep -P kompatibel, und die Option -P zum Abrufen von regulären Ausdrücken im Perl-Stil ist für die?! -Syntax erforderlich.)

Testprogramm und Ausgabe:

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

Erläuterung

dc part (die Argumente sind x und 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 und grep Teil:

Ein kleines Problem ist, dass dc zwar willkürlich große Ganzzahlen verarbeitet, diese aber beim Drucken einer großen Zahl in 69-stellige Zeilen aufteilt, wobei jede Zeile mit Ausnahme der letzten mit einem Backslash endet und nach jeder Zeile eine neue Zeile.

Der Befehl tr löscht alle Backslashes und Newlines. Dies lässt nur eine einzige Zeile.

Der Befehl grep verwendet dann einen regulären Ausdruck im Perl-Stil (-P-Option, eine GNU-Erweiterung). Der reguläre Ausdruck stimmt überein, wenn die Zeile eine 1 enthält, nicht gefolgt von mindestens y 0 oder mindestens y 2, die dann die Zeichenfolge beenden.

Genau dies ist erforderlich, um x / y als nicht in der Cantor-Menge enthalten zu kennzeichnen, da der sich wiederholende Teil der Basis-3-Darstellung der rationalen Zahl x / y so angesehen werden kann, dass er bei Ziffer # y + 1 nach dem ternären Punkt beginnt und ist höchstens y Ziffern lang.

Mitchell Spector
quelle
1

CJam (19 Bytes)

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

Online-Testsuite

Dies ist ein anonymer Block (eine Funktion), der zwei Argumente auf den Stapel nimmt und 0oder 1auf den Stapel verlässt . Es funktioniert durch die Basis , um die Fraktion Umwandlung x/yin yBasis 3Ziffern und gibt true zurück , genau dann , wenn sie nicht enthalten 1oder nur einen 1Teil eines Suffix ist 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
}
Peter Taylor
quelle
1

Pyth , 14 Bytes

gu*3hS,G-QGQE0

Basierend auf meiner C-Lösung. yin der ersten Eingabezeile, xin der zweiten.

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

Ob x/y innerhalb des Cantor-Satzes, xbleibt zwischen 0und y. Sonst xwird größer alsy an einem Punkt und weicht in den verbleibenden Iterationen nach negativ unendlich ab.

Probieren Sie es online!

nwellnhof
quelle
0

Batch, 91 Bytes

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

Testet die ersten y-13 Stellen der Basis von x/y. iist die Anzahl der getesteten Ziffern. nist der nächste Wert von x. jist wahr, wenn nNull erreicht wird (weil die Erweiterung beendet ist) oder wir y-1Ziffern getestet haben, ohne a zu finden 1. fist wahr, wenn jwahr ist oder wenn die nächste Ziffer a ist 1, an welchem ​​Punkt wir aufhören, eine Schleife zu bilden und auszugeben j.

Neil
quelle