Найти сортируемые годы


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 Это должно закончиться с 1 минутой для всех входов до 98764. Это было разъяснено в посте.
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

Лучшее, что вы получаете, это то, 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 байта

Сохранено 10 байтов, благодаря Нейлу

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

Контрольные примеры


2
Вы можете сохранить 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 не выражает -matchпротив 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 байт

Новая версия 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

Предыдущая 103-байтовая версия благодаря Xanderhall:

<?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.

Ungolfed версия с тестовыми примерами:

$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 спасибо за ваши улучшения. На самом деле я пытался найти способ убрать это break( exitв версии для гольфа), вы нашли это! Отлично.
Марио

Ссылка, которую я разместил, была просто кодом, чтобы дать вам представление о том, как ее улучшить, она не полностью игра в гольф XD
Xanderhall

$i=0не нужен (-4). joinпсевдоним для implode(-3). echo$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;}

-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 Я добавил большинство предложенных вами изменений, если не все!
Алфи Гудэйк

1
Удалить use System;и использовать stringвместо String11 байт. Используйте string.Concatвместо string.Joinи оставьте только 2-й параметр для 1 байта. Изменение ""+ ++nв ++n+""1 байт. Оставлено для вас в качестве упражнения: можно удалить еще 14 байтов.
Ссылка Ng

@LinkNg были внесены изменения - я чувствую себя дураком для массива xD
Алфи Гудэйк

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

Попробуйте онлайн!

Мы проверяем, отсортирован ли год, путем создания «массива» (записанного в строковый литерал в строке пять), и для каждой цифры года мы устанавливаем этот индекс в массив равным 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

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 Отбитый уже,
я знаю, что этот ответ будет легко отброшен ...
repl.it demo

Ungolfed

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 байт благодаря @ Габору Фекете

-6 байт благодаря @Zachary T


Вы можете сохранить 1 байт, используя псевдоним sortedфункции.
Габор Фекете

Не можете ли вы сэкономить несколько байтов путем преобразования в 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)))))

Ungolfed:

(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 нет собственного способа сделать это. Следовательно, мы должны принудительно ввести ввод в символ, разделить его на вектор символов и затем преобразовать обратно в любой числовой тип.

Попробуйте онлайн

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.