Gerar elementos básicos da álgebra de Steenrod


16

A álgebra de Steenrod é uma álgebra importante que surge na topologia algébrica. A álgebra de Steenrod é gerada por operadores chamados "quadrados de Steenrod", existe um para cada número inteiro positivo i. Existe uma base para a álgebra de Steenrod que consiste em "monômios admissíveis" nas operações quadráticas. Nosso objetivo é gerar essa base.

Uma sequência de números inteiros positivos é chamada admissível se cada número inteiro for pelo menos duas vezes o próximo. Assim, por exemplo, [7,2,1]é admissível porque 722 e 221 . Por outro lado, [3,2]não é admissível porque 3<22 . (Em topologia, escreveríamos Sq7Sq2Sq1 para a sequência [7,2,1]).

O grau de uma sequência é o total de entradas. Assim, por exemplo, o grau de [7,2,1]é 7+2+1=10 . O excesso de uma sequência admissível é o primeiro elemento menos o total dos elementos restantes, portanto, [7,2,1]tem excesso 7-2-1=4 .

Tarefa

Escreva um programa que pegue um par de números inteiros positivos (d,e)e produza o conjunto de todas as seqüências admissíveis de grau de excesso menores ou iguais a e. A saída é um conjunto para que a ordem das seqüências admissíveis não importe.

Exemplos:

 Input: 3,1
 Output: [[2,1]]

Aqui estamos procurando sequências admissíveis com o total 3. Existem duas opções, [3]e [2,1]. ( [1,1,1]e [1,2]possui a soma 3, mas não é admissível). O excesso de [3]é 3 e o excesso de [2,1]é 2-1=1 . Assim, a única sequência com excesso 1 é [2,1].

Input: 6, 6
Output: [[6], [5, 1], [4, 2]] (or any reordering, e.g., [[5,1],[4,2],[6]])

Como o excesso é sempre menor ou igual ao grau, não temos condição de excesso. Assim, nós estamos apenas tentando encontrar todas as sequências admissíveis de grau 6. As opções são [6], [5, 1]e [4, 2]. (Eles têm excesso de 6 , 5-1=4 e 4-2=2 )

Input: 10, 5
Output: [[7,3], [7,2,1], [6,3,1]]

As seqüências admissíveis do grau 10 são:

[[10], [9,1], [8,2], [7,3], [7,2,1], [6,3,1]]

Eles têm excesso de 10 , 9-1=8 , 8-2=6 , 7-3=4 , 7-2-1=4 e 6-3-1=2 respectivamente, portanto os três últimos funcionam.

Pontuação

Este é o código golf: A solução mais curta em bytes vence.

Casos de teste:

Qualquer reordenação da saída é igualmente boa, portanto, para entradas (3, 3), saídas [[3],[2,1]]ou [[2,1],[3]]são igualmente aceitáveis ​​(no entanto, [[1,2],[3]]não).

Input: 1, 1
Output: [[1]]

Input: 3, 3
Output: [[2,1], [3]]

Input: 3, 1
Output: [[2,1]]

Input: 6, 6
Output: [[6], [5, 1], [4, 2]]

Input: 6, 4
Output: [[5,1], [4,2]]

Input: 6, 1
Output: []

Input: 7, 7
Output: [[7], [6,1], [4,2,1], [5,2]]

Input: 7,1
Output: [[4,2,1]]

Input: 10, 10
Output: [[10], [9,1], [7,2,1], [6,3,1], [8,2], [7,3]]

Input: 10, 5
Output: [[7,3], [7,2,1], [6,3,1]]

Input: 26, 4
Output: [15, 7, 3, 1]

Input: 26, 6
Output: [[16, 7, 2, 1], [16, 6, 3, 1], [15, 7, 3, 1], [16, 8, 2], [16, 7, 3]]

1
Ok, vou fornecer uma breve explicação.
capa de

Respostas:


6

05AB1E , 16 12 bytes

Economizou 4 bytes graças ao Grimy

Åœíʒx¦@P}ʒÆ@

Experimente online!

Explicação

Ŝ              # integer partitions
  í             # reverse each
   ʒ    }       # filter, keep only elements true under:
    x           # each element doubled
     ¦          # remove the first element in the doubled list
      @         # compare with greater than or equal with the non-doubled
       P        # product
         ʒ      # filter, keep only elements true under:
          Æ     # reduce by subtraction
           @    # compare with greater than or equal to second input

ćsO-é o embutido Æ.
Grimmy

Também À@¨pode ser ¦@.
Grimmy #

1
@Grimy: Oh uau, como eu perdi isso :) Obrigado!
Emigna

5

Wolfram Language (Mathematica) , 67 62 bytes

Cases[IntegerPartitions@#,a_/;2a[[1]]-#<=#2>Max@Ratios@a<=.5]&

Experimente online!

-4 bytes por @attinat

  • IntegerPartitions@d : Obtenha todas as listas de números inteiros que somam d
  • Cases[,...]: Filtre pela seguinte condição:
    • 2#& @@# - d <= e &&: Duas vezes o primeiro elemento menos a soma é menor que ee ...
    • Max@Ratios@#<=.5: As proporções de elementos sucessivos da lista são menores que 1/2.

Como eé menor que 0,5, podemos transformar isso em uma desigualdade encadeada.

Para alguns bytes extras, isso é significativamente mais rápido: Experimente online!



5

Geléia ,  16  15 bytes

-1 graças a Erik the Outgolfer (um ajuste inteligente na verificação que permite um único filtro)

:Ɲ;_/>¥’Ạ
ŒṗUçƇ

Um link diádico que aceita um número inteiro positivo, dà esquerda e um número inteiro positivo e, à direita, que produz uma lista de listas de números inteiros positivos.

Experimente online! (o rodapé formata os resultados para evitar a lista, a formatação implícita da lista que o Jelly faz como um programa completo)

Quão?

:Ɲ;_/>¥’Ạ - Link 1: admissible and within excess limit? descending list, L; excess limit, e
 Ɲ        - neighbour-wise:
:         -   integer division  -- admissible if all these are >1
      ¥   - last two links as a dyad - i.e. f(L,e):
    /     -   reduce (L) by:
   _      -     subtraction
     >    -   greater than (e)? (vectorises)  -- within excess if all these are ==0
  ;       - concatenate
       ’  - decrement (vectorises)
        Ạ - all (non-zero)?

ŒṗUçƇ - Main link: integer, d; integer, e
Œṗ    - partitions (of d)
  U   - reverse each
    Ƈ - filter keep those (v in that) for which:
   ç  -   call last Link (1) as a dyad - i.e. f(v, e)

Você pode salvar um byte com um truque inteligente . Pode demorar um pouco para entender por que isso funciona. : P
Erik the Outgolfer

@EriktheOutgolfer awesome, eu tentei algumas maneiras semelhantes de alinhar os dois filtros (incluindo concatenação), mas tudo estava saindo como 16, pois eu não pensava em usar o truque de decremento ao mesmo tempo.
Jonathan Allan


3

JavaScript (V8) ,  88 87  81 bytes

Toma entrada como (e)(d). Imprime as seqüências para STDOUT.

e=>g=(d,s=x=d,a=[])=>s>0?d&&g(d-1,s,a,g(d>>1,s-d,[...a,d])):a[s]*2-x<=e&&print(a)

Experimente online!

Comentado

e =>                  // e = maximum excess
  g = (               // g is a recursive function taking:
    d,                //   d   = expected degree; actually used as the next candidate
                      //         term of the sequence in the code below
    s =               //   s   = current sum, initialized to d; we want it to be equal
                      //         to 0 when a sequence is complete
    x = d,            //   x   = copy of the expected degree
    a = []            //   a[] = current sequence
  ) =>                //
    s > 0 ?           // if s is positive:
      d &&            //   if d is not equal to 0:
        g(            //     outer recursive call:
          d - 1,      //       decrement d
          s,          //       leave s unchanged
          a,          //       leave a[] unchanged
          g(          //       inner recursive call:
            d >> 1,   //         update d to floor(d / 2)
            s - d,    //         subtract d from s
            [...a, d] //         append d to a[]
          )           //       end of inner recursive call
        )             //     end of outer recursive call
    :                 //   else:
      a[s] * 2 - x    //     s if either 0 (success) or negative (failure)
                      //     if s is negative, a[s] is undefined and this expression
                      //     evaluates to NaN, forcing the test to fail
      <= e            //     otherwise, we test whether the excess is valid
      && print(a)     //     and we print a[] if it is

3

Pitão , 23 bytes

f!>-FTvzf!<#2/MCtBT_M./

Experimente online!

f!>-FTvzf!<#2/MCtBT_M./Q   Implicit: Q=input 1, vz=input 2
                           Trailing Q inferred
                     ./Q   Generate partitions of Q (ordered lists of integers which sum to Q)
                   _M      Reverse each
        f                  Filter keep elements of the above, as T, where:
               CtBT          Pair the set with itself without the first element and transpose
                             This yields all adjacent pairs of values
             /M              Integer divide each pair
           #                 Filter keep elements...
          < 2                ... less than 2
                             For admissible sequences this will be empty
         !                   Logical NOT - maps [] to true, populated lists to false
                           Result of filter are all admissible sequences
f                          Filter keep the above, as T, where:
   -FT                       Reduce T by subtraction to get degree
 !>   vz                     Is the above not greater than vz?
                           Implicit print

3

Python 3 , 213 bytes

Lista gigante de compreensão. Provavelmente não é a melhor maneira de fazer isso, mas não consigo descobrir como pular as instruções if

import itertools as z
f=lambda d,e:[c for c in [[b for b in list(z.permutations(range(1,d+1),i)) if sum(b)==d and b[0]-sum(b[1:i])<=e and all([b[i]>=b[i+1]*2 for i in range(len(b)-1)])] for i in range(1,5)] if c]

Python 3 , 172 bytes

from itertools import*
r=range
f=lambda d,e:filter(len,[[b for b in permutations(r(1,d+1),i)if d==sum(b)and~e<d-2*b[0]and all(i>=j*2for i,j in zip(b,b[1:]))]for i in r(5)])

Experimente online!

Conforme editado por @Jonas Ausevicius


2
Bem vindo ao site. Algumas dicas: Parece que você não está familiarizado com o espaçamento necessário em python. Você tem alguns lugares em que os espaços podem ser removidos muito bem, então eu examinaria isso. Também funções como allpodem levar um gerador para que você possa fazer em all(...)vez de all([...]). Por fim, como o envio é uma função completamente anônima, você não é penalizado pela atribuição ( f=) e, portanto, pode deduzi-la da sua pontuação (-2 bytes).
Post Rock Garf Hunter


Ah, e também no python3 você pode converter para listar em [*(...)]vez de list(...)que normalmente salva um byte, mas no seu caso salva 2, pois também permite remover um espaço.
Post Rock Garf Hunter

2
189 bytes, se for bom retornar um objeto de filtro, caso contrário 192 com [*filter(...)]. Dê as boas-vindas :)
Reinstate Monica


2

Carvão , 42 bytes

Fθ⊞υ⟦⊕ι⟧FυF…·⊗§ι⁰θ⊞υ⁺⟦κ⟧ιIΦυ›⁼Σιθ‹η⁻⊗§ι⁰Σι

Experimente online! Link é a versão detalhada do código. Explicação:

Fθ⊞υ⟦⊕ι⟧

Primeiro, crie uma lista de listas [1]..[d].

FυF…·⊗§ι⁰θ⊞υ⁺⟦κ⟧ι

Para cada lista, crie novas listas prefixando todos os números do primeiro número dobrado até d e anexe essas listas à lista de listas a serem processadas. Isso garante que todas as seqüências admissíveis que contenham números não maiores que o dsejam criadas.

IΦυ›⁼Σιθ‹η⁻⊗§ι⁰Σι

Saída apenas as listas cujo grau é de excesso não é maior que e. (A soma do grau e do excesso é igual ao dobro do primeiro número da lista.)


2

Python 3 , 156 bytes

lambda d,e:[x for y in range(5)for x in permutations(range(1,d+1),y)if all(i>=j*2for i,j in zip(x,x[1:]))and d==sum(x)and~e<d-2*x[0]]
from itertools import*

leva d,e como entrada; produz lista de tuplas

Semelhante à resposta do @OrangeCherries e ajuda dos comentários; mas mais bytes salvos

Experimente online!



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.