ตัวเลขที่โชคร้าย!


22

สิ่งที่ควรรู้:

ก่อนอื่นหมายเลขนำโชค

หมายเลขที่โชคดีถูกสร้างขึ้นเช่น:

รับหมายเลขธรรมชาติทั้งหมด:

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

จากนั้นลบแต่ละหมายเลขที่สอง

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

ตอนนี้3ปลอดภัยแล้ว

ลบทุกหมายเลขที่ 3:

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

ตอนนี้7ปลอดภัยแล้ว

ลบทุกหมายเลขที่ 7

ดำเนินการต่อและลบทุกnหมายเลขที่ซึ่งnเป็นหมายเลขที่ปลอดภัยแรกหลังจากการกำจัด

รายการสุดท้ายของหมายเลขที่ปลอดภัยคือหมายเลขนำโชค


[U1, U2, U3... Un]หมายเลขโชคร้ายประกอบด้วยรายการแยกต่างหากของตัวเลขซึ่งเป็น

U1 เป็นตัวเลขชุดแรกที่ถูกลบออกจาก "ผู้สมัคร" ที่โชคดีดังนั้นจึงเป็น:

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

U2 เป็นการลบหมายเลขชุดที่สอง:

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

และต่อ ๆ ไปเรื่อย ๆ ( U3เป็นรายการที่สามU4คือที่สี่เป็นต้น)


ท้าทาย:

งานของคุณคือเมื่อได้รับสองอินพุตmและn, สร้างจำนวนวันในรายการmUn

ตัวอย่างอินพุตและเอาต์พุต:

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

รายละเอียด:

  • การทำงานของโปรแกรมต้องของคุณสำหรับการmขึ้นไป1e6และขึ้นไป n100
    • คุณรับประกันได้ว่าทั้งสองmและnเป็นจำนวนเต็มบวก
    • U(1e6, 100)หากคุณอยากรู้อยากเห็น 5,333,213,163= (ขอบคุณ @pacholik!)
  • โปรแกรมของคุณต้องคำนวณว่าภายใน 1 วันบนคอมพิวเตอร์ที่ทันสมัยพอสมควร

นี่คือดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ!

PS: มันจะดีถ้ามีคนคิดสูตรทั่วไปสำหรับสร้างสิ่งเหล่านี้ หากคุณมีสูตรโปรดใส่ไว้ในคำตอบของคุณ!


ใน OEIS: A219178และA255543
Arnauld


2
คุณใช้รหัสที่สามารถทำงานได้จริง(1e6,1e6)หรือไม่?
Jonathan Allan

2
หากคุณต้องการเวลาคุณจะต้องระบุสภาพแวดล้อมการจับเวลา (เช่นเครื่องของคุณ VM ออนไลน์ที่พร้อมใช้งานได้อย่างอิสระหรือ "คอมพิวเตอร์สมัยใหม่ที่มีเหตุผล")
Mego

1
มันเป็นที่ยอมรับสำหรับฟังก์ชั่นที่จะไม่ทำงานสำหรับn=1กรณี? เช่นนี้เป็น special-- สำหรับกรณีอื่น ๆ ทั้งหมดที่ดัชนี 0 n-1ตามจำนวนโชคดีต่อไปคือ
Myridium

คำตอบ:


1

CJam , 74 ไบต์

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

ลองออนไลน์! จะหมดเวลาสำหรับกรณีที่มีขนาดใหญ่ขึ้นตามเวลาที่ จำกัด ด้านล่าง


คำอธิบาย:

โปรแกรมของเรายืมรหัสของ aditsu อย่างไร้ยางอายเพื่อสร้างรายการของเลขนำโชคNซึ่งการแทนที่ 1 ด้วย 2 จะเป็นการเพิ่มขึ้นในแต่ละขั้นตอนของตะแกรง โค้ดที่เหลือจะลดลงในทุกองค์ประกอบจนกว่าจะพบศูนย์ (โดยการแบ่งและต่อท้ายส่วนที่ไม่ลด) และนับขั้นตอนอย่างมีประสิทธิภาพในNเฟสของตะแกรงแต่ละอันในคราวเดียว

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

เวลา:

หากคุณต้องรันโปรแกรมในเบราว์เซอร์เป็นจำนวนมากคุณสามารถใช้ล่ามนี้และอนุญาตให้สคริปต์ดำเนินการต่อหากได้รับแจ้ง แต่อาจช้าเกินไปที่จะมีคุณสมบัติ การใช้ ( M , N ) = (100,100) ใช้เวลาประมาณ 247 วินาที การทำซ้ำโปรแกรมค่อนข้างเชิงเส้นในแง่ของMดังนั้นการคำนวณ (1e6,100) อาจใช้เวลาประมาณ 29 วัน

การใช้ตัวแปลเชลล์บนพีซีโปรแกรมจะคำนวณ (100,100) ใน ~ 6s และคำนวณ (1e4,100) ใน ~ 463 วินาที โปรแกรมควรสามารถคำนวณได้ (1e6,100) ใน ~ 13-17 ชั่วโมง ในกรณีนี้ฉันจะถือว่าโปรแกรมมีคุณสมบัติ

หมายเหตุเวลาทั้งหมดถูกปัดเศษขึ้นทั้งในการวัดและการคำนวณ


7

Perl, 87 85 82 81 ไบต์

รวมถึง +4 สำหรับ -pX

ให้อินพุตกับ STDIN เป็นหนึ่งบรรทัดด้วย n ก่อน (สังเกตว่านี่คือสิ่งที่ตรงกันข้ามกับคำสั่งที่แนะนำในการท้าทาย) ดังนั้นในการคำนวณU(1000000, 100):

unlucky.pl <<< "100 1000000"

อัลกอริทึมที่อิงตามหมายเลขนำโชคของaditsu ตอบ เวลาที่ซับซ้อนO(n^2)จึงค่อนข้างเร็วสำหรับช่วงที่ต้องการ 100, 1000000กรณีให้5333213163ใน 0.7 วินาที เนื่องจากปัญหา Perl มีการdo$0เรียกซ้ำตามที่ใช้หน่วยความจำจำนวนมาก เขียนใหม่เป็นฟังก์ชั่นจะทำให้การใช้หน่วยความจำO(n)แต่เป็นจำนวนไบต์ยาว

unlucky.pl:

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

ใช้งานได้ตามที่แสดง แต่ใช้ตัวอักษร^Sเพื่อรับคะแนนที่อ้างสิทธิ์

ฉันไม่ได้ตระหนักถึงการใช้งานก่อนหน้านี้$^Sใน perlgolf


แต่มันใช้เวลานานเท่า(1e6,100)ไหร่?
Myridium

@ Myridium เนื่องจากการระเบิดของหน่วยความจำที่เกิดจากการที่do$0มันไม่สามารถเข้าถึงได้บนคอมพิวเตอร์จริง ๆ แต่ถ้าความทรงจำนั้นมีอยู่ประมาณ 2 ปี ฉันไม่ได้เขียนออกมาและทดสอบเวอร์ชันที่ใช้รูทีนย่อยปกติ แต่ฉันคาดว่าจะเสร็จในอีกไม่กี่เดือนและทำงานได้แม้กระทั่งบนคอมพิวเตอร์ที่มีหน่วยความจำน้อยมาก ดังนั้นจึงเป็นเรื่องดีที่ค่าเหล่านี้ไม่อยู่ในช่วงที่ต้องการสำหรับความท้าทายนี้
Ton Hospel

ความท้าทายในการคำนวณ(1e6,100)ภายในหนึ่งวันไม่ใช่หรือ คุณหมายความว่าไม่จำเป็นต้องใช้ค่าเหล่านี้
Myridium

@ Myridium โปรดสังเกตว่าในโปรแกรมของฉันnและmจะได้รับในลำดับที่กลับกัน 100 1000000คำนวณการป้อนข้อมูลU(1000000, 100)และให้5,333,213,163ใน 0.7 วินาที มันเป็นโปรแกรมที่เร็วที่สุดของโพสต์เหล่านี้ในปัจจุบัน
Ton Hospel

อาโอเคฉันคาดว่า(100,1e6)จะเร็วกว่า(1e6,100)และคิดว่านี่เป็นคำอธิบายสำหรับฟ้าผ่าเร็ว 0.7 วินาที!
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สร้างแถวของหมายเลขนำโชคที่เป็นไปได้ (ถ้าkเป็นจริง) หรือUn (ถ้าเป็นเท็จ) ประเมินขี้เกียจ (ดังนั้นฉันไม่ต้องสร้างรายการที่ไม่มีที่สิ้นสุดn-1หากฉันต้องการUn )

ฟังก์ชั่นเรียกU

ความเร็ว

U (1,000,000; 100)ใช้เวลาประมาณ 1 ชม. 45 นาทีในการทำงานกับเครื่องของฉันด้วย PyPy ฉันสงสัยว่าสี่ชั่วโมงด้วย CPython (ใช่ 4h 20 นาทีเพื่อความแม่นยำ)

ถ้าฉันใช้รายการแทนกำเนิดฉันอาจได้รับความเร็วบ้าง แต่ฉันต้องการรายการขนาดที่ใหญ่กว่า Python ให้ฉัน และถ้าเป็นเช่นนั้นก็จะต้องใช้แรมนับสิบกิกะไบต์


ใช่และU (1,000,000; 100) = 5333213163


ควรจะถูกต้องในขณะนี้
clismique

3

Haskell

ไม่สามารถคำนวณได้สำหรับ n = 1: 175 160 ไบต์

เมื่อคอมไพล์ฉันใช้คอมพิวเตอร์ 2h 35m ในการคำนวณสำหรับการป้อนข้อมูล(1000000,100)โดยใช้:

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)

ฉันลองขับโมดูwhereแต่ดูเหมือนว่ามันจะส่งผลต่อความเร็วและฉันก็ไม่แน่ใจว่าทำไม ... แต่ฉันคิดว่ามีการตัดแต่งมากกว่านี้ที่นี่

วิธีการที่จะใช้เป็นที่m?nสำหรับการสอบถามคำตอบที่ได้รับและmn

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.

ฉันคิดว่าอาจเป็นไปได้ที่จะรวมฟังก์ชั่น 'skipeverynth' และ 'everynth' เป็นฟังก์ชั่นเดียวซึ่งจะคืนค่าคู่

ฉันใช้รหัสของคนประเภทนี้เพื่อข้ามทุกองค์ประกอบที่ n ฉันทำมันเองสองสามครั้ง แต่มันก็ไร้ประสิทธิภาพมากกว่าและฉันก็ไม่สามารถหาสาเหตุได้

สามารถคำนวณได้สำหรับ n ทั้งหมด: 170 ไบต์

นี้เป็นพื้นเดียวกัน แต่คู่ของฟังก์ชั่นจะต้องมีการโยนในการจัดการกับกรณีพิเศษของmaxn=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 ไบต์

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

การใช้

f(5,2)
Returns 29

นี่จำเป็นต้องมีเวกเตอร์ที่มีขนาดใหญ่พอที่จะเริ่มต้นด้วยดังนั้นจึงมีจำนวนที่เหลือเพียงพอเพื่อส่งคืนค่า เวกเตอร์ที่สร้างขึ้นนั้นมีขนาดประมาณ 800Mb และฟังก์ชันสามารถจัดการได้มากถึง m = 1e4 และ n = 100 ดังนั้นจึงยังสั้นตามเป้าหมาย

ในการสร้างเวกเตอร์ที่มีขนาดใหญ่พอที่จะคำนวณ f (1e6,100) จะใช้เวกเตอร์เริ่มต้นที่ 1: 2e10 เนื่องจากขั้นตอนการจัดสรรข้อมูล Rs นี้จะสร้างเวกเตอร์> 70Gb ซึ่งไม่สามารถเรียกใช้บนคอมพิวเตอร์เครื่องใดก็ได้ที่ฉันรู้แม้ว่ารหัสจะทำงาน

Error: cannot allocate vector of size 74.5 Gb

สำหรับการอ้างอิง f (1e4,100) ใช้เวลาประมาณ 30 วินาที จากการทดสอบนี้และการทดสอบที่น้อยกว่าสองเท่า f (1e6,100) จะใช้เวลาประมาณหนึ่งชั่วโมง


การทำเครื่องหมายคำตอบของคุณว่าไม่ใช่การแข่งขันไม่ใช่ข้อแก้ตัวจากการไม่สามารถทำตามข้อกำหนดการท้าทายได้
Mego

@Mego ฉันเห็นคำตอบมากมายที่ไม่สามารถทำตามข้อกำหนดได้ (มีอย่างน้อย 1 ข้อในการท้าทายนี้) ฉันเขียนมันและฉันรู้สึกว่ามันเป็นไปตามจิตวิญญาณของการร้องขอการเข้ารหัสฉันยังระบุไว้อย่างชัดเจนว่ามันสั้นเพียงใด นอกจากนี้เมื่อคุณพูดถึงความคิดเห็นของคุณกับคำถามมันไม่ได้ระบุประเภทของคอมพิวเตอร์ที่จะต้องทดสอบ ฉันแน่ใจว่ามีคอมพิวเตอร์ที่นั่นที่สามารถเขียน 7 Gb ไปยังหน่วยความจำและประมวลผล คนที่ฉันทำไม่สามารถทำได้ แต่ฉันยังต้องการโพสต์และฉันคิดว่าข้อความที่ชัดเจนคือการประนีประนอมที่ถูกต้อง
gtwebb

เรามีความชัดเจนนโยบายเกี่ยวกับคำตอบที่ไม่ตรงตามสเปคที่ท้าทาย ที่ถูกกล่าวว่าฉันไม่แน่ใจว่าทำไมคุณระบุว่าคำตอบของคุณไม่ใช่การแข่งขัน ถ้าฉันเข้าใจถูกต้องควรให้หน่วยความจำเพียงพอ แต่คุณไม่สามารถทดสอบได้เพราะคุณมี RAM ไม่เพียงพอ ถูกต้องไหม
Dennis

1
1.นโยบายนี้มีการบังคับใช้ แต่ผู้ดูแลสี่คนไม่สามารถทดสอบคำตอบทั้งหมดในไซต์ได้ หากคุณพบว่ามีการส่งที่ไม่เป็นไปตามกฎให้ตั้งค่าสถานะนั้นเพื่อให้ผู้ดูแลสนใจเพื่อให้เราสามารถตรวจสอบได้ 2.คุณไม่จำเป็นต้องเรียนรู้ภาษากอล์ฟเพื่อเข้าร่วม ภาษาการผลิตเช่น R ยินดีต้อนรับ ฉันโพสต์ Python ตอบตัวเองเป็นประจำ
เดนนิส

1
3.ข้อมูลจำเพาะไม่ได้กล่าวถึงการ จำกัด หน่วยความจำ แต่มีการ จำกัด เวลา 24 ชั่วโมง ในกรณีที่ไม่มีคอมพิวเตอร์ที่มี 70 GiB (หรือคุณหมายถึง giga bits ) ในการทดสอบนี้มันยากที่จะตรวจสอบว่าคำตอบนี้ถูกต้องหรือไม่ ฉันขอแนะนำให้พยายามคาดการณ์รันไทม์เช่นเดียวกับที่คุณสามารถ หากน้อยกว่าหนึ่งวันให้ลบส่วนหัวที่ไม่ใช่คู่แข่งและรวมถึงการประมาณของคุณในโพสต์ หากใช้เวลานานกว่านั้นการส่งของคุณควรได้รับการปรับปรุงหรือลบออก
เดนนิส

1

แร็กเก็ต 332 ไบต์

(λ(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)))))))

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

การทดสอบ:

(f 100 5 2)

เอาท์พุท:

29

1

Clojure 221 ไบต์

อันยิ่งใหญ่ (f 1)แต่ยาวด้ามจับกรณี หากไม่มีกรณีพิเศษนั่นคือ 183 ไบต์ นี่เป็นความพยายามมากเกินไปที่จะไม่โพสต์

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

ตัวอย่างผลลัพธ์:

(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 รายการในเวลาประมาณ 4.7 ชั่วโมงอย่างน้อยก็ไม่ได้ผิดพลาด

java -jar target\stackoverflow-0.0.1-SNAPSHOT-standalone.jar 1000000 100
5333213163
"Elapsed time: 1.7227805535565E7 msecs"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.