¡Mi "keybore" me está aburriendo! Ayúdame a encontrar unas teclas mínimas

13

Créditos a @ Agawa001 por hacer esta pregunta.

Explicación

Mi nuevo "keybore" solo tiene 2 botones, a saber, +y -.

El número en la memoria comienza en 0.

Cada presión consecutiva de +o -aumentará / disminuirá la memoria exactamente cuántas veces se ha presionado consecutivamente.

Por lo tanto, si presiona +4 veces, la primera vez agrega 1, la segunda vez agrega 2, la tercera vez agrega 3, la cuarta vez agrega 4, lo que le da 10(diez).

Ahora, si presiona -3 veces, la primera vez que resta 1, la segunda vez 2, la tercera vez 3, dejándolo con 4(cuatro).

TL; DR

Dada una cadena de + y -, divídala en cada cambio de carácter. Luego, cada cadena resultante de m +símbolos suma el m-ésimo número de triángulo, y cada cadena de n -símbolos resta el n-ésimo número de triángulo.

Recorrido

Ahora, si todavía no entiendes, te mostraré cómo se +++--+--crea 1.

Program   | Counter | Memory
----------------------------
          |  0      | 0
+         | +1      | 1
++        | +2      | 3
+++       | +3      | 6
+++-      | -1      | 5
+++--     | -2      | 3
+++--+    | +1      | 4
+++--+-   | -1      | 3
+++--+--  | -2      | 1

Tarea

  • Tomarás un entero positivo como entrada, ya sea como argumento funcional o desde STDIN.
  • Luego, generará / imprimirá el número mínimo de pulsaciones de teclas necesarias para crear ese número utilizando el método anterior.

Casos de prueba

Dado que la reorganización de las ejecuciones +o -da el mismo número, para cada grupo solo se enumera la secuencia lexicográfica más temprana.

Input | Output | Possible corresponding sequences
-------------------------------------------------
    4 |      5 | -+++-
    6 |      3 | +++
    9 |      5 | ++++-
   11 |      7 | +++-+++
   12 |      7 | +++++--, ++++-++
   19 |      8 | -++++++-
   39 |     12 | +++++++++---
   40 |     13 | +++++++++---+, ++++++++-+++-
   45 |      9 | +++++++++
   97 |     20 | ++++++++++++++--+---, +++++++++++++-++++--, ++++++++++++-++++++-
  361 |     34 | ++++++++++++++++++++++++++-+++-+++

Recursos extra

Puntuación

Este es el . La solución más corta en bytes gana.

Monja permeable
fuente
99
¿Eso quiere decir que ... estás abucheado?
busukxuan
Creo que ahora estás de acuerdo con 10 casos de prueba (incluido el mío).
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος Se agregó el caso de prueba 12, con una ligera modificación (ya +++++--que también es una alternativa, pero eliminé ++-++++ya que es equivalente a ++++-++). Todavía tengo un caso más que me gustaría agregar más tarde en caso de que alguien presente una solución eficiente, si logro generarla.
Sp3000
@ Sp3000 no quería ++-++++eliminar. Además, esta fue MI edición, no TUYA.
Erik the Outgolfer
@ ΈρικΚωνσταντόπουλος Solo se enumera 1 solución de cada conjunto de soluciones equivalentes. Pensé que si se enumeraran todas las soluciones mínimas, los casos de prueba serían innecesariamente largos (hay 6 soluciones para 40 y 17 soluciones para 97). Pido disculpas si esa intención no fue clara. También faltabas +++++--(o, de manera equivalente --+++++), por lo que sentí la necesidad de editar en primer lugar.
Sp3000

Respuestas:

2

Python 2, 119 bytes

def g(n,i=0,s=''):
 c=x=t=0
 for d in s:C=int(d)*2-1;t=(c==C)*t+1;c=C;x+=c*t
 return(x==n)*len(s)or g(n,i+1,bin(i)[3:])

Enfoque muy lento de fuerza bruta. La tercera línea calcula el puntaje de una cadena x; las otras líneas recorren todas las cadenas binarias posibles hasta encontrar una cuya puntuación sea igual al argumento.

@Leaky salvó tres bytes!

Lynn
fuente
s/x==n and len/(x==n)*len/
Leaky Nun
Podría ahorrar algunos bytes para deshacerse de ellos sy simplemente usar una división repetida, como esta:def f(n): \n while n>0:print n%2;n/=2
Leaky Nun
2

Pyth, 25 bytes

ffqyQ.as-Mc*RhdY2{s.pM./T

Pruébalo en línea.

Esto es extremadamente ineficiente y se queda sin memoria durante f(n)≥ 11. Calcula f(22)= 10 en aproximadamente 10 segundos en mi computadora portátil.

Explicación

  • A partir de 1, recorra los números T. ( f)
    • Generar todas las particiones de T. ( ./T)
    • Generar todas las permutaciones de esos. ( .pM)
    • Acoplar la lista. ( s)
    • Uniquificar la lista. ( {) Este paso podría eliminarse, pero hace que el código sea mucho más rápido.
    • Filtre las permutaciones resultantes de particiones: ( f)
      • Multiplique cada número dde la partición ( *R) por sí mismo más uno ( hd). Esto le da el doble de número para sumar / restar al resultado.
      • Corta la lista a partes de longitud 2. ( c... 2)
      • Resta cualquier segundo número en esas partes del segundo número. ( -M)
      • Suma los resultados. Esto da el doble del número resultante si la permutación de la partición se interpretó como un número de sumas, restas, etc.
      • Toma el valor absoluto. ( .a) Si el resultado fue negativo, intercambiar las sumas y restas obtiene el resultado positivo.
      • Compruebe si el resultado es igual al doble de la entrada. ( qyQ) En este caso, la permutación de la partición es correcta, devuélvala.
    • Si el filtro arrojó algún resultado, hubo una solución de longitud T. Devolución e impresión T.
PurkkaKoodari
fuente
2

MATL , 43 29 bytes

E:"@TFEqZ^!"@Y'tQ**s]vGE=a?@.

Esto es ineficiente en cuanto a memoria y tiempo. El compilador en línea puede manejar 45solo entradas .

Pruébalo en línea!

Aquí hay una versión modificada con todos los casos de prueba hasta 40(se tarda casi un minuto en el compilador en línea).

Explicación

Esto prueba todas las posibles secuencias de pulsación de teclas de cada longitud, en orden de longitud creciente, hasta que se encuentre una secuencia válida.

E:       % Range [1 2 ... 2*N] where N is implicit input. The required sequence length is
         % less than 2*N, so this is enough
"        % For each
  @      %   Push current value: length of sequence
  TFEq   %   Push array [1 -1]
  Z^     %   Cartesian power. Gives all possible sequences of 1, -1 of that length
  !      %   Transpose. Each sequence is now a row
  "      %   For each sequence
    @    %     Push current sequence
    Y'   %     Run-length decoding: Pushes an array of values 1 and -1, and then an
         %     array of run-lengths
    tQ*  %     Duplicate, add 1, multiply. Gives twice the triangular number for each run
    *    %     Multiply element-wise by 1 or -1 to produce correct sign
    s    %     Sum of array. This is the number produced by the current sequence
  ]      %   End for
  v      %   Concatenate all numbers into an array
  GE=a   %   True if any of those numbers equals twice the input
  ?      %   If so
    @    %     Push current sequence length. This is the final result
    .    %     Break loop
         %   End if
         % End for
         % Implicit display
Luis Mendo
fuente
@ Sp3000 También agregué uno, así que, para referencia, 4, 6, 9 y 19 son los casos de prueba mencionados, en orden.
Erik the Outgolfer
1

Python, 105100 bytes

Utiliza una búsqueda ineficiente de amplitud.

def k(n):
 m=t=l=0;h=[]
 while m-n:o=1-2*(t>0);(m,t,l),*h=h+[(m+t-o,t-o,l+1),(m+o,o,l+1)]
 return l
  • h es una lista utilizada como cola
  • m es el valor de la secuencia al principio de la lista
  • t es el último número agregado a m
  • l es la longitud de la secuencia que generó m
  • o es +/- 1, el signo es opuesto al signo de t

Editar: Leaky Nun afeitó cinco bytes.

RootTwo
fuente
s/m,t,l,h=0,0,0,[]/m=t=l=0,h=[]/
Leaky Nun
s/while m!=n/while m-n/
Leaky Nun