45
7
The Shotgun numbers are a sequence with a rather simple definition but some interesting structure. Start with the natural numbers:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Now take all numbers at indices divisible by 2, group them into pairs, and swap the numbers in each pair:
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, ...
Now do the same with indices divisible by 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, ...
And then for 4, 5, 6, and so on:
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, ...
...
After k such steps, the first k+1 numbers will be fixed. So we can define the infinite sequence of Shotgun numbers as the limit of letting k go to infinity. The first 66 numbers are:
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, ...
Fun fact: Despite being obtained by only permuting the natural numbers, this sequence does not contain any primes.
The Challenge
Given an integer n > 0
, find the n
th Shotgun number. You may write a program or function, taking input via STDIN (or closest alternative), command-line argument or function argument and return the output or print it to STDOUT (or closest alternative).
This is code golf, so the shortest submission (in bytes) wins.
Leaderboards
This is getting more answers than I thought, as well as several people competing in the same language. So here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
# Language Name, N bytes
where N
is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
# 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>
1That fun fact is crazy, this algorithm shuffles all the primes to the end? Or are there other natural numbers that also will not occur? – Devon Parsons – 2015-03-04T13:39:47.953
1@DevonParsons Yes it shuffles all primes "to the end". But I think there are other numbers missing as well. It looks like
10
,21
,25
and30
don't appear either, for example. – Martin Ender – 2015-03-04T13:41:09.6933This sounds like a Project Euler question. I don't think it is... but maybe it should be. – Corey Ogburn – 2015-03-04T23:27:03.157
Wow, interesting fun fact! Although after a while it becomes obvious that prime number will always get shifted upwards at steps
p*2^k
for anyk >= 0
and so will not appear in the sequence. – justhalf – 2015-03-05T08:35:24.1339In general, at the
k
th iteration, thek
th element in the array gets transposed to the2k
th position, and won't get touched again until the2k
th iteration, at which time it gets transposed to the4k
th position, ad infinitum. A prime doesn't get transposed until its turn comes along, so to speak, so all primes get shuffled forward. But we can easily make a list of the innocent victims simply by printing off the first element to be transposed at iteration 2 and each odd iteration. The list goes: 2, 3, 5, 7, 10, 11, 13, 21, 17, 19, 30, 23, 27, 25, 29, 31, 45, 42, 37, 54, 41, 43, 65, ... – Théophile – 2015-03-05T13:34:53.757@Théophile You should submit your sequence to the OEIS, it doesn't seem to be listed currently – aPaulT – 2015-03-06T15:06:30.830
@aPaulT It is, in order: https://oeis.org/A064627
– Martin Ender – 2015-03-06T15:38:16.503@MartinBüttner Ah, thanks, hadn't noticed that the list above was not in order when I searched on it... – aPaulT – 2015-03-06T15:40:15.343
@aPaulT Thèophile sorted them by the order in which they "disappear", whereas OEIS just has them sorted by value. – Martin Ender – 2015-03-06T15:41:35.567
Does anyone know what the upper bound on this sequence is? – AJMansfield – 2015-03-11T13:08:58.677
@AJMansfield You can show that the upper bound is at most
N(N+3)/2 - 1
, soN^2
would be a conservative but simple bound. However, I did run my Mathematica implementation systematically for a bit, and numbers that are greater than4N
are already quite rare (the first one beingN = 3465
and the next ones all being multiples of that), and up to aboutN = 70,000
I haven't found any which exceeded5N
. However, I don't have a proof that a linear bound exists. – Martin Ender – 2015-03-11T16:22:59.5771@Théophile You should still submit your method of determining oeis.org/A064627 to the OEIS. – Sherlock9 – 2016-01-02T14:47:28.603
3
@Sherlock9 Done! If approved, it will be https://oeis.org/A266679. Happy new year!
– Théophile – 2016-01-02T18:54:02.517@Théophile Very cool! Happy new year! – Sherlock9 – 2016-01-02T18:57:05.020
@Théophile Ignore my last comment. You should probably also propose an edit to the existing sequence linking to your new one if it gets approved. – Martin Ender – 2016-01-02T18:57:19.543