Implemente a Transformação rápida de Fourier com o menor número possível de caracteres.
Regras:
- Menor solução ganha
- Pode-se supor que a entrada seja uma matriz 1D cujo comprimento seja uma potência de duas.
- Você pode usar o algoritmo de sua escolha, mas a solução deve ser realmente uma transformação rápida de Fourier, não apenas uma transformada discreta de Fourier ingênua (ou seja, deve ter um custo de computação assintótico de )
Editar:
o código deve implementar a Fast Fourier Transform padrão, cuja forma pode ser vista na equação (3) deste artigo da Wolfram ,
- Não é permitido o uso de uma função FFT de uma biblioteca padrão pré-existente ou de um pacote de estatísticas. O desafio aqui é implementar sucintamente o próprio algoritmo FFT.
code-golf
math
complex-numbers
jakevdp
fonte
fonte
FFT
(3 caracteres): está na biblioteca padrão"? Alguns casos de teste também seriam bons.Respostas:
Mathematica, 95 bytes
Outra implementação do Cooley – Tukey FFT com a ajuda de @ chyaong .
Ungolfed
fonte
#[[;;;;2]]==#[[1;;N;;2]]
e[[2;;;;2]]==[[2;;N;;2]]
.With[{L=Length@#},If[L>1,Join[+##,#-#2]&[#0@#[[;;;;2]],#0@#[[2;;;;2]]E^(-2I*Pi(Range[L/2]-1)/L)],#]]&
J, 37 bytes
Uma melhoria depois de alguns anos. Ainda usa o algoritmo Cooley-Tukey FFT.
Salvou 4 bytes usando e πi = -1, graças a @ Leaky Nun .
Experimente online!
Uso
Explicação
fonte
Python,
166151150 caracteresUtiliza o algoritmo radix-2 Cooley-Tukey FFT
Testando o resultado
fonte
from x import*
esum(([x for x in y] for y in z),[])
é maior que[x for y in z for x in y]
.Python 3:
140134113 caracteresVersão curta - curta e doce, cabe em um tweet (com agradecimentos às milhas ):
(No Python 2,
/
é truncar a divisão quando os dois lados são inteiros. Então substituímos(i*4/n)
por(i*4.0/n)
, que aumenta o comprimento para 115 caracteres.)Versão longa - mais clareza nas partes internas do clássico Cooley-Tukey FFT:
fonte
e^(-2j * pi * i / n) = (-1)^(2 * i / n) = (1j)^(4 * i / n)
R:
1421339995 bytesObrigado a @ Giuseppe por me ajudar a reduzir
3236 bytes!Um truque adicional aqui é usar os argumentos padrão da função principal para instanciar algumas variáveis.
O uso ainda é o mesmo:
Versão de 4 anos em 133 bytes:
Com recuos:
Ele também usa o algoritmo Cooley-Tukey. Os únicos truques aqui são o uso de funções
Recall
que permitem recursividade e o uso de vetorização R que diminui bastante o cálculo real.Uso:
fonte
Recall
já que é uma função nomeada, mas, ei, é fácil jogar golfe em retrospectiva! :) +1, muito bom.Recall
agora é desnecessário, de fato. Notei isso há alguns meses, mas estava com preguiça de mudar :) Vou modificá-lo.y
lá em cima, mas não percebi que poderia ser usado para oexp(...)
papel também.Python, 134
Isso empresta muito a solução do jakevdp, então eu configurei este em um wiki da comunidade.
Alterar:
-12 caracteres: matar
t
.-1 char: truque do expoente,
x*y**-z == x/y**z
(isso pode ajudar alguns outros)-2 char: substitua
and
por*
+1 caractere:
lambda
ize, matandoN
-2 char: use em
enumerate
vez dezip(range(len(
fonte
f=lambda x:x*(len(x)<2)or[u+v/1j**(4*i/len(x))for i,(u,v)in enumerate(zip(f(x[::2])*2,f(x[1::2])*2))]
for s in(1,-1)for
porfor s in 1,-1for
ou mesmo, se o pedido não interessarfor s in-1,1for
,.C, 259
O problema é que essas implementações são inúteis e o algoritmo direto é MUITO mais rápido.
fonte
step < n
pode ser alteradostep<n
estep * 2
alteradostep*2
.Matlab,
1281181071021019493 bytesEDIT6: obrigado @algmyr por outro byte!
EDIT5: Ainda está ficando mais curto :) graças a @sanchises
EDIT4: Yay, -1 caractere a mais (também poderia ter acontecido sem o
k
):EDIT2 / 3: Obrigado por @sanchises por mais melhorias!
EDIT: poderia fazer algumas melhorias e percebeu que a constante de escala não é necessária.
Esta é a versão expandida, a contagem de caracteres é válida se você remover as novas linhas / espaços. (Funciona apenas para vetores de coluna.)
fonte
d=
linhas em um:m=n/2;d=f(Y(2:2:n)).*exp(-pi*i*(0:m-1)/m).';
. Além disso, considere mudary=f(Y)
paraY=f(Y)
e remover a linha 3 (e prometo que você nunca vai fazer isso fora do código-golf)function Y = f(Y)
outras desvantagens além da ilegibilidade?m=n/2
poderia ser removido em
substituído porn/2
en*2
respectivamente. E então, acredito firmemente, o programa é o mais curto possível no MATLAB.Gelatina,
31302826 bytes , não concorrenteA geléia foi criada após esse desafio, portanto não é competitiva.
Isso usa o algoritmo recursivo Cooley-Tukey radix-2. Para uma versão sem golfe, veja minha resposta no Mathematica.
Experimente online ou verifique vários casos de teste .
Explicação
fonte
C (gcc) ,
188186184188bytesExperimente online!
Pouco golfe menos
fonte
Pari / GP, 76 caracteres
Uso
fonte
Oitava ,
109 103 101100 bytesExperimente online!
Ooooo meus olhos sangram desta lambda
recursivaamaldiçoada. Grande parte disso foi retirada da resposta de @ flawr.fonte
Axiom,
259,193,181, 179 bytesMesmo que h (a) possa passar em todo o teste e seja aceitável, como entrada para essa 'competição', é preciso chamar h () ou hlp () através de fft () abaixo, para verificar os argumentos . Não sei se este software pode ser bom, porque eu só tinha visto o que os outros escreveram e pesquisei como ele poderia ser executado no Axiom para retornar algum resultado possível. Abaixo código não-destruído com poucos comentários:
nos poucos que eu tinha visto h () ou fft () retornaria a solução exata, mas se a simplificação não for boa como em:
do que é suficiente, altere o tipo de apenas um elemento da lista, como na escrita 8. (Float) para encontrar a solução aproximada:
Eu escrevi, vi todas as outras respostas, porque no link a página era muito difícil, então não sei se esse código pode estar correto. Eu não sou um especialista em FFT, então tudo isso pode (é provável) estar errado.
fonte
APL (NARS), 58 caracteres, 116 bytes
teste
fonte