Temukan tahun yang dapat disortir

26

Tahun 2013 memiliki properti yang menarik: digitnya berurutan ketika diurutkan (0123). Sebut jenis nomor ini nomor yang dapat diurutkan: integer non-negatif yang basis-10 digitnya berurutan setelah pengurutan. Sayangnya, ini tidak akan terjadi lagi sampai 2031, dan setelah itu, tidak sampai 2103. Tantangan Anda adalah menulis sebuah program atau fungsi yang, ketika diberi bilangan bulat non-negatif melalui metode standar apa pun, mengeluarkan atau mengembalikan nomor yang dapat diurutkan berikutnya.

Aturan

  • Input dan output harus dalam basis 10.
  • Output dapat dalam format apa pun yang wajar (angka literal, string literal, array item tunggal, ...).
  • Kode Anda harus menghasilkan output yang tepat dalam 1 menit untuk semua input hingga 98764.

Uji kasus

    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

Angka-angka yang dapat diurutkan membentuk A215014 . Daftar semua entri hingga 98765 dapat ditemukan di sini .

Mencetak gol

Ini adalah , jadi kode terpendek dalam byte menang.

Produksi ETH
sumber
Apa yang kamu maksud dengan pekerjaan ? Apakah boleh jika butuh waktu yang sangat lama?
Dennis
@ Dennis Ini harus selesai dengan 1 menit untuk semua input hingga 98764. Ini telah diklarifikasi dalam posting.
ETHproductions
@ ETHproductions Apakah harus mendukung input yang lebih besar?
Martin Ender
@ MartinEnder Tidak, walaupun saya berharap sebagian besar (jika tidak semua) solusi akan. Haruskah persyaratannya lebih tinggi?
ETHproductions
@ ETHproductions Saya rasa tidak, saya hanya ingin memastikan.
Martin Ender

Jawaban:

9

Python 2 , 61 byte

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

Cobalah online!

Dennis
sumber
1
Saya ingin '0123456789'menjadi seperti itu 1./81, tetapi itu tidak berhasil.
xnor
Yang terbaik yang Anda dapatkan adalah 1./81.0000001yang masih tidak berfungsi dengan baik dan lebih lama
Alfie Goodacre
@AlfieGoodacre Anda dapat melakukannya dengan lebih baik 1./81-1e-10tetapi masih 10 byte dan Anda masih harus memotongnya.
Martin Ender
7

Jelly , 11 10 9 byte

⁵ḶwṢ
‘Ç1#

Mengembalikan array tunggal. Cobalah online!

Bagaimana itu bekerja

‘Ç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.
Dennis
sumber
6

MATL , 8 byte

`QtVSdqa

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

`     % 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)
Luis Mendo
sumber
5

JavaScript (ES6), 64 54 byte

Menyimpan 10 byte besar, terima kasih kepada Neil

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

Uji kasus

Arnauld
sumber
2
Anda dapat menyimpan 2 byte dari jawaban asli Anda dengan mencatat bahwa parameter ketiga untuk mappanggil balik adalah array itu sendiri, tetapi Anda dapat melanjutkan untuk melakukan jauh lebih baik:f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n
Neil
4

PowerShell v2 +, 71 68 67 byte

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

Cobalah online!

Solusi berulang yang berjalan cukup instan di mesin saya.

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

TotalSeconds : 0.0487127

Ya, itu a do/ untilloop dalam kode-golf. Maaf, tidak menyesal. Pada dasarnya kita loop ke atas dari input kita $nsampai $n|sorted -matchmelawan 0123456789. Kemudian kami menempatkan $npada pipeline, dan output tersirat.

Menyimpan byte dengan menyadari bahwa -join(0..9)satu byte lebih pendek dari string literal 0123456789.

AdmBorkBork
sumber
3

Mathematica, 63 byte

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

Mengganti #+1dengan nilai berikutnya asalkan Differences@Sort@IntegerDigits@x~MatchQ~{1...}salah, yang merupakan kondisi bahwa nilai saat ini dapat diurutkan.

Ini ide lain yang menyenangkan, yang sayangnya terlalu panjang:

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

Dalam yang ini, saya menghasilkan semua tahun yang dapat disortir pertama dan kemudian saya memilih yang pertama yang lebih besar dari input.

Beberapa gagasan lain yang ternyata tidak lebih pendek dari upaya pertama:

#+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&
Martin Ender
sumber
3

PHP, 105 103 89 byte

Versi baru 89 byte berkat Titus:

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

Pemakaian:

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

Versi 103 byte sebelumnya berkat Xanderhall:

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

Versi 105 byte sebelumnya:

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

Pemakaian: sortable-years.php?n=9000 output 9678.

Versi tidak dikoleksi dengan kasus uji:

$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

Tes online! (Versi 89 byte baru)

Tes online! (Versi 103 byte sebelumnya)

Tes online! (Versi 105 byte sebelumnya)

Waktu pelaksanaan mungkin <= 1 detik untuk semua kasus uji.

Mario
sumber
@Xanderhall terima kasih atas peningkatan Anda. Sebenarnya saya sedang berusaha menemukan cara untuk mengambil break( exitpada versi golf), Anda menemukannya! Besar.
Mario
Tautan yang saya poskan hanyalah kode untuk memberi Anda gambaran tentang bagaimana memperbaikinya, itu tidak sepenuhnya
golf
$i=0tidak perlu (-4). joinadalah alias untuk implode(-3). echo$ncukup output (-5). $argv[1]alih-alih $_GET[n]memungkinkan -ryang memungkinkan Anda untuk menghilangkan <?tag (-2).
Titus
@Titus terima kasih banyak atas tip golf yang hebat ini, saya masih harus belajar banyak tentang hal itu, dan saya juga harus lebih memperhatikan beberapa detail yang saya lewatkan ... Saya belum tahu tentang joinalias alias implode! Mengenai php -rparameternya, saya pernah menggunakannya di masa lalu tetapi belakangan ini saya tidak menggunakannya karena (saya tidak tahu mengapa) kadang-kadang saya tidak dapat membuatnya berfungsi dengan baik dalam beberapa kasus.
Mario
2

Perl 6 , 49 byte

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

Penjelasan

{

  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

}

Uji:

# 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
Brad Gilbert b2gills
sumber
2

C #, 153 130 101 byte ( 122 99 83 tidak termasuk deklarasi namespace)

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

-23 byte berkat pinkfloydx33

lain -29 terima kasih kepada Link Ng (saya benar-benar seharusnya tahu saya tidak perlu mengubahnya menjadi array)

Konversi sialan.

(Bonus tambahan ini sangat cepat)

Alfie Goodacre
sumber
Anda tidak perlu merangkai, menggunakan $"{n}".ToCharArray()atau (""+n).ToCharArray()dan Anda tidak perlu tanda kurung setelah beberapa saat: while(!s.Contains...)n++;atau lebih baik menggabungkannya dan meninggalkan tubuh loop kosong: while(!s.Contains(.....$"{n++}".ToCharArray()....);return n; menyatakan s dengan var s="... "atau menghapus seluruhnya:while(!"0123456789".Contains(...
pinkfloydx33
Saya pikir Anda juga dapat menghapus yang pertama n++dan sebaliknya menggabungkannya dengan yang di atas dan lakukan$"{++n}".ToCharArray()
pinkfloydx33
@ pinkfloydx33 Saya menambahkan sebagian besar perubahan yang Anda sarankan, jika tidak semua!
Alfie Goodacre
1
Hapus use System;dan gunakan stringbukan Stringuntuk 11 byte. Gunakan string.Concatalih-alih string.Joindan simpan hanya parameter ke-2 untuk 1 byte. Ubah ""+ ++nke ++n+""untuk 1 byte. Ditinggalkan sebagai latihan: 14 byte lebih dapat dihapus.
Tautan Ng
@LinkNg perubahan telah dibuat - Saya merasa seperti orang bodoh untuk array xD
Alfie Goodacre
1

Befunge , 117 byte

&>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@._<$<>

Cobalah online!

Cara kami menguji apakah satu tahun diurutkan adalah dengan membuat "array" (ditulis ke dalam string literal pada baris lima) dan untuk setiap digit dalam tahun tersebut, kami menetapkan indeks ke dalam array menjadi 1. Setelah semua digit telah diproses, kami menghitung berapa banyak 1s yang ada secara berurutan, dan jika jumlah itu sama dengan panjang tahun kami dapat menganggap tahun itu diurutkan.

Penjelasan detail

&>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.
James Holderness
sumber
1

Ruby, 51 byte

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

Python 2, 68 byte

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

Dipukul dengan baik oleh @ Dennis tetapi hanya diposting sebagai metode alternatif pula.

ElPedro
sumber
1

C #, 127 byte

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

Kalahkan pengajuan C # saat ini sebanyak 3 byte: p Sudah
dikalahkan Saya tahu jawaban ini akan dikalahkan dengan mudah ...
demo repl.it

Tidak disatukan

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;
};
Tautan Ng
sumber
1

05AB1E , 10 9 byte

-1 terima kasih kepada Emigna.

[>D{žhså#

Cobalah online!

Deskripsi baru datang ketika saya punya waktu.

Guci Gurita Ajaib
sumber
2
[>D{žhså#untuk 9 byte.
Emigna
1

Python 2, 118 117 114 108 Bytes

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

EDIT:

-1 Byte berkat @ Gábor Fekete

-6 Bytes berkat @Zachary T

sonrad10
sumber
Anda dapat menyimpan 1 byte dengan aliasing sortedfungsinya.
Gábor Fekete
Tidak bisakah Anda menyimpan beberapa byte dengan mengkonversi ke python 2?
Zacharý
Ya saya bisa, terima kasih, saya tidak memikirkan itu.
sonrad10
1

PHP, 90 89 88 byte

pendekatan yang sama sekali berbeda:

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

Jalankan dengan -r.

kerusakan

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
Titus
sumber
0

Clojure, 104 96 91 byte

Nama metode panjang tidak membuat ini sesingkat ... Setidaknya map-indexeddan -menyelesaikan perhitungan utama dengan rapi.

Sunting 1 : Rapi, saya lupa juga =dapat mengambil beberapa argumen jadi saya tidak perlu memeriksa apakah jumlah nilai yang berbeda adalah 1.

Sunting 2 : Tidak perlu dijalankan (sort(seq(str %))), (sort(str %))berfungsi sama baiknya.

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

Tidak Disatukan:

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

R, 87 byte

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

Seperti biasa dalam hal membagi angka menjadi angka, R tidak memiliki cara asli untuk melakukan ini. Akibatnya, kita harus memaksa input menjadi karakter, membelah menjadi vektor karakter dan kemudian mengkonversi kembali ke jenis numerik apa pun.

Cobalah online

Billywob
sumber