Loops de Divisão Inteira

8

Desafio

Dado qualquer número inteiro positivo suportado pelo seu idioma:

  1. Pegue a entrada e divida-a em duas metades. Para todas as divisões deste programa, se a entrada for ímpar, arredonde uma metade para cima e outra para baixo (ex:, 7 -> 3,4não 7 -> 3.5,3.5).
  2. Divida qualquer número ao meio, pegue a maior dessas duas novas metades e adicione-a novamente ao número que não foi dividido. Ex: 3,4 -> (1,2),4 -> 1,6ou 3,4 -> 3,(2,2) -> 5,2.
  3. Repita a etapa 2 até chegar a um conjunto que você já viu antes. Ex: 5 -> 3,2 -> (1,2),2 -> 1,4 -> 1,(2,2) -> 3,2. Como já vimos 3,2antes, podemos parar de repetir. Você pode esgotar completamente uma pilha no processo de fazer isso. Ex: 5 -> 3,2 -> (1,2),2 -> 1,4 -> (0,1),4 -> 0,5.
  4. Saída de cada par no loop (ou seja, acima sem as etapas intermediárias, desde a primeira aparição de um par até o segundo, mas não incluindo o segundo). Ex: 3,2 -> 1,4. Se a entrada estiver incluída, não a 0a - 5 -> 3,2 -> 1,4, não 0,5 -> 3,2 -> 1,4.
  5. Repita as etapas 1 a 4 dividindo os pares de maneira diferente.

I / O

A entrada é um número inteiro positivo maior 1e menor que o número máximo máximo suportado pelo seu idioma ou o número máximo máximo que não trava o computador, o que for menor.

Saída são os loops de cima em qualquer formato que você desejar (string, lista, array, etc.). Espaço em branco à direita é permitido.

Não produza o mesmo loop duas vezes, nem versões diferentes do mesmo loop. Ex: 2 -> 1,1e 1,1 -> 2são dois loops válidos, mas descrevem o mesmo loop, começando em diferentes pontos do loop. Da mesma forma, dois loops que são idênticos, mas vão na ordem inversa, não devem ser gerados. Ex: 3 -> 1,2 -> 2,1e 3 -> 2,1 -> 1,2são o mesmo loop, mas eles vão na direção oposta um do outro.

Você pode usar qualquer delimitador para diferenciar entre os pares, entre cada número nos pares e entre cada loop, desde que sejam três caracteres ou cadeias de caracteres distintas. Acima, dividi os números usando vírgulas, os pares usando ->'s e os loops usando instruções chatas. Nos meus exemplos abaixo, usarei parênteses em torno de cada par, vírgulas entre cada número dentro de um par e novas linhas entre cada loop.

Exemplos

Os créditos ao código do @ WheatWizard por corrigir minha lista de exemplos. Como eu disse em um rascunho anterior, eu tinha certeza de que estava faltando alguns desde que estava fazendo isso à mão, mas cara, eu estava sentindo falta de alguns.

Entrada: 2
Saída:(2)(1,1)

Entrada: 3
Saída:

(3)(1,2)
(1,2)(2,1)
(3)(1,2)(2,1)

Entrada: 4
Saída:

(4)(2,2)(1,3)
(1,3)(3,1)
(4)(2,2)(1,3)(3,1)
(4)(2,2)(3,1)(1,3)
(3,1)(1,3)
(4)(2,2)(3,1)

Entrada: 5

Resultado:

(5)(2,3)(1,4)
(1,4)(3,2)
(2,3)(1,4)(3,2)(4,1)
(5)(2,3)(1,4)(3,2)(4,1)
(2,3)(4,1)
(5)(2,3)(4,1)

Entrada: 6

Resultado:

(6)(3,3)(1,5)
(1,5)(4,2)(2,4)
(4,2)(2,4)
(1,5)(4,2)(5,1)(2,4)
(4,2)(5,1)(2,4)
(6)(3,3)(1,5)(4,2)(5,1)
(6)(3,3)(5,1)(2,4)(1,5)
(2,4)(1,5)(4,2)
(5,1)(2,4)(1,5)(4,2)
(2,4)(4,2)
(5,1)(2,4)(4,2)
(6)(3,3)(5,1)

Entrada: 7

Resultado:

(7)(3,4)(1,6)
(1,6)(4,3)(2,5)
(2,5)(5,2)
(3,4)(1,6)(4,3)(2,5)(5,2)(6,1)
(7)(3,4)(1,6)(4,3)(2,5)(5,2)(6,1)
(3,4)(1,6)(4,3)(6,1)
(7)(3,4)(1,6)(4,3)(6,1)
(7)(3,4)(5,2)(2,5)(1,6)
(2,5)(1,6)(4,3)
(3,4)(5,2)(2,5)(1,6)(4,3)(6,1)
(7)(3,4)(5,2)(2,5)(1,6)(4,3)(6,1)
(5,2)(2,5)
(3,4)(5,2)(6,1)
(7)(3,4)(5,2)(6,1)

Pontuação

Isso é , então a menor contagem de bytes vence.


Este é o meu primeiro desafio aqui, portanto qualquer feedback seria muito apreciado. Link para sandbox aqui .

Curiosidade: um dia eu estava entediado e brincava com pequenos pedaços aleatórios de lápis dessa maneira e, por fim, percebi que eu poderia continuar com esses tipos de loops. Por alguma razão, minha primeira reação foi "ei, isso seria um grande desafio para o código de golfe".

DonielF
fonte
4
Bem-vindo ao PPCG, bom primeiro desafio!
FlipTack
Podemos imprimir (a,0)no lugar de (a)? Isso tende a fazer sentido em idiomas fortemente tipados.
Ad Hoc Garf Hunter
@WheatWizard Nope. Ao imprimir a entrada, basta imprimir a entrada sem o zero. Eu não vi um desafio aqui, que se resume a apenas um ou dois bytes.
DonielF
Ok, isso é justo o suficiente. Mas, para constar, eu certamente não chamaria isso de um ou dois bytes. Para mim, parece que cerca de 30% da minha contagem de bytes é removida do zero.
Ad Hoc Garf Hunter
Como o mesmo loop invertido é o mesmo, podemos gerar os loops invertidos?
Οurous

Respostas:

2

Limpo , 267 ... 167 bytes

import StdEnv
f s l|any((==)s)l=[dropWhile((<>)s)l]#[h,t:_]=s
|1>h*t=f[max h t]l=f[h/2,(h+1)/2+t](l++[s])++(f[(t+1)/2+h,t/2](l++[s]))
@n=removeDup(f[n/2,(n+1)/2][[n]])

Experimente online!

Ungolfed:

loops num
    = removeDup (half (divide num) [[num]])
where
    divide num
        = [num/2, (num+1)/2]
    half [_, 0] list
        = list
    half [0, _] list
        = list
    half [a, b] list
        | isMember [a, b] list
            = [dropWhile ((<>) [a, b]) list]
        # [u, v: _]
            = divide a
        # [x, y: _]
            = divide b
        = (half [u, v+b] (list ++ [a, b])) ++ (half [a+y, x] (list ++ [a, b]))
Furioso
fonte
2

Haskell , 227 203 bytes

17 bytes economizados graças ao Οurous

(%)=div
u x|odd x=x%2+1|1>0=x%2
[0,b]!l=[b]!l
[b,0]!l=[b]!l
t!l|elem t l=[dropWhile(/=t)l]
t@[a,b]!l|q<-l++[t]=[a%2,u a+b]!q++[u b+a,b%2]!q
f x|q<-[x%2,u x]![[x]]=[a|(a,b)<-zip q[0..],notElem a$take b q]

Experimente online!

Caçador Ad Hoc Garf
fonte
O uso de listas não seria mais curto que as tuplas, pois você poderia lidar com os casos de 1 e 2 elementos com o mesmo show?
Οurous
@ Ousurous Na verdade, você está certo, é mais curto, apenas leva algum trabalho.
Ad Hoc Garf Hunter