Generuj liczby przyjazne Numpadowi

22

Zainspirowany przez generowanie przyjaznych dla klawiatury numerów .

tło

Wiele klawiszy numerycznych ma następujący układ:

789

456

123

    0    

Definiujemy sąsiedztwo liczby jako zbiór komórek prostopadle do niego przylegających na pokazanym numpad, w tym także on sam. Na przykład sąsiedztwo 2 to, a sąsiedztwo {1,5,3,0,2}0 to {1,2,0}. Poniżej znajduje się lista sąsiedztwa każdego numeru, powyżej przypadków testowych.

Definiujemy przyjazną liczbę na klawiaturze numerycznej jako dodatnią liczbę całkowitą, gdzie zapisana dziesiętnie bez zer wiodących, każda cyfra oprócz pierwszej znajduje się w sąsiedztwie poprzedniej cyfry.

Na przykład,

  • 7856 jest liczbą przyjazną dla klawiatury numerycznej, ponieważ 8 jest w sąsiedztwie 7, 5 jest w sąsiedztwie 8, a 6 w sąsiedztwie 5.
  • 1201 jest liczbą przyjazną dla klawiatury numerycznej, ponieważ 2 jest w sąsiedztwie 1, 0 jest w sąsiedztwie 2, a 1 jest w sąsiedztwie 0.
  • 82 nie jest jest liczbą przyjazną dla klawiatury numerycznej, ponieważ 2 nie znajduje się w pobliżu 8.
  • 802 nie jest liczbą przyjazną dla klawiatury numerycznej, ponieważ 0 nie znajduje się w pobliżu 8 (dzielnice się nie zawijają).

Powiązana sekwencja OEIS . Zauważ, że ta powiązana sekwencja jest odrębna, ponieważ liczy się 0jako sąsiadująca z 7zamiast 1i 2.

Wyzwanie

Biorąc pod uwagę dodatnią liczbę całkowitą n, zwróć n-ty lub pierwszy nprzyjazny numerom numerycznym, gdzie pierwszy to 1. Możesz użyć indeksowania opartego na 0, gdzie 0-ty przyjazny numeryczny numer to 1.

Okolice

Okolice każdej cyfry są wymienione tutaj:

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}

Przypadki testowe / sekwencja

To jest pierwsze 100 warunków

[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]
fireflame241
źródło
5
Podoba mi się, jak w tym wyzwaniu uwzględniane są tylko liczby całkowite dodatnie (co zachowuje istotę i pozwala na udział większej liczby języków) i pozwala wyświetlać n- ty lub pierwsze n wyników dla elastyczności
Luis Mendo,
Całkowicie źle odczytałem wyzwanie, oto skrypt „czy ten termin jest ważny w sekwencji”: Wypróbuj online!
Magic Octopus Urn

Odpowiedzi:

9

JavaScript (ES6), 104 93 89 88 bajtów

Zwraca N-ty ciąg sekwencji, indeksowany 1.

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)

Próbny

Arnauld
źródło
Najlepsze, co mogłem uzyskać, to 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-1może 151, może coś tam pomaga, mój test jest prawdopodobnie zbyt długi
Conor O'Brien
Ta odpowiedź przenosi koncepcję magicznych liczb na zupełnie nowy poziom ... Nawet nie rozumiem, jak je znalazłeś o_O
scottinet
2
@ scottinet W dużym stopniu moje wyjaśnienie tej odpowiedzi dotyczy również tego. Absolutna różnica nie działała zbyt dobrze na tym, więc zamiast tego spróbowałem z XOR. Na marginesie, znalazłem inną formułę, która działała w 96% przypadków bez potrzeby wyszukiwania maski bitowej. Ale przetwarzanie pozostałych 4% oddzielnie było zbyt kosztowne w JS. Nie próbowałem w Galaretce , a teraz i tak nie pamiętam formuły ... ¯ \ _ (ツ) _ / ¯
Arnauld
Dziękuję za wyjaśnienia. To wciąż imponujące :-)
scottinet
4

Perl 5 , 123 + 1 (-p) = 124 bajty

while($_){$r=@d=++$\=~/./g;map$r&&=(120,1240,12350,236,1457,24568,3569,478,5789,689)[$d[$_-1]]=~/$d[$_]/,1..$#d;$r&&$_--}}{

Wypróbuj online!

Xcali
źródło
3

Galaretka , 27 24 bajtów

Zwraca N pierwsze warunki sekwencji.

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

Wypróbuj online!

To jest port mojej odpowiedzi JS .

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
Arnauld
źródło
3

05AB1E , 24 23 bajty

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

Wypróbuj online!

Zwraca n-tą liczbę w sekwencji.

Objaśnienia:

µ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

Główną ideą jest to, że oprócz 0klucza każda cyfra zmniejszona i przekonwertowana do bazy 3 ma następujące właściwości:

  • lewy i prawi sąsiedzi mają absolutną różnicę 1
  • w górę i w dół sąsiedzi mają bezwzględną różnicę 10, która, odwrócona, jest dogodnie równa 1
  • każda inna para klawiszy numerycznych powoduje różne wartości, nawet po odwróceniu

Oczywiście potrzebujemy ifinstrukcji do obsługi 0klawisza numpad.

szkocki
źródło
Solidna odpowiedź, przyszła zaoferować więcej ulepszeń, nie można jej znaleźć. Oooo ... i ta para też stawia cię na czele :).
Magic Octopus Urn
Nie sądzę, bym był w stanie wymyślić te 3 zasady, całkiem imponujące tbh; co dało ci ten pomysł?
Magic Octopus Urn
2

MATL , 29 27 bajtów

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

Wysyła pierwsze nliczby przyjazne dla klawiatury numerycznej.

Wypróbuj online!

Wyjaśnienie

Każda cyfra od 1do 9jest kodowana jako liczba zespolona reprezentująca jej pozycję na klawiaturze numerycznej, z wykorzystaniem siatki kroku 2, gdzie część rzeczywista reprezentuje pozycję pionową, a część wyobrażona reprezentuje pozycję poziomą. Tak 1jest 0+0j, 2jest 0+2j, 3jest 0+4j, 4jest 2+0j, ... 9jest4+4j .

Cyfra 0jest zakodowana jako 0+1j, tj. Tak jakby była umieszczona dokładnie pomiędzy 1i 2.

Dla każdego numeru KN-przyjazny kandydujących, „dziesiętny” konwersja baza nanosi wyżej liczb zespolonych zamiast cyfr 0, 1, ..., 9. Daje to tablicę, z której obliczane są bezwzględne kolejne różnice. Liczba kandydatów jest przyjazna dla klawiatury numerycznej wtedy i tylko wtedy, gdy wszystkie absolutne różnice są co najwyżej2 (tj. Krok siatki). W takim przypadku liczba pozostawia się na stosie.

Kod wykorzystuje pętlę do... while, która jest zamykana, gdy liczba liczb na stosie jest równa wartości wejściowej n.

Siatka jednostkowa byłaby bardziej naturalnym wyborem. Cyfry 1, 2i 0będzie wtedy odpowiadać 0+0j, 1+0ja 0.5+0jrespecrively. Ale golfistą jest użycie siatki kroku 2, ponieważ pomnożenie przez 2(funkcja E) i pchanie 0+1j(funkcja J) jest o jeden bajt krótsze niż pchanie 0+0.5j( J2/lub .5j)

Luis Mendo
źródło
2

Galaretka , 26 bajtów

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

Wypróbuj online!

-2 bajty dzięki cairdowi coinheringaahing
-2 bajty dzięki Erikowi Outgolfer

Wyjaśnienie

’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
HyperNeutrino
źródło
Możesz usunąć []za 2 bajty
caird coinheringaahing 24.09.17
@cairdcoinheringaahing dzięki!
HyperNeutrino,
1
Golf kilka off.
Erik the Outgolfer,
2

Python 2 , 134 bajty

g=lambda n,k=1:n and g(n-(lambda l:all(abs(a-b)<1.2for a,b in zip(l,l[1:])))([~-d%3+~-d/3*1j-d/~d*1.5for d in map(int,`k`)]),k+1)or~-k

Wypróbuj online!

Lynn
źródło
Gdy zdefiniujesz, fa następnie użyjesz go raz , możesz wstawić go i zapisać dwa bajty .
Jonathan Frech,
1

Mathematica, 249 234 202 bajty

(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)&


Wypróbuj online!

dzięki użytkownik202729 za kompresję danych (-32 bajtów)

Moje wyniki:

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

J42161217
źródło
Myślę, że możesz skompresować dane za pomocą IntegerDigits: IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}i użyjFreeQ , Trużyj Dozamiast For, użyj notacji infiksowej AppendToi użyj Dozamiast Whilepowtarzać Tr[1^s]czasy, również wyeliminuj zmienną p. Nie udowodniłeś również, że algorytm jest poprawny, to znaczy, że wynikowa liczba jest zawsze mniejsza niż jej kwadrat podniesiony do kwadratu, co jest konieczne, aby odpowiedź była poprawna.
user202729,
1
@ user202729 Zmieniłem wiele rzeczy. Moja odpowiedź jest zdecydowanie poprawna. Teraz skompresuję dane.
J42161217,
dlaczego głosowanie negatywne?
J42161217,
1

PHP, 124 + 1 bajtów

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;

Uruchom jako potok z -nRlub spróbuj online .

Tytus
źródło
0

Java 8, 192 190 bajtów

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;}

Zwraca (indeksowaną 1) nliczbę w sekwencji.

To było zaskakująco trudniejsze, niż myślałem… Prawdopodobnie po południu pierdnięcie w mózgu…

Wyjaśnienie:

Wypróbuj tutaj.

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
Kevin Cruijssen
źródło