Erweitern und verkleinern


19

Nehmen Sie eine positive ganze Zahl als Eingabe. Beginnen Sie mit und erhöhen Sie wiederholt um die größte ganzzahlige Potenz von zehn so dass und .kn:=1niini+nk

Wiederholen Sie diesen Vorgang, bis und geben Sie eine Liste aller Zwischenwerte von , einschließlich der ersten und der letzten .n=kn1k

Während dieses Prozesses wird das Wachstum zunächst durch die erstere Ungleichung und erst danach durch die letztere begrenzt; Das Wachstum wird in Form einer anfänglichen "Expansions" -Periode erfolgen, in der durch immer größere Potenzen erhöht wird, gefolgt von einer "Kontrakt" -Periode, in der durch immer kleinere Potenzen erhöht wird, um zu "zoomen". auf die richtige Nummer.nn

Testfälle

1 => [1]
10 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
321 => [1,  2,  3,  4,  5,  6,  7,  8,  9,
        10, 20, 30, 40, 50, 60, 70, 80, 90,
        100, 200, 300, 310, 320, 321]
1002 => [1,   2,   3,   4,   5,   6,   7,   8,   9,
         10,  20,  30,  40,  50,  60,  70,  80,  90,
         100, 200, 300, 400, 500, 600, 700, 800, 900,
         1000, 1001, 1002]

Das ist , also gewinnt die kürzeste Antwort (in Bytes).


2
Dürfen wir die Zahlen drucken, anstatt eine Liste zurückzugeben?
Adám

@Adam Ja, das darfst du.
Esolanging Fruit

Antworten:


8

Haskell , 72 68 64 63 Bytes

f=(1!)
c!t|t==c=[c]|t>c=c:(c+10^(pred.length.show.min c$t-c))!t

Probieren Sie es online!

Vielen Dank an Sriotchilism O'Zaic für -4 Bytes!

Verwendung

f 321
[1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,310,320,321]

Erläuterung

c!t         -- c=current number, t=target number
 |t==c=[c]  -- Target is reached, return last number
 |t>c=c:(c+10^(pred.length.show.min c$t-c))!t
      c:                                        -- Add current number to list
                                min c$t-c       -- The minimum of the current number, and the difference between the current number and the target
                    length.show.                -- The length of this number
               pred.                            -- Minus 1
           10^(                          )      -- Raise 10 to this power
         c+                                     -- Add that to the current number
        (                                 )!t   -- Recursion

4
Willkommen bei PPCG! Schöne erste Antwort.
Arnauld

2
Ich kenne Haskell nicht, aber vielleicht kann einer dieser Tipps helfen: Tipps zum Golfen in Haskell und Tipps zum Golfen in <allen Sprachen> . Aber ich stimme zu, nette Antwort. +1 von mir.
Kevin Cruijssen

2
Willkommen auf der Seite! Da (^)hat eine höhere Priorität, als dass (+)Sie keine Klammern um den (^)Ausdruck benötigen . Gleiches gilt für (!)und(:)
Wheat Wizard

1
pred.length.show.min c$t-ckann auf gekürzt werden length(show.min c$t-c)-1. Anonyme Funktionen sind akzeptabel, daher können Sie die Führung löschen, f=wie in unserem Handbuch zu den Golfregeln in Haskell erläutert .
Laikoni,

1
Statt der Wachen, können Sie nur einen Fall und eine bedingte benutzen c!t=c: if t>c then (c+10^(length(show.min c$t-c)-1))!t else []. Auf diese Weise können Sie diesen Tipp anwenden , um ein paar weitere Bytes zu sparen: Probieren Sie es online aus!
Laikoni

6

JavaScript (ES6), 50 Byte

f=n=>n?[...f(n-(1+/(^10)?(0*$)/.exec(n)[2])),n]:[]

Probieren Sie es online!

Wie?

Theorie

Die folgenden Schritte werden wiederholt, bis n=0 :

  • Suchen Sie nach der Anzahl k der nachgestellten Nullen in der Dezimaldarstellung von n
  • Dekrementiere k wenn n eine exakte Potenz von 10
  • subtrahiere x=10k von n

Implementierung

Der Wert von x wird direkt als Zeichenfolge mit dem folgenden Ausdruck berechnet:

+---- leading '1'
|
1 + /(^10)?(0*$)/.exec(n)[2]
     \____/\___/
        |    |
        |    +---- trailing zeros (the capturing group that is appended to the leading '1')
        +--------- discard one zero if n starts with '10'

Hinweis : Ohne Berücksichtigung der führenden '10'wirkt sich nur auf genaue Potenzen von 10 (zB n=1000 ) , aber die Anzahl der erfassten Nullen für Werte nicht wie ändern n=102300 (wegen der zusätzlichen nicht-Null mittleren Ziffern, '10'eigentlich ist in solchen Fällen überhaupt nicht übereinstimmen).


Genial ist, dass Sie die Iteration "rückwärts" durchführen können, indem Sie nur eine Variable im Auge behalten! Es ist ein bisschen verwirrend, dass Sie ketwas völlig anderes als in der Beschreibung der Herausforderung verwenden (in der Tat ist Ihr nOP eine Mischung aus nund kund Ihr xist ihr i.)
Ørjan Johansen


2

Perl 6 , 48 41 Bytes

->\k{1,{$_+10**min($_,k-$_).comb/10}...k}

Probieren Sie es online!

Erläuterung:

->\k{                                   }  # Anonymous code block taking k
     1,                             ...k   # Start a sequence from 1 to k
       {                           }       # Where each element is
        $_+          # The previous element plus
           10**      # 10 to the power of
                           .comb     # The length of
               min($_,k-$_)          # The min of the current count and the remainder
                                /10  # Minus one

2

APL (Dyalog Unicode) , 30 Byte SBCS

Anonyme implizite Präfixfunktion. Druckt Zahlen in separaten Zeilen auf Standardausgabe.

{⍺=⍵:⍺⋄⍺∇⍵+10*⌊/⌊10⍟⍵,⍺-⎕←⍵}∘1

Probieren Sie es online!

{}∘1n

⍺=⍵kn

  k

  sonst:

  ⎕←⍵n

  ⍺-k

  ⍵,n

  10⍟Log10

   Boden diejenigen

  ⌊/ Minimum davon

  10* zehn, die dazu erzogen wurden

  ⍵+n

  ⍺∇kn


2

05AB1E , 15 Bytes

1[=ÐIαD_#‚ßg<°+

Port von @PaulMutsers (erster) Haskell-Antwort , also stelle sicher, dass du ihn positiv bewertest !!

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Gibt die durch Zeilenumbrüche getrennten Zahlen aus.
Wenn es eine Liste sein muss, müsste ich 3 Bytes hinzufügen:

X[DˆÐIαD_#‚ßg<°+}¯

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

1             # Push a 1 to the stack
 [            # Start an infinite loop
  =           #  Print the current number with trailing newline (without popping it)
  Ð           #  Triplicate the current number
   Iα         #  Get the absolute difference with the input
     D        #  Duplicate that absolute difference
      _       #  If this difference is 0:
       #      #   Stop the infinite loop
      ‚ß      #  Pair it with the current number, and pop and push the minimum
        g   #  Calculate 10 to the power of the length of the minimum minus 1
           +  #  And add it to the current number



1

Batch, 131 Bytes

@set/an=i=1
:e
@if %n%==%i%0 set i=%i%0
@echo %n%
:c
@set/an+=i
@if %n% leq %1 goto e
@set/an-=i,i/=10
@if %i% neq 0 goto c

Übernimmt die Eingabe als Befehlszeilenparameter und gibt die Liste der Zahlen an STDOUT aus. Erläuterung:

@set/an=i=1

Beginnen Sie mit n=1und i=1repräsentieren Sie die Potenz von 10.

:e
@if %n%==%i%0 set i=%i%0

Mit i10 multiplizieren, wenn ndie nächste Zehnerpotenz erreicht ist.

@echo %n%

Den aktuellen Wert von ausgeben n.

:c
@set/an+=i
@if %n% leq %1 goto e

Das Wiederholen von while ikann hinzugefügt werden, nohne dass die Eingabe überschritten wird.

@set/an-=i,i/=10

Stellen Sie den vorherigen Wert von wieder her nund dividieren Sie idurch 10.

@if %i% neq 0 goto c

Wenn inicht dann Null versuchen Sie izu nwieder.


1

R , 67 65 Bytes

-2 Bytes dank Giuseppe

k=scan();o=1;i=10^(k:0);while(T<k)o=c(o,T<-T+i[i<=T&i+T<=k][1]);o

Ziemlich einfach. Es werden Potenzen von 10 benötigt, die über die in umgekehrter Reihenfolge erforderliche Menge hinausgehen i.

(Ich würde es vorziehen, i=10^rev(0:log10(k))anstatt zu verwenden, i=10^(k:0)da letzteres rechnerisch ineffizient ist, aber Golf ist Golf!).

Wendet dann in einer while-Schleife die Bedingungen auf idie erste (dh die größte) an und nimmt sie an. wird aktualisiert nund an die Ausgabe angehängt

Probieren Sie es online!


1
Speichern Sie ein Byte mit Tstatt n; es sollte 2 sein, aber ich denke nicht, dass dies TRUEeine akzeptable Ausgabe für ist k=1, also setzen wir o=+T. Versuch es!
Giuseppe

2
Das ist eine schreckliche Codierung, ich mag es. Übrigens kann ich o=1das zweite Byte setzen und abrufen.
Aaron Hayman


1

Pip , 27 Bytes

Wa>Po+:y/t*Y1Ty>o|o+y>ay*:t

Probieren Sie es online!

Im Pseudocode:

a = args[0]
o = 1
print o
while a > o {
  y = 1
  till y > o || o + y > a
    y *= 10
  o += y / 10
  print o
}

Ich bin ziemlich zufrieden mit den Golf-Tricks, die ich anwenden konnte, um diesen Algorithmus zu verkürzen. Durch Initialisieren, Aktualisieren und Drucken von Inhalten im Schleifenkopf konnte ich geschweifte Klammern für den Schleifenkörper vermeiden. Es gibt jedoch wahrscheinlich einen golferischeren Algorithmus.


0

Japt , 18 Bytes

ÆT±ApTmTnU)sÊÉÃf§U

Versuch es

ÆT±ApTmTnU)sÊÉÃf§U     :Implicit input of integer U
Æ                      :Map the range [0,U)
 T±                    :  Increment T (initially 0) by
   A                   :  10
    p                  :  Raised to the power of
     Tm                :    The minimum of T and
       TnU             :      T subtracted from U
          )            :    End minimum
           s           :    Convert to string
            Ê          :    Length
             É         :    Subtract 1
              Ã        :End map
               f       :Filter
                §U     :  Less than or equal to U


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.