Secuencia ordenada de combinaciones enteras ascendentes

8

Escriba un programa o función para producir la siguiente salida en el orden correcto.

EDITAR: ¡ Los símbolos no son matemáticos! Los números solo representan datos únicos y los +y -podrían ser dos símbolos arbitrarios.

Tome una entrada entera no negativa n. La primera línea es siempre -, incluso para n = 0.

  • Si la línea actual es -, la siguiente línea es1+2+ ... (n-1)+n-
    • n = 4: -=>1+2+3+4-
  • Si el último entero es igual a n, elimine todos los enteros del final seguidos inmediatamente por a -, luego cambie el último +a-
    • n = 4: 1-2+3-4-=>1-2-
    • EDITAR: cuando la cadena está llena (se incluyen todos los enteros del 1 al n), elimine todos los enteros del final seguidos de a -, hasta llegar a un entero seguido de a +. Deje ese número entero pero cambie su seguimiento +a un-
    • Usando el mismo ejemplo que el anterior (que no sigue -), elimine 4-, elimine 3-, cambie 2+a 2-. 1-no cambia desde que nos detenemos en 2. Resultado: 1-2-
  • Si el último entero es menor que n, agregue los enteros restantes con un +después de cada uno, excepto el entero final que debería haber -agregado
    • n = 4: 1+2-=>1+2-3+4-
    • EDITAR: si la cadena actual no está llena (no contiene todos los enteros del 1 al n), agregue cada entero que no esté incluido en orden ascendente hasta n-1 con un +después de cada uno, y luego agregue el último entero n seguido por un-
    • Si la línea actual es 1-, agregar 2+, agregar 3+que es n-1 si n = 4. Entonces anexar 4-. Resultado:1-2+3+4-
  • Si la línea actual contiene todos los enteros y cada uno es seguido inmediatamente por un -, salga del código
    • n = 4: 1-2-3-4-=> FIN

No debe haber espacios iniciales o finales en ninguna línea. Debe haber un salto de línea entre cada línea. Puede haber o no un salto de línea en la última línea.

EDITAR: debe probar su código hasta al menos n = 10 (más de 1000 líneas de salida, por lo que no puedo incluirlo aquí). ¡Cualquier número que no haga que su código se quede sin recursos debería (eventualmente!) Producir el resultado correcto, ¡pero no tiene que esperar a que termine el universo!

Este es el , por lo que gana el código más corto en bytes.

Entrada n = 0:

-

Entrada n = 1:

-
1-

Entrada n = 2:

-
1+2-
1-
1-2-

Entrada n = 4:

-
1+2+3+4-
1+2+3-
1+2+3-4-
1+2-
1+2-3+4-
1+2-3-
1+2-3-4-
1-
1-2+3+4-
1-2+3-
1-2+3-4-
1-2-
1-2-3+4-
1-2-3-
1-2-3-4-
CJ Dennis
fuente

Respuestas:

5

Haskell , 89 bytes

g toma un entero y devuelve una cadena.

g n=unlines$max"-".foldr(\(s,i)r->id=<<[show i++s:r|s:r>"+"])""<$>mapM(mapM(,)"+-")[1..n]

Pruébalo en línea!

Cómo funciona

  • Hablando en términos generales, el algoritmo construye una lista de todas las 2^ncombinaciones 1+2+...n+, 1+2+...n-hasta 1-2-...n-, elimina los +números finales y, si el resultado está vacío, lo reemplaza por -.

  • mapM(,)"+-"es una forma más corta (usando la función mónada) para escribir \i->[('+',i),('-',i)].

  • mapM(mapM(,)"+-")[1..n]genera (usando la lista mónada para el exterior mapM) una lista con todas las combinaciones como listas de tuplas, por ejemplo [(1,'+'),(2,'-'),...,(n,'+')].
  • foldr ... <$> ... combina cada una de estas listas de tuplas en una cadena, utilizando la expresión lambda para construirla desde la derecha.
    • (s,i)es una tupla de un signo y un número, y res la cadena construida a partir de las tuplas a su derecha.
    • id=<<[show i++s:r|s:r>"+"]antecede iy sa la cadena rconstruida hasta ahora, pero no si el signo ses positivo y restá vacío.
      • Esto se prueba comparando s:rcon "+". Por suerte, esta es la cadena lexicográficamente más pequeña que puede resultar de concatenarlas, por lo que la comparación puede usarse en >lugar de /=.
  • Además, por suerte, "-"es más pequeño que cualquier cadena no vacía que se pueda construir por el pliegue, por lo que la cadena vacía se puede reemplazar con ella usando max.
  • Finalmente unlinesconvierte las cadenas en una sola cadena de líneas.
Ørjan Johansen
fuente
5

Python 2 , 101 bytes

n=input()
for i in range(2**n):s='';m=n;exec"s=`m`+'+-'[i%2]+s;s*='-'in s;i/=2;m-=1;"*m;print s or'-'

Pruébalo en línea!

xnor
fuente
Buen uso des*=<condition>
Chas Brown
3

Python 2 , 136 141 133 bytes

def f(n,s="+"):
 while"+"in s:s=s[:s.rfind("+")]+"-";print s[s>"-":];s+="+".join(map(str,range(len(s)/2+1,n+1)))+"-";print(n>0)*s[1:]

Pruébalo en línea!

El primero -(des) sorprendentemente agregó unos pocos bytes al código.

notjagan
fuente
Entonces, ¿la solución de manipulación de cuerdas fue más corta después de todo?
HyperNeutrino
O simplemente soy malo: P
HyperNeutrino
El enfoque parece ser más corto, pero hay algunas cosas que podrían mejorarse con las suyas; Publicaré un comentario con algunos consejos en un momento.
notjagan
n = 0 produce incorrectamente dos -líneas.
CJ Dennis
@CJDennis fijo.
notjagan
3

Python 2 , 150 164 159 154 146 118 bytes 115 112 bytes

def f(n,i=0):
 while i<2**n:t=''.join(`j+1`+'+-'[i>>n+~j&1]for j in range(n));print t[:t.rfind('-')+1]or'-';i+=1

Pruébalo en línea!

Editar: ¡Uy! También tiene que funcionar para números mayores que 4 ... luego escamotear ... hasta que me di cuenta de que estaba pensando demasiado y ahorré 28 bytes ... y luego 6 más a través de pequeños campos de golf.

Chas Brown
fuente
La salida es incorrecta para la entrada superior a n = 4.
CJ Dennis
@CJ Dennis Creo que funciona ahora; la salida es la misma que notjagan para, por ejemplo, n = 5
Chas Brown
¡El resultado parece ser correcto ahora! Agregaré que debes probar al menos a 10 ...
CJ Dennis
¡Acabo de notar que estableces i = 0 en la entrada! ¡Eso significa que solo puedo generar líneas desde i en adelante, como f (24,16777200)! :-)
CJ Dennis
3

Pyth, 23 bytes

j+\-mssVSQd<Lx_d\-t^"+-

Demostración

La base de este programa es notar que, aparte de la inicial -, la secuencia más y menos corresponde a la secuencia estándar de combinaciones de +y -con reemplazo, con todo el resto +eliminado.

Explicación:

j+\-mssVSQd<Lx_d\-t^"+-
j+\-mssVSQd<Lx_d\-t^"+-"Q    Implicit string completion and variable introduction
                   ^"+-"Q    Form all sequences of + and - of length equal to
                             the input, ordered lexicographically.
                  t          Remove the first one, which we don't use.
           <L                Take the prefix of each one of length
             x               index in
              _d             the reversed string
                \-           of '-'.
    m                        Map the results to
      sV                     Apply the sum function to pairs of
        SQ                   [1, 2, 3 ... input]
          d                  and the previous string
     s                       Sum the pairs.
 +\-                         Add a '-' on to the front of the list
j                            Join on newlines.
isaacg
fuente
0

Python 3 , 305 bytes

x=int(input())
o=lambda:list(range(1,x+1))or[0]
q=o()
q[-1]*=-1
print('-')
def f(a):print(''.join(str(abs(x))+'-+'[x>0]for x in a))
while any([k>0 for k in q])or[-k for k in q]!=o():
	f(q)
	if-q[-1]==x:
		while q[-1]<0:q=q[:-1]
		q[-1]*=-1
	elif-q[-1]<x:
		while q[-1]<x:q+=[abs(q[-1])+1]
		q[-1]*=-1
f(q)

Pruébalo en línea!

Hiperneutrino
fuente
Estoy un poco confundido por tu mezcla de tabulación / espacio. Primero, ni siquiera pensé que PODRÍAS en Python 3, y segundo, ¿parece tener poco propósito? ¿Por qué molestarse <tab><space>cuando <space><space>sería el mismo número de bytes? Supongo que si <space><tab>
hicieras
@ nmjcman101 erm. Debo estar realmente cansado, o estúpido, o ambos. Estaba tratando de guardar bytes haciendo ese espacio / tabulación de sangría no tab / tabulador> <¡gracias!
HyperNeutrino
Esto es 17 bytes más corto, pero sale por un error. Aún tratando de acortar ese molesto q[-1]a q[0]. Por cierto: mezclar pestañas y espacios no funciona en Python 3, por lo que el código actual produce un error.
notjagan
@notjagan oh hm. No importa entonces, debe haber sido porque antes estaba siendo tonto: P pero está bien, gracias por la sugerencia; Trataré de trabajar desde allí
HyperNeutrino