ソート可能な年を見つける


26

2013年には興味深い特性がありました。ソートされたとき、数字は連続しています(0123)。このタイプの数値をソート可能な数値と呼びましょう。ソート後、10進数が連続する負でない整数です。残念ながら、これは2031年まで、その後2103年までは発生しません。あなたの課題は、標準的な方法で負でない整数が与えられたときに、次のソート可能な数値を出力または返すプログラムまたは関数を書くことです。

ルール

  • 入力と出力は基数10でなければなりません。
  • 出力は、任意の妥当な形式(数値リテラル、文字列リテラル、単一項目配列など)になります。
  • コードは、98764までのすべての入力に対して1分以内に適切な出力を生成する必要があります。

テストケース

    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

@ETHproductionsより大きな入力をサポートする必要がありますか?
マーティンエンダー

@MartinEnderいいえ、ほとんどの(すべてではないにしても)ソリューションが期待しています。要件を高くする必要がありますか?
ETHproductions

@ETHproductions私はそうは思わない、ただ確認したかった。
マーティンエンダー

回答:


9

Python 2、61バイト

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

オンラインでお試しください!


1
'0123456789'ようなものになりたいのです1./81が、うまくいきません。
xnor 16

あなたが取得しているベストです1./81.0000001どのまだ希望はない、適切な作業長い
アルフィー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バイト

ニールのおかげで、大量の10バイトを節約しました

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

テストケース


2
あなたは3番目のパラメータということに注目することによって、あなたのオリジナルの答えから2つのバイトを保存することができmap、コールバックが配列そのものですが、あなたはもっとよくするために行くことができます:f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n
ニール


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)リテラル文字列よりも1バイト短いことを認識して、バイトを保存しました0123456789


3

Mathematica、63バイト

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

falseである#+1限り、次の値に置き換えられますDifferences@Sort@IntegerDigits@x~MatchQ~{1...}。これは、現在の値がソート可能であるという条件です。

残念ながら、あまりにも長すぎた別の楽しいアイデアを次に示します。

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

$i=0不要です(-4)。(-3)のjoinエイリアスですimplodeecho$n十分な出力です(-5)。$argv[1]代わりの$_GET[n]可能-rあなたが省略することを可能にする<?タグを(-2)。
タイタス

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

pinkfloydx33のおかげで-23バイト

Link Ngのおかげで別の-29(配列に変換する必要がないことを本当に知っていたはずです)

くそコンバージョン。

(追加されたボーナスこれは驚くほど速いです)


文字列を使用する必要はありません、$"{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すべてではないにしても、あなたが提案した変更の大部分を追加しました!
アルフィーGoodacre

1
削除してuse System;、11バイトstringStringはなく使用します。string.Concat代わりに使用しstring.Join、1バイトの2番目のパラメーターのみを保持します。1バイトに変更""+ ++n++n+""ます。演習としてあなたに任せてください:さらに14バイトを削除できます。
リンクNg

@LinkNg変更が行われました-私は、アレイのxDのための愚か者のように感じる
アルフィー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;};

現在のC#の提出を3バイトで破り
ます。pすでにBeatられています。この回答は簡単にbeatられます
。repl.it demo

非ゴルフ

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

パイソン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に感謝

@Zachary Tのおかげで-6バイト


sorted関数をエイリアスすることで1バイトを節約できます。
ガボールフェケテ

python 2に変換していくつかのバイトを節約できませんか?
ザカリー16

はい、できませんでした、ありがとう、私はそれを考えていませんでした。
sonrad10 16

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にはこれを行うネイティブな方法がありません。そのため、入力を文字に強制し、文字ベクトルに分割し、その後で数値型に変換し直す必要があります。

オンラインで試す

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.