生成数字键友好的数字


22

生成键盘友好数字的启发。

背景

许多数字键盘的布局如下:

789

456

123

    0    

我们将数字的邻域定义为在所示数字键盘上与其正交正交的一组单元格,包括其自身。例如,2的邻居是{1,5,3,0,2},0的邻居是{1,2,0}。在测试用例的上方,下面列出了每个数字的邻域。

我们将小键盘友好数字定义为正整数,其中当以十进制形式编写而没有前导零时,除第一个数字外的每个数字都位于前一个数字附近。

例如,

  • 7856是小键盘的友好数字,因为8在7的附近,5在8的邻居中,6在5的附近。
  • 1201是一个小键盘的友好数字,因为2在1附近,0在2附近,而1在0附近。
  • 82 不是小键盘的友好数字,因为2不在8附近。
  • 802 不是小键盘的友好数字,因为0不在8附近(邻居不会环绕)。

相关OEIS序列。请注意,此相关的序列是不同的,因为它计算0为邻近7的,而不是12

挑战

给定正整数n,返回第- n个或第一个n数字键盘友好数字,其中第一个为1。您可以使用基于0的索引,第0个数字键盘友好数字为1。

邻里

每个数字的邻居在这里列出:

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

我完全误解了挑战,这是一个“此术语在序列中是否有效”脚本:在线尝试!
魔术章鱼缸

Answers:


9

JavaScript(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或许真的有帮助,我的测试可能是太长时间
康纳尔奥布莱恩

这个答案将魔术数的概念带到了一个全新的水平……我什至不明白你是怎么找到它们的o_O
scottinet

2
@scottinet在很大程度上,我对此答案的解释也适用于此答案。绝对差异在该代码上效果不佳,因此我尝试使用XOR。作为附带说明,我发现了另一个公式,该公式可在96%的情况下使用,而无需查找位掩码。但是在JS中单独处理剩余的4%的成本太高。我没有尝试过Jelly,现在无论如何我都不记得这个公式...¯\ _(ツ)_ /¯–
Arnauld

感谢您的解释。这仍然令人印象深刻:-)
scottinet

4

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

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

在线尝试!


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

05AB1E24 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键盘键。


确实的答案,可以提供更多的改进,但找不到任何改进。噢...这成对也使您处于领先地位:)。
Magic Octopus Urn'Oct

我认为我无法提出这3条规则,令人印象深刻。是什么给了你这个主意?
Magic Octopus Urn'Oct

2

MATL29 27字节

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

输出第一个n数字键盘友好的数字。

在线尝试!

说明

使用第2步网格,将从1到的每个数字9编码为表示其在小键盘中位置的复数,其中实数部分表示垂直位置,虚数部分表示水平位置。所以,10+0j20+2j30+4j42+0j,...... 94+4j

0被编码为0+1j如同其被准确地之间放置,即,12

对于每个候选数字键盘友好号,“小数”基转换是使用上述复数而不是数字应用01,..., 9。这给出了一个数组,其绝对连续差被计算。当且仅当所有绝对差值都最大时2(即网格步长),候选编号才是小键盘友好的。在这种情况下,数字将保留在堆栈中。

该代码使用do... while循环,当堆栈中的数字量等于input时退出n

单位网格本来是更自然的选择。数字120随后将对应0+0j1+0j0.5+0jrespecrively。但是使用step-2网格比较容易,因为乘以2(function E)和推入0+1j(function J)比推入0+0.5jJ2/or .5j)短一字节。


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

@cairdcoinheringaahing谢谢!
HyperNeutrino



1

Mathematica,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


我想你可以通过使用压缩数据IntegerDigitsIntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}和使用FreeQTr使用Do替代For,使用中缀表示法AppendTo并用Do,而不是While要重复Tr[1^s]多次,也消除了变量p。另外,您还没有证明算法是正确的,也就是说,结果数始终小于其索引平方,这对于使答案有效是必不可少的。
user202729

1
@ user202729我做了很多事情。我的答案是肯定有效的。我现在将压缩数据。
J42161217

为什么要下票?
J42161217

1

PHP,124 + 1字节

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;

与管道一起运行-nR在线尝试


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个索引)。

这比我想象的要难得多。.可能今天下午有一些脑瘫。

说明:

在这里尝试。

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.