Sequência ordenada de combinações de números inteiros ascendentes

8

Escreva um programa ou função para produzir a seguinte saída na ordem correta.

EDIT: Os símbolos não são matemáticos! Os números representam apenas dados únicos +e -podem ser quaisquer dois símbolos arbitrários.

Tome uma entrada inteira não negativa n. A primeira linha é sempre -, mesmo para n = 0.

  • Se a linha atual for -, a próxima linha será1+2+ ... (n-1)+n-
    • n = 4: -=>1+2+3+4-
  • Se o último número inteiro for igual a n, remova todos os números inteiros do final imediatamente seguidos de a -e altere o último +para um-
    • n = 4: 1-2+3-4-=>1-2-
    • EDIT: Quando a string estiver cheia (todos os números inteiros de 1 a n estão incluídos), remova todos os números inteiros do final que são seguidos por a -até chegar a um número inteiro seguido por a +. Deixe esse número inteiro, mas altere o seguinte+ para um-
    • Usando o mesmo exemplo imediatamente acima (que não segue -), remova 4-, remova 3-, mude 2+para 2-. 1-não muda desde que paramos às 2. Resultado: 1-2-
  • Se o último número inteiro é menos do que n, acrescentar os restantes números inteiros com um +depois de cada um, à excepção do número inteiro final, que deve ter um -anexado
    • n = 4: 1+2-=>1+2-3+4-
    • EDIT: Se a cadeia atual não estiver cheia (não contém todos os números inteiros de 1 a n), adicione cada número inteiro ainda não incluído em ordem crescente até n-1 com um+ após cada um e, em seguida, acrescente o último número inteiro n seguido por um-
    • Se a linha atual for 1-, acrescente 2+, acrescente 3+que é n-1 se n = 4. Depois acrescente 4-. Resultado:1-2+3+4-
  • Se a linha atual contiver todos os números inteiros e cada um for imediatamente seguido por a -, saia do código
    • n = 4: 1-2-3-4-=> FIM

Não deve haver espaços à esquerda ou à direita em nenhuma linha. Deve haver uma quebra de linha entre cada linha. Pode ou não haver uma quebra de linha na última linha.

EDITAR: você deve testar seu código até pelo menos n = 10 (mais de 1000 linhas de saída, então não posso incluí-lo aqui). Qualquer número que não faça com que seu código fique sem recursos deve (eventualmente!) Produzir a saída correta, mas você não precisa esperar que o universo termine!

Isso é , então o código mais curto em bytes vence!

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
fonte

Respostas:

5

Haskell , 89 bytes

g pega um número inteiro e retorna uma string.

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

Experimente online!

Como funciona

  • Em termos gerais, o algoritmo constrói uma lista de todas as 2^ncombinações 1+2+...n+, 1+2+...n-até 1-2-...n-, retira os +números finais e, se o resultado estiver vazio, substitui-o por -.

  • mapM(,)"+-"é uma maneira mais curta (usando a função monad) de escrever \i->[('+',i),('-',i)].

  • mapM(mapM(,)"+-")[1..n]gera (usando a lista mônada para o exterior mapM) uma lista com todas as combinações como listas de tuplas, por exemplo [(1,'+'),(2,'-'),...,(n,'+')].
  • foldr ... <$> ... combina cada uma dessas listas de tuplas em uma sequência, usando a expressão lambda para construí-la a partir da direita.
    • (s,i) é uma tupla de um sinal e um número e r é a string construída a partir das tuplas à sua direita.
    • id=<<[show i++s:r|s:r>"+"]precede ie sà string rconstruída até agora, mas não se o sinal sfor positivo er estiver vazio.
      • Isso é testado comparando s:rcom "+". Por sorte, essa é a string lexicograficamente menor que pode resultar da concatenação, para que a comparação possa ser usada em >vez de /=.
  • Também por sorte, "-"é menor do que qualquer string não vazia que pode ser construída pela dobra, portanto, a string vazia pode ser substituída por ela usando max.
  • Finalmente, unlinestransforma as strings em uma única string de linhas.
Ørjan Johansen
fonte
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'-'

Experimente online!

xnor
fonte
Bom 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:]

Experimente online!

O primeiro -(des) surpreendentemente adicionou alguns bytes justos ao código.

notjagan
fonte
Então a solução de manipulação de strings era mais curta, afinal?
HyperNeutrino
Ou eu sou apenas ruim: P
HyperNeutrino
A abordagem parece ser mais curta, mas há algumas coisas que poderiam ser melhoradas na sua; Vou postar um comentário com algumas dicas daqui a pouco.
notjagan
n = 0 produz incorretamente duas -linhas.
CJ Dennis
@CJDennis Fixed.
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

Experimente online!

Editar: Opa! Tem que funcionar para números maiores que 4 também ... e depois se afastar ... até que eu percebi que estava pensando demais e salvou 28 bytes ... e mais 6 através de pequenos golfinhos.

Chas Brown
fonte
A saída está incorreta para a entrada acima de n = 4.
CJ Dennis
@CJ Dennis Acho que funciona agora; a saída é igual a notjagan para, por exemplo, n = 5
Chas Brown
A saída parece estar correta agora! Vou acrescentar que você deve testar a pelo menos 10 ...
CJ Dennis
Acabei de notar que você define i = 0 na entrada! Isso significa que eu posso apenas gerar linhas a partir de i, como f (24,16777200)! :-)
CJ Dennis
3

Pitão, 23 bytes

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

Demonstração

A base deste programa é perceber que, além da inicial -, a sequência de mais e menos corresponde à sequência padrão de combinações de +e -com substituição, com todas as trilhas +removidas.

Explicação:

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
fonte
2

Python 2 , 73 bytes

f=lambda n,a=2,d='\n1':a<n+2and f(n,a+1,d+'+'+`a`)+d+f(n,a+1,d+`-a`)or'-'

Experimente online!

Anders Kaseorg
fonte
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)

Experimente online!

HyperNeutrino
fonte
Estou um pouco confuso com a sua mistura de abas / espaço. Primeiro, eu nem pensei que você PODERIA no Python 3, e segundo ele parece ter pouco propósito? Por que se preocupar em fazer <tab><space>quando <space><space>seria o mesmo número de bytes? Eu acho que talvez se você fizesse os pequenos recuos <space>e o maior com <tab>ele economizaria um byte ...
nmjcman101
@ nmjcman101 erm. Eu devo estar realmente cansado, ou estúpido, ou ambos. Eu estava tentando salvar bytes, fazendo esse recuo de espaço / tab, não tab / tabspace> <obrigado!
HyperNeutrino
este é 17 bytes mais curto, mas sai com erro. Ainda tentando encurtar esse maldito q[-1]para q[0]. BTW: misturar guias e espaços não funciona no Python 3; portanto, o código atual gera um erro.
notjagan
@notjagan oh hm. não importa então, deve ter sido porque antes eu estava sendo burro: P mas tudo bem, obrigado pela sugestão; vou tentar trabalhar a partir daí
HyperNeutrino