Şanssız Sayılar!


22

Bilinecek şeyler:

İlk olarak, şanslı sayılar.

Şanslı sayılar şöyle üretilir:

Tüm doğal sayıları al:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20...

Sonra her ikinci numarayı kaldırın.

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39...

Şimdi 3güvende.

Her 3 numarayı kaldır:

1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 59...

Şimdi 7güvende.

Her 7. numarayı kaldırın.

Devam edin ve nelemeden nsonraki ilk güvenli numara olan her bir sayıyı kaldırın .

Güvenli numaraların son listesi şanslı numaralardır.


Şanssız sayılar, ayrı sayılar listesinden oluşur [U1, U2, U3... Un].

U1 şanslı "adaylar" dan kaldırılan ilk sayı kümesidir, yani:

2, 4, 6, 8, 10, 12, 14, 16, 18, 20...

U2 kaldırılan ikinci sayı kümesidir:

5, 11, 17, 23, 29, 35, 41, 47, 53, 59...

Ve diğerleri ve diğerleri ( U3üçüncü liste, U4dördüncü vb.)


Meydan okuma:

Göreviniz iki girişi olmaktadır ki, mve n, üretmek mlistede inci numarayı Un.

Örnek girişler ve çıkışlar:

(5, 2) -> 29
(10, 1) -> 20

Özellikleri:

  • Programınız men çok 1e6ve nen çok için çalışmalıdır 100.
    • Her ikisinin de pozitif mve ntam sayı olduğu garantilidir .
    • Merak ediyorsanız, U(1e6, 100)= 5,333,213,163. (Teşekkürler @pacholik!)
  • Programınız makul bir modern bilgisayarda 1 gün içinde bunu hesaplamalıdır.

Bu , bayt cinsinden en kısa kod kazanır!

Not: Birisi bunları üretmek için genel bir formül bulmuşsa iyi olurdu. Bir formülünüz varsa, lütfen cevabınıza yazınız!




2
Gerçekten gerçekleştirebilecek bir kod uyguladınız mı (1e6,1e6)?
Jonathan Allan

2
Bir zaman gereksiniminiz olacaksa, zamanlama ortamını belirtmeniz gerekir (örneğin, makineniz, özgürce erişilebilen bir çevrimiçi VM veya "makul bir modern bilgisayar").
Mego

1
İşlevin n=1dava için çalışmaması kabul edilebilir mi? Bu özel olduğu için - diğer tüm durumlar için, bir sonraki şanslı sayının 0-tabanlı endeksidir n-1.
Myridium

Yanıtlar:


1

CJam , 74 bayt

ri0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A0@{@:B:(_0#):D{D(_A=tD<BD>+}&@)@DU=-}h]1=

Çevrimiçi deneyin! Daha büyük davalar için zaman aşımına uğrayacak, daha fazla zaman kısıtlaması olacak.


Açıklama:

Programımız utanmadan Aditsu'nun kodunu ödüllendirir ve N şanslı sayılardan oluşan bir liste oluşturur , 1'i 2 ile değiştirmek, eleklerin her aşamasında artış sağlar. Kalan kod, sıfır bulunana kadar her elemanda azalır (azaltılmamış bir kuyruğu dilimleyerek ve ekleyerek) ve eleklerin N fazının her birindeki adımları bir kerede etkili bir şekilde sayar .

ri                               e# read M
0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A  e# list steps (also becomes B)
0@                               e# arrange stack [B I M]
{                                e# while M
   @:B                           e#   get current B
   :(                            e#   decrement every element in B
   _0#):D                        e#   find first 0
   {                             e#   if there is a 0
      D(_A=t                     e#     reset that element in B
      D<BD>+                     e#     replace tail after 0
   }&                            e#   end if
   @)                            e#   increment I
   @DU=-                         e#   decrement M if N-th phase of sieve
}h                               e# end loop
]1=                              e# return I

Zamanlama:

Programı kesinlikle daha büyük sayılar için tarayıcıda çalıştırmanız gerekiyorsa, bu yorumlayıcıyı kullanabilir ve istendiğinde komut dosyasının devam etmesine izin verebilirsiniz, ancak bu hak kazanmak için çok yavaş olabilir. ( M , N ) = (100,100) kullanılması ~ 247s sürer. Programlar yineleme M açısından nispeten doğrusaldır , bu nedenle hesaplama (1e6,100) ~ 29 gün sürebilir.

Bir bilgisayardaki kabuk yorumlayıcısını kullanarak, program ~ 6s'de hesaplar (100,100) ve ~ 463s'de hesaplar (1e4,100). Program ~ 13-17hrs içinde hesaplayabilmelidir (1e6,100). Bu durumda programın kalifiye olduğunu varsayacağım.

Tüm zamanların hem ölçümlerde hem de hesaplamalarda yuvarlandığına dikkat edin.


7

Perl, 87 85 82 81 bayt

İçin +4 içerir -pX

STDIN'e ilk önce n ile tek satır olarak giriş verin (bunun meydan okumada önerilen sıranın tersi olduğuna dikkat edin). Yani hesaplamak için U(1000000, 100):

unlucky.pl <<< "100 1000000"

Aditsu'nun şanslı sayıları temel alan algoritma cevap Zaman karmaşıklığı bu O(n^2)yüzden gerekli aralık için oldukça hızlı. 100, 1000000Vaka verir 53332131630.7 saniyede. Perl do$0temelli özyinelemeyle ilgili problemlerden dolayı çok fazla bellek kullanır. Bir işlev olarak yeniden yazmak, hafızanın kullanılmasını sağlar, O(n)ancak bir kaç bayt daha uzundur.

unlucky.pl:

#!/usr/bin/perl -pX
$_=$a{$_}||=/\d+$/>--$_?2*$&+$^S:($_=$_.A.(do$0,$^S?0|$&+$&/~-$_:$&*$_-1),do$0)

Bu gösterildiği gibi çalışır, ancak ^Siddia edilen puanı almak için değişmez kullanın.

$^SPerlgolf'un önceki kullanımlarından haberdar değilim .


Ama bu ne kadar zaman alıyor (1e6,100)?
Myridium

@ Myridium Neden olduğu bellek patlaması nedeniyle do$0herhangi bir gerçekçi bilgisayarda temel olarak ulaşılamaz. Ancak bu kadar hafıza yaklaşık 2 yıl olsaydı. Normal bir alt yordam tabanlı sürümü gerçekten yazmadım ve test etmedim, ancak birkaç ay içinde bitmesini ve çok az belleğe sahip bilgisayarlarda bile çalışmasını beklerdim. Bu yüzden bu değerlerin bu zorluk için gerekli aralıkta olmaması iyi bir şey.
Ton Hospel

(1e6,100)Bir gün içinde hesaplanması zor değil mi? Ne demek bu değerlerin gerekli değil?
Myridium

@ Myridium Programımda nve mters sırada verildiğine dikkat edin . 100 1000000Giriş hesaplar U(1000000, 100)verir ve 5,333,213,1630.7 saniye. Şu ana kadar yayınlanan en hızlı program şu ana kadar
Ton Hospel

Ah tamam, ben (100,1e6)çok daha hızlı olması bekleniyor (1e6,100)ve bu yıldırım 0,7 saniye yıldırım için açıklama olduğunu düşündüm!
Myridium

7

Python 3, 170

from itertools import*
def L(n,k=1):
 if n<2:yield from count(2+k,2)
 t=L(n-1);l=next(t)
 for i in t:
  n+=1
  if(n%l>0)==k:yield i
U=lambda m,n:sum(islice(L(n,0),m-1,m))

L işlevi , olası şanslı numaraların satırını ( k , Doğru ise) veya Un (Yanlış ise) oluşturur. Lazily olarak değerlendirildi (bu nedenle Un istiyorsam n-1 sonsuz listeler oluşturmak zorunda değilim ).

Run işlev U .

hız

U (1,000,000; 100) makinemde PyPy ile çalıştırmak yaklaşık 1 saat 45 dakika sürer. CPython ile dört saat kadar şüpheleniyorum. (Evet, 4 saat 20 dakika kesin.)

Jeneratörler yerine bir liste kullanırsam, biraz hız kazanabilirim, ancak Python'un izin verdiğinden daha büyük bir listeye ihtiyacım olacaktı. Ve eğer öyle olsaydı, onlarca gigabayt RAM'e ihtiyaç duyardı.


Evet ve U (1,000,000; 100) = 5,333,213,163 .


Şimdi geçerli olmalı.
Clismique

3

Haskell

N = 1: 175 160 bayt için hesaplanamadı

Derlendiğinde, bunu (1000000,100)kullanmak için giriş yapmak için bilgisayarım 2 saat 35m sürdü :

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 2=[1,3..]
l m=((l$m-1)!!(m-2))%(l$m-1)
m?n=(((l n)!!(n-1))#(l$n))!!(m-1)

whereModülleri kaldırmayı denedim , ama hızı etkiliyor gibi görünüyorlar ve nedenini bilmiyorum ... Ama burada daha fazla budama yapıldığını düşünüyorum.

Kullanımına yöntemdir m?nbir verilen cevap sorgulamak için mve n.

Ungolfed

everynth n xs = y:(everynth n ys) -- Takes every nth element from a list 'xs'
  where y:ys = drop (n-1) xs

skipeverynth n xs = f' n xs $ []  -- Removes every nth element from a list 'xs'
  where f' n xs = (take (n-1) xs ++) . f' n (drop n xs) 

l 2 = [1,3..] -- The base case of the list of lucky numbers for 'n=2'
l m = skipeverynth ((l$m-1)!!(m-2)) (l$m-1) -- Recursively defining next case as being the last one with every 'ath' element skipped. Here, 'a' is the (m-1)th elemnent of the (l (m-1)) list.
ul m = everynth ((l m)!!(m-1)) (l$m) -- This is not used other than to compute the final, required unlucky number list. It picks out every 'ath' element.

ans m n = (ul n)!!(m-1) -- The function giving the answer.

Sanırım 'skipeverynth' ve 'everynth' işlevlerini bir çift döndüren tek bir işlevde birleştirmek mümkün olabilir.

Her nevi öğeyi atlamak için bu kibar kişinin kodunu kullandım . Birkaç kez kendim yaptım, ama her zaman çok daha verimsizdi ve nedenini bulamadım.

Tüm n: 170 bayt için hesaplamak mümkün

Bu temelde aynıdır, ancak maxözel durumun üstesinden gelmek için birkaç işlev atılmalıdır n=1.

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 1=[1..]
l m=((l$m-1)!!(max 1$m-2))%(l$m-1)
m?n=(((l n)!!(max 1$n-1))#(l$n))!!(m-1)

2

R 82 bayt

f<-function(m,n){a=1:2e8
i=1
while(i<n){a=c(0,a)[c(F,rep(T,i))]
i=i+1}
a[(n+1)*m]}

kullanım

f(5,2)
Returns 29

Bunun başlayabilmesi için yeterince büyük bir vektöre sahip olması gerekir, böylece değeri döndürecek yeterli sayı vardır. Oluşturulan vektör zaten 800Mb civarındadır ve fonksiyon m = 1e4 ve n = 100'e kadar kaldırabilir, bu nedenle hedef hala kısadır.

F (1e6,100) 'ı hesaplamak için yeterince büyük bir vektör oluşturmak 1: 2e10 başlangıç ​​vektörünü alır. Rs veri tahsis prosedürleri nedeniyle, kodun çalışmasına rağmen bildiğim herhangi bir bilgisayarda çalıştırılamayan bir> 70Gb vektörü yaratır.

Error: cannot allocate vector of size 74.5 Gb

Referans için f (1e4,100) yaklaşık 30 saniye içinde çalışır. Buna ve birkaç küçük teste dayanarak f (1e6,100) yaklaşık bir saat sürer.


Yanıtınızı rakipsiz olarak işaretlemek, zorunluluk şartlarını yerine getirememesi için mazeret bulmaz.
Mego

@Mego Ive, gereksinimleri karşılayamayan birçok cevap gördü (bu mücadelede en az 1 tane daha var). Kodladım ve kodlama isteğinin ruhunu karşıladığını hissediyorum, ayrıca nerede yetersiz kaldığını da açıkça söyledim. Ayrıca soruya yorumlarınızda bahsettiğiniz gibi, ne tür bir bilgisayarda test edilmesi gerektiğini belirtmez. Dışarıda belleğe 7 Gb yazabilen ve işleyebilen bilgisayarlar olduğundan eminim. Yaptığım bir şey yapamadı ama hala göndermek istedim ve açık ifadenin geçerli bir uzlaşma olduğunu düşündüm.
gtwebb

Zorluk şartlarını yerine getirmeyen cevaplar hakkında net bir politikamız var . Olduğu söyleniyor, cevabınızı neden rakipsiz olarak nitelendirdiğinizden emin değilim. Eğer doğru anlıyorsam, bu yeterli hafızaya sahip olmalı , ancak yeterince RAM'iniz olmadığı için test edemezsiniz. Bu doğru mu?
Dennis,

1
1. Bu politika olduğu uygulandığına, ancak dört moderatörler sitedeki tüm cevapları test edemez. Kurallara uymayan bir gönderi bulursanız, dikkatini çekmek için onu dikkatle işaretleyin, böylece bir göz atalım. 2. Katılmak için bir golf dili öğrenmek zorunda değilsiniz. R gibi üretim dilleri de aynı şekildedir. Python'un cevaplarını düzenli olarak kendim gönderiyorum.
Dennis,

1
3. Spesifikasyon hafıza sınırlarından bahsetmiyor, ancak 24 saatlik bir zaman sınırı var. Bunu test etmek için 70 GiB olan bir bilgisayarın yokluğunda (veya giga bitleri mi demek istediniz ), bu cevabın geçerli olup olmadığını belirlemek zor. Çalışma zamanını olabildiğince fazla tahmin etmeye çalışıyorum. Bir günden azsa, rakip olmayan başlığı kaldırın ve gönderinize ekstrapolasyonunuzu ekleyin. Daha uzun sürerse, gönderiminiz optimize edilmeli veya kaldırılmalıdır.
Dennis,

1

Raket 332 bayt

(λ(N m n)(let loop((l(filter odd?(range 1 N)))(i 1))(define x (list-ref l i))(if(= i (sub1 n))
(begin(set! l(for/list((j(length l))#:when(= 0(modulo(add1 j)x)))(list-ref l j)))(list-ref l(sub1 m)))
(begin(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 m n)
    (let loop ((l (filter odd? (range 1 N))) (i 1))
      (define x (list-ref l i))
      (if (= i (sub1 n))
          (begin (set! l (for/list ((j (length l)) 
                                   #:when (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (list-ref l (sub1 m)))
          (begin (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 5 2)

Çıktı:

29

1

Clojure, 221 bayt

Çok uzun ama davayı idare ediyor (f 1). Bu özel durum olmadan 183 bayttı. Bu ilan edilmemesi için çok fazla çaba sarf etti.

(defn f([n](if(< n 2)(take-nth 2(drop 2(range)))(f n 1(take-nth 2(rest(range))))))([n i c](if (< n 2)c(let[N(first(drop i c))F #((if(= 2 n)= >)(mod(inc %)N)0)](f(dec n)(inc i)(filter some?(map-indexed #(if(F %)%2)c)))))))

Örnek çıktılar:

(pprint (map #(take 10 (f %)) (range 1 10)))
((2 4 6 8 10 12 14 16 18 20)
 (5 11 17 23 29 35 41 47 53 59)
 (19 39 61 81 103 123 145 165 187 207)
 (27 57 91 121 153 183 217 247 279 309)
 (45 97 147 199 253 301 351 403 453 507)
 (55 117 181 243 315 379 441 505 571 633)
 (85 177 277 369 471 567 663 757 853 949)
 (109 225 345 465 589 705 829 945 1063 1185)
 (139 295 447 603 765 913 1075 1227 1377 1537))

1000000 100 vakası yaklaşık 4,7 saatte hesaplandı, en azından çökmedi.

java -jar target\stackoverflow-0.0.1-SNAPSHOT-standalone.jar 1000000 100
5333213163
"Elapsed time: 1.7227805535565E7 msecs"
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.