Роздрукуйте перетин послідовностей


9

Послідовності

Вам надаються чотири послідовності чисел, пронумеровані 1до кінця 4.

  1. OEIS Місце розташування 0s, коли натуральні числа перераховані у двійковій формі. Ось приклад, як обчислити послідовність:

     0,1,10,11,100,101,110,111
     ^    ^     ^^  ^    ^
     0    3     78  10   14
    

    Початок послідовності відбувається так: 0, 3, 7, 8, 10, 14, 19, 20, 21, 23, 24, 27, 29, 31, 36, 37, 40, 45, 51, ...


  1. OEIS Ця послідовність включає перше природне число, пропускає наступні два, потім включає наступні три, потім пропускає наступні чотири і продовжує.

     0, 3, 4, 5, 10, 11, 12, 13, 14, 21, 22, 23, 24, 25, 26, 27, 36, ...
    

  1. Позитивні цілі числа OEIS, де і число 0s, і число 1s у двійковому представленні числа є повноваженнями 2.

    2, 4, 5, 6, 9, 10, 12, 16, 23, 27, 29, 30, 33, 34, 36, 39,
    

  1. OEIS Хофштадтера Q послідовності .

    a (1) = a (2) = 1;
    a (n) = a (na (n-1)) + a (na (n-2)) для n> 2.

    1, 1, 2, 3, 3, 4, 5, 5, 6, 6, 6, 8, 8, 8, 10, 9, 10, 11, 11, 12, 12, 12, 12, 16, 14, ...
    

    Про цю послідовність мало що підтверджено, але існує багато емпіричних результатів. Один особливо важливий, і ви можете припустити, що він дійсний для всієї серії:

    У цій роботі було помічено, що елементи серії можна групувати в покоління. Якщо пронумерувати їх, починаючи з 1, то k- е покоління містить рівно 2 k елементів. Відповідна властивість полягає в тому, що всі числа в поколінні k отримуються шляхом підсумовування двох чисел від поколінь k-1 та / або k-2 , але ніколи від попередніх поколінь. Ви можете використовувати це (і лише це) спостереження, щоб поставити нижню межу для решти елементів у послідовності.


Виклик

Ваше завдання полягає в тому, щоб надрукувати перші xчисла в перетині заданих послідовностей введення.

Введення: Два числа, розділені пробілом STDIN. Перше число є цілим числом від 1до 15включно , де кожен біт відповідає послідовності. Найнижчий біт відповідає послідовності 1, а найвищий відповідає послідовності 4. Друга - кількість чисел x, для виведення на STDIN.

Вихід: перші xчисла, що перетинаються із заданими послідовностями введення. Роздрукуйте числа на STDOUTбудь-якому чіткому пробілі чи розділові знаки як роздільник (пробіли, вкладки, нові рядки, коми, крапки, періоди тощо).


Приклади

1. Роздрукуйте перші 3числа, які є у кожній послідовності.

Вхід: 15 3

Вихід: 10,23,40


2. Роздрукуйте перші 12числа в порядкових числах 1і 4.

Вхід: 9 12

Вихід: 3,8,10,14,19,20,21,23,24,31,37,40


3. Друкуйте перші 10цифри послідовно 2.

Вхід: 2 10

Вихід: 0,3,4,5,10,11,12,13,14,21


4. Роздрукуйте перші 6числа в послідовностях 3та 4.

Вхід: 12 6

Вихід: 2,4,5,6,9,10


Деталі

  • Ви можете надрукувати вихід під час переходу або всі відразу в кінці.

Величезне спасибі всім, хто допоміг із цим у чаті! Це питання значно виграло від того, що опинився в пісочниці .


@chilemagic: Насправді як ви визначаєте "перші X числа" в перетині? Якщо ви берете обидві послідовності в 12 5прикладі до одного і того ж індексу, то 10справді це відбувається раніше 9на перетині ... як, як би ви, перебираючи послідовності, вирішили, чи пропустити 9номер 3 як можливий перехрестя? Як якщо б 7у ній був номер 3, то вам потрібно буде пропустити його, оскільки це не відображається в №4
Клавдіу

@Claudiu Ваші вихідні номери завжди збільшуватимуться, і кожне число відображатиметься лише один раз у вашому висновку.
hmatt1

Чи існує максимальна межа x?
Ypnypn

@ypnypn не жорстко кодує обмеження, але якщо ваш алгоритм дуже повільний або не закінчується для дуже великих входів, це нормально. Це код гольфу, тому ви можете бути неефективними для економії байтів.
hmatt1

Відповіді:


2

Хаскелл, 495 442 402

import Data.List
d=1:1:1%2
f=filter
p 0="0"
p 1="1"
p n=p(div n 2)++p(mod n 2)
l=length
u z[a,b]=sort.head.dropWhile((<b).l)$m(nub.foldl1 intersect.y(tail.p$31-a).(`m`[d,f(v.group.sort.p)[1..],z#1,y(z>>=p)z]).take)z
w=(=='0')
v[a]=1>2
v x=all(all w.tail.p.l)x
y x=m snd.f(w.fst).zip x
x#n=n`take`x++drop(n+n+1)x#(n+2)
n%m=d!!(m-d!!n)+d!!(m-d!!(n-1)):m%(m+1)
main=interact$show.u[0..].m read.words
m=map

Це працює досить добре. Ось кілька прикладів ОП:

Flonk@home:~>echo 15 10 | codegolf
[10,23,40,57,58,139,147,149,212,228]
Flonk@home:~>echo 9 12 | codegolf
[3,8,10,14,19,20,21,23,24,31,37,40]
Flonk@home:~>echo 2 10 | codegolf
[0,3,4,5,10,11,12,13,14,21]
Flonk@home:~>echo 12 6 | codegolf
[2,4,5,6,9,10]

4

Python 3, 590 639 символів

from itertools import count as C
D=lambda n,t='1':bin(n).count(t)
Y=range
def O():
 for n in C(0):yield from bin(n)[2:]
def B():
 s=i=0
 while 1:
  i+=s
  for j in Y(i,i+s+1):yield j
  s+=2;i+=s-1
def s(i):return D(i)==1
def F():
 a=[1]*3
 for n in C(3):a+=[a[n-a[n-1]]+a[n-a[n-2]]];yield a[-1]
L,R=input().split()
J=[x for x,U in zip([F(),(n for n in C(0)if s(D(n,'0')-1)and s(D(n))),B(),(i for i,c in enumerate(O())if'1'>c)],"{0:04b}".format(int(L)))if U>'0']
X=[set()for _ in J]
M=[]
Z=int(R);K=1
while len(M)<Z:
 for x,j in zip(X,J):x.add(next(j))
 for _ in Y(K):X[0].add(next(J[0]));K+=1
 M=X[0]
 for x in X:M=M&x
print(sorted(M)[:Z])

Це пряме рішення: використовуйте генератори для визначення кожної з нескінченних послідовностей, і поки перетин недостатньо великий, додайте крок до кожної послідовності.

Для врахування немонотонно зростаючої послідовності Hofstadter: на кожному кроці я генерую вдвічі більше для цієї послідовності, наприклад, 1, потім 2, 4, 8, 16, 32 і т.д. , і це все ще досить швидко для всіх тестових випадків, представлених там.


2
Гольфи: from itertools import count as C-> from itertools import* C=count, def s(i):return D(i)==1-> s=lambda i:D(i)==1(я навіть не думаю, що ця функція скорочує ...), "{0:04b}".format(int(L)))if U>'0'->"{0:04b}".format(int(L)))if'0'<U
Джастін

3

C #, 1923 рік

Це, мабуть, не буде найкоротшою програмою, але я вважав, що завдання є цікавим, тому ось моє рішення.

Запуск усіх 4 з 35 Числами (15 35) займає близько 5 секунд.

Ви можете протестувати його тут , але зауважте, що якщо ви хочете, щоб OEIS4, кількість цифр, які ви хочете, має бути невеликими, або пам'ять не вичерпається.

Гольф

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 (число, 2) фреймворків. Це перетворює будь-яке число у його бінарне подання у вигляді рядка.

Мені довелося написати власний метод для перетину послідовностей, оскільки метод перетинання методу Лінька обчислює перетин повної послідовності, і це було буквально неможливо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.