Produto com comprimento de gancho

27

Um diagrama Young é um arranjo de caixas em linhas justificadas à esquerda e colunas justificadas na parte superior. Para cada caixa, todos os espaços acima e à esquerda estão ocupados.

XXXXX
XXX
XXX
X

O comprimento do gancho de uma caixa é o número de caixas à sua direita na linha e abaixo da coluna, também contando uma vez. Por exemplo, a segunda caixa tem um comprimento de gancho de 6:

X****
X*X
X*X
X

Aqui estão todos os comprimentos de gancho:

86521
532
421
1

Seu objetivo é calcular o produto dos comprimentos do gancho, aqui 8*6*5*2*1*5*3*2*4*2*1*1 = 115200.

(Leia sobre a fórmula do comprimento do gancho, se você estiver interessado em saber por que essa expressão é importante.)

Entrada: Uma coleção de tamanhos de linha como números como [5,3,3,1]ou como um símbolo unário repetido como [[1,1,1,1,1], [1,1,1], [1,1,1], [1]]ou "XXXXX XXX XXX X". Você pode esperar que a lista seja classificada crescente ou decrescente, conforme desejar. A lista não ficará vazia e conterá apenas números inteiros positivos.

Saída: o produto do comprimento do gancho, que é um número inteiro positivo. Não se preocupe com estouros de número inteiro ou tempo de execução.

Built-ins que lidam especificamente com diagramas Young ou partições inteiras não são permitidos.

Casos de teste:

[1] 1
[2] 2
[1, 1] 2
[5] 120
[2, 1] 3
[5, 4, 3, 2, 1] 4465125
[5, 3, 3, 1] 115200
[10, 5] 798336000
xnor
fonte

Respostas:

13

CJam, 20 19 bytes

{ee::+W%}_q~%z%:+:*

Isso inclui a lista unária do estilo CJam em uma ordem crescente. Por exemplo:

[[1] [1 1 1] [1 1 1] [1 1 1 1 1]]

115200

Como funciona

Esta versão é fornecida por Dennis e usa o fato de que Block ArrayList %ainda funciona no CJam: D

{       }_             e# Put this block on stack and make a copy
          q~           e# Read the input and evaluate it to put the array of arrays on stack
            %          e# Use the copy of the block and map the array using that block
 ee                    e# Here we are mapping over each unary array in the input. ee converts
                       e# the array to [index value] pair.
   ::+                 e# Add up each index value pair. Now we have the horizontal half of
                       e# hook length for each row
      W%               e# Reverse the array to make sure the count is for blocks to the right
             z%        e# Transpose and do the same mapping for columns
               :+      e# Now we have all the hook lengths. Flatten the array
                 :*    e# Get the product of all hook lengths.

Esta é a versão original de 20 bytes

1q~:,Wf%z:ee{:+)*}f/

Isso inclui uma lista de tamanhos de linha no estilo CJam em uma ordem crescente. Por exemplo:

[1 3 3 5]

115200

Como funciona

Se olharmos para ele, o comprimento do gancho de cada bloco em um diagrama de blocos Young é a soma do índice desse bloco em sua linha e coluna, contando para trás. ou seja, inicie o índice em cada linha do lado direito e inicie o índice em cada coluna da parte inferior.

Tomamos a entrada em ordem crescente do tamanho da linha para iniciar facilmente o índice da parte inferior de cada coluna. Primeiro, obtemos o índice por linha e o invertemos. Então nós transpomos. Como a ordem da linha original foi revertida, assumir o índice neste diagrama transposto fornecerá diretamente o índice de baixo para cima.

Expansão de código

1                       e# This serves as the initial term for product of hook lengths
 q~                     e# Read the input and eval it to put an array on stack
   :,                   e# For each row-size (N), get an array of [0..N-1]
     Wf%                e# Reverse each row so that each row becomes [N-1..0]
        z               e# Transpose for the calculation of blocks below each block
         :ee            e# Enumerate each row. Convert it into array of [index value] pairs
            {    }f/    e# Apply this mapping block to each cell of each row
             :+         e# Add the index value pair. Here, index is the blocks below the
                        e# block and value is the blocks to the right of it in the Young diag
               )        e# Increment the sum by 1 to account for the block itself
                *       e# Multiply it with the current holding product, starting with 1

Experimente online aqui

Optimizer
fonte
{ee::+W%}_q~%z%:+:*(19 bytes) Formato de entrada:[[1][1 1 1][1 1 1][1 1 1 1 1]]
Dennis
@Dennis Nice (ab) uso da ordem arity para %: P
Optimizer
6

J, 24 bytes

*/@,@(1|@-+/\."1++/\)@:>

25 bytes (com explicação):

*/@,@(+/\."1|@<:@++/\)@:>

Recebe a entrada como lista de listas ascendentes de dígitos unários semelhantes ao exemplo [[1], [1,1,1], [1,1,1], [1,1,1,1,1]].

Uso:

   f=.*/@,@(+/\."1|@<:@++/\)@:>

   f 1;1 1 1;1 1 1;1 1 1 1 1
115200

Método

  • Crie uma matriz binária a partir da entrada
  • Calcule as diferenças de execução nas duas dimensões.
  • Para cada célula, adicione os dois resultados, subtraia 1, use o valor absoluto (para mapear as células originalmente zero para 1)
  • Percorra a matriz e pegue o produto dos números.

Resultados intermediários mostrados na entrada 1 1 1 1 1;1 1 1;1 1 1;1 (5,3,3,1 in unary)( isto é para uma versão anterior com comprimentos descendentes, mas usando o mesmo método ):

   ]c=.1 1 1 1 1;1 1 1;1 1 1;1
┌─────────┬─────┬─────┬─┐
│1 1 1 1 1│1 1 1│1 1 1│1│
└─────────┴─────┴─────┴─┘

   (>)  c
1 1 1 1 1
1 1 1 0 0
1 1 1 0 0
1 0 0 0 0

   (+/\.@:>)  c
4 3 3 1 1
3 2 2 0 0
2 1 1 0 0
1 0 0 0 0

   (+/\."1@:>)  c
5 4 3 2 1
3 2 1 0 0
3 2 1 0 0
1 0 0 0 0

   ((+/\."1++/\.)@:>)  c
9 7 6 3 2
6 4 3 0 0
5 3 2 0 0
2 0 0 0 0

   ((+/\."1<:@++/\.)@:>)  c
8  6  5  2  1
5  3  2 _1 _1
4  2  1 _1 _1
1 _1 _1 _1 _1

   ((+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1
5 3 2 1 1
4 2 1 1 1
1 1 1 1 1

   (,@(+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1 5 3 2 1 1 4 2 1 1 1 1 1 1 1 1

   (*/@,@(+/\."1|@<:@++/\.)@:>)  c
115200

Versão explícita do mesmo comprimento:

3 :'*/,|<:(+/\."1++/\)>y'

Experimente online aqui.

randomra
fonte
4

Pitão - 21 bytes

Estou perdendo muitos bytes no cálculo vertical. Vamos focar no golfe.

*Fs.em+lf>Td>Qkt-bdbQ

Toma entrada como [5, 3, 3, 1].

Experimente aqui online .

Maltysen
fonte
4

Pitão, 18 bytes

*Fsm.e+k-bdf>TdQeQ

Recebe entrada em ordem crescente, como [1, 3, 3, 5].

Demonstração.


Solução alternativa, 19 bytes

*Fs.em+s>Rd<Qk-bdbQ
isaacg
fonte
3

Python 2, 89 88 bytes

p=j=-1;d={}
for n in input():j+=1;i=0;exec"a=d[i]=d.get(i,j);p*=n-i+j-a;i+=1;"*n
print-p

(Graças a @xnor por um byte insano, salve combinando pe j)

o d.get parece um pouco suspeito para mim, mas caso contrário, eu sou relativamente feliz com isso. Tentei algumas outras abordagens, como recursão e fechamento, mas essa é a única que consegui obter abaixo dos 100.

Recebe a entrada do STDIN como uma lista em ordem crescente, por exemplo [1, 3, 3, 5].

Sp3000
fonte
3

Haskell, 68 bytes

f[]=1
f g@(h:t)=(h+length t)*f[x-1|x<-g,x>1]
p[]=1
p g@(_:t)=f g*p t

Exemplo de uso: p [5,4,3,2,1]->4465125

fvarre da esquerda para a direita multiplicando o comprimento do gancho mais externo com uma chamada recursiva para si mesma, onde cada elemento da lista de entrada é reduzido 1(deixando-o cair ao alcançá-lo 0). pdigitaliza de cima para baixo multiplicando fa lista inteira por pda cauda.

nimi
fonte
2

R, 174 bytes

Então ... Esta solução é bastante longa e provavelmente poderia ser mais golfe. Vou pensar sobre isso !

v=c();d=length;m=matrix(-1,l<-d(a<-scan()),M<-max(a));for(i in 1:l)m[i,(1:a[i])]=c(a[i]:1);for(j in 1:M)m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)));abs(prod(m))

Ungolfed:

v=c()          #Empty vector
d=length       #Alias

m=matrix(-1,l<-d(a<-scan()),M<-max(a)) #Builds a matrix full of `-1`

for(i in 1:l)
    m[i,(1:a[i])]=c(a[i]:1) #Replaces each row of the matrix by `n` to 1, `n` being the 
                            #corresponding input : each number is the number of non-empty
                            #cells at its left + itself

for(j in 1:M)
    m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)))

    #This part calculates the number of "non-empty" (i.e. without `-1` in a column), -1,
    #because the count for the cell itself is already done.
    # Then, it creates a vector of those count, appending 0's at the end if necessary 
    #(this avoids recycling)

abs(prod(m)) #Outputs the absolute value of the product (because of the `-1`'s)
Frédéric
fonte
1

Python 2, 135 128 bytes

Isso pega uma lista de tipos Python do stdin:

r=input()
c=[-1]*r[0]
for a in r:
 for b in range(a):c[b]+=1
s=1
y=0
for a in r:
 for x in range(a):s*=a-x+c[x]-y
 y+=1
print s

Essa é uma implementação muito canônica, mas ainda não cheguei a algo muito mais inteligente. Tenho a sensação de que haverá soluções muito mais curtas, mesmo com linguagens de programação "reais".

Nós obtemos o número de caixas em cada linha como entrada. Essa solução conta primeiro o número de caixas em cada coluna, as quais são armazenadas c(na verdade, é a contagem menos 1 para simplificar seu uso no cálculo posterior). Em seguida, itera sobre todas as caixas e multiplica os comprimentos do gancho. O comprimento do gancho em si é trivial para calcular depois de ter a contagem de caixas em cada linha e coluna.

Reto Koradi
fonte
1
Parece que você não está usando m?
xnor
Poderia jurar que o apaguei! Lembro-me de perceber que estava usando apenas uma vez e substituindo o único uso. Mas então eu devo ter esquecido de excluir a variável. :(
Reto Koradi
1

JavaScript ( ES6 ) 69

Uma função que recebe uma matriz de números inteiros em ordem crescente ordem .

Execute o trecho para testar (apenas Firefox)

F=x=>x.map(r=>{for(i=-1;++i<r;p[i]=-~p[i])t*=r-i+~~p[i]},p=[],t=1)&&t

// TEST
out=x=>O.innerHTML += x + '\n';

test=[
 {y:[1], h: 1}
,{y:[2], h: 2}
,{y:[1, 1], h: 2}
,{y:[5], h: 120}
,{y:[2, 1], h: 3}
,{y:[5, 4, 3, 2, 1], h: 4465125}
,{y:[5, 3, 3, 1], h: 115200}
,{y:[10, 5], h: 798336000}
]

test.forEach(t=>{ 
  t.y.reverse(); // put in ascending order
  r=F(t.y);
  out((r==t.h? 'Ok':'Fail')+' Y: ['+t.y+'] Result:'+r+' Check:'+t.h)
})  
<pre id=O></pre>

edc65
fonte
1

Python, 95 91 bytes

Esta é uma implementação em Python da resposta Haskell de nimi . Sugestões de golfe são bem-vindas.

f=lambda z:z==[]or(z[0]+len(z)-1)*f([i-1for i in z if~-i])
p=lambda z:z==[]or f(z)*p(z[1:])
Sherlock9
fonte
Bem-vindo ao golfe Python! Você pode fazer z and _ or 1como z==[]or _quando zé uma lista, usando o fato de que True==1. As declarações de função do Python são mais elaboradas do que Haskell, por isso geralmente oferece uma boa recompensa para definir uma única função recursiva que executa os loops recursivos interno e externo, embora eu não saiba o quão viável isso é aqui.
Xnor
@xnor "Bem-vindo ao golfe em Python"?
Sherlock9
Desculpe, você pratica golfe em Python. Eu associo você a Na verdade.
Xnor
@xnor Muito, muito antes de eu começar, na verdade, eu estava jogando golfe em Python. Eu estou um pouco ofendido que você não lembre-se: P
Sherlock9
Não posso falar pelo xnor, mas reconheço os usuários principalmente pelo avatar.
Dennis