Ruban à mesurer

15

Motivation : Parfois, vous devez savoir où vous en êtes dans une chaîne. Vous voulez pouvoir regarder n'importe quelle partie d'une chaîne et savoir exactement où vous êtes, dans la mesure du possible.

Défi : écrire un programme pour sortir une chaîne de ruban à mesurer d'une longueur donnée. Un ruban à mesurer décrit lui-même sa longueur aussi souvent que possible sur sa propre longueur.

Règles :

  1. Votre programme doit prendre un paramètre entier positif, pour la longueur totale de la chaîne de ruban à mesurer
  2. Pour chaque chaîne de chiffres contiguës dans la sortie, ces chiffres doivent indiquer avec précision la longueur de la sortie jusqu'à présent - inclus !
    1. Les longueurs sont mesurées du début de la chaîne à la fin de chaque numéro
  3. Il faut inclure autant de numéros de longueur que possible dans la chaîne
  4. Évitez toute ambiguïté. Des séparateurs / délimiteurs peuvent être utilisés pour éviter la juxtaposition de nombres, c'est-à-dire 12dit douze et non un, deux.
  5. La chaîne doit toujours indiquer avec précision sa longueur totale à sa fin, sans séparateurs de fin
  6. Vous pouvez avoir besoin de plusieurs séparateurs pour garder les longueurs précises, par exemple, voici un exemple de chaîne de ruban à mesurer de longueur 4: 1--4

Exemples non normatifs / exhaustifs:

  • ruban à mesurer de longueur 1: 1
  • ruban à mesurer chaîne de longueur 2: -2
  • ruban à mesurer de longueur 3: 1-3
  • ruban à mesurer de longueur 4: 1--4ou -2-4(les deux longueurs de rapport aussi souvent que possible, c'est-à-dire deux fois, et se terminent par la longueur totale correcte)
  • ruban à mesurer de longueur 10: 1-3-5-7-10
  • ruban à mesurer chaîne de longueur 11: 1-3-5-7--11ou 1-3-5--8-11ou 1-3--6-8-11ou 1--4-6-8-11ou -2-4-6-8-11(tous ont autant de numéros de longueur que possible et finissent par la longueur totale de la chaîne)
Tom Viner
la source
Donc, chaque chiffre de la chaîne n'est pas adjacent à un autre chiffre, la chaîne est entièrement composée de tirets -, et vous devez avoir autant de marques de longueur que possible dans la chaîne?
Rɪᴋᴇʀ
Peut-on utiliser une indexation basée sur 0?
Rɪᴋᴇʀ
@EasterlyIrk La règle 3 est que le plus grand nombre possible de chiffres doit être inséré dans la chaîne.
Post Rock Garf Hunter
En relation.
Martin Ender
@EasterlyIrk, vous ne pouvez pas avoir tous les tirets car cela ne répond pas à la motivation et enfreint les règles 3 et 5. Il n'y a pas d'indexation. Juste des longueurs. Donc non, une chaîne de ruban à mesurer de longueur un ne peut pas l'être 0.
Tom Viner

Réponses:

12

Python, 50 48 47 46 octets

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

Explication

Solution lambda récursive assez simple

Nos cas de base sont 1 et 0 qui sont couverts par "1"*xsinon nous obtenons la chaîne de -xwith `-x`et ajoutons le résultat de l'appel de la fonction sur len(`-x`)less.

Post Rock Garf Hunter
la source
1
Pouvez-vous économiser des octets en stringifiant -x?
Martin Ender
@MartinEnder Ok, je l'ai fait fonctionner. Merci pour le conseil! Je me sens un peu stupide de ne pas l'avoir remarqué plus tôt.
Post Rock Garf Hunter
5

Mathematica, 67 57 octets

Merci à Martin Ender d'avoir largué 10 octets!

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

Fonction sans nom prenant un argument entier non négatif et retournant une chaîne. À peu près l'algorithme récursif évident: assurez-vous que la chaîne se termine par le numéro d'entrée précédé de a "-", puis appelez à nouveau la fonction à l'aide de #0.

Mais il y a un plaisir golfique à implémenter l'algorithme. ""["1"][[#]]désigne le #th argument de l'expression ""["1"]: le 0ème argument est la tête ""et le 1er argument est visiblement "1", ce qui fournit les cas de base de la récursivité. Si #dépasse 1, ""["1"][[#]]lance alors un message d'erreur et reste comme une fonction non évaluée. Mais /._@__:>c'est une règle qui prend n'importe quelle fonction non évaluée et la transforme en l'expression qui vient ensuite, qui est l'appel récursif à la fonction d'origine.

Soumission originale:

If[#<2,""["1"][[#]],#0[#-1-IntegerLength@#]<>"-"<>IntegerString@#]&
Greg Martin
la source
2
""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&enregistre un octet en évitant le Ifet un tas d'octets en évitant IntegerStringet "-"<>.
Martin Ender
1
omg, _@__is evil magic
Greg Martin
3

JavaScript (ES6), 49 octets

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
la source
1
Je pense que vous devez définirf
Tom Viner
@TomViner Je fais toujours ça. (Au moins, j'avais le bon nombre d'octets.)
Neil
2

Pyth, 23 octets

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

Volé ouvertement la solution récursive de la réponse de l'assistant de blé . De plus, je crois que ce n'est pas joué correctement.

Essayez-le ici!

Gurupad Mamadapur
la source
1

Perl 6 , 43 octets

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

Explication:

{                                         }  # 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".

Ainsi, par exemple pour l'entrée 10, il génère la séquence (-10, -7, -5, -3, -1), et à partir de là, la chaîne-1-3-5-7-10 , et à partir de cela la chaîne finale 1-3-5-7-10.

Essayez-le en ligne .

smls
la source