Cadena de cinta métrica

15

Motivación : a veces necesitas saber dónde estás en una cadena. Desea poder mirar cualquier parte de una cadena y saber exactamente dónde se encuentra, en la medida de lo posible.

Desafío : escriba un programa para generar una cadena de cinta métrica de una longitud determinada. Una cadena de cinta métrica describe su longitud tan lejos como sea posible a lo largo de su propia longitud.

reglas :

  1. Su programa debe tomar un parámetro entero positivo, para la longitud total de la cadena de cinta métrica
  2. Para cada cadena contigua de dígitos en la salida, estos dígitos deben informar con precisión la longitud de la salida hasta el momento, ¡ inclusive !
    1. Las longitudes se miden desde el inicio de la cadena hasta el final de cada número.
  3. Se deben incluir tantos números de longitud como sea posible en la cadena
  4. Evita la ambigüedad. Se pueden usar separadores / delimitadores para evitar que los números se yuxtapongan, es decir 12, doce, no uno, dos.
  5. La cadena siempre debe informar con precisión su longitud total al final, sin separadores finales
  6. Es posible que necesite varios separadores para mantener las longitudes precisas, por ejemplo, aquí hay un ejemplo de cadena de cinta métrica de longitud 4: 1--4

Ejemplos no prescriptivos / exhaustivos:

  • cinta de medir cuerda de longitud 1: 1
  • cuerda de cinta métrica de longitud 2: -2
  • cadena de cinta métrica de longitud 3: 1-3
  • cadena de cinta métrica de longitud 4: 1--4o -2-4(ambas longitudes de informe con la mayor frecuencia posible, es decir, dos veces, y terminan con la longitud total correcta)
  • cuerda de cinta métrica de longitud 10: 1-3-5-7-10
  • cadena de cinta métrica de longitud 11: 1-3-5-7--11o 1-3-5--8-11o 1-3--6-8-11o 1--4-6-8-11o -2-4-6-8-11(todos tienen tantos números de longitud como sea posible y terminan con la longitud total de la cuerda)
Tom Viner
fuente
Entonces, ¿cada dígito en la cadena no es adyacente a otro dígito, la cadena se compone completamente de guiones -y necesita tener tantas marcas de longitud como sea posible en la cadena?
Rɪᴋᴇʀ
¿Podemos usar indexación basada en 0?
Rɪᴋᴇʀ
@EasterlyIrk La regla 3 es que la mayor cantidad posible de números debe caber en la cadena.
Post Rock Garf Hunter
Relacionado.
Martin Ender
@EasterlyIrk no puede tener todos los guiones, ya que no cumple con la motivación y rompe las reglas 3 y 5. No hay indexación. Solo largos. Entonces no, una cinta métrica de longitud uno no puede ser 0.
Tom Viner

Respuestas:

12

Python, 50 48 47 46 bytes

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

Explicación

Solución lambda recursiva bastante simple

Nuestros casos base son 1 y 0 que estén provistos de "1"*xotro modo se obtiene la serie de -xcon `-x`y anteponer el resultado de llamar a la función en len(`-x`)menos.

Post Rock Garf Hunter
fuente
1
¿Se pueden guardar bytes mediante stringificación -x?
Martin Ender
@ MartinEnder Ok, lo tengo para trabajar. ¡Gracias por el consejo! Me siento un poco tonto por no haber notado eso antes.
Post Rock Garf Hunter
5

Mathematica, 67 57 bytes

¡Gracias a Martin Ender por tirar 10 bytes!

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

Función sin nombre que toma un argumento entero no negativo y devuelve una cadena. Prácticamente el algoritmo recursivo obvio: asegúrese de que la cadena termina con el número de entrada precedido por a "-", y luego llame a la función nuevamente usando #0.

Pero es divertido jugar al golf al implementar el algoritmo. ""["1"][[#]]denota el #argumento th de la expresión ""["1"]: el argumento 0 es la cabeza ""y el primer argumento es visible "1", lo que proporciona los casos básicos de la recursión. Si #excede 1, ""["1"][[#]]arroja un mensaje de error y permanece como una función no evaluada. Pero luego /._@__:>es una regla que toma cualquier función no evaluada y la transforma en la expresión que sigue, que es la llamada recursiva a la función original.

Presentación original:

If[#<2,""["1"][[#]],#0[#-1-IntegerLength@#]<>"-"<>IntegerString@#]&
Greg Martin
fuente
2
""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&ahorra un byte al evitar el Ify un montón de bytes al evitar IntegerStringy "-"<>.
Martin Ender
1
Dios mío, _@__es magia malvada
Greg Martin
3

JavaScript (ES6), 49 bytes

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
fuente
1
Creo que necesitas definirlof
Tom Viner
@TomViner Siempre estoy haciendo eso. (Al menos tenía el recuento de bytes correcto.)
Neil
2

Pyth, 23 bytes

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

Escandalosamente robó la solución recursiva de la respuesta del mago de trigo . Además, creo que esto no se juega correctamente.

Pruébalo aquí!

Gurupad Mamadapur
fuente
1

Perl 6 , 43 bytes

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

Explicación:

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

Entonces, por ejemplo, para la entrada 10, genera la secuencia (-10, -7, -5, -3, -1), y de ahí la cadena -1-3-5-7-10, y de ahí la cadena final 1-3-5-7-10.

Pruébalo en línea .

smls
fuente