C#,1923年
它可能不会是最短的程序,但是我发现挑战很有趣,所以这是我的解决方案。
用35个数字(15 35)运行所有4个过程大约需要5秒钟。
您可以在此处进行测试,但请注意,如果您要使用OEIS4,则所需的位数必须较小,否则netfiddle将耗尽内存。
打高尔夫球
using System;using System.Collections;using System.Collections.Generic;using System.Linq;class p{public static void Main(string[] args){int b=0;IEnumerable<int>a=null;foreach(char c in Convert.ToString(int.Parse(args[0]),2).Reverse()){++b;if(c=='0')continue;switch(b){case 1: a=d(a,e());break;case 2: a=d(a,f());break;case 3: a=d(a,g());break;case 4: a=d(a,h(),true);break;}}if(a==null)return;bool j=true;foreach(int i in a.Take(int.Parse(args[1]))){if(j)j=false;else Console.Write(",");Console.Write(i);}}static IEnumerable<int>d(IEnumerable<int>k,IEnumerable<int>l,bool m=false){if(k==null)foreach(int n in l)yield return n;int o=0;int p=1;foreach(int i in k){Dictionary<int,HashSet<int>>q=m ? new Dictionary<int,HashSet<int>>(): null;int s=0;foreach(int n in l){if(!m){if(i<n)break;}else{if(!q.ContainsKey(o))q.Add(o,new HashSet<int>());q[o].Add(n);if(q.Count==1){int r=q[o].OrderBy(gi =>gi).Take(2).Sum();if(i<r)break;}else{int r=q[o].Concat(q[o-1]).OrderBy(gi =>gi).Take(2).Sum();if(i<r)break;}if(++s==p){o++;p=(int)Math.Pow(2,o);}}if(i==n){yield return i;break;}}}}static IEnumerable<int>e(){int t=0;for(int i=0;i<int.MaxValue;i++)foreach(char c in Convert.ToString(i,2)){if(c=='0')yield return t;t++;}}static IEnumerable<int>f(){int t=1;int u=0;bool v=true;using(IEnumerator<int>w=Enumerable.Range(0,int.MaxValue).GetEnumerator()){while(w.MoveNext()){if(v){if(u==0)u=t+1;yield return w.Current;if(--t==0)v=false;}else{if(t==0)t=u+1;if(--u==0)v=true;}}}}static IEnumerable<int>g(){for(int i=0;i<int.MaxValue;i++){string s=Convert.ToString(i,2);if(x(s.Count(c =>c=='0'))&& x(s.Count(c =>c=='1')))yield return i;}}static bool x(int y){return(y != 0)&&((y &(y-1))==0);}static IEnumerable<int>h(){return Enumerable.Range(1,int.MaxValue).Select(z);}static Dictionary<int,int>_=new Dictionary<int,int>();static int z(int n){int a;if(!_.TryGetValue(n,out a)){if(n<3)a=1;else a=z(n-z(n-1))+z(n-z(n-2));_.Add(n,a);}return a;}}
可读的
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class Programm
{
public static void Main(string[] args)
{
int index = 0;
IEnumerable<int> intersection = null;
foreach (char c in Convert.ToString(int.Parse(args[0]), 2).Reverse())
{
++index;
if (c == '0')
continue;
switch (index)
{
case 1: intersection = _join(intersection, OEIS1()); break;
case 2: intersection = _join(intersection, OEIS2()); break;
case 3: intersection = _join(intersection, OEIS3()); break;
case 4: intersection = _join(intersection, OEIS4(), true); break;
default: throw new ArgumentException();
}
}
if (intersection == null)
return;
bool first = true;
foreach (int i in intersection.Take(int.Parse(args[1])))
{
if (first) first = false;
else Console.Write(",");
Console.Write(i);
}
Console.ReadKey();
}
private static IEnumerable<int> _join(IEnumerable<int> intersection, IEnumerable<int> newSequence, bool hof = false)
{
if (intersection == null)
foreach (int n in newSequence) yield return n;
int generation = 0;
int generationMax = 1;
foreach (int i in intersection)
{
Dictionary<int, HashSet<int>> generationCache = hof ? new Dictionary<int, HashSet<int>>() : null;
int count = 0;
foreach (int n in newSequence)
{
if (!hof)
{
if (i < n)
break;
}
else
{
if (!generationCache.ContainsKey(generation))
generationCache.Add(generation, new HashSet<int>());
generationCache[generation].Add(n);
if (generationCache.Count == 1)
{
int lowerBound = generationCache[generation].OrderBy(gi => gi).Take(2).Sum();
if (i < lowerBound)
break;
}
else
{
int lowerBound = generationCache[generation].Concat(generationCache[generation - 1]).OrderBy(gi => gi).Take(2).Sum();
if (i < lowerBound)
break;
}
if (++count == generationMax)
{
generation++;
generationMax = (int)Math.Pow(2, generation);
}
}
if (i == n)
{
yield return i;
break;
}
}
}
}
static IEnumerable<int> OEIS1()
{
int position = 0;
for (int i = 0; i < int.MaxValue; i++)
foreach (char c in Convert.ToString(i, 2))
{
if (c == '0')
yield return position;
position++;
}
}
static IEnumerable<int> OEIS2()
{
int take = 1;
int skip = 0;
bool doTake = true;
using (IEnumerator<int> enumerator = Enumerable.Range(0, int.MaxValue).GetEnumerator())
{
while (enumerator.MoveNext())
{
if (doTake)
{
if (skip == 0)
skip = take + 1;
yield return enumerator.Current;
if (--take == 0)
doTake = false;
}
else
{
if (take == 0)
take = skip + 1;
if (--skip == 0)
doTake = true;
}
}
}
}
static IEnumerable<int> OEIS3()
{
for (int i = 0; i < int.MaxValue; i++)
{
string s = Convert.ToString(i, 2);
if (_isPowerOfTwo(s.Count(c => c == '0')) && _isPowerOfTwo(s.Count(c => c == '1')))
yield return i;
}
}
static bool _isPowerOfTwo(int number)
{
return (number != 0) && ((number & (number - 1)) == 0);
}
static IEnumerable<int> OEIS4()
{
return Enumerable.Range(1, int.MaxValue).Select(HofstadterQ);
}
static Dictionary<int, int> _hofstadterQCache = new Dictionary<int, int>();
static int HofstadterQ(int n)
{
int result;
if (!_hofstadterQCache.TryGetValue(n, out result))
{
if (n < 3)
result = 1;
else
result = HofstadterQ(n - HofstadterQ(n - 1)) + HofstadterQ(n - HofstadterQ(n - 2));
_hofstadterQCache.Add(n, result);
}
return result;
}
}
说明
这充分利用了懒惰的评估,这使它更加美观。我也懒于通过使用框架Convert.ToString(number,2)方法来执行任何“ bitlogic”。这会将任何数字转换为字符串形式的binray表示形式。
当Linq-Method相交计算完整序列的交集时,我必须编写自己的方法来相交序列,而这实际上是不可能的。
12 5
示例中的两个序列都取到相同的索引,那么10
确实确实9
在交点之前出现了……就像,您如何在遍历序列时决定是否跳过9
#3作为可能的交点?就像如果#3包含7
在其中,那么您将被要求跳过,因为它没有出现在#4中