숫자로 친숙한 숫자 생성


22

키보드 친화적 인 숫자 생성에서 영감을 얻었습니다 .

배경

많은 숫자 패드의 레이아웃은 다음과 같습니다.

789

456

123

    0    

우리는 숫자의 이웃을 자신을 포함하여 표시된 숫자 키패드에서 직교 적으로 인접한 셀 세트로 정의합니다. 예를 들어, 2의 이웃은 {1,5,3,0,2}이고 0의 이웃은 {1,2,0}입니다. 아래에는 테스트 사례 위에 각 숫자의 이웃 목록이 있습니다.

우리는 숫자 친숙한 숫자 를 양의 정수로 정의하며 , 앞에 0이없는 10 진수로 쓰여질 때 첫 번째 숫자를 제외한 각 숫자는 이전 숫자 근처에 있습니다.

예를 들어

  • 7856은 숫자가 친숙한 숫자입니다. 8은 7, 7의 근처에 있고 5는 8의 이웃, 6은 5의 이웃입니다.
  • 2는 1 근처에 있고, 0은 2 근처에 있고, 1은 0에 있기 때문에 1201은 숫자 친숙한 숫자입니다.
  • 82는 아닙니다 (2) (8)의 근처에없는 때문에 숫자 패드 친화적 인 수.
  • (802)은 하지 0 8 (지역 주위에 포장하지 않음)의 근처에없는 때문에 숫자 패드 친화적 인 수.

관련 OEIS 시퀀스 . 이 관련 시퀀스는 및 대신에 0인접한 것으로 계산되므로 고유합니다 .712

도전

양의 정수가 주어지면 첫 번째 숫자 는 1 인 첫 번째 숫자 키패드 친숙한 숫자를 n반환합니다 n. 첫 번째 n숫자는 1이되는 0 기반 인덱싱을 사용할 수 있습니다.

이웃

각 숫자의 이웃은 다음과 같습니다.

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}

테스트 사례 / 시퀀스

이들은 처음 100 개의 용어입니다

[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
나는이 도전이 양의 정수만을 고려 하고 (본질을 유지하고 더 많은 언어가 참여할 수 있도록) 유연성을 위해 n 번째 또는 첫 번째 n 출력을 표시 할 수있는 방법을 좋아합니다.
Luis Mendo

도전 과제를 완전히 읽었습니다. 여기에 "이 용어는 순서대로 유효합니다"라는 스크립트 가 있습니다.
Magic Octopus Urn

답변:


9

자바 스크립트 (ES6), 104 93 89 88 바이트

시퀀스의 N 번째 항을 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)

데모


내가 얻을 수있는 최선의 결과는 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-1일 것입니다. 아마도 테스트가 너무 길었을 것입니다.
Conor O'Brien

이 답변은 완전히 새로운 수준으로 마법의 숫자의 개념을 제공합니다 ... 난 당신이 그 (것)들을 O_O 찾을 방법을 이해하지 않습니다
scottinet

2
@ scottinet 이 답변에 대한 나의 설명은 대부분 이것 에도 적용됩니다. 절대 차이는 그 점에서 잘 작동하지 않았으므로 대신 XOR로 시도했습니다. 참고로, 검색 비트 마스크가 필요없는 96 %의 사례에서 작동하는 또 다른 수식을 찾았습니다. 그러나 나머지 4 %를 개별적으로 처리하는 것은 JS에서 너무 비용이 많이 들었습니다. 나는 젤리 에서 시도하지 않았고 이제는 공식을 기억하지 못합니다 ... ¯ \ _ (ツ) _ / ¯
Arnauld

설명 주셔서 감사합니다. 이것은 여전히 ​​인상적입니다 :-)
scottinet


3

젤리 , 27 24 바이트

시퀀스의 N 번째 항을 반환합니다.

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

온라인으로 사용해보십시오!

이것은 내 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

3

05AB1E , 24 23 바이트

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

온라인으로 사용해보십시오!

시퀀스에서 n 번째 숫자를 반환합니다.

설명 :

µ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

주요 아이디어는 0 키 감소하고 밑수 3으로 변환 된 숫자는 다음과 같은 특성을가집니다.

  • 왼쪽과 오른쪽 이웃의 절대 차이는 1입니다
  • 상하 이웃은 10의 절대 차이를 가지며, 반대로 1과 편리하게 같습니다.
  • 다른 숫자 키패드 키 쌍은 반대로해도 다른 값을 생성합니다

물론 숫자 키패드 키 if를 처리하기 위한 명령문이 필요합니다 0.


확실한 대답은 더 많은 개선점을 제공하며 찾을 수 없습니다. Oooo ... 그리고 쌍으로 당신을 리드에 넣었습니다 :).
매직 문어 Urn

나는 그 3 가지 규칙, 꽤 인상적인 tbh를 생각해 낼 수 없을 것이라고 생각합니다. 무슨 생각을 했니?
매직 문어 Urn

2

MATL , 29 27 바이트

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

n숫자 키패드에 적합한 첫 번째 숫자를 출력합니다 .

온라인으로 사용해보십시오!

설명

에서 시작 1까지의 각 숫자는 92 단계 그리드를 사용하여 숫자 패드에서 해당 위치를 나타내는 복소수로 인코딩됩니다. 여기서 실제 부분은 수직 위치를 나타내고 가상 부분은 수평 위치를 나타냅니다. 그래서 1이다 0+0j, 2있다 0+2j, 3있다 0+4j, 4있다 2+0j, ..., 9이다 4+4j.

Digit 0는로 0+1j, 즉 정확히 ~ 1와 사이에있는 것처럼 인코딩됩니다 2.

각 후보의 숫자 키패드 친화적 인 수를 들어, "소수"기본 변환 대신 숫자의 복잡한 숫자 이상으로 사용하여 적용됩니다 0, 1, ..., 9. 이것은 절대 연속적인 차이가 계산되는 배열을 제공합니다. 모든 절대 차이가 최대 인 경우에만 2(즉, 그리드 단계) 후보 번호는 숫자판 친화적 입니다. 이 경우 스택에 숫자가 남습니다.

코드는 do... while루프를 사용하는데 , 스택의 숫자가 input과 같을 때 종료됩니다 n.

단위 그리드가 더 자연스러운 선택이었을 것입니다. 숫자가 1, 2그리고 0다음에 해당하는 것 0+0j, 1+0j그리고 0.5+0jrespecrively. 그러나 2(function E)과 pushing 0+1j(function J)을 곱하는 것이 0+0.5j( J2/또는 .5j) 보다 1 바이트 짧기 때문에 2 단계 그리드를 사용하는 것이 골퍼입니다


2

젤리 , 26 바이트

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

온라인으로 사용해보십시오!

caird coinheringaahing 덕분에
-2 바이트-Outgolfer Erik 덕분에 -2 바이트

설명

’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

[]대한 2 바이트를 제거 할 수 있습니다
caird coinheringaahing

트윗 담아 가기
HyperNeutrino



1

매쓰, 249 (234) 202 바이트

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


온라인으로 사용해보십시오!

데이터를 압축 해 주셔서 감사합니다 user202729 (-32 바이트)

내 결과 :

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


난 당신이 사용하여 데이터를 압축 할 수 있다고 생각 IntegerDigits: IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}및 사용FreeQ , Tr사용하는 Do대신 For에, 사용 중위 표기 AppendTo하고 사용 Do대신 While반복에 Tr[1^s]또한 변수를 제거, 시간 p. 또한 알고리즘이 올바른지 입증하지 못했습니다. 즉 결과 숫자가 항상 제곱보다 작으므로 응답을 유효하게 만드는 데 필요합니다.
user202729

1
@ user202729 나는 많은 것들을 바꿨다. 나의 대답은 확실히 유효하다. 이제 데이터를 압축하겠습니다.
J42161217

왜 downvote?
J42161217


0

자바 8, 192 190 바이트

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

n시퀀스에서 (1-indexed) '번째 숫자를 반환합니다 .

이것은 내가 생각했던 것보다 놀라 울 정도로 어려웠다. 아마 오늘 오후에 약간의 뇌 방귀가있을 것이다.

설명:

여기에서 시도하십시오.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.