Encuentra los años clasificables

26

El año 2013 tuvo una propiedad interesante: los dígitos son consecutivos cuando se ordenan (0123). Llamemos a este tipo de número un número ordenable: un número entero no negativo cuyos dígitos de base 10 son consecutivos después de la clasificación. Desafortunadamente, esto no volverá a suceder hasta 2031, y después de eso, no hasta 2103. Su desafío es escribir un programa o función que, cuando se le da un número entero no negativo a través de cualquier método estándar, genera o devuelve el siguiente número ordenable.

Reglas

  • La entrada y la salida deben estar en la base 10.
  • La salida puede tener cualquier formato razonable (número literal, literal de cadena, matriz de un solo elemento, ...)
  • Su código debe producir la salida adecuada en 1 minuto para todas las entradas hasta 98764.

Casos de prueba

    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

Los números ordenables forman A215014 . Una lista de todas las entradas de hasta 98765 se puede encontrar aquí .

Tanteo

Este es el , por lo que gana el código más corto en bytes.

ETHproducciones
fuente
¿Qué quieres decir con trabajo ? ¿Está bien si lleva mucho tiempo?
Dennis
@Dennis Debe finalizar con 1 minuto para todas las entradas hasta 98764. Esto se ha aclarado en la publicación.
ETHproductions
@ETHproductions ¿Tiene que admitir entradas más grandes?
Martin Ender
@ MartinEnder No, aunque espero que la mayoría (si no todas) las soluciones lo harán. ¿Debería ser mayor el requisito?
ETHproductions
@ETHproductions No lo creo, solo quería asegurarme.
Martin Ender

Respuestas:

9

Python 2 , 61 bytes

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

Pruébalo en línea!

Dennis
fuente
1
Quiero '0123456789'ser algo así 1./81, pero no funciona del todo.
xnor
Lo mejor que obtienes es lo 1./81.0000001que todavía no funcionaría correctamente y es más largo
Alfie Goodacre
@AlfieGoodacre Podrías hacerlo mejor, 1./81-1e-10pero aún son 10 bytes y aún tendrías que truncarlo .
Martin Ender
7

Gelatina , 11 10 9 bytes

⁵ḶwṢ
‘Ç1#

Devuelve una matriz singleton. Pruébalo en línea!

Cómo funciona

‘Ç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
fuente
6

MATL , 8 bytes

`QtVSdqa

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

`     % 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
fuente
5

JavaScript (ES6), 64 54 bytes

Ahorró 10 bytes masivos, gracias a Neil

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

Casos de prueba

Arnauld
fuente
2
Puede guardar 2 bytes de su respuesta original al observar que el tercer parámetro para la mapdevolución de llamada es la matriz en sí, pero puede hacerlo mucho mejor:f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n
Neil
4

PowerShell v2 +, 71 68 67 bytes

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

Pruébalo en línea!

Una solución iterativa que se ejecuta casi instantáneamente en mi máquina.

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

TotalSeconds : 0.0487127

Sí, eso es un bucle do/ untilen un código de golf. Lo siento no lo siento. Básicamente, hacia arriba de nuestro bucle de entrada $nhasta $n|sorted expresión regular -matches en contra 0123456789. Luego colocamos $nen la tubería, y la salida es implícita.

Se guardó un byte al darse cuenta de que -join(0..9)es un byte más corto que la cadena literal 0123456789.

AdmBorkBork
fuente
3

Mathematica, 63 bytes

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

Reemplaza #+1con el siguiente valor siempre que Differences@Sort@IntegerDigits@x~MatchQ~{1...}sea ​​falso, que es la condición de que el valor actual sea ordenable.

Aquí hay otra idea divertida, que desafortunadamente terminó siendo demasiado larga:

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

En este, primero estoy generando todos los años clasificables y luego selecciono el primero que es mayor que la entrada.

Algunas ideas más que no resultaron ser más cortas que el primer intento:

#+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
fuente
3

PHP, 105 103 89 bytes

Nueva versión de 89 bytes gracias a Titus:

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

Uso:

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

Versión anterior de 103 bytes gracias a Xanderhall:

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

Versión anterior de 105 bytes:

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

Uso: sortable-years.php?n=9000salidas 9678.

Versión sin golf con casos de prueba:

$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

Prueba en línea! (Nueva versión de 89 bytes)

Prueba en línea! (Versión anterior de 103 bytes)

Prueba en línea! (Versión anterior de 105 bytes)

El tiempo de ejecución puede ser <= 1 segundo para todos los casos de prueba.

Mario
fuente
Hice
@ Xanderhall gracias por tus mejoras. En realidad estaba tratando de encontrar una manera de quitar eso break( exiten la versión de golf), ¡lo encontraste! Excelente.
Mario
El enlace que publiqué era solo un código para darte una idea de cómo mejorarlo, no está totalmente desarrollado XD
Xanderhall
$i=0es innecesario (-4). joines un alias para implode(-3). echo$nes suficiente salida (-5). $argv[1]en lugar de $_GET[n]permite -rque le permite omitir la <?etiqueta (-2).
Titus
@Titus muchas gracias por sus excelentes consejos de golf, todavía tengo mucho que aprender al respecto, y también tengo que prestar más atención a algunos detalles que también echo de menos ... ¡Todavía no lo sabía joincomo alias implode! Sobre el php -rparámetro, lo usé en el pasado pero últimamente no lo estoy usando porque (no sé por qué) a veces no puedo hacer que funcione correctamente en algunos casos.
Mario
2

Perl 6 , 49 bytes

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

Explicación

{

  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

}

Prueba:

# 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
fuente
2

C #, 153 130 101 bytes ( 122 99 83 excluyendo declaraciones de espacio de nombres)

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

-23 bytes gracias a pinkfloydx33

otro -29 gracias a Link Ng (realmente debería haber sabido que no necesito convertirlo en una matriz)

Malditas conversiones.

(Bono adicional esto es sorprendentemente rápido)

Alfie Goodacre
fuente
No necesita encadenar, usar $"{n}".ToCharArray()o (""+n).ToCharArray()y no necesita los corchetes después de un tiempo: while(!s.Contains...)n++;o mejor aún combinarlos y dejar un cuerpo de bucle vacío: while(!s.Contains(.....$"{n++}".ToCharArray()....);return n; declarar s con var s="... "o eliminarlo por completo:while(!"0123456789".Contains(...
pinkfloydx33
Creo que también puedes eliminar el primero n++y combinarlo con lo anterior y hacer$"{++n}".ToCharArray()
pinkfloydx33
@ pinkfloydx33 ¡Agregué la mayoría de los cambios que sugirió, si no todos!
Alfie Goodacre
1
Eliminar use System;y usar en stringlugar de Stringpor 11 bytes. Use en string.Concatlugar de string.Joiny mantenga solo el segundo parámetro para 1 byte. Cambie ""+ ++na ++n+""por 1 byte. Dejado a usted como ejercicio: se pueden eliminar 14 bytes más.
Enlace del
Se han realizado cambios en @LinkNg - Me siento como un tonto por la matriz xD
Alfie Goodacre
1

Befunge , 117 bytes

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

Pruébalo en línea!

La forma en que probamos si un año está ordenado es creando una "matriz" (escrita en el literal de cadena en la línea cinco) y para cada dígito en el año, establecemos ese índice en la matriz en 1. Una vez que todos los dígitos han sido procesados, contamos cuántos 1 hay en secuencia, y si ese recuento es igual a la duración del año, podemos suponer que el año está ordenado.

Explicación detallada

&>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
fuente
1

Ruby, 51 bytes

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

Python 2, 68 bytes

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

Bien golpeado por @Dennis pero publicado de todos modos como un método alternativo.

ElPedro
fuente
1

C #, 127 bytes

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

Batir el envío actual de C # por 3 bytes: p Retrocedido ya
sé que esta respuesta se revertirá fácilmente ...
repl.it demo

Sin golf

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;
};
Enlace Ng
fuente
1

05AB1E , 10 9 bytes

-1 gracias a Emigna.

[>D{žhså#

Pruébalo en línea!

Nueva descripción viene cuando tengo tiempo.

Urna de pulpo mágico
fuente
2
[>D{žhså#por 9 bytes.
Emigna
1

Python 2, 118117114108 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

EDITAR:

-1 Byte gracias a @ Gábor Fekete

-6 Bytes gracias a @Zachary T

sonrad10
fuente
Puede guardar 1 byte aliasing la sortedfunción.
Gábor Fekete
¿No puedes guardar algunos bytes convirtiendo a python 2?
Zacharý
Sí, podría, gracias, no había pensado en eso.
sonrad10
1

PHP, 90 89 88 bytes

Un enfoque completamente diferente:

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

Corre con -r.

Descompostura

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
fuente
0

Clojure, 104 96 91 bytes

Los nombres largos de métodos no hacen que esto sea tan corto ... Al menos, map-indexedy -haga los cálculos principales de forma ordenada.

Edición 1 : ordenado, olvidé que también =puede tomar varios argumentos, por lo que no necesito verificar si el recuento de valores distintos es 1.

Edición 2 : no es necesario ejecutar (sort(seq(str %))), (sort(str %))funciona igual de bien.

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

Sin golf:

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

R, 87 bytes

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

Como de costumbre cuando se trata de dividir números en dígitos, R no tiene una forma nativa de hacerlo. En consecuencia, tenemos que forzar la entrada en un carácter, dividirlo en un vector de caracteres y posteriormente convertirlo de nuevo a cualquier tipo numérico.

Pruébalo en línea

Billywob
fuente