Os números da espingarda são uma sequência com uma definição bastante simples, mas com alguma estrutura interessante. Comece com os números naturais:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Agora pegue todos os números nos índices divisíveis por 2 , agrupe-os em pares e troque os números em cada par:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...
^ ^ ^ ^ ^ ^ ^
<---> <---> <-----> <----
1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...
Agora faça o mesmo com índices divisíveis por 3 :
1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...
^ ^ ^ ^
<------> <--------->
1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...
E depois para 4 , 5 , 6 e assim por diante:
1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...
1, 4, 8, 6, 5, 3, 7, 2, 10, 12, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 3, 7, 2, 10, 5, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 14, 7, 2, 10, 5, 11, 3, 13, 16, ...
...
Após k tais etapas, os primeiros números k + 1 serão corrigidos. Assim, podemos definir a sequência infinita de números de espingarda como o limite de deixar k ir ao infinito. Os primeiros 66 números são:
1, 4, 8, 6, 12, 14, 16, 9, 18, 20, 24, 26, 28, 22, 39, 15, 36, 35, 40, 38, 57, 34, 48, 49, 51, 44,
46, 33, 60, 77, 64, 32, 75, 56, 81, 68, 76, 58, 100, 55, 84, 111, 88, 62, 125, 70, 96, 91, 98, 95,
134, 72, 108, 82, 141, 80, 140, 92, 120, 156, 124, 94, 121, 52, 152, 145, ...
Curiosidade: apesar de ter sido obtida permutando apenas os números naturais, essa sequência não contém números primos.
O desafio
Dado um número inteiro n > 0
, encontre o n
número da espingarda. Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e retornar a saída ou imprimi-la em STDOUT (ou alternativa mais próxima).
Isso é código de golfe, então a submissão mais curta (em bytes) vence.
Classificação
Isso está recebendo mais respostas do que eu pensava, além de várias pessoas competindo no mesmo idioma. Então, aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:true,success:function(e){answers.push.apply(answers,e.items);if(e.has_more)getAnswers();else process()}})}function shouldHaveHeading(e){var t=false;var n=e.body_markdown.split("\n");try{t|=/^#/.test(e.body_markdown);t|=["-","="].indexOf(n[1][0])>-1;t&=LANGUAGE_REG.test(e.body_markdown)}catch(r){}return t}function shouldHaveScore(e){var t=false;try{t|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(n){}return t}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading);answers.sort(function(e,t){var n=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0],r=+(t.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0];return n-r});var e={};var t=0,c=0,p=-1;answers.forEach(function(n){var r=n.body_markdown.split("\n")[0];var i=$("#answer-template").html();var s=r.match(NUMBER_REG)[0];var o=(r.match(SIZE_REG)||[0])[0];var u=r.match(LANGUAGE_REG)[1];var a=getAuthorName(n);t++;c=p==o?c:t;i=i.replace("{{PLACE}}",c+".").replace("{{NAME}}",a).replace("{{LANGUAGE}}",u).replace("{{SIZE}}",o).replace("{{LINK}}",n.share_link);i=$(i);p=o;$("#answers").append(i);e[u]=e[u]||{lang:u,user:a,size:o,link:n.share_link}});var n=[];for(var r in e)if(e.hasOwnProperty(r))n.push(e[r]);n.sort(function(e,t){if(e.lang>t.lang)return 1;if(e.lang<t.lang)return-1;return 0});for(var i=0;i<n.length;++i){var s=$("#language-template").html();var r=n[i];s=s.replace("{{LANGUAGE}}",r.lang).replace("{{NAME}}",r.user).replace("{{SIZE}}",r.size).replace("{{LINK}}",r.link);s=$(s);$("#languages").append(s)}}var QUESTION_ID=47338;var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:<(?:s>[^&]*<\/s>|[^&]+>)[^\d&]*)*$)/;var NUMBER_REG=/\d+/;var LANGUAGE_REG=/^#*\s*([^,]+)/
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><link rel=stylesheet type=text/css href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id=answer-list><h2>Leaderboard</h2><table class=answer-list><thead><tr><td></td><td>Author<td>Language<td>Size<tbody id=answers></table></div><div id=language-list><h2>Winners by Language</h2><table class=language-list><thead><tr><td>Language<td>User<td>Score<tbody id=languages></table></div><table style=display:none><tbody id=answer-template><tr><td>{{PLACE}}</td><td>{{NAME}}<td>{{LANGUAGE}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table><table style=display:none><tbody id=language-template><tr><td>{{LANGUAGE}}<td>{{NAME}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table>
10
,21
,25
e30
não aparecem tanto, por exemplo.k
th iteração, ok
th elemento na matriz é transposto para a2k
th posição, e não será tocado novamente até a2k
th iteração, momento em que é transposto para a4k
th posição, ad infinitum. Um primo não é transposto até a sua vez, por assim dizer, para que todos os primos sejam embaralhados para a frente. Mas podemos facilmente fazer uma lista das vítimas inocentes simplesmente imprimindo o primeiro elemento a ser transposto na iteração 2 e cada iteração ímpar. A lista é: 2, 3, 5, 7, 10, 11, 13, 21, 17, 19, 30, 23, 27, 25, 29, 31, 45, 42, 37, 54, 41, 43, 65, ...Respostas:
Pyth, 19
22Uma implementação bastante ingênua da resposta do golfscript de @ PeterTaylor .
Experimente online aqui
Isso usa os mesmos truques para converter um loop while em uma dobra, como o outro programa Pyth abaixo.
Uma cópia ingênua do algoritmo do @ Sp3000 traduzida para Pyth.
Você pode experimentá-lo online aqui
Usa reduzir (o nome do python para fold) para emular o loop while. Ele enumera sobre o
range(input, 2)
que em Pyth funcionarange(2, input)[::-1]
. Os outros campos de golfe relacionadas com Pyth envolve o usonot
em vez de<2
e usandoy
's modo de dobrar o valor de argumentos numéricos escondido.fonte
> <>,
5245 bytesPágina Esolangs para> <>
Existem muitos elementos de cópia e movimentação, graças aos vários módulos e multiplicações necessárias. A lógica é exatamente a mesma da minha solução Python .
Recebe entrada através de um ponto de código de STDIN, por exemplo
"!" = 33 -> 75
.fonte
-v
conta como três: /Python 2, 58 bytes
Como a maioria das outras respostas, a idéia é trabalhar para trás.
Vamos chamar step
k+1
stepi
, para que no stepi
todos os múltiplos dei
sejam trocados. Precisamos de duas observações simples:n
na matriz é trocada apenas na etapai
sen
é divisível pori
,n/i mod 2
. Se este for 1, você é o número mais baixo (e será trocado), caso contrário, você é o número mais alto (e será trocado).Isso nos dá um algoritmo para trabalhar de trás para frente. Vamos tentar com 6, começando na última etapa (etapa
i = 6
):Então agora sabemos que o número veio da posição 12. Então:
Então agora sabemos que veio dos 16 antes disso. Finalmente:
Como este é o primeiro passo (lembre-se
k+1
), terminamos e o número que termina na posição 6 veio originalmente da posição 14, ou seja, o sexto número da espingarda é 14.Então agora a explicação do Python:
fonte
i-1
como~-i
while
. Bom trabalho, Sp3000.u+G**H!%GHty%/GH2rhQ2Q
Haskell, 68 bytes
Provavelmente ainda mais jogável, especialmente a primeira linha. Isso define uma função
s
que pegan
e retorna on
número da espingarda.Explicação
A função auxiliar
#
recebe dois númerosn
ek
, e retorna ok
número th na lista definida aplicando a operação de troca de pares a cadan
número th. Por exemplo, aplicá-lo aos 20 primeiros números comn = 4
isso:O resultado de
s n
é obtido reduzindo ("dobrando") a lista[2..n]
pela função de segunda ordem(.).(#)
, que recebe um númerom
e uma funçãof
(inicialmente a função de identidadeid
) e retorna uma função que recebek
e retornaf (m # k)
. Por exemplo, no caso,n = 4
a lista[2,3,4]
é reduzida a uma função que recebek
e retornaid (4 # (3 # (2 # k)))
. Aid
só é necessário para o caso de basen = 1
, em que a lista está vazia. Finalmente, damos a esta função a entradak = n
, obtendo on
número da espingarda.fonte
CJam, 32 bytes
Apenas seguindo as especificações ao ponto. Executando as instruções em um conjunto maior para não afetar o enésimo número.
Experimente online aqui
fonte
Ruby, 92 bytes
Meu primeiro esforço de golfe com código. Não se baseia em nenhuma outra resposta.
Agora que já observei algumas outras, percebo que a maioria apenas define uma função, não um programa completo que aceita entrada e produz saída. O OP solicitou um programa completo com entrada e saída. É habitual ignorar esses requisitos?
84 bytes
Depois de examinar outras respostas e perceber que é possível uma solução iterativa.
fonte
ARGV
para o$*
global mágico. 2. Oto_s
é desnecessário. 3. Em vez de atribuird
an
uma linha separada, faça apenasd=n=...
para raspar um personagem. Bom trabalho para o seu primeiro golfe! :)n+=
linha são desnecessários e as duas ocorrências de==0
podem ser alteradas com segurança para<1
.Python 2,
9779 caracteresEle determina para cada índice o valor correto, perseguindo recursivamente o número. O algoritmo foi descoberto independentemente.
editar: Agora, apenas imprime o
n
número th em vez dos primeirosn
números. É claro que uma abordagem iterativa seria mais curta, mas não quero copiar o código do Sp3000.fonte
g(i,i)
parte particularmente irritante ...print
declaração.Haskell, 79 bytes
Uso:
p 66
quais saídas145
Não há muito a explicar: a função
#
calcula recursivamente o número da espingarda na posiçãoi
do passos
.p n
retorna o número na posiçãon
da etapan
.fonte
k, 41 bytes
{{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]}
{...}
lambda, xey são o primeiro e o segundo argumentos implícitos$[b;t;f]
operador ternário, avalia b seguido de t / f, respectivamenteb!a
a módulo b_
chão, lança o resultado da divisão para um int%
divisão{...}/[x;y]
prime {...} com x e aplique sobre a lista y, é equivalente a f [f [.. f [f [x; y0]; y1]; .. yn-1]; yn]|
marcha ré!
função iota, gere a lista de 0 a n-1fonte
Lisp comum,
11391(iterativo: 91)
(original, recursiva: 113)
Exemplo
Com a versão recursiva:
Testes
Verificações e medidas para a versão iterativa:
fonte
Mathematica,
5349 bytesEu decidi jogar golfe minha implementação de referência. O
∣
é o símbolo Unicode para "divide" e conta com 3 bytes. Caso contrário, isso usa o mesmo algoritmo que todos os outros.Ele define uma função sem nome que recebe
n
como único parâmetro e retorna on
número da espingarda.fonte
GolfScript, 27 caracteres
Explicação
Se
f(i, n)
é o valor na posiçãon
após asi-1
transformações, temosonde
^
denota xor bit a bit; dada entradan
, queremos calcularf(n, n)
.A conversão de uma função recursiva para um loop é desinteressante; o que é interessante é a maneira pela qual
pode ser reescrito. A abordagem mais óbvia é dizer que deve ser
para alguns
g
. Obviamenteg
alterna entre1
e-1
, à medida que as posições se alternam alternadamente para cima e para baixo; desdeg(1) = 1
(porque1
muda até2
), temosonde
**
denota exponenciação. A economia final vem da reescrita comoDissecação
fonte
u-G*H^_!%GH/GHrhQ2Q
Se você não quiser publicar isso por conta própria, diga-me / inclua-o na resposta da CW.CJam, 24 bytes
Demonstração online
Esta é uma porta da minha resposta GolfScript , pegando emprestado o loop da resposta CJam de Martin e explorando o
divmod
operador da CJam . ( Eu disse que seria útil!).fonte
Julia,
6157 bytesIsso cria uma função sem nome, que recebe um único argumento
n
e retorna on
número da espingarda. Para chamá-lo, dê um nome, por exemplof=n->(...)
.Exemplos:
Atualmente, isso se baseia na incrível resposta em Python do @ Sp3000 . Vou revisitar isso em breve, porque deve haver uma maneira mais curta de fazer isso em Julia do que o que eu fiz aqui. Qualquer entrada é bem-vinda, como sempre.
fonte
GML, 76 bytes
Informações sobre GML
fonte
CJam,
2827 bytesPortanto, isso é um pouco embaraçoso ... antes de postar isso, tentei jogar sozinho e cheguei a 30 bytes no CJam. Nenhuma das respostas existentes superou isso ainda. Enquanto isso, também consegui raspar mais três bytes. Não é uma solução mais curto Pyth em um comentário, mas nada mais curto foi postado em uma resposta, por isso aqui está. Talvez inspire o pessoal da APL / J a se esforçar um pouco mais (ou alguém realmente postar a solução Pyth), antes que eu tenha que aceitar minha própria resposta. ;)
Teste aqui.
Explicação
fonte
J,
3432 bytesVai tentar jogar um pouco mais e adicionar algumas explicações mais tarde.
Experimente online aqui.
fonte
TI-Basic 83/84, 40 bytes
Informações sobre o TI-Basic
fonte
Ruby,
5747 bytesEsta é essencialmente a solução Python do Sp3000 (com sugestão do xnor ) traduzida para Ruby. Eu provavelmente poderia jogar golfe em alguns lugares.
fonte