Numpad-freundliche Nummern generieren


22

Inspiriert von Generate Keyboard Friendly Numbers .

Hintergrund

Viele Nummernblöcke haben das folgende Layout:

789

456

123

    0    

Wir definieren die Nachbarschaft einer Zahl als die Menge von Zellen, die orthogonal dazu auf dem gezeigten Nummernblock benachbart sind, einschließlich sich selbst. Zum Beispiel ist die Nachbarschaft von 2{1,5,3,0,2} 0 {1,2,0}. Unterhalb der Testfälle befindet sich eine Liste der Nachbarschaften der einzelnen Nummern.

Wir definieren a Numpad-freundliche Zahl als eine positive Ganzzahl, bei der sich jede Ziffer mit Ausnahme der ersten in der Nachbarschaft der vorherigen Ziffer befindet, wenn sie dezimal ohne führende Nullen geschrieben wird.

Beispielsweise,

  • 7856 ist eine Numpad-freundliche Zahl, weil 8 in der Nachbarschaft von 7 ist, 5 in der Nachbarschaft von 8 ist und 6 in der Nachbarschaft von 5 ist.
  • 1201 ist eine Numpad-freundliche Zahl, weil 2 in der Nachbarschaft von 1 ist, 0 in der Nachbarschaft von 2 ist und 1 in der Nachbarschaft von 0 ist.
  • 82 ist nicht Numpad-freundliche Zahl, da 2 nicht in der Nähe von 8 liegt.
  • 802 ist keine Numpad-freundliche Zahl, da 0 nicht in der Nähe von 8 liegt (Nachbarschaften werden nicht umbrochen).

Verwandte OEIS-Sequenz . Beachten Sie, dass diese verwandte Sequenz verschieden ist , weil es zählt 0als neben 7statt 1und 2.

Herausforderung

Bei einer positiven Ganzzahl ngeben Sie die n-te oder die ersten nAnzeigenummern zurück, wobei die erste 1 ist. Sie können eine 0-basierte Indizierung verwenden, wobei die 0-te Anzeigenummer 1 ist.

Nachbarschaften

Die Nachbarschaft der einzelnen Ziffern ist hier aufgelistet:

0:{0,1,2}
1:{0,1,2,4}
2:{0,1,2,3,5}
3:{2,3,6}
4:{1,4,5,7}
5:{2,4,5,6,8}
6:{3,5,6,9}
7:{4,7,8}
8:{5,7,8,9}
9:{6,8,9}

Testfälle / Sequenz

Dies sind die ersten 100 Begriffe

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 20, 21, 22, 23, 25, 32, 33, 36, 41, 44, 45, 47, 52, 54, 55, 56, 58, 63, 65, 66, 69, 74, 77, 78, 85, 87, 88, 89, 96, 98, 99, 100, 101, 102, 110, 111, 112, 114, 120, 121, 122, 123, 125, 141, 144, 145, 147, 200, 201, 202, 210, 211, 212, 214, 220, 221, 222, 223, 225, 232, 233, 236, 252, 254, 255, 256, 258, 320, 321, 322, 323, 325, 332, 333, 336, 363, 365, 366, 369, 410, 411, 412, 414, 441, 444, 445, 447]

5
Ich mag, wie diese Herausforderung nur positive ganze Zahlen berücksichtigt (was das Wesentliche beibehält und mehr Sprachen zur Teilnahme zulässt) und es ermöglicht, aus Gründen der Flexibilität entweder die n- ten oder die ersten n Ausgaben anzuzeigen
Luis Mendo,

Ich habe die Herausforderung völlig falsch verstanden. Hier ist ein Skript, das besagt, dass
Magic Octopus Urn

Antworten:


9

JavaScript (ES6), 104 93 89 88 Byte

Gibt den N-ten Term der Sequenz zurück, der 1-indiziert ist.

f=(i,k,n=k,N=n/5>>1)=>(N?8530025>>(n%10*6191^N%10*6191)%26&1:!i--)?N?f(i,k,N):k:f(i,-~k)

Demo


Das Beste, was ich bekommen konnte, ist 151, k=(n,a=1)=>n?k(n-([...(x=a+[]).slice(0,-1)].reduce((a,c)=>a*!!~"012 0124 01235 236 1457 24568 3569 478 5789 689".split` `[c].indexOf(x[i++]),i=1)),a+1):a-1vielleicht hilft etwas, mein Test ist wahrscheinlich zu lang
Conor O'Brien

Diese Antwort bringt das Konzept der magischen Zahlen auf eine ganz neue Ebene ... Ich verstehe nicht einmal , wie man fand sie o_O
scottinet

2
@scottinet In hohem Maße gilt meine Erklärung für diese Antwort auch für diese. Der absolute Unterschied funktionierte bei diesem nicht sehr gut, also habe ich es stattdessen mit XOR versucht. Als Randnotiz fand ich eine andere Formel, die in 96% der Fälle ohne die Notwendigkeit einer Nachschlagebitmaske funktionierte. Aber die restlichen 4% separat zu verarbeiten, war in JS zu kostspielig. Ich habe es nicht mit Jelly versucht , und jetzt kann ich mich sowieso nicht an die Formel erinnern ... ¯ \ _ (ツ) _ / ¯
Arnauld

Danke für die Erklärungen. Das ist immer noch beeindruckend :-)
Scottinet


3

Jelly , 27 24 Bytes

Gibt die N ersten Terme der Sequenz zurück.

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ
1Ç#

Probieren Sie es online!

Dies ist ein Port meiner JS-Antwort .

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ    - helper link: test numpad-friendliness of a number, e.g. 1257
D                       - get decimal digits             -> [1, 2, 5, 7]
    ×                   - multiply by ...
 ⁽ÞȦ                    - ... the integer 6191           -> [6191, 12382, 30955, 43337]
     ^2\                - bitwise XOR overlapping reduce -> [10353, 18613, 53666]
        %26             - modulo 26                      -> [5, 23, 2]
                æ»      - right-shift by each value ...
           “⁷wð’        - ... the integer 8530025        -> [266563, 1, 2132506]
                  Ḃ     - isolate the LSB                -> [1, 1, 0] which means that 1->2
                                                            and 2->5 are OK and 5->7 is not
                   Ạ    - all (0 if there's any 0)       -> 0, i.e. not numpad-friendly :'(

1Ç#                     - main link: return the [input] first matching numbers,
                          using our helper link as a monad and starting with 1

3

05AB1E , 24 23 Bytes

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P

Probieren Sie es online!

Gibt die n-te Zahl in der Sequenz zurück.

Erklärungen:

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P    Full program
µ                          Until counter is equal to input
 N                         Push current iteration number (e.g. 1025)
  S                        Split to a list of chars (-> ['1', '0', '2', '5'])
   ü‚                      Group into pairs (-> ['1', '0'], ['0', '2'], ['2', '5'])
     ε                     For each pair
      W_                      Is smallest digit equal to 0?
        iO<                      True: sum all digits and decrement 
           ë                     False: 
            <                       - decrement all digits
             3B                     - convert to base 3
               Æ                    - reduced substraction
                }             End if
                 Ä            Absolute value
                  R           Reverse 
                   2‹         1 if result is < 2, 0 otherwise
                     }     End for each
                      P    Cumulative product (1 if all pair results are 
                                     1, 0 otherwise)
                           -- implicit counter increment if stack value is 1

Die Hauptidee ist, dass, abgesehen von der 0 jede in Basis 3 dekrementierte und konvertierte Ziffer Schlüssel die folgenden Eigenschaften aufweist:

  • linke und rechte Nachbarn haben einen absoluten Unterschied von 1
  • Aufwärts- und Abwärtsnachbarn haben eine absolute Differenz von 10, die umgekehrt günstigerweise gleich 1 ist
  • Jedes andere Paar von Zifferntasten führt zu anderen Werten, auch wenn es umgekehrt ist

Natürlich brauchen wir eine ifAnweisung, um mit der 0Zifferntaste umgehen zu können.


Solide Antwort, kam, um weitere Verbesserungen anzubieten, kann keine finden. Oooo ... und das brachte dich auch paarweise in Führung :).
Magic Octopus Urn

Ich glaube nicht, dass ich in der Lage gewesen wäre, mir diese drei Regeln auszudenken, ziemlich beeindruckend, oder? was hat dich auf die idee gebracht
Magic Octopus Urn

2

MATL , 29 27 Bytes

`@J3:qEt!J*+hYAd|2>~A?@]NG-

nGibt die ersten Nummernblock-freundlichen Nummern aus.

Probieren Sie es online!

Erläuterung

Jede Ziffer von 1bis 9wird als komplexe Zahl codiert, die ihre Position im Nummernblock darstellt. Dabei wird in einem Schritt-2-Raster ein Realteil für die vertikale Position und ein Imaginärteil für die horizontale Position verwendet. So 1ist 0+0j, 2ist 0+2j, 3ist 0+4j, 4ist 2+0j, ... 9ist 4+4j.

Die Ziffer 0wird so codiert 0+1j, als ob sie genau zwischen 1und platziert wäre 2.

Für jeden Kandidaten numpad freundliche Nummer, eine „dezimal“ Basis Umwandlung wird die obige komplexe Zahlen anstelle der Ziffern angewendet mit 0, 1, ..., 9. Dies ergibt ein Array, aus dem die absoluten aufeinanderfolgenden Differenzen berechnet werden. Die Kandidatennummer ist genau dann nummernfreundlich, wenn alle absoluten Unterschiede maximal sind2 (dh der ). In diesem Fall bleibt die Nummer auf dem Stapel.

Der Code verwendet eine do... while-Schleife, die beendet wird, wenn die Anzahl der Zahlen im Stapel der Eingabe entspricht n.

Ein Einheitsraster wäre eine natürlichere Wahl gewesen. Ziffern 1, 2und 0würden dann entsprechen 0+0j, 1+0jund 0.5+0jrespecrively. Es ist jedoch besser, ein Step-2-Gitter zu verwenden, da das Multiplizieren mit 2(Funktion E) und Drücken 0+1j(Funktion J) ein Byte kürzer ist als Drücken 0+0.5j( J2/oder .5j).


2

Gelee , 26 Bytes

’d-,.⁸?3µ€ạ/S
Dṡ2Ç€<2Ạ
1Ç#

Probieren Sie es online!

-2 Bytes dank caird coinheringaahing
-2 Bytes dank Erik the Outgolfer

Erläuterung

’d-,.⁸?3µ€ạ/S  Helper Link; compute the distance between two keys z = [x, y]
      ?        Switch:
     ⁸         If z (is not 0):
’              Decrement
 d             Divmod by:
  -,.          Else: [-1, 0.5] (special position for 0)
       3       3; right argument for divmod otherwise ignored
        µ      Begin a new monadic link / end this link
         €     Compute the position for each [x, y]
           /   Reduce on
          ạ    Absolute Difference
            S  Sum (this gives the Manhattan Distance)
Dṡ2Ç€<2Ạ       Helper Link; determine if a number <z> is numpad friendly
D              Convert number to decimal digits
 ṡ             Slice into overlapping slices of length
  2            2 (pairs)
    €          For each pair,
   Ç           The distance between the keys
     <2        Compare with 2 (the distance between two adjacent keys is 1; corners 2; 0 - 1 and 0 - 2 are 1.5)
       Ạ       All; either all of the distances are less than 2 or there were no distances
1Ç#            Main Link; find the first (input) numpad friendly numbers
  #            nfind; counting up from _ collect the first _______ matches that are
1                                      1
                                                           (input)
 Ç             Numpad Friendly

Sie können die []für 2 Bytes
Caird Coinheringaahing

@cairdcoinheringaahing danke!
HyperNeutrino



1

Mathematica, 249 234 202 Bytes

(a=o=1;While[a<=#,s=IntegerDigits@o;t=1;p=0;While[t+p<Length@s,If[!FreeQ[(IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986})[[s[[t]]+1]],s[[t+1]]],t++,p++]];If[t==Length@s,a++];o++];o-1)&


Probieren Sie es online!

danke user202729 für das komprimieren von daten (-32 bytes)

Meine Ergebnisse:

100 -> 447
1000 -> 20023
10000 -> 788777


Ich glaube , Sie können die Daten komprimieren , indem Sie IntegerDigits: IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}und Verwendung FreeQ, Trverwenden Sie DostattFor , Verwendung Infixschreibweise für AppendTound verwendet Dostatt Whilezu wiederholen Tr[1^s]Zeiten, auch die Variable beseitigen p. Sie haben auch nicht bewiesen, dass der Algorithmus korrekt ist, dh, die resultierende Zahl ist immer kleiner als das Quadrat des Index, das erforderlich ist, um eine gültige Antwort zu erhalten.
user202729

1
@ user202729 Ich habe viele Dinge geändert. Meine Antwort ist definitiv gültig. Ich werde die Daten jetzt komprimieren.
J42161217

Warum die Gegenstimme?
J42161217

1

PHP, 124 + 1 Bytes

while($argn-=$r)for($p=$r=~0,$x=++$n;$x>=1;$p=[7,23,47,76,178,372,616,400,928,832][$c],$x/=10)$r&=!!($p&1<<$c=$x%10);echo$n;

Laufen Sie als Pipe mit -nRoder versuchen Sie es online .


0

Java 8, 192 190 Bytes

n->{int r=1,p;a:for(;n>0;){p=-1;for(int c:(r+++"").getBytes())if(p>-1&!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48].contains(p+""))continue a;else p=c;n--;}return~-r;}

Gibt die (1-indizierte) n'te Zahl in der Sequenz zurück.

Das war überraschend schwieriger als ich dachte. Wahrscheinlich hatte ich heute Nachmittag nur ein paar Hirn-Fürze.

Erläuterung:

Probieren Sie es hier aus.

n->{                 // Method with integer as both parameter and return-type
  int r=1,           //  Return-integer
      p;             //  Previous digit
  a:for(;n>0;){      //  Loop (1) as long as the input is larger than 0
    p=-1;            //   Start `p` at an integer that is not 0-9 (-1 in this case)
    for(int c:(r+++"").getBytes())
                     //   Loop (2) over the digits of the current number
      if(p>=0        //    If this is not the first digit (`p` != -1),
         &!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48]
           .contains(p+""))
                     //    and the adjacent digits are NOT part of a NumberPad-Friendly Nr:
        continue a;  //     Go to the next iteration of loop (1)
      else           //    Else:
        p=c;         //     Set `p` to the current digit for the next iteration
                     //   End of loop (2) (implicit / single-line body)
      n--;           //   If we haven't encountered the `continue`, decrease `n` by 1
  }                  //  End of loop (1)
  return~-r;         //  Return the result-integer - 1
}                    // End of method
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.