Finde die sortierbaren Jahre

26

Das Jahr 2013 hatte eine interessante Eigenschaft: Die Ziffern sind nacheinander sortiert (0123). Nennen wir diesen Zahlentyp eine sortierbare Zahl: eine nicht negative Ganzzahl, deren 10-stellige Basis nach dem Sortieren fortlaufend ist. Leider wird dies erst 2031 und danach erst 2103 wieder vorkommen. Ihre Herausforderung besteht darin, ein Programm oder eine Funktion zu schreiben, die die nächste sortierbare Zahl ausgibt oder zurückgibt, wenn sie mit einer Standardmethode eine nicht negative Ganzzahl enthält.

Regeln

  • Eingabe und Ausgabe müssen in Basis 10 sein.
  • Die Ausgabe kann in jedem vernünftigen Format erfolgen (Zahlenliteral, Zeichenfolgenliteral, Einzelelementarray usw.).
  • Ihr Code muss innerhalb von 1 Minute für alle Eingaben bis 98764 die richtige Ausgabe erzeugen.

Testfälle

    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

Die sortierbaren Zahlen bilden A215014 . Eine Liste aller Einträge bis 98765 finden Sie hier .

Wertung

Das ist , also gewinnt der kürzeste Code in Bytes.

ETHproductions
quelle
Was meinst du mit Arbeit ? Ist es in Ordnung, wenn es sehr lange dauert?
Dennis
@Dennis Es muss mit 1 Minute für alle Eingaben bis 98764 beendet werden. Dies wurde im Beitrag geklärt.
ETHproductions
@ETHproductions Muss es überhaupt größere Eingänge unterstützen?
Martin Ender
@MartinEnder Nein, obwohl ich die meisten (wenn nicht alle) Lösungen erwarte. Sollte die Anforderung höher sein?
ETHproductions
@ETHproductions Ich glaube nicht, ich wollte nur sicher gehen.
Martin Ender

Antworten:

9

Python 2 , 61 Bytes

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

Probieren Sie es online!

Dennis
quelle
1
Ich möchte '0123456789'so etwas sein 1./81, aber es funktioniert nicht ganz.
Xnor
Das Beste, was Sie bekommen, ist, 1./81.0000001was immer noch nicht richtig funktioniert und länger ist
Alfie Goodacre
@AlfieGoodacre Du könntest es besser machen, 1./81-1e-10aber es sind immer noch 10 Bytes und du müsstest es immer noch kürzen .
Martin Ender
7

Jelly , 11 10 9 Bytes

⁵ḶwṢ
‘Ç1#

Gibt ein Singleton-Array zurück. Probieren Sie es online!

Wie es funktioniert

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

MATL , 8 Bytes

`QtVSdqa

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

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

JavaScript (ES6), 64 54 Bytes

Dank Neil konnten 10 Bytes eingespart werden

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

Testfälle

Arnauld
quelle
2
Sie können 2 Bytes Ihrer ursprünglichen Antwort einsparen, indem Sie feststellen, dass der dritte Parameter für den mapRückruf das Array selbst ist. Sie können jedoch noch viel besser 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

Probieren Sie es online!

Eine iterative Lösung, die auf meinem Computer praktisch sofort ausgeführt wird.

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

TotalSeconds : 0.0487127

Ja, das ist eine do/ untilloop in einem Code-Golf. Tut mir leid, nicht leid. Grundsätzlich schleifen wir von unserer Eingabe nach oben, $nbis die $n|sortregulären -matchAusdrücke entgegenstehen 0123456789. Dann platzieren wir $nin der Pipeline und die Ausgabe ist implizit.

Ein Byte wurde gespeichert, indem erkannt wurde, dass -join(0..9)es ein Byte kürzer als die Literalzeichenfolge ist 0123456789.

AdmBorkBork
quelle
3

Mathematica, 63 Bytes

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

Wird #+1durch den nächsten Wert ersetzt, solange dieser Differences@Sort@IntegerDigits@x~MatchQ~{1...}falsch ist. Dies ist die Bedingung, dass der aktuelle Wert sortiert werden kann.

Hier ist eine weitere lustige Idee, die leider viel zu lange gedauert hat:

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

In dieser generiere ich zuerst alle sortierbaren Jahre und wähle dann die erste aus, die größer als die Eingabe ist.

Weitere Ideen, die nicht kürzer waren als der erste Versuch:

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

PHP, 105 103 89 Bytes

Neue 89-Byte-Version dank Titus:

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

Verwendung:

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

Vorherige 103-Byte-Version dank Xanderhall:

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

Vorherige 105-Byte-Version:

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

Verwendung: sortable-years.php?n=9000Ausgänge 9678.

Ungolfed-Version mit Testfällen:

$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

Online testen! (Neue 89-Byte-Version)

Online testen! (Vorherige 103-Byte-Version)

Online testen! (Vorherige 105-Byte-Version)

Ausführungszeit für alle Testfälle möglicherweise <= 1 Sekunde.

Mario
quelle
@Xanderhall danke für deine Verbesserungen. Eigentlich habe ich versucht, einen Weg zu finden, um das break( exitauf der Golf-Version) wegzunehmen, du hast es gefunden! Groß.
Mario
Der Link, den ich gepostet habe, war nur Code, um Ihnen eine Vorstellung davon zu geben, wie Sie ihn verbessern können. Er ist nicht voll besetzt. XD
Xanderhall
$i=0ist unnötig (-4). joinist ein Alias ​​für implode(-3). echo$nist genug Leistung (-5). $argv[1]anstelle von $_GET[n]allow -rkönnen Sie das <?Tag (-2) weglassen .
Titus
@Titus, vielen Dank für deine tollen Golftipps, ich habe noch so viel zu lernen und ich muss auch ein paar Details mehr beachten, die ich vermisse ... Ich wusste es noch nicht joinals Pseudonym von implode! Über den php -rParameter, den ich in der Vergangenheit verwendet habe, aber in letzter Zeit verwende ich ihn nicht, weil (ich weiß nicht warum) ich ihn manchmal nicht richtig funktionieren lassen kann.
Mario
2

Perl 6 , 49 Bytes

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

Erläuterung

{

  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

}

Prüfung:

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

C #, 153 130 101 Bytes ( 122 99 83 ohne Namespace-Deklarationen)

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

-23 Bytes dank pinkfloydx33

ein weiteres -29 dank Link Ng (ich hätte wirklich wissen müssen, dass ich es nicht in ein Array konvertieren muss)

Verdammte Umbauten.

(Zusätzlicher Bonus, das ist überraschend schnell)

Alfie Goodacre
quelle
Sie haben nicht zu bespannen, verwenden müssen $"{n}".ToCharArray()oder (""+n).ToCharArray()und Sie brauchen nicht die Klammern nach dem während: while(!s.Contains...)n++;oder besser noch , sie kombinieren und eine leere Schleife Körper verlassen: while(!s.Contains(.....$"{n++}".ToCharArray()....);return n; declare s mit var s="... "oder entfernen Sie ganz:while(!"0123456789".Contains(...
pinkfloydx33
Ich denke, Sie können auch das erste entfernen n++und es stattdessen mit dem obigen kombinieren und tun$"{++n}".ToCharArray()
pinkfloydx33
@ pinkfloydx33 Ich habe einen Großteil der von Ihnen vorgeschlagenen Änderungen hinzugefügt, wenn nicht alle!
Alfie Goodacre
1
Entfernen Sie use System;und verwenden Sie stringstatt Stringfür 11 Bytes. Verwenden Sie string.Concatanstelle von string.Joinund behalten Sie nur den 2. Parameter für 1 Byte bei. Wechseln Sie ""+ ++nzu ++n+""für 1 Byte. Ihnen als Übung überlassen: 14 weitere Bytes können entfernt werden.
Link Ng
@LinkNg Änderungen vorgenommen wurden - Ich fühle mich wie ein Idiot für das Array 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@._<$<>

Probieren Sie es online!

Die Art und Weise, wie wir testen, ob ein Jahr sortiert ist, besteht darin, ein "Array" (in das String-Literal in Zeile 5 geschrieben) zu erstellen. Für jede Ziffer im Jahr setzen wir diesen Index in das Array auf 1. Sobald alle Ziffern vorhanden sind Bei der Verarbeitung wird gezählt, wie viele Einsen der Reihe nach vorhanden sind. Wenn diese Anzahl der Länge des Jahres entspricht, können wir davon ausgehen, dass das Jahr sortiert ist.

Ausführliche Erklärung

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

Ruby, 51 Bytes

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

Python 2, 68 Bytes

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

Gut geschlagen von @Dennis, aber trotzdem nur als alternative Methode gepostet.

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

Schlagen Sie die aktuelle C # -Übertragung um 3 Byte: p Bereits zurückgeschlagen
Ich weiß, dass diese Antwort leicht zurückgeschlagen werden kann ...
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;
};
Link Ng
quelle
1

05AB1E , 10 9 Bytes

-1 danke an Emigna.

[>D{žhså#

Probieren Sie es online!

Neue Beschreibung kommt, wenn ich Zeit habe.

Magische Kraken-Urne
quelle
2
[>D{žhså#für 9 Bytes.
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

BEARBEITEN:

-1 Byte danke an @ Gábor Fekete

-6 Bytes dank @Zachary T

sonrad10
quelle
Sie können 1 Byte durch Aliasing der sortedFunktion speichern .
Gábor Fekete
Kannst du nicht ein paar Bytes sparen, indem du zu Python 2 konvertierst?
Zacharý
Ja, ich konnte, danke, daran hatte ich nicht gedacht.
sonrad10
1

PHP, 90 89 88 Bytes

Ein ganz anderer Ansatz:

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

Laufen Sie mit -r.

Nervenzusammenbruch

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

Clojure, 104 96 91 Bytes

Lange Methodennamen machen das nicht so kurz ... Zumindest map-indexedund führen -Sie die Hauptberechnungen ordentlich durch.

Edit 1 : Gut, ich habe vergessen, dass ich auch =mehrere Argumente verwenden kann, sodass ich nicht überprüfen muss, ob die Anzahl der unterschiedlichen Werte 1 ist.

Edit 2 : Keine Notwendigkeit zu laufen (sort(seq(str %))), (sort(str %))funktioniert genauso gut.

(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)))
NikoNyrh
quelle
0

R 87 Bytes

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

Wie üblich, wenn es darum geht, Zahlen in Ziffern aufzuteilen, verfügt R nicht über eine systemeigene Methode, um dies zu tun. Folglich müssen wir die Eingabe in ein Zeichen zwingen, in einen Zeichenvektor aufteilen und anschließend wieder in einen beliebigen numerischen Typ konvertieren.

Probieren Sie es online aus

Billywob
quelle