Alle Quadrate, die einer Platzhalterfolge entsprechen [geschlossen]

9

Dies wurde von einem Teil des ARML-Wettbewerbs Team Problem # 6 2016 inspiriert.

Hier ist die Herausforderung:

Sie erhalten eine "Platzhalterfolge", bei der es sich um eine Folge von Ziffern und einem anderen Zeichen handelt. Eine Zeichenfolge entspricht dieser Platzhalterfolge mit dem folgenden Pseudocode:

w = wildcard
s = string
# s matches w iff
for all 0 >= i > wildcard.length, w[i] == '?' or s[i] == w[i]

Wo '?' ist ein Charakter Ihrer Wahl.

Stellen Sie sich in Bezug auf Regex das '?'vor '.'.

Die Herausforderung besteht darin, alle quadratischen Zahlen zu finden (die Anforderung beträgt bis zu 1 Million), deren Dezimalzeichenfolgen mit dieser Platzhalterfolge übereinstimmen. Das "Platzhalterzeichen" kann ein beliebiges ASCII-Zeichen Ihrer Wahl sein, sofern es sich offensichtlich nicht um eine Ziffer handelt.

Zum Beispiel 4096stimmt 4**6und stimmt 4*9*aber 4114auch nicht überein.

Eingang

Die Eingabe erfolgt als Sequenz, die dem regulären Ausdruck entspricht [0-9?]+. Dies kann eine Zeichenfolge, ein Zeichenarray oder ein Bytearray der Zeichen in ASCII sein.

Ausgabe

Die Ausgabe erfolgt durch eine beliebige Liste / Menge / Anordnung von Zahlen, die perfekte Quadrate sind und mit der Platzhalterfolge übereinstimmen.

Beispiele für gültige Eingaben:

1234567*90
1234567?90
1234567u90
['1', '2', '3', '4', '5', '6', '7', '*', '9', '0']
[49, 50, 51, 52, 53, 54, 55, 42, 57, 48]
[1, 2, 3, 4, 5, 6, 7, '*', 9, 0]

Beispiele für gültige Ausgaben:

[1, 4, 9]
1 4 9
1, 4, 9
1-4-9

etc.

Spezifikationen

  • Sie dürfen keine eingebauten Elemente verwenden, um eine Liste von Quadraten in einem bestimmten Bereich zu finden
  • Standardschlupflöcher gelten
  • Sie müssen in der Lage sein, bis zu 1 000 000 (1 Million) zu verarbeiten.
  • Wenn mit der Eingabe versehen 1******, ist das Drucken korrekt [1000000]. Es ist auch richtig zu drucken[1000000, 1002001, 1004004, 1006009, 1008016, 1010025, ...]
  • Platzhaltersequenzen beginnen niemals mit dem Platzhalterzeichen. Das heißt, sie stimmen immer mit Zeichenfolgen gleicher Länge überein.

Testfälle

4**6  ->  [4096, 4356]
1**1  ->  [1521, 1681]
1**  ->  [100, 121, 144, 169, 196]
9****9  ->  [908209, 915849, 927369, 935089, 946729, 954529, 966289, 974169, 986049, 994009]
9*9***  ->  [919681, 929296]
1**0*  ->  [10000, 10201, 10404, 10609, 12100, 14400, 16900, 19600]
9***4  ->  [91204, 94864, 97344]

Gewinnen

Kürzeste (gültige) (Arbeits-) Einreichung bis zum 14. Februar, Gleichstand durch frühesten Gewinner der Einreichung.

HyperNeutrino
quelle
1
Ich denke, ein guter Anfang, um dies klarer zu machen, wäre die Angabe, ?welche vom Antwortenden zu wählen ist.
FryAmTheEggman
2
Warum ist 25eine gültige Antwort für, ***aber nicht für *2*?
Neil
3
Ich denke, das wäre sauberer, wenn die Zahlen niemals führende Nullen hätten, also nur übereinstimmende Sequenzen ihrer Länge.
xnor
@Neil Das wäre ein Problem mit meiner eigenen Lösung. Ich werde Xnors Vorschlag annehmen.
HyperNeutrino
Kann die Eingabe ein Array aus einstelligen Ganzzahlen und dem Sonderzeichen wie {4, "w", "w", 6}(oder noch besser {4, w, w, 6}) sein, anstatt ein Array von Zeichen wie {"4", "w", "w", "6"}?
Greg Martin

Antworten:

0

05AB1E , 22 Bytes

Hier gibt es wahrscheinlich viel Raum für Verbesserungen.
Jede Nicht-Ziffer ist als Platzhalter in Ordnung.

3°LnvyS¹)ø€Æ0QPyg¹gQ&—

Probieren Sie es online aus!

Erklärung nach weiterem Golfen.

Emigna
quelle
Dies scheint für alle Eingänge zu funktionieren. Gut gemacht.
HyperNeutrino
1

Mathematica, 44 Bytes

Print@@@IntegerDigits[Range@1*^3^2]~Cases~#&

Die Eingabe ist eine Liste von Ziffern mit einem _(keine Anführungszeichen) als Platzhalter. z.B{4, _, _, 6}

Erläuterung

Range@1*^3

Liste erstellen {1, 2, 3, ... , 1000}

... ^2

Platziere es. (Liste aller Quadrate von 1 bis 1.000.000)

IntegerDigits[ ... ]

Teilen Sie jedes Quadrat in eine Ziffernliste.

... ~Cases~#

Suchen Sie diejenigen, die dem durch die Eingabe angegebenen Muster entsprechen.

Print@@@ ...

Drucken Sie sie aus.

JungHwan min
quelle
Dies scheint für alle Testfälle zu funktionieren. Gut gemacht.
HyperNeutrino
1

Brachylog , 23 Bytes

@e:{@$|,}a#0:{c.~^#I,}f

Probieren Sie es online aus!

Erläuterung

@e                        Split into a list of characters
  :{@$|,}a                Replace each digit char by the corresponding digit, and each things
                            that are ot digits into variables
          #0              All elements of the resulting list must be digits
            :{       }f   Output is the result of finding all...
              c.            ...concatenations of those digits which...
               .~^#I,       ...result in a number which is the square of an integer #I

Unterschiedliches Eingabeformat, 13 Bytes

Abhängig davon, was Sie als Eingabe für gültig halten, können Sie Folgendes tun:

#0:{c.~^#I,}f

Probieren Sie es online aus!

Dies ist im Grunde der zweite Teil der obigen Antwort mit einer Liste als Eingabe, die Ziffern und Variablen enthält, in denen sich die Platzhalter befinden.

Ich halte dies jedoch nicht für gültig, da es in Brachylog nur 26 Variablennamen gibt (Großbuchstaben). Dies würde also nicht funktionieren, wenn Sie mehr als 26 Wilcards hätten.

Fatalisieren
quelle
Dies scheint für alle Eingänge zu funktionieren. Gut gemacht. Ich würde dies jedoch als 24 Byte betrachten, da ein 1-Byte-Argument erforderlich ist. Ich bin mir nicht sicher, wie das Scoring dafür funktionieren würde.
HyperNeutrino
1
@AlexL. Das Argument gibt nur den Namen der Ausgabevariablen an (Sie können einen anderen Großbuchstaben verwenden, wenn Sie möchten). Dies ähnelt Antworten in Prolog / Sprachen mit Funktionen, bei denen das Prädikat / die Funktion benannt ist, Sie jedoch die Bytes, die Sie beim Aufrufen verwenden, nicht zählen.
Fatalisieren
Okay. Ich bin mir nicht sicher, ob man es mit 24 bewerten soll, da das Argument notwendig ist (andernfalls wird es nur zurückgegeben true.), aber ich habe noch keine Sprachen verwendet, die dies erfordern. Ich werde versuchen, eine Referenz zu finden, um zu bestimmen, wie ich dies bewerten soll, aber es wäre sinnvoll, es als 23 zu bewerten, also werde ich es dabei belassen.
HyperNeutrino
1

Perl 6 , 30 26 Bytes

Danke an @ b2gills für -4 Bytes!

{grep /^<$_>$/,map * **2,^1e4}

{grep /^<$_>$/,(^1e4)»²}

Verwendet den Punkt als Platzhalterzeichen, damit die Eingabe als regulärer Ausdruck verwendet werden kann:

{                            }   # a lambda
                         ^1e4    # range from 0 to 9999
               map * **2,        # square each value
 grep /      /,                  # filter numbers that match this regex:
        <$_>                     #   lambda argument eval'ed as sub-regex
       ^    $                    #   anchor to beginning and end

Probieren Sie es online aus .

Eine Variante, die das Sternchen als Platzhalter akzeptiert (wie in einer früheren Überarbeitung der Aufgabenbeschreibung vorgeschlagen), wäre 42 Byte:

{grep /^<{.trans("*"=>".")}>$/,(^1e4)»²}
smls
quelle
Ich habe die Regeln angepasst, und Sie können ein beliebiges Platzhalterzeichen auswählen. Ich bewerte dies als 38 Bytes.
HyperNeutrino
Ähm, wie benutzt du das? Ich weiß nichts über Perl.
HyperNeutrino
@AlexL.: Danke, ich habe die Antwort aktualisiert (und auch eine Erklärung hinzugefügt). Es ist ein Lambda; Sie können es direkt aufrufen (z. B. { ... }("9*9***")) oder einer Variablen / einem Symbol zur späteren Verwendung zuweisen. Beachten Sie, dass Perl 6 eine von Perl getrennte Sprache ist, sodass es mit einem Perl-Interpreter nicht funktioniert.
smls
Früher sudo apt-get install rakudohabe ich einen vermeintlichen Perl6-Interpreter bekommen ... Wenn ich perl6einen Befehl in mein Terminal eingebe, wird ein scheinbar Perl6-Interpreter gestartet, aber ich weiß nicht, wie ich ihn verwenden soll. Ich weiß, dass es ein Lambda ist, aber ich weiß nicht, wie ich es nennen soll.
HyperNeutrino
@AlexL.: Ich habe einen Link "Online testen" hinzugefügt, der es als vollständiges Skript anzeigt, als das Sie ausführen können perl6 foo.p6. Sie können es auch in einem Shell-Oneliner testen, wieperl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
smls
1

Ruby, 54 Bytes

Funktion, die ein String-Argument akzeptiert. Probieren Sie es online aus.

->s{(0..1e3).map{|i|"#{i**2}"[/^#{s.tr ?*,?.}$/]}-[p]}
Wert Tinte
quelle
Sie könnten ein Byte speichern, indem Sie i * i anstelle von i ** 2
GB
Dies scheint nicht zu funktionieren, da der zweite Teil #den Rest der Zeile zu einem Kommentar macht.
HyperNeutrino
@AlexL Oh, es funktioniert alles in Ordnung. repl.it/FJCV
Value Ink
ohhhh okay, ich wusste einfach nicht, wie ich Ruby testen soll. Entschuldigen Sie. Dies scheint für alle Eingaben zu funktionieren. Gut gemacht!
HyperNeutrino
0

Stapel, 109 Bytes

@for /l %%i in (0,1,999)do @set/aj=%%i*%%i&call copy nul %%j%%.%%j%%$>nul
@for %%s in (%1.%1$)do @echo %%~ns

Wird ?als Platzhalter verwendet. Funktioniert durch Erstellen von 1000 Dateien. Der Name der Datei ist die quadratische Nummer, und die Erweiterung der Datei ist die quadratische Nummer mit einem $Suffix. Dies liegt daran , Batch des Musterabgleich zählt nachlauf ?s als optional, so 1?passt auf beide 1und 16; das $zwingt daher die Übereinstimmung, genau zu sein. Wir möchten das jedoch nicht ausgeben $, daher geben wir den Dateinamen nur ohne Erweiterung aus.

Neil
quelle
0

JavaScript (ES6), 68 66 Byte

BEARBEITEN: Meine Lösung unten wurde aktualisiert, nachdem ich mich von der Antwort von JungHwan Min inspirieren ließ . Es ist jetzt ES6-kompatibel.

Nimmt Eingaben in dem Format vor, '1..4'in dem .sich der Platzhalter befindet.

Anstatt zu 1e6 zu iterieren und das Quadrat zu verwurzeln, iteriert dieses zu 1e3 und Quadraten.

p=>[...Array(1e3)].map((_,n)=>''+n*n).filter(n=>n.match(`^${p}$`))

JavaScript (ES7), 71 69 Bytes

p=>[...Array(1e6).keys()].filter(n=>n**.5%1?0:(''+n).match(`^${p}$`))

Erstellt ein Array von Zahlen von 0 bis 1e6 und filtert es dann nach Zahlen, die quadratisch sind und mit dem Muster übereinstimmen.

Es ist schrecklich langsam, weil es immer zu 1e6 iteriert.

George Reith
quelle
Ich denke nicht, dass **es funktioniert, weil es mir eine gibt "SyntaxError: expected expression, got '*'".
HyperNeutrino
@AlexL. Die Regeln scheinen sich geändert zu haben. Die vorherigen Regeln schlugen vor, dass ich das Platzhalterzeichen wählen könnte.
George Reith
Sie müssen nur bis zu 1e6...
HyperNeutrino
Außerdem habe ich die Regeln wieder geändert. Das Problem liegt nicht in den Regeln, sondern darin, dass der **Operator nicht existiert, zumindest nicht in meinem System.
HyperNeutrino
@AlexL. Tut mir leid, ich dachte du meinst die Eingabe **. Ja, es ist ES7. Ich werde den Titel aktualisieren. Hier ist eine Liste der derzeit unterstützten Browser. Developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
George Reith
0

Perl, 42 45 38 Bytes

EDIT: Klarstellung von Alex, wir können den Punkt als Platzhalterzeichen verwenden, das die y // -Operation abschneidet.

perl -pe 's|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

BEARBEITEN: Lösung, die das Sternchen als Platzhalterzeichen verwendet und die Platzhalterfolge auf STDIN erwartet

perl -pe 'y/*/./;s|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

Dieser lässt zweifellos viel Raum für Verbesserungen, es ist ziemlich einfach. Der Platzhalterausdruck wird als Befehlszeilenargument mit dem Punkt-Platzhalterzeichen erwartet (was noch?).

say"@{[grep/^$ARGV[0]$/,map$_*$_,1..1e3]}"
Daniel
quelle
Die Frage gibt an, dass Platzhalter als Sternchen angegeben werden. Hat eine frühere Überarbeitung der Frage die Auswahl Ihres eigenen Platzhalterzeichens ermöglicht?
smls
1
@smls: In der Frage wird weiterhin angegeben, ob Sie Ihren eigenen Platzhalter auswählen möchten, obwohl dies nicht im Regelabschnitt enthalten ist: Das als Platzhalter verwendete Zeichen muss nicht unbedingt ein Sternchen sein, es kann ein beliebiges ASCII-Zeichen Ihrer Wahl sein, solange es vorhanden ist ist offensichtlich keine Ziffer.
Emigna
Ja, das hat mich verwirrt. Später heißt es deutlich, dass das Platzhalterzeichen ein Sternchen sein muss. Ich denke, die Definition mit dem regulären Ausdruck ist führend. Ich werde meine Lösung überarbeiten.
Daniel
1
Hm eigentlich ist der von @Emigna zitierte Satz ziemlich klar, dass wir unseren eigenen Platzhalter wählen können , nicht wahr ?
smls
Zur Verdeutlichung kann das Platzhalterzeichen beliebig sein. Ich habe versehentlich die Regeln durcheinander gebracht, als ich die Erklärung neu formulierte.
HyperNeutrino
0

Python 3 - 98 97 Bytes

import re;print(re.findall(r"\b"+input()+r"\b",("\n".join([str(x*x) for x in range(1,1001)]))))

Benötigt Eingaben wie '4..6'.

Carra
quelle
Sie können 3 Bytes mit import reund speichern re.findall; Die Optimierung mit dem from...import *optimiert es in diesem Fall nicht wirklich.
HyperNeutrino
Vorausgesetzt 1...., es gibt 1 4 9und 16 25als gültige Antworten, was nicht korrekt ist. Bitte korrigieren Sie Ihr Programm.
HyperNeutrino
Korrigieren Sie den Fall, indem Sie auf "\ n" klicken.
Carra
Das funktioniert nicht für 1....... Es kehrt zurück [], aber es sollte geben [1000000]. Dies kann zu einem Preis von 0 Bytes behoben werden, indem range(0, 1001)anstelle von verwendet wird range(0, 1000).
HyperNeutrino
Guter Punkt, ich habe gerade alle Testfälle aus der Beschreibung überprüft :)
Carra
0

k - 28 Zeichen

{s(&:)($:s:s*s:!1001)like x}

Wird ?als Platzhalterzeichen verwendet. Die likeFunktion wird ?als Platzhalter verwendet. Diese Funktion erstellt eine Liste der ersten 1001 Quadrate (einschließlich 1M), wandelt sie alle in Zeichenfolgen um und überprüft dann, wo sie mit dem Muster übereinstimmen.

    {s(&:)($:s:s*s:!1001)like x} "1??"
100 121 144 169 196
C. Quilley
quelle
Ich bekomme diesen Fehler dafür : type error {s(&:)($:s:s*s:!1001)like x} "1" at execution instance 2 of ":". Könnten Sie einen Link zu einer funktionierenden Testsuite bereitstellen oder prüfen, ob ein Problem vorliegt?
HyperNeutrino
@AlexL. Es funktioniert für mich im k-Modus von kdb +
C. Quilley
Hmm. Ich werde versuchen, es mit verschiedenen Dolmetschern zu testen.
HyperNeutrino
0

Bash + Unix-Dienstprogramme, 33 Bytes

dc<<<'0[2^pv1+lax]dsax'|grep ^$1$

Dies verwendet '.' als Platzhalterzeichen.

Das DC-Programm druckt die quadratischen Zahlen in einer Endlosschleife:

0     Push 0 on the stack.

[     Start a macro (called a).

2^    Square the number at the top of the stack.

p     Print the number at the top of the stack, followed by a newline.

v     Replace the number at the top of the stack (a square number) with its square root.

1+    Increment the number at the top of the stack.

lax   Run the macro again (looping).

]     End of the macro.

dsax  Store the macro in register a and run it.

Die Gleichstromausgabe wird an grep weitergeleitet, wodurch nur die Quadrate gedruckt werden, die dem erforderlichen Muster entsprechen.

Dies funktioniert, wenn ich es auf einem tatsächlichen Linux- oder OS X-System ausführe (aber es funktioniert nicht bei TIO, wahrscheinlich weil das DC-Programm versucht, für immer zu rekursieren, und ich vermute, dass TIO nicht mehr genügend Speicherplatz für die Rekursion hat und / oder hat ein Problem mit der nie endenden Pipe).

Mitchell Spector
quelle
Ich verwende dies mit Linux Mint 17.3 Rosa und es wird nicht beendet. Ich denke, das Problem liegt im unendlichen dcBefehl.
HyperNeutrino
Ich vermute, es ist tatsächlich die Pufferung, die das Problem verursacht. Ich habe diese Linux-Version nicht, aber Sie könnten versuchen, das grep durch grep --line-buffered zu ersetzen (damit jede Zeile so gedruckt wird, wie sie grepped ist). [Natürlich fügt das eine Anzahl von Bytes hinzu.]
Mitchell Spector
Ich habe das grep-Argument hinzugefügt, aber es macht keinen Unterschied. Ich habe versucht, das --line-bufferedauf beiden Seiten des zu platzieren ^$1$, aber es funktioniert nicht so oder so.
HyperNeutrino
@ AlexL.Danke, dass du es versucht hast. Ich weiß nicht, ob der Unterschied im Kernel oder in der Bash-Version liegt, die ich verwende. Ich habe es in TIO zum Laufen gebracht, indem ich ein Ende der Eingabe von grep mit head wie folgt erzwungen habe: dc <<< '0 [2 ^ pv1 + lax] dsax' | head -1 sed s/./0/g<<<$1| grep ^ $ 1 $ Dies verwendet die Länge von Muster zur Begrenzung der getesteten Zahlen (4-stellige Muster prüfen nur bis zu 9999 usw.). Hier ist ein TIO-Link: tio.run/nexus/…
Mitchell Spector
Vielen Dank für das Update. Ich glaube nicht, dass die aktuelle Lösung tatsächlich funktionieren würde (obwohl ich nicht viel über Bash weiß), da es den Anschein hat, dass alle Werte berechnet werden müssen, bevor sie eingespeist werden grep. Da es sich derzeit jedoch nicht um die kürzeste Lösung handelt, werde ich sie für die Bewertung auf 33 Byte belassen. Es scheint für alle Eingaben zu funktionieren, also gute Arbeit!
HyperNeutrino