Stampa l'intersezione delle sequenze


9

sequenze

Ti vengono date quattro sequenze numeriche, numerate 1attraverso 4.

  1. OEIS La posizione di 0quando i numeri naturali sono elencati in binario. Ecco un esempio di come calcolare la sequenza:

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

    L'inizio della sequenza è il seguente: 0, 3, 7, 8, 10, 14, 19, 20, 21, 23, 24, 27, 29, 31, 36, 37, 40, 45, 51, ...


  1. OEIS Questa sequenza include il primo numero naturale, salta i successivi due, quindi include i successivi tre, quindi salta i successivi quattro e continua.

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

  1. OEIS Numeri positivi in ​​cui sia il numero di 0's che il numero di 1' nella rappresentazione binaria del numero sono poteri di 2.

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

  1. OEIS Il Hofstadter Q sequenza .

    a (1) = a (2) = 1;
    a (n) = a (na (n-1)) + a (na (n-2)) per 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, ...
    

    Poco è dimostrato rigorosamente su questa sequenza, ma esistono molti risultati empirici. Uno è particolarmente importante e puoi supporre che sia valido per l'intera serie:

    Questo documento ha osservato che gli elementi della serie possono essere raggruppati in generazioni. Se li numeriamo a partire da 1, la ka generazione contiene esattamente 2 k elementi. La proprietà pertinente è che tutti i numeri nella generazione k sono ottenuti sommando due numeri dalle generazioni k-1 e / o k-2 , ma mai dalle generazioni precedenti. Puoi usare questa (e solo questa) osservazione per mettere un limite inferiore sugli elementi rimanenti nella sequenza.


Sfida

La tua sfida è stampare i primi xnumeri nell'intersezione delle sequenze di input fornite.

Input: due numeri separati da uno spazio attivo STDIN. Il primo numero è un intero da 1a 15inclusivo in cui ciascun bit corrisponde a una sequenza. Il bit più basso corrisponde alla sequenza 1e il più alto corrisponde alla sequenza 4. Il secondo è la quantità di numeri x, su cui emettere STDIN.

Output: i primi xnumeri che si intersecano con le sequenze di input fornite. Stampa i numeri STDOUTcon qualsiasi spazio bianco o punteggiatura come delimitatore (spazi, tabulazioni, nuove righe, virgole, due punti, punti, ecc.).


Esempi

1. Stampa i primi 3numeri presenti in ogni sequenza.

Ingresso: 15 3

Produzione: 10,23,40


2. Stampa i primi 12numeri nelle sequenze numeriche 1e 4.

Ingresso: 9 12

Produzione: 3,8,10,14,19,20,21,23,24,31,37,40


3. Stampa i primi 10numeri in sequenza 2.

Ingresso: 2 10

Produzione: 0,3,4,5,10,11,12,13,14,21


4. Stampa i primi 6numeri in sequenza 3e 4.

Ingresso: 12 6

Produzione: 2,4,5,6,9,10


Dettagli

  • È possibile stampare l'output mentre si procede o tutto in una volta alla fine.

Grazie infinite a tutti coloro che ci hanno aiutato con questo in chat! Questa domanda ha tratto grande beneficio dall'essere nella sandbox .


@chilemagic: In realtà come definisci i "primi numeri X" in un incrocio? Se prendi entrambe le sequenze 12 5nell'esempio fino allo stesso indice, allora 10davvero prima 9dell'intersezione ... come, come faresti, mentre attraversi le sequenze, decidere se saltare 9in # 3 come possibile intersezione? Come se il n. 3 fosse 7presente, ti verrà richiesto di saltarlo perché non appare nel n. 4
Claudiu,

@Claudiu I tuoi numeri di output dovrebbero essere sempre in aumento e ogni numero apparirà solo una volta nell'output.
hmatt1,

C'è un limite massimo a x?
Ypnypn,

@ypnypn non fissa un limite, ma se l'algoritmo è molto lento o non termina per input molto grandi, va bene. Questo è il golf del codice, quindi puoi essere inefficiente per salvare byte.
hmatt1,

Risposte:


2

Haskell, 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

Si comporta abbastanza bene. Ecco un paio di esempi di OP:

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 caratteri

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])

Questa è la soluzione diretta: usa i generatori per definire ciascuna delle sequenze infinite, e fintanto che l'intersezione non è abbastanza grande, aggiungi un passaggio ad ogni sequenza.

Per tenere conto della sequenza di Hofstadter non monotonicamente crescente: ad ogni passaggio ne generi il doppio per quella sequenza, ad esempio 1, quindi 2, 4, 8, 16, 32, ecc. Penso che soddisfi il limite indicato nella domanda ed è ancora abbastanza veloce per tutti i casi di test presentati lì.


2
Golf: from itertools import count as C-> from itertools import* C=count, def s(i):return D(i)==1-> s=lambda i:D(i)==1(Non penso nemmeno che questa funzione lo renda più breve ...), "{0:04b}".format(int(L)))if U>'0'->"{0:04b}".format(int(L)))if'0'<U
Justin

3

C #, 1923

Probabilmente non sarà il programma più breve ma ho trovato la sfida interessante, quindi ecco la mia soluzione.

L'esecuzione di tutti e 4 con 35 numeri (15 35) richiede circa 5 secondi.

Puoi testarlo qui , ma nota che se vuoi OEIS4 la quantità di cifre che vuoi deve essere piccola o il netfiddle esaurisce la memoria.

golfed

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;}}

Leggibile

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;
    }
}

Spiegazione

Questo fa uso di una valutazione pigra alla grande, che lo rende veloce e veloce. Inoltre ero pigro a fare qualsiasi "bitlogic" usando il metodo Convert.ToString (numero, 2) dei framework. Questo trasforma qualsiasi numero nella sua rappresentazione binray come una stringa.

Ho dovuto scrivere il mio metodo per intersecare le sequenze poiché l'intersezione Metodo Linq calcola l'intersezione dell'intera sequenza, ed era letteralmente impossibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.