Teilen und teilen und erobern


22

Manchmal, wenn ich müßig versuche, die vor mir auftauchende Zahl zu berücksichtigen¹, merke ich nach einer Weile, dass es einfacher ist, als ich dachte. Nehmen wir 2156zum Beispiel: Irgendwann fällt mir ein, dass beide 21und ein 56Vielfaches von sind 7, und so sicherlich 2156 = 21 x 100 + 56auch ein Vielfaches von 7.

Ihre Aufgabe ist es, einen Code zu schreiben, der Zahlen identifiziert, die aufgrund eines solchen Zusammentreffens leichter zu faktorisieren sind.

Etwas präziser:

Schreiben Sie ein Programm oder eine Funktion mit einer positiven Ganzzahl n als Eingabe verwendet und einen Wahrheitswert zurückgibt, wenn ein Divisor d(größer als 1) vorhanden nist, der in zwei Teile geteilt werden kann, um zwei positive Ganzzahlen zu erhalten, von denen jede ein Vielfaches von ist d. Wenn nicht, wird ein falscher Wert zurückgegeben.

  • "In zwei Hälften geteilt" bedeutet, was Sie denken: Die übliche Basis-10-Darstellung unterteilt sich nirgendwann in eine vordere und eine hintere Hälfte, um zwei weitere Basis-10-Ganzzahlen zu erhalten. Es ist in Ordnung, wenn die zweite Ganzzahl eine führende Null hat (beachten Sie jedoch, dass es sich um eine positive Ganzzahl handeln muss, sodass die Aufteilung 1230in 123und 0ungültig ist).
  • Die Wahrheits- und Falschheitswerte können von der Eingabe abhängen. Wenn beispielsweise eine Ganzzahl ungleich Null in der Sprache Ihrer Wahl wahr ist, können Sie den Teiler doder eines der "Teile" von n(oder sich nselbst) zurückgeben.
  • Zum Beispiel {2, 4, 6, 8}ergibt jede gerade Zahl mit mindestens zwei Ziffern im Satz einen Wahrheitswert: Teilen Sie ihn einfach nach der ersten geraden Ziffer. Zum Beispiel nliefert jede Primzahl ebenso wie jede einstellige Zahl einen falschen Wert.
  • Beachten Sie, dass es ausreicht, Primteiler zu berücksichtigen d.
  • Sie können davon ausgehen, dass die Eingabe gültig ist (dh eine positive Ganzzahl).

Das ist , also gewinnt der kürzeste Code in Bytes. Lösungen in allen Sprachen sind jedoch willkommen, sodass wir in jeder Sprache den kürzesten Code anstreben können, nicht nur den kürzesten Code insgesamt.

Testfälle

(Sie müssen nur einen Wahrheitswert oder einen falschen Wert ausgeben. Die folgenden Anmerkungen dienen lediglich der Erläuterung.) Einige Eingaben, die Wahrheitswerte liefern, sind:

39  (3 divides both 3 and 9)
64  (2 divides both 6 and 4)
497  (7 divides both 49 and 7)
990  (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233  (11 divides both 22 and 33)
9156  (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791  (13 divides both 117 and 91)
91015  (5 divides both 910 and 15)
1912496621  (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892  (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)

Einige Eingaben, die falsche Werte ergeben, sind:

52
61
130  (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300  (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803

¹ Ja, das mache ich wirklich

Antworten:


7

Retina , 31 29 Bytes


,$';$`
\d+
$*
;(11+)\1*,\1+;

Probieren Sie es online!

Gibt eine positive Ganzzahl für gültige Eingaben und eine Null für ungültige Einsen aus.

Ich würde nicht empfehlen, auf die größeren Testfälle zu warten ...

Erläuterung


,$';$`

Fügen Sie an jeder Stelle der Eingabe ein Komma ein, dann alles vor dieser Stelle, dann ein Semikolon, dann alles nach dieser Stelle. Was macht das Es gibt uns alle möglichen Teilungen einer Zahl (geteilt durch ,, getrennt durch ;) und dann die Eingabe am Ende erneut. So Eingang 123wird

,123;1,23;12,3;123,;123
     ^     ^     ^

wo ich die ursprünglichen Eingabezeichen markiert habe (das Zeug, das nicht markiert ist, haben wir eingefügt). Beachten Sie, dass hierdurch ungültige Aufteilungen erstellt werden, die keine tatsächlichen Aufteilungen sind, und dass es auch nicht wichtig ist, ob die nachgestellte Komponente nur Nullen enthält. Wir vermeiden jedoch, diese später zu akzeptieren. Der Vorteil der Erstellung ungültiger Teilungen besteht darin, dass wir wissen, dass jede gültige Teilung ein ;vor und nach sich hat, sodass wir zwei Bytes an Wortgrenzen sparen können.

\d+
$*

Wandle jede Zahl in eine unäre um.

;(11+)\1*,\1+;

Passen Sie eine Aufteilung an, indem Sie beide Hälften als Vielfaches einer Zahl zuordnen, die mindestens 2 beträgt.


Kurze Frage zu Retina: Was macht die führende Newline?
HyperNeutrino

@HyperNeutrino Nun, die erste Zeile ist die erste Regex, mit der wir übereinstimmen, und wir möchten die leere Regex abgleichen, um die Ersetzung an jeder einzelnen Stelle zwischen den Zeichen einzufügen.
Martin Ender

Oh ok. Vielen Dank! Ich sollte mir Retina wahrscheinlich etwas genauer ansehen. da es weitgehend auf Regex basiert zu sein scheint, ist es möglicherweise gut für Probleme mit der Kolmogorov-Komplexität .
HyperNeutrino

Könnte die letzte Zeile sein;(11+)+,\1+;
Riley

@Riley, der nicht garantiert, dass das erste Segment ein Vielfaches desselben Faktors ist.
Martin Ender

6

Brachylog (2), 8 Bytes

~c₂ḋᵐ∋ᵐ=

Probieren Sie es online!

Erläuterung

~c₂ḋᵐ∋ᵐ=
~c₂       Split the input into two pieces
    ᵐ ᵐ   On each of those pieces:
   ḋ ∋      Choose a prime factor
       =  such that both the chosen factors are equal

Wenn dieselbe Zahl (größer als 1) beide Teile teilt, teilt dieselbe Primzahl beide Teile. Das Erfordernis, dass der Faktor Primzahl ist, verbietet 1 als Faktor. Außerdem wird verhindert, dass ein Literal 0als Segment einer Zahl ausgewählt wird (da 0es keine Primfaktorisierung gibt und dies zum Fehlschlagen führt).

Es ist nicht erforderlich, nach übereinstimmenden internen Nullen zu suchen. Wenn eine Aufteilung von xund 0ygültig ist x0und ygenauso gut funktioniert (und umgekehrt, wenn x0und yfunktioniert, dann haben wir eine funktionierende Lösung, unabhängig davon, ob xund ob 0ynicht).

Ein volles Brachylog-Programm wie dieses gibt einen Booleschen Wert zurück. true.Wenn es eine Möglichkeit gibt, es ohne Fehler auszuführen (dh Entscheidungen so zu treffen, dass kein Fehler auftritt), false.wenn alle Pfade zu einem Fehler führen. Genau das wollen wir hier.


4

Jelly , 14 12 11 10 Bytes

ŒṖḌo1g/€P>

Vielen Dank an @JonathanAllan für das Abschlagen von 1 Byte!

Probieren Sie es online!

Wie es funktioniert

ŒṖḌo1g/€P>  Main link. Argument: n

ŒṖ          Compute all partitions of n's decimal digits.
  Ḍ         Undecimal; convert each array in each partition back to integer.
   o1       OR 1; replace disallowed zeroes with ones.
     g/€    Reduce (/) each (€) partition by GCD (g).
            The last GCD corresponds to the singleton partition and will always be
            equal to n. For a falsy input, all other GCDs will be 1.
        P   Take the product of all GCDs.
         >  Compare the product with n.

Ich denke du kannst das fallen lassen D, wie make_digitses in Kraft ist ŒṖ.
Jonathan Allan

Aus irgendeinem Grund bin ich davon ausgegangen, dass sich daraus ein Bereich ergibt ... Danke!
Dennis

3

Mathematica, 63 62 Bytes

(1 Byte danke an Greg Martin)

1<Max@@GCD@@@Table[1~Max~#&/@Floor@{Mod[#,t=10^n],#/t},{n,#}]&

Es ist eine Funktion, die eine Ganzzahl als Eingabe verwendet und Trueoder zurückgibt False. Wenn Sie es an einer großen Zahl testen, bringen Sie ein Buch zum Lesen mit, während Sie warten.

Erläuterung:

  • Floor@{Mod[#,t=10^n],#/t}Teilt die Eingabe arithmetisch in die letzten nund die verbleibenden m-nZiffern auf (wobei mdie Gesamtzahl der Ziffern ist).
  • Table[1~Max~#&/@...,{n,#}]Tut dies für jeden nbis zur eingegebenen Nummer. (Dies ist viel zu groß. Wir müssen dies nur bis zur Anzahl der Stellen der Eingabe tun , aber auf diese Weise werden Bytes gespeichert und es wird immer noch das richtige Ergebnis 1~Max~#&/@erzielt .) Das Bit wird von Nullen befreit, sodass Zahlen wie 130 -> {13,0}nicht zählen als True.
  • 1<Max@@GCD@@@... findet den größten gemeinsamen Teiler jedes dieser Paare und prüft, ob einer dieser Teiler größer als 1 ist.

1
Gute Antwort! Sie können ein Byte mit {#~Mod~10^n,#/10^n}oder speichern {Mod[#,t=10^n],#/t}.
Greg Martin

Ich habe es versucht #~Mod~10^n, aber es scheint, als würde es Mod[#,10]^nstattdessen in Klammern gesetzt Mod[#,10^n]. An Ihren zweiten Vorschlag habe ich allerdings nicht gedacht!
Kein Baum

fair point onMod[#,10]^n
Greg Martin


2

C 145 142 139 138 135 Bytes

i,a,b;f(){char s[99];scanf("%s",s);for(char*p=s;*p++;)for(b=atoi(p),i=*p,*p=0,a=atoi(s),*p=i,i=1;i++<b;)*s=a%i-b%i|b%i?*s:0;return!*s;}

2

JavaScript (ES6), 74 71 70 Byte

f=(s,t='',u)=>u?s%t?f(t,s%t,1):t:s&&f(t+=s[0],s=s.slice(1),1)>1|f(s,t)
<input oninput=o.textContent=f(this.value)><span id=o>

Übernimmt die Eingabe als String, was für das Snippet praktisch ist. Bearbeiten: 3 Bytes dank @ user81655 gespeichert.


Speichert zwei Bytes: (c,i)-> c, i+1-> ++i, t=''-> i=t='', dieser Trick ist nützlich, wann immer Sie benötigen 1-basierte Indizes zu verwenden , und irgendwo zu initialisieren haben izu 0.
user81655

Auch ich glaube t=''könnte sein t=0, da das Hinzufügen ces sowieso zu einer Zeichenfolge zwingt.
User81655

@ user81655 Das ist passiert, weil ich ursprünglich von und nach geschnitten habe i, also keine 1-basierten Indizes benötigt habe, aber dann habe ich das erste Stück nach Golf gespielt t+=c.
Neil

Ah, ok. Auch eine letzte Sache, ich denke , das ist auch kürzer als eine rekursive Funktion sein könnte: f=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0. Ich habe auch Ihre GCD-Funktion damit kombiniert f. Könnte wahrscheinlich weiter golfen werden. Letzter Vorschlag, das verspreche ich! : P
user81655

@ user81655 Leider gcdfunktioniert meine übervereinfachte Funktion nicht, wenn x=0, und das Umgehen und Ihr Tippfehler haben mich auf 72 Bytes gebracht, so dass ich glücklicherweise 2 Bytes weggolfen konnte.
Neil

2

Python 3, 133 118 117 Bytes

i,j=int,input()
from fractions import*
print(any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j))))

Mit Sicherheit nicht die kürzeste, könnte wohl etwas gekürzt werden. Funktioniert in der O(n)Zeit. Die Eingabe erfolgt im Format \d+und die Ausgabe erfolgt (True|False)standardmäßig im Format Python-Boolescher Wert
-3 Byte dank Dead Possum
-15 Byte dank Ovs
-1 Byte dank This Guy


from fractions import*würde 3 Bytes sparen
Dead Possum

Es gibt True für 900 zurück. Ich denke, das ist falsch. MB sollten Sie innere ändern anyzu all? In diesem Fall können Sie den gesamten Teil i(j[k:])and i(j[:k])auf 125 Byte ändern . Hier sind Korrekturen
Dead Possum

Sie können das und und alles durch Multiplikation ersetzen:any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
ovs

@DeadPossum Oh ja, das hätte ich tun sollen. Und ja, meine derzeitige Methode enthält viele Golf-Teile, aber ich werde den Vorschlägen von ovs folgen. Vielen Dank für den Hinweis! (Eigentlich hätte ich es selbst testen sollen ...
na ja

Sie können ein Byte (fast nichts) entfernen, indem Sie das Leerzeichen zwischen)) for
caird coinheringaahing am

1

QBIC , 91 bis 90 Bytes

;_LA|[a-1|B=left$(A,b)┘C=right$(A,a-b)┘x=!B!┘y=!C![2,x|~(x>1)*(y>1)*(x%c=0)*(y%c=0)|_Xq}?0

Erläuterung:

;               Get A$ from the command prompt
_LA|            Get the length of A$ and place it in a% (num var)
[a-1|           for b%=1; b% <= a%-1; b%++
B=left$(A,b)    break A$ in two components on index b%
C=right$(A,a-b)
x=!B!┘y=!C!     Convert both parts from string to num, assign to x% and y%
[2,x|           FOR c% = 2; c% <= x%; c%++

This next IF (~ in QBIC) is a bit ... iffy. It consists of a set of comparators.
Each comparator yields a -1 or a 0. We take the product of these. At any failed
comparison this will yield 0. When successful, it yields 1, which is seen as true by QBasic.

~(x>1)*(y>1)        IF X>1 and Y>1 --> this stops '00' and '1' splits.
*(x%c=0)*(y%c=0)    Trial divide the splits on loop counter c%.

|_Xq            Success? THEN END, and PRINT q (which is set to 1 in QBIC)
}               Close all language constructs (2 FOR loops and an IF)
?0              We didn't quit on match, so print 0


1

Perl 5 , 46 Bytes

43 Byte Code + 3 Byte für -pFlag.

s~~$\|=grep!($`%$_|$'%$_),2..$`if$`*$'~ge}{

Probieren Sie es online! oder versuchen Sie es mit dieser modifizierten Version, die mehrere Eingaben zulässt.
Sie möchten dies wahrscheinlich nicht bei der größten Eingabe versuchen, da dies eine (sehr lange) Zeit in Anspruch nehmen kann.

Erklärungen:
Wir durchlaufen jede Stelle im Wort mit s~~~g, wobei wir $`die Zahlen davor und $'die Zahlen danach enthalten. Wenn $`*$'wahr ist (es bedeutet, dass keiner leer ist und keiner leer ist 0), prüfen wir, ob eine Zahl zwischen 2 und $`dividiert beide (mit dem grep!(...),2..$`). Wenn ja, $\|=..wird der $\Wert auf einen Wert ungleich Null gesetzt, der am Ende dank -pFlag implizit ausgegeben wird .


2
Wenn jemand weiß, wie man einen $<backquote>Abschlag in SE rendert, wäre ich dankbar, wenn Sie mir sagen, wie.
Dada

1
Sie können dies tun, indem Sie explizit <code>... </code>(anstatt `... `) verwenden und dann die Anführungszeichen als maskieren \`. Dieser Kommentar war auch sehr schwierig zu schreiben, da er doppelt maskiert werden muss (und die beiden Regeln für die Maskierung sind unterschiedlich!).

@ ais523 Wundervoll, vielen Dank! :)
Dada

0

Python 2 , 69 Bytes

f=lambda n,d=10,k=2:k<d<n and(n/d%k+n%d%k<1<n%d)|f(n,d,k+1)|f(n,10*d)

Verwendet die Rekursion anstelle der integrierten GCD-Funktionen.

Probieren Sie es online!

Wie es funktioniert

Wenn f ist mit einem bis drei Argumente (genannt D standardmäßig auf 10 , k bis 2 ), prüft er zuerst den Wert des Ausdrucks k<d<n. Wenn die Ungleichungen k <d und d <n beide gelten, wird der folgende Ausdruck andausgeführt und sein Wert zurückgegeben. Andernfalls gibt f einfach Falsch zurück .

Im ersteren Fall beginnen wir mit der Auswertung des Ausdrucks n/d%k+n%d%k<1<n%d.

d wird immer eine Zehnerpotenz sein, so n/dund n%deffektiv die Dezimalziffern auf aufgeteilt n in zwei Scheiben. Diese Schichten sind beide genau dann durch k teilbar, wenn sie n/d%k+n%d%kzu 0 ausgewertet werden , was durch Vergleichen des Ergebnisses mit 1 überprüft wird .

Da es Teil der Anforderungen ist, dass beide Schichten positive ganze Zahlen darstellen müssen, wird der Wert von n%dauch mit 1 verglichen . Beachten Sie, dass 1 keine Primteiler hat, so dass der teurere Vergleich mit 0 nicht erforderlich ist. Beachten Sie auch, dass d <n dies bereits sicherstelltn/d eine positive Ganzzahl ausgewertet wird.

Schließlich rekursiv alle f(n,d,k+1)(versuchen Sie den nächsten potenziellen gemeinsamen Divisor) und f(n,10*d)(versuchen Sie die Aufteilung) und gibt das logische ODER aller drei Ergebnisse zurück. Diese Mittel f kehrt Wahr , wenn (und nur wenn) k ein gemeinsamer Teiler von ist n / d und n% d oder das gleiche gilt für einen größeren Wert von k und / oder einer höheren Potenz von zehn d .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.