Bestimmen Sie, ob eine Zahl in Ihrem Quellcode 2017 ohne Primzahlen brüchig ist

41

Von all den Jahren, in denen ich diese Herausforderung gemeistert habe, war 2017 das erste Jahr, das eine Primzahl war. Die Frage wird also nach Primzahlen und ihren Eigenschaften sein.

Ihre Aufgabe ist es, ein Programm oder eine Funktion zu erstellen, die eine willkürlich große positive Ganzzahl als Eingabe verwendet und ausgibt oder zurückgibt, ob die Zahl 2.017-brüchig ist oder nicht, dh ob der größte Primfaktor in dieser Zahl 2.017 oder weniger ist.


Einige Beispieleingaben und ihre Ausgaben:

1 (has no prime factors)
true

2 (= 2)
true

80 (= 2 x 2 x 2 x 2 x 5)
true

2017 (= 2017)
true

2019 (= 3 x 673)
true

2027 (= 2027)
false

11111 (= 41 x 271)
true

45183 (= 3 x 15061)
false

102349 (= 13 x 7873)
false

999999 (= 3 x 3 x 3 x 7 x 11 x 13 x 37)
true

1234567 (= 127 x 9721)
false

4068289 (= 2017 x 2017)
true

Ihr Programm muss nicht buchstäblich trueund false- irgendwelche wahren oder falschen Werte ausgeben, und tatsächlich sind zwei verschiedene Ausgaben, die über wahre und falsche Fälle hinweg konsistent sind, in Ordnung.


Sie dürfen jedoch keine Primzahlen in Ihrem Quellcode verwenden. Es gibt zwei Arten von Primzahlen:

  • Zeichen oder Zeichenfolgen, die Primzahlliterale darstellen.

    • Die Zeichen 2, 3, 5, und 7sind illegal in Sprachen , in denen Zahlen gelten Token.

    • Die Nummer 141ist illegal, weil sie enthält 41, obwohl 1und 4sonst gültig sind.

    • Die Zeichen Bund D(oder bund d) sind in Sprachen, in denen sie normalerweise als 11 und 13 verwendet werden, wie z. B. CJam oder Befunge, illegal.

  • Zeichen, die Unicode-Werte mit dem höchsten Wert haben oder in ihrer Codierung Bytes mit dem höchsten Wert enthalten.

    • Die Zeichen %)+/5;=CGIOSYaegkmqsind in ASCII unzulässig, ebenso wie das Wagenrücklaufzeichen.

    • Das Zeichen óist in UTF-8 unzulässig, da die Codierung darin enthalten ist 0xb3. In ISO-8859-1 ist die Codierung jedoch einfach 0xf3, was zusammengesetzt ist und daher in Ordnung ist.

Der kürzeste Code, der in einer beliebigen Sprache für die oben genannten Aufgaben verwendet wird, gewinnt.

Joe Z.
quelle
Randnotiz: "zerbrechlich" ist eine Verbesserung, die in diesem Zusammenhang gegenüber dem althergebrachten "glatt" übernommen wird.
Greg Martin
1
Müssen wahrheitsgemäße und falsche Werte konsistent sein? Oder können sie variieren, solange sie wahr oder falsch sind?
Luis Mendo
10
Das Fehlen =schließt die meisten Standardsprachen aus ...
Neil
4
-1 für eine do X ohne Y Herausforderung. Es ist wirklich ziemlich trivial, versteckt hinter einer ziemlich unnötigen Reihe von Zeichenbeschränkungen
Downgoat
1
Ich mag es nicht, wenn sie beliebig groß sind. Es wäre besser, wenn sie auf 2 ^ 31-1 aufsteigen würden.
Bijan

Antworten:

37

Gelee , 8 Bytes

44‘²!*ḍ@

Probieren Sie es online! Beachten Sie, dass die Testfälle 11111 und höher für TIO etwas zu viel sind.

Nachprüfung

$ source="34,34,fc,82,21,2a,d5,40"
$ xxd -ps -r > 2017.jelly <<< $source
$ xxd -g 1 2017.jelly
0000000: 34 34 fc 82 21 2a d5 40                          44..!*.@
$ eval printf '"%d "' 0x{$source}; echo # Code points in decimal
52 52 252 130 33 42 213 64
$ test_cases="1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289"
$ for n in $test_cases; do printf "%11d: %d\n" $n $(jelly f 2017.jelly $n); done
      1: 1
      2: 1
     80: 1
   2017: 1
   2019: 1
   2027: 0
  11111: 1
  45183: 0
 102349: 0

Der Testfall 999999 wurde 13 Stunden lang ausgeführt. Ich bin pessimistisch in Bezug auf das Rechnen 2025! 4068289 ...

Wie es funktioniert

44‘²!*ḍ@  Main link. Argument: n

44        Yield 44.
  ‘       Increment to yield 45.
   ²      Square to yield 2025.
          Note that no integers in [2018, ..., 2025] are prime numbers.
    !     Take the factorial of 2025.
     *    Raise it to the n-th power.
          This repeats all prime factors in 2025! at least n times, so the result
          will be divisible by n if (and only if) all of its prime factors fall
          in the range [1, ..., 2025].
      ḍ@  Test the result for divisibility by n.
Dennis
quelle
22
Sie sind grausam gegenüber Zahlen. :)
Greg Martin
3
@ GregMartin Bah. Ich habe eine Antwort (in einer anderen Sprache) gesehen, bei der eine Eingabe der Größe 6 den Speicher für mehrere Stunden belastet und dann abstürzt. Ich werde einfach sagen: (2^n)!. Dies gilt auch für Eingaben in sechs Größen, aber zumindest sind die Eingaben in einem Dezimalalphabet und nicht in einem Binäralphabet.
John Dvorak
Sind das nicht 13 Bytes? Dennis, du hast so viel Ruf, dass ich sicher derjenige bin, der hier einen Fehler macht hahah ah
Albert Renshaw
7
@AlbertRenshaw In UTF-8 wären es in der Tat 13 Byte, aber Jelly verwendet eine benutzerdefinierte Codepage , die alle Zeichen, die es versteht, als ein einzelnes Byte codiert.
Dennis
3
@Dennis wusste, dass es eine Erklärung geben würde; sehr cool zu lernen, danke!
Albert Renshaw
11

Jelly , 8 Zeichen, 14 Byte UTF-8

Æf½ṀḤ<90

Probieren Sie es online!

Jelly verwendet normalerweise eine eigene Codepage für Programme. Die meisten seiner primitiven Buildins beginnen jedoch mit ÆCodepoint 13; nicht sehr hilfreich. Glücklicherweise unterstützt der Interpreter auch UTF-8, das eine freundlichere Codierung aufweist.

Nachprüfung

Dieses Programm erstellt in UTF-8 Hexdumps wie folgt:

00000000: c386 66c2 bde1 b980 e1b8 a43c 3930  ..f........<90

Überprüfung, dass alle Bytes zusammengesetzt sind:

$ for x in c3 86 66 c2 bd e1 b9 80 e1 b8 a4 3c 39 30; do factor $((0x$x)); done
195: 3 5 13
134: 2 67
102: 2 3 17
194: 2 97
189: 3 3 3 7
225: 3 3 5 5
185: 5 37
128: 2 2 2 2 2 2 2
225: 3 3 5 5
184: 2 2 2 23
164: 2 2 41
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Überprüfung, dass alle Unicode-Codepunkte zusammengesetzt sind:

$ perl -Mutf8 -E '$a = ord, print `factor $a` for split //, "Æf½ṀḤ<90"'
198: 2 3 3 11
102: 2 3 17
189: 3 3 3 7
7744: 2 2 2 2 2 2 11 11
7716: 2 2 3 643
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Das einzige als Zahl analysierte Token ist 90. Nichts von 9, 0und 90sind Primzahl.

Erläuterung

Die wichtigste mathematische Erkenntnis hier ist, dass 45² 2025 ist, was genau zwischen 2017 (das aktuelle Jahr) und 2027 (die nächste Primzahl) liegt. Wir können also die Quadratwurzel jedes Primfaktors der Zahl ziehen und sehen, ob einer größer als 45 ist. Leider können wir 45aufgrund des Literal nicht schreiben 5, also müssen wir ihn verdoppeln und stattdessen mit 90 vergleichen.

Æf½ṀḤ<90
Æf        In the list of prime factors,
  ½       taking the square root of each element
   Ṁ      then taking the largest element
    Ḥ     and doubling it
     <90  produces a result less than 90.

quelle
2
Benötigt Jelly kein Flag (1 Byte), um UTF-8 zu verwenden?
Luis Mendo
@ LuisMendo: Der Befehlszeilen-Interpreter funktioniert, aber der Interpreter bei Try It Online! ist anders konfiguriert und benötigt es nicht. In diesem Fall müssen Sie nur den Interpreter auswählen, der Ihr Programm so interpretiert, wie Sie es möchten. (In jedem Fall ist die fragliche Flagge uzusammengesetzt, es geht also nur darum, die Punktzahl zu ändern und nicht um etwas, das sie ungültig macht.)
10

Mathematica, 62 58 55 Bytes

Die letzten drei Bytes, die gespeichert wurden, sind Martin Ender zu verdanken!

#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&

Unbenannte Funktion, die ein positives ganzzahliges Argument verwendet und Trueoder zurückgibt False.

Rekursiver Algorithmus, #4<4der der wahre Basisfall ist (wir brauchen ihn nur, um Trueauf den Eingang 1 zurückzukehren, aber die zusätzlichen Basisfälle sind in Ordnung). Ansonsten berechnen wir den zweitkleinsten Divisor (der notwendigerweise Primzahl ist) der Eingabe mit Divisors[#][[6-4]]; Wenn es größer als 2024 ( 44*46) ist, beenden wir mit False, andernfalls rufen wir die Funktion rekursiv (mit #6set to #0) für die Eingabe dividiert durch diesen kleinen Primfaktor auf #(den wir als #^-1Zeiten der Eingabe ausdrücken müssen #4, da dies /nicht zulässig ist).

Strukturell die erste Hälfte #4<4||#<44*46&&#6[#^-1#4]&ist eine anonyme Funktion der sechs Argumente, mit Argumenten aufgerufen wird Divisors[#][[6-4]], Null, Null, #, Null, und #0; Dies soll das Verbot der Charaktere 2umgehen 3, und 5.

Vorherige Version, die durch Ersetzen vier Bytes gespeichert 8018-6000mit 44*46, inspiriert von ais523 Gelee Antwort (Martin Ender schien auch von einem ais523 Kommentar inspiriert):

#<4||Divisors[#][[6-4]]<44*46&&#0[Divisors[#][[6-4]]^-1#]&

Das war ziemlich unangenehm: Ich weiß immer noch nicht, wie ich eine Variable in Mathematica unter diesen Einschränkungen setzen kann! Sowohl =und die ein Setsind nicht zulässig. Vermeiden +und )war auch ein Problem, aber nicht zu schwer zu umgehen auf Kosten von mehr Bytes.

Greg Martin
quelle
Sie könnten möglicherweise einen Lambda-Parameter anstelle einer Variablen festlegen. (Das heißt, #2wäre auch nicht erlaubt, so dass Sie vorsichtig sein müssten, wie Ihre Lambdas verschachtelt sind, und das Fehlen von Klammern könnte dies schwierig machen.)
Durch die Implementierung des Vorschlags von @ ais523 werden drei Bytes gespart: Es werden #4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&eine Reihe von Warnungen ausgegeben, da jetzt versucht wird, Divisors[#][[2]]sicherzustellen, dass die Eingabe größer als 1 (oder 3) ist, das Ergebnis jedoch weiterhin korrekt ist.
Martin Ender
Oh man, das ist eine verdammte List.
Greg Martin
7

Haskell, 48 47 Bytes

\n->[snd$[product[1..44*46]^n]!!0`divMod`n]<[1]

Grundsätzlich eine Übersetzung von Dennis 'Jelly Antwort . xnor hat ein Byte gespeichert.

Wird […]!!0als Klammer verwendet, weil )gesperrt ist und snd+, divModweil min modund remgesperrt ist.

Lynn
quelle
Schöner Trick mit dem divMod! Ich denke du kannst das !!0<1mit ersetzen <[1]. Aber es sieht es , es zu benutzen kurzgeschlossen ist , divwie [\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46].
Xnor
Es gibt auch \n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]]Verwendungen, bei denen Ausgaben nur konsistent sein müssen.
Xnor
@ Xnor Fühlen Sie sich frei, diese als separate Antwort (en) zu posten, ich denke, sie unterscheiden sich ausreichend von meinen ^^
Lynn
6

Pyke, 10 8 7 9 Bytes

P_Z|hwMX<

Probieren Sie es hier aus!

1 Byte mit Dennis 'Methode zur Generierung von 2025 eingespart

P         -     factors(input)
 _        -    reversed(^)
  Z|      -   ^ or 0
    h     -  ^[0] or 1
        < - ^ < V
     wM   -  ⁴45 (ord("M")-32)
       X  -  ^**2
Blau
quelle
5

Brachylog , 9 10 Bytes

*$ph$r*<90

Probieren Sie es online!

Grundsätzlich mit dem gleichen Algorithmus wie meine andere Antwort. $phfindet den ersten ( h) Primfaktor ( $p); Dies ist der größte Primfaktor, da Brachylogs Primfaktorlisten vom größten zum kleinsten gehen. Dann nehme ich die Quadratwurzel ( $r), double ( *) und teste, ob es weniger als 90 ist ( <90).

Ich musste zuerst die Eingabe verdoppeln, weil 1 keine Primfaktoren (und damit keinen ersten Primfaktor) hat. Dies fügt einen zusätzlichen Primfaktor von 2 hinzu, der keinen Einfluss darauf hat, ob eine Zahl 2017 brüchig ist, aber einen Fehler bei der Behandlung von 1 verhindert.


quelle
5

Eigentlich 9 Bytes

τyM:44u²≥

Danke an Dennis für die vielen Bytes!

Probieren Sie es online!

Erläuterung:

τyM:44u²≥
τyM        largest prime factor of 2*input (doubled to deal with edge case of n = 1)
   :44u²   2025 (2027 is the next prime after 2017, so any number in [2017, 2026] can be used here - 2025 is very convenient)
        ≥  is 2025 greater than or equal to largest prime factor?
Mego
quelle
5

Mathematica, 66 74 Bytes

Vielen Dank an Dennis für den Hinweis, dass dies U+F4A1verboten ist.

Fold[Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]],0<1,Divisors@#]&

Erläuterung:

Divisors@#: Liste der ganzzahligen Teiler des ersten Arguments #.

0<1: Golf für True(vermeidet auch die Verwendung des Buchstabens e).

Divisors@d^0: Liste des Formulars {1, 1, ..., 1}mit der Länge gleich der Anzahl der Teiler von d.

Tr: Gibt für eine flache Liste Trdie Summe dieser Liste zurück. So Tr[Divisors@d^0]gibt die Anzahl der Teiler von d.

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]: Anonyme Funktion mit zwei Argumenten xund d. Die Idee ist, dass dies dein Teiler von ist #und wir testen, ob es entweder zusammengesetzt oder kleiner oder gleich 2017(einschließlich) ist. 2017-Die Brüchigkeit entspricht allen Teilern, die diese Bedingung erfüllen. Wie ais523 herausgefunden hat , ist Primzahl kleiner oder gleich 2017Primzahl kleiner als 2025. Wie Greg Martin betonte, reicht es aus, zu testen, ob es weniger ist als 2024=44*46. Das Argument xdient als Akkumulator dafür, ob alle bisher angetroffenen Divisoren diese Eigenschaft erfüllen. FoldDiese Funktion haben wir dann durch alle Teiler von #mit Startwert verlassenTrue, da wir weder Zugang haben Mapnoch /@.

Genisis
quelle
1
Weg, um die Einschränkungen zu überwinden!
Greg Martin
2

05AB1E , 10 Bytes

fθ46n99-›È

Gibt 1 zurück, wenn wahr, andernfalls 0.

Probieren Sie es online!

Erläuterung

f          # Push the list of prime factors (ordered)
 θ         # Get the last element
  46n99-   # Push 2017 (46² - 99)
        >  # Push 1 if the last prime factor is greater than 2017, 0 otherwise
         È # Is the resulting number even ? Transforms 1 to 0 and 0 to 1.
           # Implicit display
Kaldo
quelle
Willkommen bei PPCG!
Martin Ender
1

MATL , 15 Bytes

t:\~ftZp*44QU<A

Ausgänge 0für Nicht-2017-Bröckelig oder 1für 2017-Bröckelig.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Dieses Programm prüft, ob alle Bytes zusammengesetzt sind.

Erläuterung

t       % Implicit input n. Duplicate
:       % Range [1 2 ... n]
\       % Modulo. Gives 0 for divisors of n
~f      % Indices of zero values
t       % Duplicate
Zp      % Is-prime. Gives 1 for primes, 0 for composites
*       % Multiply
44QU    % 44, add 1, square: 2025
<       % Less than, element-wise
A       % True (1) if all entries are nonzero
Luis Mendo
quelle
1

Bash, 144 Bytes

ASCII-Codierung:

{
printf '[ '
`tr D-Z _-z <<<KFH`tor $1|tr -d :|`tr B-Z _-z <<<JUH`p -o '[0-9]*$'
printf ' -lt $[24*86-46] ]'
}|tr \\n \ |`tr B-Z _-z <<<EDVK`

Wie bei Shell üblich, zeigt der Exit-Code Erfolg (0) oder Misserfolg (nicht 0) an.

Dies ist effektiv eine andere Schreibweise von

[ factor $1|tr -d :|grep -o '[0-9]*$' -lt 2018 ]

Wir bekommen den größten Faktor mit factor $1|grep -o '[0-9]*$'; Das tr -d :ist zu Sonderfall für Eingabe = 1.

Der Ausdruck wird $[6*6*69-466]bis 2018 ausgewertet.

Es war schwierig, trdie Befehlsnamen zu verwenden und trotzdem die Befehlssubstitution zu verwenden. Ich konnte die Verschachtelungsform nicht verwenden $( ), also leitete ich das Ergebnis in eine andere Bash um.

Testergebnisse:

$ for i in 1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289; do printf '%d %s\n' $i `./105241.sh $i  && echo true || echo false`; done
1 true
2 true
80 true
2017 true
2019 true
2027 false
11111 true
45183 false
102349 false
999999 true
1234567 false
4068289 true

Bestätigung der Zeichencodes:

$ grep -v '^#' ./105241.sh | perl -n -Mutf8 -E '$a = ord, print `factor $a` for split //, $_' | grep -v ': .* ' | wc -l
0
Toby Speight
quelle
0

Japt , 14 Bytes

k æ¨44*46 ?0:1

Gibt 1 zurück, wenn wahr, 0, wenn falsch.

Probieren Sie es hier aus .

Oliver
quelle
khat einen Primwert
Verkörperung der Ignoranz
0

Braingolf , 11 Bytes [sehr nicht konkurrierend]

VRp#ߢ-?0:1

Probieren Sie es online!

Unleserlich wegen der ߢwelche Schrauben mit den Nummern, funktioniert aber noch in einem Interpreter.

Ich habe die Zeichenbeschränkungen nicht einmal bemerkt, als ich das geschrieben habe, aber alles, was ich tun musste, war, das seltsame Unicode-Zeichen von 2017 auf 2018 zu ändern.

Da 2018 keine Primzahl <= 2018ist , ist auch keine Primzahl<= 2017

Erläuterung

VRp#ߢ-?0:1  Implicit input from command-line args
VR            Create stack2, return to stack1
  p           Split last item into prime factors, push each one to stack in asc order
   #ߢ         Push 2018
     -      Subtract last 2 items (highest prime factor - 2017)
      ?     If last item > 0..
       0    ..push 1
        :   Else..
         1  ..Push 1
            Implicit output of last item on stack
Skidsdev
quelle