Die Knight Numbers eines Numpads


33

Für die Ziffern ungleich Null auf einem Standard- Nummernblock

789
456
123

Stellen Sie einen Schachritter auf eine beliebige Ziffer und bewegen Sie ihn mit einer beliebigen Anzahl von normalen L-förmigen Sprüngen, wobei Sie eine positive Dezimalzahl nachzeichnen. Welche positiven ganzen Zahlen können so ausgedrückt werden?

Einer von ihnen ist 38, dass der Ritter auf der anfangen 3und sich nach links und nach oben bewegen könnte 8. 381und 383sind auch möglich.

3selbst ist möglich, wenn keine Sprünge gemacht werden (was erlaubt ist). 5ist auch, aber es können keine anderen Ziffern von der aus erreicht werden 5, so dass es die einzige Zahl ist, bei der die Ziffer 5erscheint.

Schreiben Sie ein Programm oder eine Funktion, die eine positive Dezimalzahl enthält (Sie können diese auch als Zeichenfolge verwenden) und einen Wahrheitswert ausgeben oder zurückgeben , wenn die Zahl auf die beschriebene Weise von einem Ritter auf einem Nummernblock ausgedrückt werden kann, ansonsten aber ausgegeben wird ein falscher Wert.

Der kürzeste Code in Bytes gewinnt. Tiebreaker ist frühere Antwort

Beispiele

Wahrheit:

1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276

Falsch:

10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760

2
Was ist heute mit Schachrittern ? :-D
Luis Mendo

1
Tipp: Wenn Sie die Zahlen als Umbruchzeile ausschreiben, springt der Springer immer entweder vier Felder im Uhrzeigersinn oder vier Felder gegen den Uhrzeigersinn. Ich weiß nicht, ob das hilfreich ist.
Nic Hartley

3
@ LuisMendo Wrapping. Wie in, wenn Sie als endlose Liste behandeln 78963214, immer und immer wieder wiederholt. Zählen Sie die Entfernungen - es sind immer vier, so oder so. Ich hätte klarer sein und ausdrücklich sagen sollen, dass Sie es in Kreisreihenfolge schreiben müssen.
Nic Hartley

@QPaysTaxes Oh, ich dachte du meinst doch Kreis 123...9. Entschuldigung
Luis Mendo

@ LuisMendo Keine Sorge. Wie gesagt, ich hätte klarer sagen sollen, was ich meinte.
Nic Hartley

Antworten:


16

Jelly, 19 15 14 Bytes

Doȷ’d3ạ2\P€=2P

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

Wie es funktioniert

Doȷ’d3ạ2\P€=2P  Main link. Argument: n (integer)

D               Convert n to base 10 (digit array).
  ȷ             Yield 1000.
 o              Logical OR. This replaces each 0 with 1000.
   ’            Decrement each digit.
    d3          Divmod; replace each digit k with [k:3, k%3].
      ạ2\       Pairwise reduce by absolute difference.
                For each pair of adjacent digits [i, j], this computes
                [abs(i:3 - j:3), abs(i%3 - j%3)].
         P€     Compute the product of each result.
                n is a Numpad's Knight Number iff all products yield 2.
           =2   Compare each product with 2.
             P  Multiply the resulting Booleans.

18

Python 2, 52 Bytes

f=lambda n:n<6or`n%100`in'18349276167294381'*f(n/10)

Überprüft, ob zwei aufeinanderfolgende Ziffern in der Zeichenfolge enthalten sind '18349276167294381'. Um aufeinanderfolgende Ziffern zu erhalten, zip(`n`,`n`[1:])überprüft die Funktion wiederholt die letzten beiden Ziffern und entfernt die letzte Ziffer.


13

Retina , 58 40 Bytes

Vielen Dank an Sp3000 für diesen Vorschlag:

M&!`..
O%`.
A`16|18|27|29|34|38|49|67
^$

Probieren Sie es online! (Leicht modifiziert, um die gesamte Testsuite gleichzeitig auszuführen.)

Druck 1für truthy und 0für falsy Ergebnisse.

Erläuterung

M&!`..

Finden Sie alle überlappenden Übereinstimmungen .., dh alle aufeinander folgenden Ziffernpaare, und verbinden Sie sie mit Zeilenvorschüben.

O%`.

Sortieren Sie die Ziffern in jeder Zeile, so dass nur halb so viele Paare überprüft werden müssen.

A`16|18|27|29|34|38|49|67

Entfernen Sie alle Zeilen, die einem gültigen Zug entsprechen.

^$

Zähle die Übereinstimmungen dieses Regex. Das heißt, wenn alle Zeilen entfernt wurden, stimmt dies einmal mit der resultierenden leeren Zeichenkette überein, andernfalls stimmt es nicht überein und gibt stattdessen Null.



7

Ruby, 57 Bytes

Anonyme Funktion. Argument ist eine Zeichenfolge.

->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

Programm mit der Testsuite:

f=->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

a=%w{1 2 3 4 5 6 7 8 9 16 18 38 61 81 294 349 381 383 729 767 38183 38383 18349276 183492761 618349276
10 11 50 53 55 65 95 100 180 182 184 185 186 187 188 189 209 305 2009 5030 3838384 4838383 183492760}

a.each {|e|p [e, f[e]]}

Ich habe gerade alle möglichen Springerzüge in eine Zeichenfolge codiert und überprüft, ob alle 2 Ziffern in der Eingabe in dieser Zeichenfolge vorhanden sind.


Oh, diese Suchzeichenfolge würde mir auch 17 Bytes sparen. Stört es Sie, wenn ich das für meine Retina-Antwort verwende?
Martin Ender

Tue es! Geben Sie einfach Kredit, denke ich.
Value Ink

Danke, aber ich habe eine noch kürzere Lösung gefunden, die auf einem Vorschlag von Sp3000 basiert :)
Martin Ender

6

grep 58 Bytes

grep "^((?=18|16|29|27|34|38|49|43|61|67|72|76|81|83|94|92).)*.$"

Denn wirklich, wenn Sie grep nicht schlagen können ...


2
Weder mit deiner Kommandozeile 5noch mit ihr 185ausgeben 1, solange 5in der Wahrheit und 185in der falschen Liste steht.
Guntram Blohm unterstützt Monica am

1
@GuntramBlohm behoben - wurde in der regelmäßigen Verneinung verloren
Yakk

6

Haskell 46 Bytes

q=zip<*>tail
all(`elem`q"16729438183492761").q

Anwendungsbeispiel: all(`elem`q"16729438183492761").q $ "183492761"->True

So funktioniert es: Es wird die in der Antwort von @Kevin Lau angegebene Suchzeichenfolge verwendet . qerstellt eine Liste von Paaren benachbarter Zeichen aus einer Zeichenfolge, z q "1672" -> [('1','6'),('6','7'),('7','2')]. Die Funktion gibt true zurück, wenn alle Paare aus der Eingabe in den Paaren aus der Suchzeichenfolge enthalten sind. qwandelt einstellige Eingaben in die leere Liste um, ist also elemimmer erfolgreich.


Warum funktioniert zip<*>taileine gekippte Version von zip=<<tail? Ich glaube, ich verstehe nicht, was Antragsteller verallgemeinern.
XNOR

@ xnor: Ich benutze es einfach. <*> ist definiert als (<*>) f g x = f x (g x) .
Nimi

6

JavaScript (ES6), 65 62 Byte

s=>[...s].every((c,i)=>!i|"16729438183492761".match(s[i-1]+c))

Gibt true oder false zurück. Ich hatte vorher eine rekursive Lösung ausprobiert, die 63 Bytes benötigt, mapund sogar, reduceaber sie hat mich 73 Bytes gekostet.

Bearbeiten: 3 Bytes dank @ user81655 gespeichert.


Besser geht es nicht, mein bester Versuch lag bei 88 Bytes. Bravo!
Naouak

@ user81655 Du meinst matcharbeitet statt ~search(aber so oder so, das ist wirklich hinterhältig) und |kann ersetzen ||(aber leider nicht in der rekursiven Version.)
Neil

@ user81655 Ich bezog mich auf die Funktionsweise, !i|...matchda das Übereinstimmungsergebnis, wenn es erfolgreich ist, ein Array aus einer einzelnen Zeichenfolge mit zwei Ziffern ist, die der |Operator schließlich in eine gültige Ganzzahl umwandelt.
Neil

@ Neil Ah, richtig.
user81655

6

C, 85 81 Bytes

Golf gespielt:

i;f(char*b){i=*b++-49;return*b?(*b=="8749x7214"[i]||*b=="6983x1632"[i])&&f(b):1;}

Alte nicht rekursive Version (85 Bytes):

i;f(char*b){for(;(i=*b++-49),*b&&*b=="8749x7214"[i]||*b=="6983x1632"[i];);return!*b;}

Alter Code mit Leerzeichen und Hauptprogramm:

i;
f(char*b){
    for (; (i=*b++-49), *b     // i = index of digit + 1 in following arrays
        &&*b=="8749x7214"[i]   // 1st possible jump for 1..9
        ||*b=="6983x1632"[i];  // 2nd possible jump for 1..9
    );
    return !*b;
}

main(){
    char b[16];
    while(scanf("%s", b) == 1) printf("%d",f(b));
    return 0;
}

Dieser akzeptiert durch Leerzeichen getrennte Zahlen über die Standardeingabe und gibt 0 aus, wenn kein Numpad-Ritter vorhanden ist, oder 1, wenn dies nicht der Fall ist.

Die neue rekursive 81-Byte-Version spart 4 Byte.


5

MATL , 38 37 29 Bytes

Dies nutzt @ QPaysTaxes Idee .

I:8JK5:7Pvj!Uttnqh?)d|2:EQm}h

Die Ausgabe ist ein zweidimensionales, komplexes, nicht leeres Array. Es ist wahr, wenn alle seine Werte einen Realteil ungleich Null haben, und anders falsch.

Probieren Sie es online!


1
Ist das überhaupt erlaubt ??
CalculatorFeline

Die Frage fragt nach einer truthy oder einem falsy Wert, nicht eine ganze Reihe.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳

2
@CatsAreFluffy Dies ist unsere Definition von Wahrhaftigkeit / Falschheit. Wie in MATLAB / Octave sind Arrays in MATL wahr, wenn alle Elemente wahr sind. ( Beispiel )
Dennis

CC @ n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
Dennis


4

MATL, 25 24 33 26 Bytes

1 Byte weniger dank @LuisMendo!
@Dennis hat einen Fehler gefunden und dann behoben! Vielen Dank!

'bSVYXbTUZW'j47-)d2^48\1=A

Übernimmt eine Ganzzahl als Eingabe. Ausgänge 1/0.

Probieren Sie es online!


@ LuisMendo Gleich in beiden Punkten, danke!
Becher

@ Tennis Aktualisiert und hoffentlich richtig. Danke für Ihre Hilfe.
Becher

Ich glaube nicht, dass du das Aam Ende brauchst . Die Vektoren von MATL sind wahr, wenn sie keine 0 enthalten.
Dennis

4

C, 140 92 Bytes

c;L(char*i){while(*i&&(!c||*i=="6743x1212"[c-49]||*i=="8989x7634"[c-49]))c=*i++;return !*i;}

Angenommen, ASCII

Detailliert Probieren Sie es hier

// valid transition from x to n[x-'1'][0 or 1]

int n[9][2] =
{
    {'6','8'},{'7','9'},{'4','8'},
    {'3','9'},{'x','x'},{'1','7'},
    {'2','6'},{'1','3'},{'2','4'}
};

// i is a pointer to where to start on a string

bool L(char * i)
{
    char c = 0;

    // move if not \0 and (not-first-char or is a valid move)

    while((*i) && (!c || (*i)==n[c-'1'][0] || (*i)==n[c-'1'][1]))
    {
        c = (*i++);
    }

    return !(*i); // success if it's \0
}

Diese Nachschlagetabellen sind riesig. Sie können Ihre Punktzahl erheblich verbessern, wenn Sie alle Trennzeichen entfernen {,}[]und char*stattdessen als Zeichenfolge codieren . Beachten Sie außerdem, dass Ihre #defineKosten nicht hoch sind, wenn Sie sie nur zweimal verwenden: Wenn Sie sie entfernen, sparen Sie 4 Byte.
Tucuxi

@tucuxi Dank für die Tipps, schaffte ich es auf 92 zu Fall zu bringen, mit \0innerhalb des Arrays verursachte nicht definiertes Verhalten , damit ich es mit Fassungx
Khaled.K

Nizza - Vergessen Sie auch nicht, diese Option <s>oldscore</s> newscorebeim Bearbeiten zu verwenden, um die Verbesserungen der Partitur widerzuspiegeln, und <!-- language-all: lang-c -->bevor der Code beginnt, die Syntaxhervorhebung zu beheben. Ich habe es auch geschafft, meine
Byteanzahl

Ihr "detailliertes" Aussehen unterscheidet sich stark von einer einfachen Erweiterung des Golf-Codes (wo ist das nin der Kurzversion?). Außerdem sollten Sie wahrscheinlich erwähnen, dass Sie von einer ASCII-Codierung ausgehen - auf EBCDIC-Maschinen erhalten Sie unterschiedliche Zahlen.
Toby Speight

@TobySpeight die ausführliche Version soll zeigen, wie es im Grunde gebaut wurde, ja, ich gehe von ASCII aus, was in C.
Khaled.K am

3

Julia, 51 49 Bytes

n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1

Nachprüfung

julia> f=n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1
(anonymous function)

julia> all(map(f,(1,2,3,4,5,6,7,8,9,16,18,38,61,81,294,349,381,383,729,767,38183,38383,18349276,183492761,618349276)))
true

julia> any(map(f,(10,11,50,53,55,65,95,100,180,182,184,185,186,187,188,189,209,305,2009,5030,3838384,4838383,183492760)))
false

3

Eigentlich 30 Bytes

;#pXZdX`Σ"67294381";'1+R+íu`Mπ

Übernimmt die Eingabe als Zeichenfolge. Gibt eine positive Ganzzahl für true und 0 für false aus.

Probieren Sie es online!

Erläuterung:

;#pXZdX`Σ"67294381";'1+R+íu`Mπ
                                 (implicit) push input
;#pXZdx                         push zip(n[:-1], n[1;]) (pairs of digits)
       `Σ"67294381";'1+R+íu`M   map:
        Σ                         join digits
         "67294381";'1+R+         push "16729438183492761" (the magic string used in many other solutions)
                         íu       0-based index (-1 if not found), increment so 0 is not found and >=1 is the 1-based index
                             π  product

3

PowerShell v2 +, 105 96 Bytes

param($a)((1..$a.length|%{'27618349294381672'.IndexOf($a[$_-1]+$a[$_])+1})-join'*'|iex)-or$a-eq5

Durchläuft die Eingabe (mit der gekapselt werden muss ""), indem überprüft wird, ob der Index für ein sequentielles Zeichenpaar in der gültigen Suchzeichenfolge enthalten ist. Ich sehe, Kevin Lau hatte etwas Ähnliches , aber ich habe es mir unabhängig ausgedacht. Jeder dieser Indizes wird mit hinzugefügt +1, da die .IndexOf()Funktion zurückgibt, -1wenn der String nicht gefunden wird. Dies macht "nicht gefunden" zu 0.

Wir -joinberechnen dann alle resultierenden Integer-Werte mit *und leiten diese an iex(ähnlich wie eval) weiter. Dies bedeutet, wenn einer der Indizes nicht gefunden wird, ergibt sich der gesamte Ausdruck 0. Das ist in Pars und verkapselt -or‚d mit $a-eq5für den speziellen Fall von Eingang "5"unserer resultierende Ausgabe zu erzielen.

Testläufe

PS C:\Tools\Scripts\golfing> 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276 | %{.\numpad-knight-numbers.ps1 "$_"}
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

PS C:\Tools\Scripts\golfing> 10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760 | %{.\numpad-knight-numbers.ps1 "$_"}
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False

2

C 78 Bytes

char*a="9614397052";f(x){int b=x/10;return!b||abs(a[x%10]-a[b%10])%6==1&f(b);}

Da alle anderen die Eingabe als String verstanden haben, habe ich versucht, dies in ganzen Zahlen zu tun. Es funktioniert rekursiv ab der niedrigstwertigen Ziffer ( a%10). Wenn es die einzige Ziffer ist, wird true zurückgegeben. Andernfalls geben Sie nur dann true zurück, wenn die Zehnerstelle ( b%10) von der Einheitenzahl nicht erreicht werden kann und (rekursiv) der Rest der Eingabe denselben Test erfüllt.

Der Test der Erreichbarkeit funktioniert, indem die Tour des Ritters linear codiert und jede Ziffer in ihre Position (null bis sieben) auf der Tour konvertiert wird. Für Ziffern 0und 5weisen wir Position neun zu, die von den anderen Positionen getrennt ist. Dann unterscheiden sich gegenseitig erreichbare Zahlen um eins (Mod Acht); dh a[x%10]-a[b%10]ist entweder ± 1 oder ± 7. Also testen wir die absolute Differenz (Mod 6) gegen 1.

Diese Lösung funktioniert für jede Zeichenkodierung, die für C gültig ist (dh Ziffern haben zusammenhängende Codes von 0 bis 9).


1

Java 8, 179 167 Bytes

Platziert die Zifferntasten (minus 5 und 0) in einem Kreis. lenthält den Kreisindex dieser Ints. Wenn der Unterschied zwischen zwei Indizes +/- 3 mod 8 beträgt, bewegen sich Ritter zwischen den diesen Indizes entsprechenden Ints. Beachten Sie, dass dies xeine int[].

x->{if(x.length<2)return 1;int[] l={0,0,1,2,7,0,3,6,5,4};int o=l[x[1]];for(int i:x){int n=l[i];if(i%5==0||(Math.abs(n-o)!=3&&Math.abs(n-o)!=5))return 0;o=n;}return 1;}

Aktualisieren

  • -11 [16-12-10] Auf Lambda umgestellt
  • -1 [16-12-10] Verwenden Sie <2anstelle von==1
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.