Trouver les années triables


26

L'année 2013 avait une propriété intéressante: les chiffres sont consécutifs lorsqu'ils sont triés (0123). Appelons ce type de nombre un nombre triable: un entier non négatif dont les chiffres de base 10 sont consécutifs après le tri. Malheureusement, cela ne se reproduira pas avant 2031, et après cela, pas avant 2103. Votre défi est d'écrire un programme ou une fonction qui, lorsqu'il reçoit un entier non négatif par le biais d'une méthode standard, génère ou renvoie le numéro triable suivant.

Règles

  • L'entrée et la sortie doivent être en base 10.
  • La sortie peut être dans n'importe quel format raisonnable (littéral nombre, littéral chaîne, tableau à un seul élément, ...).
  • Votre code doit produire la sortie appropriée en 1 minute pour toutes les entrées jusqu'à 98764.

Cas de test

    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

Les nombres triables forment A215014 . Une liste de toutes les entrées jusqu'à 98765 peut être trouvée ici .

Notation

Il s'agit de , donc le code le plus court en octets l'emporte.


Qu'entendez-vous par travail ? Est-ce correct si cela prend vraiment du temps?
Dennis

@Dennis Il doit se terminer avec 1 minute pour toutes les entrées jusqu'à 98764. Cela a été clarifié dans le message.
ETHproductions

@ETHproductions Doit-il prendre en charge des intrants plus importants?
Martin Ender

@MartinEnder Non, même si je m'attends à ce que la plupart des solutions (sinon toutes) le soient. L'exigence devrait-elle être plus élevée?
ETHproductions

@ETHproductions Je ne pense pas, je voulais juste m'en assurer.
Martin Ender

Réponses:


9

Python 2 , 61 octets

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

Essayez-le en ligne!


1
Je veux '0123456789'être quelque chose comme ça 1./81, mais ça ne marche pas tout à fait.
xnor

Le meilleur que vous obtenez est celui 1./81.0000001qui ne fonctionne toujours pas correctement et qui est plus long
Alfie Goodacre

@AlfieGoodacre Vous pourriez faire mieux avec 1./81-1e-10mais c'est toujours 10 octets et vous auriez encore à le tronquer.
Martin Ender

7

Gelée , 11 10 9 octets

⁵ḶwṢ
‘Ç1#

Renvoie un tableau singleton. Essayez-le en ligne!

Comment ça marche

‘Ç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 octets

`QtVSdqa

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

`     % 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 octets

A sauvé un énorme 10 octets, grâce à Neil

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

Cas de test


2
Vous pouvez enregistrer 2 octets de votre réponse d'origine en notant que le troisième paramètre du maprappel est le tableau lui-même, mais vous pouvez continuer à faire beaucoup mieux:f=n=>[...++n+''].sort().some((v,i,a)=>v-i-a[0])?f(n):n
Neil


4

PowerShell v2 +, 71 68 67 octets

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

Essayez-le en ligne!

Une solution itérative qui s'exécute pratiquement instantanément sur ma machine.

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

TotalSeconds : 0.0487127

Oui, c'est une boucle do/ untildans un code-golf. Désolé, pas désolé. Fondamentalement, nous bouclons vers le haut à partir de notre entrée $njusqu'à ce que les $n|sortexpressions rationnelles soient -matchcontre 0123456789. Ensuite, nous plaçons$n sur le pipeline, et la sortie est implicite.

Enregistré un octet en réalisant qu'il -join(0..9)est un octet plus court que la chaîne littérale 0123456789.


3

Mathematica, 63 octets

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

Remplace #+1par la valeur suivante tant queDifferences@Sort@IntegerDigits@x~MatchQ~{1...} est fausse, condition à laquelle la valeur actuelle peut être triée.

Voici une autre idée amusante, qui a malheureusement fini par être trop longue:

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

Dans celui-ci, je génère d'abord toutes les années triables, puis je sélectionne la première qui est supérieure à l'entrée.

Quelques idées supplémentaires qui ne se sont pas avérées plus courtes que la première tentative:

#+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 bytes

Nouvelle version de 89 octets grâce à Titus:

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

Usage:

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

Version précédente de 103 octets grâce à Xanderhall:

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

Version précédente de 105 octets:

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

Utilisation: sortable-years.php?n=9000sorties9678 .

Version non golfée avec cas de test:

$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

Testez en ligne! (Nouvelle version de 89 octets)

Testez en ligne! (Version précédente de 103 octets)

Testez en ligne! (Version précédente de 105 octets)

Le temps d'exécution peut être <= 1 seconde pour tous les cas de test.



@Xanderhall merci pour vos améliorations. En fait, j'essayais de trouver un moyen d'enlever cela break( exitsur la version golfée), vous l'avez trouvé! Génial.
Mario

Le lien que j'ai posté n'était qu'un code pour vous donner une idée de la façon de l'améliorer, ce n'est pas entièrement joué XD
Xanderhall

$i=0est inutile (-4). joinest un alias pour implode(-3). echo$nest une sortie suffisante (-5). $argv[1]au lieu de $_GET[n]permet -rce qui vous permet d'omettre la <?balise (-2).
Titus

@Titus merci beaucoup pour vos bons conseils de golf, j'ai encore tellement de choses à apprendre à ce sujet, et je dois aussi prêter plus d'attention à certains détails qui me manquent ... Je ne connaissais pas encore l' joinalias de implode! À propos du php -rparamètre, j'ai utilisé dans le passé mais récemment je ne l'utilise pas parce que (je ne sais pas pourquoi) parfois je ne peux pas le faire fonctionner correctement dans certains cas.
Mario

2

Perl 6 , 49 octets

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

Explication

{

  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

}

Tester:

# 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 octets ( 122 99 83 hors déclarations d'espace de noms)

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

-23 octets grâce à pinkfloydx33

un autre -29 grâce à Link Ng (j'aurais vraiment dû savoir que je n'ai pas besoin de le convertir en tableau)

Putain de conversions.

(Bonus ajouté, c'est étonnamment rapide)


Vous n'avez pas besoin d'enchaîner, d'utiliser $"{n}".ToCharArray()ou (""+n).ToCharArray()et vous n'avez pas besoin des crochets après le temps: while(!s.Contains...)n++;ou mieux encore de les combiner et de laisser un corps de boucle vide: while(!s.Contains(.....$"{n++}".ToCharArray()....);return n; déclarez s avec var s="... "ou supprimez-le entièrement:while(!"0123456789".Contains(...
pinkfloydx33

Je pense que vous pouvez également supprimer le premier n++et le combiner avec ce qui précède et faire$"{++n}".ToCharArray()
pinkfloydx33

@ pinkfloydx33 J'ai ajouté la majorité des changements que vous avez suggérés, sinon tous!
Alfie Goodacre

1
Supprimez use System;et utilisez stringau lieu de Stringpour 11 octets. Utilisez string.Concatau lieu de string.Joinet ne conservez que le 2e paramètre pendant 1 octet. Passez ""+ ++nà ++n+""1 octet. Laissé à vous comme exercice: 14 octets supplémentaires peuvent être supprimés.
Link Ng

@LinkNg des modifications ont été apportées - je me sens comme un idiot pour le tableau xD
Alfie Goodacre

1

Befunge , 117 octets

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

Essayez-le en ligne!

La façon dont nous testons si une année est triée consiste à créer un "tableau" (écrit dans le littéral de chaîne à la ligne cinq) et pour chaque chiffre de l'année, nous définissons cet index dans le tableau à 1. Une fois que tous les chiffres ont été traitées, nous comptons le nombre de 1 dans l'ordre, et si ce nombre est égal à la durée de l'année, nous pouvons supposer que l'année est triée.

Explication détaillée

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

Rubis, 51 octets

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

1

Python 2, 68 octets

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

Bien battu par @Dennis mais vient tout de même d'être affiché comme méthode alternative.


1

C #, 127 octets

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

Battre la soumission C # actuelle de 3 octets: p Déjà repoussé
Je sais que cette réponse sera repoussée facilement ...
repoussée repl.it demo

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


1

Python 2, 118117114108 octets

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

MODIFIER:

-1 octet grâce à @ Gábor Fekete

-6 octets grâce à @Zachary T


Vous pouvez enregistrer 1 octet en aliasant la sortedfonction.
Gábor Fekete

Vous ne pouvez pas enregistrer certains octets en convertissant en python 2?
Zacharý

Oui, je le pouvais, merci, je n'y avais pas pensé.
sonrad10

1

PHP, 90 89 88 octets

une approche complètement différente:

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

Courez avec -r.

panne

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 octets

Les noms de méthode longs ne rendent pas cela si court ... Au moins map-indexedet -faites les calculs principaux de manière ordonnée.

Modifier 1 : soigné, j'ai oublié que je =peux également prendre plusieurs arguments, donc je n'ai pas besoin de vérifier si le nombre de valeurs distinctes est égal à 1.

Edit 2 : Pas besoin de courir (sort(seq(str %))),(sort(str %)) fonctionne aussi bien.

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

Non golfé:

(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 octets

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

Comme d'habitude quand il s'agit de diviser des nombres en chiffres, R n'a pas de manière native de le faire. Par conséquent, nous devons contraindre l'entrée en un caractère, la diviser en un vecteur de caractères et la reconvertir ensuite en n'importe quel type numérique.

Essayez-le en ligne

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.