Maßband

15

Motivation : Manchmal muss man wissen, wo man sich in einer Saite befindet. Sie möchten in der Lage sein, einen beliebigen Teil einer Zeichenfolge zu betrachten und so weit wie möglich genau zu wissen, wo Sie sich befinden.

Herausforderung : Schreiben Sie ein Programm, um einen Maßband mit einer bestimmten Länge auszugeben . Ein Maßband beschreibt seine Länge so oft wie möglich über seine eigene Länge.

Regeln :

  1. Ihr Programm muss einen positiven Ganzzahlparameter für die Gesamtlänge der Maßbandzeichenfolge verwenden
  2. Für jede zusammenhängende Folge von Ziffern in der Ausgabe müssen diese Ziffern die Länge der Ausgabe genau wiedergeben - einschließlich !
    1. Die Längen werden vom Anfang der Zeichenfolge bis zum Ende jeder Zahl gemessen
  3. In der Zeichenfolge sollten so viele Längenangaben wie möglich enthalten sein
  4. Vermeiden Sie Mehrdeutigkeiten. Trennzeichen können verwendet werden, um zu vermeiden, dass Zahlen nebeneinander stehen, dh 12zwölf, nicht eins, zwei.
  5. Die Zeichenfolge muss am Ende immer genau ihre Gesamtlänge ohne nachfolgende Trennzeichen angeben
  6. Möglicherweise benötigen Sie mehrere Trennzeichen, um die Längen genau zu halten. Hier ist beispielsweise eine Maßband-Zeichenfolge der Länge 4: 1--4

Unverbindliche / erschöpfende Beispiele:

  • Maßband der Länge 1: 1
  • Maßband mit Länge 2: -2
  • Maßband der Länge 3: 1-3
  • Maßband der Länge 4: 1--4oder -2-4(beide melden die Länge so oft wie möglich, dh zweimal, und enden mit der korrekten Gesamtlänge)
  • Maßband Länge 10: 1-3-5-7-10
  • Maßband mit der Länge 11: 1-3-5-7--11oder 1-3-5--8-11oder 1-3--6-8-11oder 1--4-6-8-11oder -2-4-6-8-11(alle haben so viele Längen wie möglich und enden mit der Gesamtlänge der Saite)
Tom Viner
quelle
Jede Ziffer in der Zeichenfolge grenzt also nicht an eine andere Ziffer an, die Zeichenfolge besteht ausschließlich aus Bindestrichen -, und Sie müssen so viele Längenmarkierungen wie möglich in der Zeichenfolge haben.
14.
Können wir eine 0-basierte Indizierung verwenden?
14.
@EasterlyIrk Regel 3 besteht darin, dass so viele Zahlen wie möglich in die Zeichenfolge passen müssen.
Weizen-Zauberer
Verbunden.
Martin Ender
@EasterlyIrk Sie können nicht alle Bindestriche verwenden, da dies die Motivation nicht erfüllt und gegen die Regeln 3 und 5 verstößt. Es erfolgt keine Indizierung. Nur Längen. Also nein, ein Maßband mit der Länge eins kann es nicht sein 0.
Tom Viner

Antworten:

12

Python, 50 48 47 46 Bytes

f=lambda x:x*"1"if x<2else f(x-len(`-x`))+`-x`

Erläuterung

Ziemlich einfache rekursive Lambda-Lösung

Unsere Basisfälle sind 1 und 0, die abgedeckt werden, "1"*xda wir sonst die Zeichenfolge von -xwith erhalten `-x`und dem Ergebnis des Aufrufs der Funktion len(`-x`)less voranstellen .

Weizen-Assistent
quelle
1
Können Sie durch Stringing Bytes sparen -x?
Martin Ender
@MartinEnder Ok, ich habe es zum Laufen gebracht. Danke für den Tipp! Ich fühle mich irgendwie dumm, dass ich das nicht früher bemerkt habe.
Weizen-Assistent
5

Mathematica, 67.57 Bytes

Vielen Dank an Martin Ender für die Freigabe von 10 Bytes!

""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&

Unbenannte Funktion, die ein nichtnegatives ganzzahliges Argument verwendet und eine Zeichenfolge zurückgibt. Ziemlich genau der offensichtliche rekursive Algorithmus: Stellen Sie sicher, dass die Zeichenfolge mit der Eingabenummer endet, die mit einem vorangestellt ist "-", und rufen Sie die Funktion dann erneut mit auf #0.

Die Implementierung des Algorithmus macht aber auch Golfspaß. ""["1"][[#]]bezeichnet das #dritte Argument des Ausdrucks ""["1"]: Das dritte Argument ist der Kopf ""und das dritte Argument ist das sichtbare Argument "1", das die Grundfälle der Rekursion liefert. Wenn #1 überschritten wird, wird ""["1"][[#]]eine Fehlermeldung ausgegeben und die Funktion bleibt unverändert. Aber dann /._@__:>ist es eine Regel, die jede unbewertete Funktion übernimmt und in den nächsten Ausdruck umwandelt, der der rekursive Aufruf der ursprünglichen Funktion ist.

Ursprüngliche Einreichung:

If[#<2,""["1"][[#]],#0[#-1-IntegerLength@#]<>"-"<>IntegerString@#]&
Greg Martin
quelle
2
""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&spart ein Byte durch Vermeiden von Ifund eine Reihe von Bytes durch Vermeiden von IntegerStringund "-"<>.
Martin Ender
1
omg, _@__ist böse Magie
Greg Martin
3

JavaScript (ES6), 49 Byte

f=(n,s='',t=''+-n)=>n>1?f(n-t.length,t+s):n?n+s:s
<input type=number oninput=o.value=f(this.value)><br><textarea id=o></textarea>

Neil
quelle
1
Ich denke, Sie müssen definierenf
Tom Viner
@TomViner Das mache ich immer. (Zumindest hatte ich die richtige Byteanzahl.)
Neil
2

Pyth, 23 Bytes

L?<b2*"1"b+y-bl+""_bs_b

Hat die rekursive Lösung offenbar aus der Antwort des Weizen-Assistenten gestohlen . Außerdem glaube ich, dass dies nicht richtig golfen wird.

Probieren Sie es hier aus!

Gurupad Mamadapur
quelle
1

Perl 6 , 43 Bytes

{[R~](-$_,{$_+.comb}...^*>-1).&{S/^\-1/1/}}

Erläuterung:

{                                         }  # A lambda.
                    ...                      # Generate a sequence...
      -$_                                    #   starting from the negated lambda argument,
         ,{        }                         #   continuing iteratively using the formula:
           $_+.comb                          #     Last element plus length of last element.
                        *>-1                 #   until we hit 0 or higher,
                       ^                         end-point not inclusive.
 [R~](                      )                # Reverse and concatenate the number sequence.
                             .&{         }   # Apply to this the transformation:
                                S/^\-1/1/    #   Remove the sign from a leading "-1".

So wird beispielsweise für Eingabe 10 die Sequenz (-10, -7, -5, -3, -1)und daraus die Zeichenfolge -1-3-5-7-10und daraus die endgültige Zeichenfolge generiert 1-3-5-7-10.

Probieren Sie es online aus .

smls
quelle