查找可排序的年份


26

2013年有一个有趣的属性:数字在排序时是连续的(0123)。让我们将这种类型的数字称为可排序数字:一个非负整数,其基数为10的数字在排序后是连续的。不幸的是,这种情况要到2031年才会再次发生,然后直到2103年才会再次发生。您的挑战是编写一个程序或函数,当通过任何标准方法给定非负整数时,该程序或函数将输出或返回下一个可排序的数字。

规则

  • 输入和输出必须以10为底。
  • 输出可以采用任何合理的格式(数字文字,字符串文字,单项数组等)。
  • 您的代码必须在1分钟内为最多98764的所有输入产生正确的输出。

测试用例

    0 -> 1
    1 -> 2
    9 -> 10
   10 -> 12
   11 -> 12
   99 -> 102
  233 -> 234
  234 -> 243
  243 -> 312
 2016 -> 2031
 2031 -> 2103
 2103 -> 2130
 2130 -> 2134
 2134 -> 2143
 9876 -> 10234
98764 -> 98765

可排序的数字为A215014。可以在此处找到所有条目的列表,直到98765 。

计分

这是,因此以字节为单位的最短代码获胜。


工作是什么意思?如果需要很长时间,可以吗?
丹尼斯

@Dennis对于所有输入(最多98764),必须在1分钟后结束。这已在帖子中阐明。
ETHproductions 2016年

@ETHproductions是否必须完全支持更大的输入?
Martin Ender

@MartinEnder不,尽管我希望大多数(如果不是全部)解决方案都可以。要求应该更高吗?
ETHproductions 2016年

@ETHproductions我不这么认为,我只是想确定一下。
Martin Ender

Answers:


9

Python 2,61个字节

f=lambda n:-~n*(`sorted(`n+1`)`[2::5]in'0123456789')or f(n+1)

在线尝试!


1
我想'0123456789'成为1./81,但效果不佳。
xnor

您得到的最好的是1./81.0000001仍然无法正常工作并且更长的时间
Alfie Goodacre

@AlfieGoodacre您可以用1./81-1e-10它做得更好,但它仍然是10个字节,您仍然必须截断它。
马丁·恩德

7

果冻11 10 9字节

⁵ḶwṢ
‘Ç1#

返回单例数组。在线尝试!

怎么运行的

‘Ç1#  Main link. Argument: n

‘     Increment; yield n+1.
 Ç1#  Apply the helper link to k = n+1, n+2, n+3, ... until one of them maps to a
      truthy value. Yield a singleton array containing that value of k.

⁵ḶwṢ  Helper link. Argument: k

⁵     Set the return value to 10.
 Ḷ    Unlength; yield [0, ..., 9].
   Ṣ  Sort; yield the sorted array of k's decimal digits.
  w   Window-index; yield the 1-based index(truthy) of the digit array in
      [0, ..., 9], 0 (falsy) if not found.

6

MATL,8字节

`QtVSdqa

在线尝试!验证所有测试用例

说明

`     % Do...while
  Q   %   Add 1. Takes input (implicit) in the first iteration
  t   %   Duplicate
  V   %   Convert to string. This gives an array of chars (same as a string)
      %   representing the digits
  S   %   Sort
  d   %   Consecutive differences between the chars (automatically converted
      %   to ASCII codes)
  q   %   Subtract 1. This gives an array where consecutive differences equal 
      %   to 1 are converted to 0, and the rest give a nonzero result
  a   %   True if any value is nonzero. This is the loop condition: if true
      %   (which means at least one consecutive difference was not 1), go on
      %   with the next iteration. Else exit loop
      % End do...while (implicit)
      % Display (implicit)

5

JavaScript(ES6),64 54字节

感谢Neil,节省了大量的10个字节

f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n

测试用例


2
您可以通过注意map回调的第三个参数是数组本身来节省原始答案的2个字节,但是您可以做得更好:f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n
Neil


4

PowerShell v2 +,71 68 67字节

param($n)do{$n++}until(-join(0..9)-match-join([char[]]"$n"|sort))$n

在线尝试!

一种迭代解决方案,几乎可以在我的计算机上立即运行。

PS C:\Tools\Scripts\golfing> measure-command {.\find-the-sortable-years.ps1 98764} | fl totalseconds

TotalSeconds : 0.0487127

是的,这是代码高尔夫球中的一个do/ until循环。对不起,对不起。基本上,我们从输入向上循环,$n直到$n|sorted regex -matches针对0123456789。然后我们放置$n在管道上,并且输出是隐式的。

通过意识到-join(0..9)比文字字符串短一个字节来保存一个字节0123456789


3

Mathematica,63个字节

#+1//.x_/;!Differences@Sort@IntegerDigits@x~MatchQ~{1...}:>x+1&

#+1只要为Differences@Sort@IntegerDigits@x~MatchQ~{1...}false,就替换为下一个值,这是当前值是可排序的条件。

这是另一个有趣的想法,不幸的是结果太长了:

FirstCase[FromDigits/@Union@@Permutations/@Join@@Array[Range,{9,10},0],x_/;x>#]&

在这一年中,我首先生成了所有可排序的年份,然后选择了比输入大的第一个年份。

没有发现比第一次尝试还短的更多想法:

#+1//.x_/;Array[Range,{9,10},0]~FreeQ~Sort@IntegerDigits@x:>x+1&
#+1//.x_/;Subsequences@Range[0,9]~FreeQ~Sort@IntegerDigits@x:>x+1&
#+1//.x_/;0~Range~9~FreeQ~{___,##&@@Sort@IntegerDigits@x,___}:>x+1&

3

PHP,105个 103 89字节

借助Titus,新的89字节版本:

for(;!$p;){$t=str_split($n=++$argv[1]);sort($t);$p=strstr('0123456789',join($t));}echo$n;

用法:

php -r "for(;!$p;){$t=str_split($n=++$argv[1]);sort($t);$p=strstr('0123456789',join($t));}echo$n;" 9000

由于Xanderhall,以前的103字节版本:

<?for($p=0;!$p;){$t=str_split($n=++$_GET[n]);sort($t);$p=strstr('0123456789',implode($t));}echo "$n\n";

前105个字节的版本:

<?for($n=$_GET[n]+1;;$n++){$t=str_split($n);sort($t);if(strstr('0123456789',implode($t))){echo$n;exit;}}

用法:sortable-years.php?n=9000输出9678

带测试用例的非高尔夫版本:

$test = array(0,1,9,10,11,99,233,234,243,2016,2031,2103,2130,2134,9876,98764);

foreach ($test as $argv[1]) {
    for(;!$p;){
        $t=str_split($n=++$argv[1]);
        sort($t);
        $p=strstr('0123456789',join($t));
    }
    echo "$n\n"; // add newline for testing
    $p=false; // reset $p for testing
}

Output:
1
2
10
12
12
102
234
243
312
2031
2103
2130
2134
2143
10234
98765

在线测试!(新的89字节版本)

在线测试!(以前的103字节版本)

在线测试!(以前的105个字节的版本)

对于所有测试用例,执行时间可能<= 1秒。



@Xanderhall感谢您的改进。实际上,我正在设法找到一种方法breakexit在高尔夫球版本上),您发现了!大。
马里奥

我发布的链接仅是代码,目的是为了给您提供有关如何改进它的想法,它并不完全适合XD
Xanderhall,2013年

$i=0是不必要的(-4)。joinimplode(-3)的别名。echo$n足够的输出(-5)。$argv[1]而不是$_GET[n]允许-r,您可以省略<?标签(-2)。
泰特斯(Titus)

@Titus非常感谢你的伟大的高尔夫技巧,我还是有那么多学习一下吧,我也有更多的关注一些细节太多,我怀念......我还不知道join作为别名implode!关于php -r参数,我过去使用过,但是最近我没有使用它,因为(我不知道为什么)有时在某些情况下无法使其正常工作。
马里奥

2

Perl 6,49个字节

{first {$/eqv($/=.comb.sort).minmax.list},$_^..*}

说明

{

  first

  {

    $/             # sorted list from later

    eqv            # is it equivalent

    (

      $/           # store in match variable ( doesn't need to be declared )
      =
      .comb.sort   # sorted list of digits from currently tested value

    ).minmax       # the Range of digits
            .list  # flattened to a list
  },

  $_  ^..  *       # Range starting just after input

}

测试:

# give it a lexical name for clarity
my &code = {first {$/eqv($/=.comb.sort).minmax.list},$_^..*}

my @all = 'sortable.txt'.IO.lines;

my @gen = code(-1), &code ... ( * >= 98765 );

say @all eqv @gen; # True

say now - INIT now; # 16.3602371

2

C#,153个 130 101字节(122 99 83不包括命名空间声明)

using System.Linq;n=>{while(!"0123456789".Contains(string.Concat((++n+"").OrderBy(x=>x))));return n;}

-23字节归功于pinkfloydx33

另一个-29感谢Link Ng(我真的应该知道我不需要将其转换为数组)

该死的转换。

(增加的奖金这出奇地快)


您不需要穿线,使用$"{n}".ToCharArray()或,(""+n).ToCharArray()并且过一会儿也不需要括号:while(!s.Contains...)n++;或者更好的是将它们组合在一起并留下一个空的循环体:使用while(!s.Contains(.....$"{n++}".ToCharArray()....);return n; 声明s var s="... "或将其完全删除:while(!"0123456789".Contains(...
pinkfloydx33

我认为您也可以删除第一个n++,而是将其与上述内容结合使用并做$"{++n}".ToCharArray()
pinkfloydx33

@ pinkfloydx33我添加了您建议的大部分更改,即使不是全部!
Alfie Goodacre

1
删除use System;并使用string代替String11个字节。使用string.Concat代替,string.Join仅将2nd参数保留1个字节。更改""+ ++n++n+""1个字节。留给您练习:可以再删除14个字节。
Link Ng

@LinkNg进行了更改-我觉得xD数组很傻
Alfie Goodacre

1

Befunge,117字节

&>1+0v
9`#v_>:9+0\4p1+:
1:$<v
0g1+>00p:55+%9+1\4p55+/:!#v_0
v+*g09:<".........." 9p09 <
>:00g-v^<
-9:p09_v|
$v@._<$<>

在线尝试!

我们测试年份是否经过排序的方法是创建一个“数组”(写在第5行的字符串文字中),对于该年份中的每个数字,我们都将该索引设置为1。一旦所有数字都处理后,我们将按顺序计算多少个1,如果该计数等于年份长度,则可以假定年份已排序。

详细说明

&>1+                              Read the year and increment it.

    0v                            The "array" is initialized with zeros prior
9`#v_>:9+0\4p1+:                     to processing each year.

1:$<v                             For every digit, set the corresponding array index
0g1+>00p:55+%9+1\4p55+/:!#v_0       to one, and increment the year length counter.

                      p09 <       Initialise the sequence counter to zero.
                     9            Push a marker onto the stack.
        ".........."              Push the values from the array onto the stack.

v+*g09:<                          Increment the sequence counter for every 1 in the
>:00g-v^<                           array and reset it on every 0. Break if it equals
-9:p09_v|                           the year length or we encounter the end marker.

  @._<$<                          If we have a match, clear the stack and output the year.
$v      >                         If we've reached the marker, drop it try the next year.

1

Ruby,51个字节

->n{n+=1 until'0123456789'[n.to_s.chars.sort*''];n}

1

Python 2,68个字节

n=input()+1
while''.join(sorted(`n`))not in'0123456789':n+=1
print n

@Dennis打败了它,但是无论如何它只是作为一种替代方法发布的。


1

C#,127个字节

using System.Linq;n=>{char[]s;while((s=(++n+"").OrderBy(x=>x).ToArray()).Select((x,i)=>i>0&&x-s[i-1]!=1).Any(x=>x));return n;};

用3个字节击败当前的C#提交:p已经
被击败我知道这个答案将很容易被击败...
repl.it演示

不打高尔夫球

n=>
{
    char[] s;
    while((
        // Store char array in variable to be referenced in Select()
        // Increment n and cast to string
        s=(++n+"")
            // Sort ascending, to array
            .OrderBy(x=>x)
            .ToArray())
        // Convert char to true if it's not at position 0,
        // and it is not 1 greater than the previous char
        .Select((x,i)=>i>0&&x-s[i-1]!=1)
        // All false: n is sortable
        // Any true: n is not sortable
        .Any(x=>x))
    // while loop body is empty
    ;
    return n;
};


1

Python 2中,118 117 114 108字节

x,s=input()+1,sorted
while[j for i,j in enumerate(s(str(x))[1:])if int(s(str(x))[i])+1!=int(j)]:x+=1
print x

编辑:

-1字节感谢@GáborFekete

-6个字节,感谢@Zachary T


您可以通过为sorted函数别名来保存1个字节。
加博尔·费克特

您不能通过转换为python 2保存一些字节吗?
扎卡里

是的,我可以,谢谢,我没有想到这一点。
sonrad10年

1

PHP,90 89 88字节

完全不同的方法:

while(array_unique($a=str_split($n=++$argv[1]))!=$a|max($a)-min($a)-count($a)+1);echo$n;

用运行-r

分解

while(
    array_unique(           // 3. unique values
        $a=str_split(       // 2. split to digits
            $n=++$argv[1]   // 1. increase number
        )
    )
    !=$a                    // 4. repeat while unique digits differ from original digits
    |                       // or
        max($a)-min($a)     // digit range
        -count($a)+1        // differs from count-1
    );
echo$n;                 // print result

0

Clojure,104 96 91字节

龙方法名不要让这个短......至少map-indexed,并-得到一个整洁的方式进行主要计算。

编辑1:整洁,我也忘记了=可以接受多个参数,所以我不需要检查不同值的计数是否为1。

编辑2:无需运行(sort(seq(str %)))(sort(str %))效果同样好。

(fn[i](first(filter #(apply =(map-indexed -(map int(sort(str %)))))(rest(iterate inc i)))))

取消高尔夫:

(defn f [i]
  (let [is-sorted? #(= 1 (->> % str sort (map int) (map-indexed -) set count))]
    (->> i (iterate inc) rest (filter is-sorted?) first)))

0

R,87个字节

f=function(x)`if`(all(diff(sort(as.double(el(strsplit(c(x+1,""),"")))))==1),x+1,f(x+1))

像往常一样,将数字拆分为数字时,R没有本机操作。因此,我们必须将输入强制为字符,拆分为字符向量,然后再转换回任何数字类型。

在线尝试

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.