Şanslı Numaralar Üret


22

Öykü:

Lucy, George'a Şanslı Numara'nın ne olduğunu sordu. Bazı tefekkürlerden sonra, George birkaç Şanslı Numaraya sahip olduğunu söyledi. Kısa bir kargaşanın ardından Lucy, George'a ilk nŞanslı Sayıların ne olduğunu sordu . George daha sonra sizden, arkadaşı olarak, onun için işi yapması için bir program yazmasını istedi.

Meydan okuma:

Standart girdi / işlev değişkeninden bir dize veya tamsayı olarak alacak bir program / işlev yazacaksınız n. Program / fonksiyon daha sonra ilk n Lucky Numbers'u döndürür / verir . Şanslı sayılar aşağıdaki gibi bir elek ile tanımlanır.

Olumlu tamsayılar ile başlayın:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, ...

Şimdi her ikinci numarayı kaldırın:

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, ...

Kalan ikinci sayı 3 , bu nedenle her üç sayıyı da çıkarın:

1, 3, 7, 9, 13, 15, 19, 21, 25, ...

Şimdi bir sonraki kalan numara 7 , bu nedenle her yedinci numarayı kaldırın:

1, 3, 7, 9, 13, 15, 21, 25, ...

Sonra, her dokuzuncu sayıyı ve benzerlerini kaldırın. Elde edilen dizi şanslı sayılardır.

Kazanan:

Codegolf için her zamanki gibi, en az bayt kazanır.

Her zamanki gibi, standart boşlukları kullanan gönderiler diskalifiye edilir.


8
İlk on kadar rakamın yanı sıra postadaki tanımı eklemenizi öneririm.
xnor

Serin bir uzatma, incelenen her madde için (3, 7, vb.) Bu işlemi bu kadar sayıda yapacaktı. Örneğin, 3 için, listedeki üçüncü elemanı 3 kez, 7. elemanı 7 kez vb. Çıkarın. (Bu sıra değil ama fikrin aynı olduğuna dikkat edin)
Ryan,

@Ryan, bu dizilimin doğal sayılara çok benzeyeceğini düşünüyorum :)
TheNumberOne

@ TheBestOne Sizce öyle mi? Daha önce math.stackexchange'e gönderdim: math.stackexchange.com/questions/1153889/…
Ryan

@Ryan Aslında, önerinizi yanlış yorumladım. Math.se konusundaki sorunuzda belirttiğiniz gibi, bunun ilginç olacağını düşünüyorum.
TheNumberOne,

Yanıtlar:


16

Python 2, 79

n=input()
L=range(1,2**n)
for r in L:r+=r<2;map(L.remove,L[r-1::r])
print L[:n]

Döngü onu değiştirir gibi bir liste üzerinde yinelenen büyüsü!

Liste L, tam sayılarla 1yeterince yüksek bir değerde başlar. Kodu, her elemanın üzerinde dolaşır rve Lher bir alt listesini alarak r'inci elemanı ve bu değerlerin her birinin çıkarılması. Sonuç olarak, kaldırılan değerler yinelenmez. Sonunda, ilk nelemanları yazdırın .

İfade map(A.remove,B)kullanmak için uzun zamandır bekliyorum bir hiledir. Tüm elemanlarının çıkarılmasına neden olan A.removeher elemanını çağırır . Etkili olarak, bir alt liste olması gerekmesine rağmen liste farkını alır . Python 2 gerektirir, çünkü Python 3 aslında haritayı değerlendirmez.BBABA

İlk döngü ihtiyaçları özel kasalı dönüştürmek için olmak rden 1üzere 2gibi r+=r<2.

Yeterince yüksek üst sınırı 2**nprogramı, büyük değerleri için çok yavaşlatır n. Kullanmak n*n+1yeterli, ancak bir karaktere mal olur. Bunun n*nişe yaramadığını unutmayın n=1.


Sadece n**2sayılara ihtiyacınız var , değil2**n
Doktor

3
mapOradaki harika bir kullanım bu. Daha iyi bir yol olup olmadığını merak ediyordum ...
Sp3000

@Optimizer Maalesef, affedilmediği n**2+1sürece n=1.
xnor

Haritanın kullanımı mükemmel. Sıralı bir set kullanmak gibi. Belki de map(A.index,B)A'daki B elementlerinin indekslerini bulmak, A'daki B elementlerinin map(A.count,B)sayısını bulmak, A'ya map(A.extend,B)düzleştirilmiş bir B listesi eklemek için de kullanılabilir.
Mantık Şövalyesi

13

Haskell, 71 69 bayt

s(n:k)p=n:s[m|(i,m)<-zip[p..]k,i`mod`n>0](p+1)
f n=take n$1:s[3,5..]3

Bir fonksiyon tanımlar f. İfade 1:s[3,5..]3, sonsuz sayıdaki sonsuz listeyi değerlendirir ve bunlardan fbirincisini alır .ntake n

f 20
[1,3,7,9,13,15,21,25,31,33,37,43,49,51,63,67,69,73,75,79]

Paralel bir liste kavrayışı kullanarak elekten 5 bayt'ı tıraş edebilirim

s(n:k)p=n:s[m|m<-k|i<-[p..],i`mod`n>0](p+1)

ancak bu -XParallelListComp, uzantıyı mümkün kılmak için nemli derleyici bayrağının GHC'ye geçirilmesini gerektirecektir .

Elek açıklaması

s(n:k)p=               -- Sieving a list with head n and tail k with accumulator p is
 n:                    -- the head n, followed by
  s[m|                 -- the result of sieving the list of numbers m
    (i,m)<-zip[p..]k,  -- where (i,m) is drawn from [(p,k_0),(p+1,k_1),(p+2,k_2),..] and
    i`mod`n>0]         -- i does not divide n,
   (p+1)               -- using p+1 as the accumulator

Temel fikir şu ki s(n:k)p, (p-1)inci şanslı sayıyı üretir, nher nsayıdaki sayıyı sonsuz kuyruğundan düşürür k( pdaha önce üretilen sayıları hesaba katar) ve bu listeye akümülatör ile tekrar başlar (p+1). İçinde f, işlemi tamamen tek sayılar elde ederek baştan başa doğru ilerleyen tekli sayılarla 3başlatıyoruz 1.


12

Python 2, 71 69 67

İlk başta, bunun Python'un dizi dilimlemesi için büyük bir zorluk olacağını düşündüm. Ancak, 1'den başka bir adıma sahip dilimlerin yalnızca kendilerine atanmış özdeş uzunluktaki başka bir dilime sahip olabileceğini keşfettiğimde tökezleyen bir blokla karşılaştım. Ancak googling "python dilimini kaldır" delifadesinden sonra inancım geri geldi: Numarayı mükemmel yapan korkak bir ifade buldum .

n=input()
l=range(n*n+9)
for v in l:del l[v&~1::v or 2]
print l[:n]

Eski versiyon

n=input()
l=range(1,n*n+9)
for v in l:del l[v-1%v::v+1/v]
print l[:n]

Sp3000 sayesinde -2 bayt.


10

> <> , 121 114 111 bayt

i2+:&:*1\
:})?v:2+>l{
nao2\r~1
)?vv>1+:&:&=?;:[{::nao}]$}l1-[01+}:l3-$%$l1-@@-{$[{~l1
3.\ ff+
!?:<]-1v
~]{43. >

Söyleyecek birkaç sözüm var ...

... "Argh beynim ağrıyor."


açıklama

> <> 2B ezoterik bir programlama dilidir ve kesinlikle dizi eksikliği nedeniyle bu görev için uygun değildir. Aslında,> <> içindeki tek veri türü int / float / char öğesinin garip bir karışımıdır ve her şey yığın yığınında gerçekleşir.

İşte yıkık:

Line 1:            i2+:&:*1\

i2+:&              Read a char as input (n) and add 2, copying n+2 into the register
:*                 Duplicate and multiply, giving (n+2)^2 on the stack
1\                 Push 1 and go to the next line

Line 2:            >l{:})?v:2+

l{:})?v            Go to the next line if the stack's length is greater than (n+2)^2
:2+                Otherwise duplicate the top of the stack and add 2 to it

Line 3:            \r~1nao2

r~                 Reverse the stack and pop; stack contains the first (n+2)^2 odd integers
1nao               Print 1 (special case)
2\                 Push 2 (let's call this "i" for "iterations") and go to the next line

Line 4:            >1+:&:&=?;:[{::nao}]$}l1-[01+}:l3-$%$l1-@@-{$[{~l1)?vv

1+                 Increment i
:&:&=?;            If i is equal to n+2 (+2 because we started at 2), halt
:[{::nao}]$}       Print the i-th element down (the next lucky number) and also
                   copy it to the top of the stack, while moving i to the bottom
l1-[               Move everything but i to a new stack
0                  Push 0 (let's call this "r" for recursion depth)

Sieve loop:

1+                 Increment r
}:l3-$%$l1-@@-{$[  Move everything up to the last element to be sieved out to a new stack
{~                 Remove said last element
1)?vv              If the length is 1, go to line 6 (sieving complete)
                   Otherwise go to line 5, which repeats this sieve loop by teleporting

Line 6:            :?!v1-]

:?!v1-]            Keep unrolling and decrementing r until r is 0

Line 7:            >~]{43.             

~]                 Pop r and unroll once more (to the stack where i waits)
43.                Loop, performing everything from line 4 all over again

İşte elenmenin nasıl çalıştığını kabaca gösteren sahte bir örnek (işte kelimizdeki şanslı sayı):

[[15 13 11 9 7 5 3 1 k=3 r=0]]     -- move -->
[[15 13] [11 9 7 5 3 1 k=3 r=1]]   -- pop  -->
[[15 13] [9 7 5 3 1 k=3 r=1]]      -- move -->
[[15 13] [9 7] [5 3 1 k=3 r=2]]    -- pop  -->
[[15 13] [9 7] [3 1 k=3 r=2]]      -- move -->
[[15 13] [9 7] [3 1] [k=3 r=3]]    -- pop  -->
[[15 13] [9 7] [3 1] [r=3]]        (now we unroll)

7
Yine de Java'dan daha iyi;)
Doktor

5
naoGörünüşe göre "şimdi bu şeyi yazdır" olarak yorumlanabilecek gerçeği seviyorum .
Zgarb

10

CJam - 25

Lri{1$W%{1$\(1e>/+}/)+}/p

Çevrimiçi deneyin

Açıklama:

Bu uygulama sayıları art arda bir diziden kaldırmaz, ancak kaç tanenin kaldırılacağına bağlı olarak her bir sayıyı hesaplar.
Her indeks i (0'dan n-1'e) ve önceki her l şanslı sayıya l, ters sırayla, i yerine i / (l-1) artırıyoruz, l = 1 dışında 0 yerine 1 kullanıyoruz ve Sonunda 1.
Örneğin, i = 4 için ilk 4 sayıya sahibiz, [1 3 7 9], ve hesapla:
4 + 4 / (9-1) = 4
4 + 4 / (7-1) = 4
4 + 4 / (3 -1) = 6
6 + 6/1 = 12
12 + 1 = 13

L              empty array - the first 0 lucky numbers :)
ri             read and convert to integer (n)
{…}/           for each number (i) from 0 to n-1
    1$         copy the previous array
    W%         reverse the order
    {…}/       for each array element (l)
        1$     copy i
        \(     swap with l and decrement l
        1e>    use 1 if l=1
        /+     divide and add to i
    )+         increment and add the new lucky number to the array
p              pretty print

İlginç teknik :)
TheNumberOne

6

Pyth: 23 22 bayt

<u-G%@GhH+0GQ%2r1^hQ2Q

Çevrimiçi deneyin: Pyth Compiler / Executor

Açıklama:

<u-G%@GhH+0GQ%2r1^hQ2Q    Q = input()
             %2r1^hQ2     create the list [1, 2, ..., (Q+1)^2-1][::2]
 u          Q%2r1^hQ2     G = [1, 2, ..., (Q+1)^2-1][::2]
                           modify G for each H in [0, 1, 2, ..., Q]:
  -G%:GhH+0G                  G = G - ([0] + G)[::G[H+1]]
                               (minus is remove in Pyth)
<                    Q    print the first Q elements of the resulting list

Azaltma aslında Qşanslı sayılardan daha fazlasını hesaplar (remove komutuna Q + 1 kez denir, Q-1 yeterlidir).


5

R, 58 bayt

n=scan();s=r=1:n^2;for(j in 1:n)r=r[-max(2,r[j])*s];r[1:n]

Satır sonları ile:

n=scan()              #user input
s=r=1:n^2             #declare r and s simultaneously, both large enough to sieve
for(j in 1:n)
  r=r[-max(2,r[j])*s] #iteratively remove elements by position in vector
r[1:n]                #print

Önceki sürüm, 62 bayt

function(n){
  s=r=1:n^2             #declare r and s simultaneously, both large enough to sieve
  for(j in 1:n)
    r=r[-max(2,r[j])*s] #iteratively remove elements by position in vector
  r[1:n]                #print
}

Önceki sürüm, 78 bayt

n=as.numeric(readline())   #ask for user input and convert it to numeric
r=1:n^2                    #create a large enough vector to sieve
for(j in 1:n){             #loop
  r=r[-max(2,r[j])*1:n^2]  #iteratively remove elements by position in vector
}
r[1:n]                     #print

64 byte: Değişim n=as.numeric(readline())için function(n){...}. Bu, atanabilen ve çağrılabilen bir fonksiyon nesnesi yaratır. Kıvrımlı parantezleri forhalka içine bırakın .
Alex A.

@Alex teşekkürler! Buna rağmen 66, bir isme ihtiyacı var mı?
freekvd

Teslim için bir isim gerekmez. Matlab / Octave çözümlerine bakın. R işlevi nesneleri, geçerli gönderimler olan diğer dillerde adsız / lambda işlevlerine benzer.
Alex A.

Ne hakkında n=scan(n=1)?
koekenbakker

2
Bu çalışır! Ve 1 karakter daha az. Eğer n = 1'i düşürürsem daha da kısa, işlev ilk önce n'nin tüm elemanlarını görmezden geliyor.
freekvd

4

CJam, 32 30 bayt

3ri:N#,N{0\__I1e>)=%-+}fI(;N<p

STDIN'den girdi alır.

Kod açıklaması :

3ri:N#,                          "Read the input in N and get first 3^N whole numbers";
       N{0\__I1e>)=%-+}fI        "Run the code block N times, storing index in I";
         0\__                    "Put 0 before the array and take 2 copies";
             I1e>)=              "Take min(2, I + 1) th index from the copy";
                   %             "Take every array[ min (2, I + 1)] element from the array";
                    -+           "Remove it from the list and prepend 0 to the list";
                         (;N<p   "Print number index 1 to N";

Burada çevrimiçi deneyin


4

Python 2, 105 101 bayt

n=input()
L=range(-1,n*n+9,2)
i=2
while L[i:]:L=sorted(set(L)-set(L[L[i]::L[i]]));i+=1
print L[1:n+1]

Sadece basit bir uygulama.

Pyth, 39 36 35 32 bayt

J%2r1h^Q2VJI>JhN=J-J%@JhN+2J;<JQ

Yukarıdaki yaklaşıma benzer, ancak işler 1 dizinli değil, 0 dizinlidir. Çevrimiçi deneyin .

Bayt tasarrufu belirtmek için @Jakube teşekkürler.


3

Mathematica, 80 bayt

(For[l=Range[#^2];i=1,(m=l[[i++]]~Max~2)<=Length@l,l=l~Drop~{m,-1,m}];l[[;;#]])&

Tanımın yalındır uygulanması. Diğer bazı cevaplar gibi, bir dizi ile başlar 1etmek ve daha sonra filtreleme tutar.n2


3

Perl, 86 81 78

86:

@a=(1..($k=<>)**2);for$n(@a){$i=1;@a=map{$i++%($n+($n<2))?$_:()}@a;$k-=$k&&print"$n "}

GÜNCELLEME: Açıkçası, 81'den grep{...}daha iyidir map{...?$_:()}:

@a=(1..($k=<>)**2);for$n(@a){$i=1;@a=grep{$i++%($n+($n<2))}@a;$k-=$k&&print"$n "}

GÜNCELLEME: Tamam, aslında şimdi bir astar. Durdurabilirim. (?) 78:

@a=(1..($k=<>)**2);for$n(@a){$k-=$i=$k&&print"$n ";@a=grep{$i++%($n+=$n<2)}@a}

3

Octave, 139 83 72

function r=l(n)r=1:2:n^2;for(i=2:n)h=r(i);r(h:h:end)=[];end;r=r(1:n);end

Ungolfed:

function r=l(n)
  r=1:2:n^2;
  for(i=2:n)
    h=r(i);
    r(h:h:end)=[];
  end
r=r(1:n);  # reduce it to only N lucky numbers
end

2

J, 60 52 bayt

   ({.}.@((>:@{.,]#~0<({~{.)|i.@#)@]^:[2,1+2*i.@*:@>:)) 8
1 3 7 9 13 15 21 25

Açıklama (sağdan sola):

2,1+2*i.@*:@>:  generates the list 2 1 3 5 7 9... with (n+1)^2 odd numbers
^:[             repeats n times the following
@]                using the list
0<({~{.)|i.@#     is the remainder of the indexes of the lists elements with the first element positive (i.e. index divisible by first element)
]#~               keep those elements from the list
>:@{.,            concatenate a first element with the value of the current one +1
}.@             drop first element
{.              take the first n element

2,1+2*i.@*:@>:Yol çok uzun görünüyor ama sadece takas 1 bayt ile kısaltın olabilir *:ile !liste katlanarak büyümeye yapma.


2

JavaScript (ES6) 96 99

Düzenleme İlk döngüde geri sayım - teşekkürler @DocMax

F=n=>(i=>{
  for(o=[1];--i;)o[i]=i-~i;
  for(;++i<n;)o=o.filter((x,j)=>++j%o[i]);
})(n*n)||o.slice(0,n)

Ungolfed

F=n=>{
  for (i = n*n, o = [1]; --i;)
    o[i] = i+i+1;
  for (; ++i < n; )
    o = o.filter((x, j) => (j+1) % o[i])
  return o.slice(0,n)
}

Firefox / FireBug konsolunda test edin

F(57)

Çıktı

[1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, 87, 93, 99, 105, 111, 115, 127, 129, 133, 135, 141, 151, 159, 163, 169, 171, 189, 193, 195, 201, 205, 211, 219, 223, 231, 235, 237, 241, 259, 261, 267, 273, 283, 285, 289, 297, 303]

1
İlk döngü ve ikinci ile geri sayım yaparak 1'den tasarruf edebilirsiniz:F=n=>{for(o=[1],i=n*n;--i;)o[i]=2*i+1;for(;++i<n;o=o.filter((x,j)=>++j%o[i]));return o.slice(0,n)}
DocMax

Ungolded'ınız burada gerçekten yardımcı olmuyor: P;)
Doktoru

@Optimizer ungolfed güncellendi - belki hala çok yardımcı olmuyor, ama en azından şimdi çalışıyor
edc65

"Basitçe bir biçimlendirme değişikliği işe
Doktor

2

Matlab, 104 bayt

function x=f(n)
k=1;N=n;x=0;while nnz(x)<n
x=1:N;m=1;while m-nnz(x)
m=x(x>m);x(m:m:end)=[];end
N=N+2;end

Çok uygun yorum ve önerileriniz için @flawr sayesinde.

Matlab komut isteminden örnek:

>> f(40)
ans =
  Columns 1 through 22
     1     3     7     9    13    15    21    25    31    33    37    43    49    51    63    67    69    73    75    79    87    93
  Columns 23 through 40
    99   105   111   115   127   129   133   135   141   151   159   163   169   171   189   193   195   201

Teşekkürler! Bunu geçmişte kullandım, ama unutmaya meyilliyim
Luis Mendo

@flawr İyi nokta. Bu cevap benimkinden daha çok sizinki haline geliyor! :-)
Luis Mendo

Emin! StackOverflow'ta daha sık takılıyorum, ama aynı ruh. Bunu takdir ediyorum!
Luis Mendo

İyi bir nokta! Öğrendiğim bütün bunların standart Matlab kullanımım için faydalı veya aslında zararlı olacağından emin değilim.
Luis Mendo

2
Eh, codegolf kullanımı ile ilgili değil , bir dilin kötüye kullanımı ile ilgilidir .
kusurları

1

Bash + coreutils, 136

Bunu daha çok golf oynamayı ümit ediyordum, ama ah evet. Her gün bir kabuk betiğinde özyinelemeli bir işleve geçtiğinizde:

f(){
mapfile -tn$2 a
(($1>$2))&&{
tr \  \\n<<<${a[@]}
sed $[${a[-1]}-$2]~${a[-1]}d
}|f $1 $[$2+1]||echo ${a[@]}
}
yes|sed -n 1~2=|f $1 2

Çıktı:

$ ./lucky.sh 23
1 3 7 9 13 15 21 25 31 33 37 43 49 51 63 67 69 73 75 79 87 93 99
$ 

Bash + coreutils, 104

Daha basit bir uygulama kullanarak daha kısa:

a=(`seq 1 2 $[3+$1**2]`)
for((;i++<$1;));{
a=($(tr \  \\n<<<${a[@]}|sed 0~${a[i]}d))
}
echo ${a[@]:0:$1}

1

Git, 326

package main
import"fmt"
func s(k, p int,in chan int)chan int{
    o := make(chan int)
    go func(){
        for p>0{
            o<-<-in;p--
        }
        for{
            <-in
            for i:=1;i<k;i++{o<-<-in}
        }
    }()
    return o
}
func main(){
    n := 20
    fmt.Print(1)
    c := make(chan int)
    go func(c chan int){
        for i:=3;;i+=2{c<-i}
    }(c)
    for i:=1;i<n;i++{
        v := <-c
        fmt.Print(" ", v)
        c = s(v, v-i-2, c)
    }
}

Elekleri yapmak için goroutine ve boruları kullanarak doğrudan uygulama.


7
Bu Code Golf, lütfen bir bayt sayısı ekleyin.
edc65

1

MATLAB, 62 karakter

n=input('');o=1:2:n^2;for i=2:n;o(o(i):o(i):end)=[];end;o(1:n)

Baştaki mücadeleyi yanlış yorumladım - gözden geçirilmiş versiyonum şimdi aslında daha kısa.


0

Raket 196 bayt

N'ye kadar şanslı sayılar üretir:

(λ(n)(let loop((l(filter odd?(range 1 n)))(i 1))(define x(list-ref l i))(set! l(for/list((j(length l))
#:unless(= 0(modulo(add1 j)x)))(list-ref l j)))(if(>= i(sub1(length l)))l(loop l(add1 i)))))

Ungolfed versiyonu:

(define f
 (λ(n)
    (let loop ((l (filter odd? (range 1 n))) (i 1))
      (define x (list-ref l i))
      (set! l (for/list ((j (length l)) #:unless (= 0 (modulo (add1 j) x)))
                (list-ref l j)))
      (if (>= i (sub1 (length l)))
          l
          (loop l (add1 i)))))
  )

Test yapmak:

(f 100)

Çıktı:

'(1 3 7 9 13 15 21 25 31 33 37 43 49 51 63 67 69 73 75 79 87 93 99)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.