จำนวนเต็มมากมาย!


40

จำนวนมากมายเป็นจำนวนใด ๆ ที่ผลรวมของตัวหารที่เหมาะสมของมันมีค่ามากกว่าจำนวนเดิม ตัวอย่างเช่นตัวหารที่เหมาะสมของ 12 คือ:

1, 2, 3, 4, 6

และการรวมผลลัพธ์เหล่านี้ใน 16 เนื่องจาก 16 มีขนาดใหญ่กว่า 12, 12 จึงอุดมสมบูรณ์ โปรดทราบว่าสิ่งนี้ไม่รวม "Perfect numbers" เช่นตัวเลขที่เท่ากับผลรวมของตัวหารที่เหมาะสมเช่น 6 และ 28

งานของคุณในวันนี้คือการเขียนโปรแกรมหรือฟังก์ชั่นที่พิจารณาว่ามีจำนวนมากหรือไม่ โปรแกรมของคุณควรใช้จำนวนเต็มเดียวเป็นอินพุทและเอาท์พุทค่าความจริง / ผิดพลาดขึ้นอยู่กับว่ามันมีอยู่มากมายหรือไม่ คุณสามารถสันนิษฐานได้ว่าอินพุตนั้นจะถูกต้องเสมอและมากกว่า 0 ดังนั้นสำหรับอินพุตที่ไม่ดีพฤติกรรมที่ไม่ได้กำหนดนั้นดี

คุณสามารถนำเข้าและส่งออกของคุณในรูปแบบที่เหมาะสมเช่น STDIN / STDOUT ไฟล์หรือค่าอาร์กิวเมนต์ / ค่าส่งคืนจะยอมรับได้

สำหรับการอ้างอิงต่อไปนี้เป็นจำนวนที่มากถึง 100:

12,
18,
20,
24,
30,
36,
40,
42,
48,
54,
56,
60,
66,
70,
72,
78,
80,
84,
88,
90,
96,
100

และอีกมากมายสามารถพบได้ในA005101

เนื่องจากนี่คือช่องโหว่มาตรฐานจึงถูกปฏิเสธและพยายามเขียนรหัสที่สั้นที่สุดเท่าที่จะเป็นไปได้ในภาษาใดก็ตามที่คุณเลือก!


11
"ความอุดมสมบูรณ์คี่แรกคือ 945 = 3 ^ 3 * 5 * 7, จำนวนที่ 232 มาก!"
mbomb007

ความหนาแน่นเชิงตัวเลขจำนวนมากมายอยู่ในช่วง [0.24761748, 0.24764422] คำนวณโดยใช้ซอร์สโค้ดที่รวมอยู่ในบทความนี้
Deadcode

1
ฉันพยายามทำสิ่งนี้ใน Geometry Dash มันเป็นฝันร้าย
MilkyWay90

คำตอบ:


41

ECMAScript Regex, 1085 855 597 536 511 508 504 ไบต์

การจับคู่ตัวเลขจำนวนมากใน ECMAScript regex เป็นสัตว์ที่แตกต่างอย่างสิ้นเชิงกว่าการทำเช่นนั้นในรสชาติของ regex อื่น ๆ การขาดการตอบโต้กลับ / ซ้อนซ้ำหรือการเรียกซ้ำหมายความว่ามันเป็นไปไม่ได้ที่จะนับโดยตรง การขาดการมองดูทำให้บ่อยครั้งเป็นสิ่งที่ท้าทายแม้จะมีพื้นที่เพียงพอที่จะทำงาน

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

ย้อนกลับไปในเดือนมีนาคมถึงเมษายน 2014 ฉันสร้างวิธีแก้ไขปัญหานี้ใน ECMAScript regex ตอนแรกฉันมีเหตุผลทุกอย่างที่ต้องสงสัยว่าปัญหานั้นเป็นไปไม่ได้อย่างสมบูรณ์ แต่แล้วนักคณิตศาสตร์teukon ได้ร่างความคิดที่สร้างกรณีที่ให้กำลังใจเพื่อทำให้มันดูแก้ไขได้หลังจากทั้งหมด - แต่เขาทำให้มันชัดเจนว่าเขาไม่ได้ตั้งใจสร้าง regex เคยแข่งขัน / ร่วมมือกับฉันในการสร้าง / ตีกอล์ฟก่อนหน้า regexes แต่ถึงขีด จำกัด ของเขาโดยจุดนี้และเป็นเนื้อหาที่จะ จำกัด การมีส่วนร่วมของเขาต่อการสร้างทฤษฎี)

เช่นเดียวกับ regex ของฉันโพสต์สองสามวันที่ผ่านมาฉันจะให้คำเตือน:ฉันขอแนะนำให้เรียนรู้วิธีการแก้ปัญหาทางคณิตศาสตร์ unary ใน ECMAScript regex มันเป็นการเดินทางที่น่าสนใจสำหรับฉันและฉันไม่ต้องการที่จะทำลายมันสำหรับใครก็ตามที่อาจต้องการลองด้วยตัวเองโดยเฉพาะผู้ที่มีความสนใจในทฤษฎีจำนวน ดูโพสต์นั้นสำหรับรายการของปัญหาแนะนำที่ติดแท็กสปอยเลอร์อย่างต่อเนื่องเพื่อแก้ปัญหาทีละคน

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

ก่อนโพสต์ regex ECMAScript ของฉันฉันคิดว่ามันจะน่าสนใจที่จะวิเคราะห์มาร์ตินพลิก.NET แก้ปัญหา regex บริสุทธิ์^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$) , กลายเป็นเรื่องตรงไปตรงมามากที่จะเข้าใจว่า regex และมันก็สง่างามในความเรียบง่าย เพื่อแสดงให้เห็นถึงความแตกต่างระหว่างโซลูชันของเรานี่คือ regex ของเขาที่ได้รับการคอมเม้นต์และค่อนข้างสวย (แต่ไม่ได้แก้ไข):

# For the purpose of these comments, the input number will be referred to as N.

^(?!                  # Attempt to add up all the divisors. Since this is a regex and we
                      # can only work within the available space of the input, that means
                      # if the sum of the divisors is greater than N, the attempt to add
                      # all the divisors will fail at some point, causing this negative
                      # lookahead to succeed, showing that N is an abundant number.

  (1                  # Cycle through all values of tail that are less than N, testing
                      # each one to see if it is a divisor of N.

    (?<=              # Temporarily go back to the start so we can directly operate both
                      # on N and the potential divisor. This requires variable-length
                      # lookbehind, a .NET feature – even though this special case of
                      # going back to the start, if done left-to-right, would actually be
                      # very easy to implement even in a regex flavour that has no
                      # lookbehind to begin with. But .NET evaluates lookbehinds right
                      # to left, so please read these comments in the order indicated,
                      # from [Step 1] to [Step 7]. The comment applying to entering the
                      # lookahead group, [Step 2], is shown on its closing parenthesis.
      (?=             # [Step 3] Since we're now in a lookahead, evaluation is left to
                      #          right.
        (?(\3+$)      # [Step 4] If \3 is a divisor of N, then...
          (           # [Step 5] Add it to \2, the running total sum of divisors:
                      #          \2 = \2 + \3         
            (?>\2?)   # [Step 6] Since \2 is a nested backref, it will fail to match on
                      #          the first iteration. The "?" accounts for this, making
                      #          it add zero to itself on the first iteration. This must
                      #          be done before adding \3, to ensure there is enough room
                      #          for the "?" not to cause the match to become zero-length
                      #          even if \2 has a value.
            \3        # [Step 7] Iff we run out of space here, i.e. iff the sum would
                      #          exceed N at this point, the match will fail, making the
                      #          negative lookahead succeed, showing that we have an
                      #          abundant number.
          )

        )
      )               # [Step 2] Enter a lookahead that is anchored to the start due to
                      #          having a "^" immediately to its right. The regex would
                      #          still work if the "^" were moved to the left of the
                      #          lookahead, but would be slightly slower, because the
                      #          engine would do some spurious matching before hitting
                      #          the "^" and backtracking.
      ^(1+)           # [Step 1] \3 = number to test for being a potential divisor – its
                      #               right-side-end is at the point where the lookbehind
                      #               started, and thus \3 cycles through all values from
                      #               1 to N-1.
    )
  )*1$                # Exclude N itself from being considered as a potential divisor,
                      # because if we included it, the test for proper abundance would be
                      # the sum of divisors exceeding 2*N. We don't have enough space for
                      # that, so instead what would happen if we did not exclude N as a
                      # divisor would be testing for "half-abundance", i.e. the sum of
                      # all divisors other than N exceeding N/2. By excluding N as a
                      # divisor we can let our threshold for abundance be the sum of
                      # divisors exceeding N.
)

ลอง. NET regex ออนไลน์

ตอนนี้กลับไปที่ ECMAScript regex ของฉัน ครั้งแรกที่นี่มันอยู่ในรูปแบบดิบช่องว่างและความคิดเห็นฟรี:

^(?=(((?=(xx+?)\3+$)(x+)\4*(?=\4$))+(?!\3+$)(?=(xx(x*?))\5*$)x)(x+))(?=\1(x(x*))(?=\8*$)\6\9+$)(?=(.*)((?=\8*$)\5\9+$))(?=(x*?)(?=(x\11)+$)(?=\12\10|(x))(x(x*))(?=\15*$)(?=\11+$)\11\16+$)(?=(x(x*))(?=\17*$)\7\18+$)((?=(x*?(?=\17+$)(?=\17+?(?=((xx(x*))(?=\18+$)\22*$))(x+).*(?=\17$)\24*(?=\24$)(?!(xx+)\25*(?!\22+$)\25$)\22+$)((?=(x\7)+$)\15{2}\14|)))(?=.*(?=\24)x(x(x*))(?=\28*$)\23\29*$)(?=.*(x((?=\28*$)\22\29+$)))(.*(?!\30)\20|(?=.*?(?!x\20)(?=\30*$)(x(x*))(?=\33*$)(?=\31+$)\31\34+$).*(?=\33\21$)))+$

(เปลี่ยน\14เป็น\14?ความเข้ากันได้กับ PCRE, .NET และแทบทุกรสชาติของ regex อื่น ๆ ที่ไม่ใช่ ECMAScript)

ลองออนไลน์!
ลองออนไลน์! (เร็วขึ้น, รุ่น 537 ไบต์ของ regex)

และตอนนี้เป็นการสรุปเรื่องราวโดยย่อ

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

ในลูป ECMAScript คุณสามารถติดตามได้เพียงหนึ่งหมายเลขที่เปลี่ยนแปลง ตัวเลขนั้นต้องไม่เกินอินพุตและจะต้องลดลงในทุกขั้นตอน regex ที่ทำงานครั้งแรกของฉันสำหรับการจับคู่คำสั่งการคูณที่ถูกต้อง A * B = C คือ 913 ไบต์และทำงานโดยการแยก A, B และ C ออกเป็นอำนาจเฉพาะของพวกเขา - สำหรับแต่ละปัจจัยหลักแบ่งคู่ของปัจจัยกำลังสำคัญของ A และ C โดยฐานที่ดีของพวกเขาจนกระทั่งผู้ที่สอดคล้องกับ A ถึง 1; หนึ่งที่สอดคล้องกับ C นั้นจะถูกเปรียบเทียบกับตัวประกอบกำลังหลักของ B ทั้งสองพลังของตัวนายกตัวเดียวกันนั้นคือ "มัลติเพล็ก" ในจำนวนเดียวโดยการเพิ่มพวกมันเข้าด้วยกัน สิ่งนี้จะแยกกันไม่ออกอย่างชัดเจนในการวนซ้ำในแต่ละครั้งที่ตามมาด้วยเหตุผลเดียวกับที่ระบบตัวเลขตำแหน่งทำงาน

เราได้ทวีคูณลงไป 50 ไบต์โดยใช้อัลกอริธึมที่แตกต่างอย่างสิ้นเชิง (ซึ่งทูซอนและฉันสามารถมาถึงได้อย่างอิสระแม้ว่ามันจะใช้เวลาเพียงไม่กี่ชั่วโมงและเขาก็ตรงไปที่มันในขณะที่มันใช้เวลาสองสามวัน ทำให้ฉันทราบว่ามีวิธีการสั้น ๆ อยู่): สำหรับA≥B, A * B = C หากมีเพียงถ้า C เป็นจำนวนที่เล็กที่สุดซึ่งเป็นไปตามC≡0 mod A และC≡B mod A-1 (สะดวกสบายข้อยกเว้นของ A = 1 ไม่จำเป็นต้องมีการจัดการพิเศษใน regex ที่ 0% 0 = 0 ให้ผลการแข่งขัน) ฉันไม่สามารถเข้าใจได้ว่ามันเรียบร้อยแค่ไหน รสชาติ regex น้อยที่สุด (และความต้องการของA≥Bสามารถถูกแทนที่ด้วยข้อกำหนดที่ A และ B เป็นพลังสำคัญของพลังเดียวกันสำหรับกรณีของA≥Bสิ่งนี้สามารถพิสูจน์ได้โดยใช้ทฤษฎีบทส่วนที่เหลือของจีน)

ถ้ามันกลับกลายเป็นว่าไม่มีอัลกอริธึมที่ง่ายกว่าสำหรับการคูณจำนวน regex ที่มากอาจจะอยู่ในลำดับหมื่นไบต์หรือมากกว่านั้น (แม้จะคำนึงถึงว่า มันมีการคูณและการหารจำนวนมากและ ECMAScript regex ไม่มีรูทีนย่อย

ฉันเริ่มทำงานกับปัญหาจำนวนมากมายในวันที่ 23 มีนาคม 2014 โดยสร้างวิธีแก้ปัญหาสำหรับสิ่งที่ดูเหมือนจะเป็นปัญหาย่อยของสิ่งนี้: การระบุปัจจัยสำคัญของความหลากหลายสูงสุดเพื่อให้มันสามารถแบ่งออกจาก N เมื่อเริ่มต้นออกจากห้องเพื่อทำการคำนวณที่จำเป็น ในเวลานี้ดูเหมือนจะเป็นเส้นทางที่มีแนวโน้มที่จะใช้ (ทางออกแรกของฉันจบลงค่อนข้างใหญ่ที่ 326 ไบท์ต่อมาลงไปที่ 185 ไบท์) แต่วิธีการที่เหลือของทูซอนแบบร่างจะซับซ้อนมากดังนั้นเมื่อมันปรากฏออกมาฉันจึงเลือกเส้นทางที่ค่อนข้างแตกต่างกัน มันพิสูจน์แล้วว่าเพียงพอที่จะแบ่งตัวประกอบกำลังหลักที่ใหญ่ที่สุดของ N ให้สอดคล้องกับตัวประกอบตัวประกอบที่ใหญ่ที่สุดของ N; การทำเช่นนี้เพื่อจุดประสงค์ของความหลากหลายสูงสุดจะเพิ่มความซับซ้อนและความยาวที่ไม่จำเป็นไปยัง regex

สิ่งที่เหลืออยู่ก็คือการรักษาจำนวนผลรวมของตัวหารเป็นผลบวกแทนที่จะเป็นผลบวกโดยตรง ตามที่อธิบายโดย teukonเมื่อวันที่ 14 มีนาคม 2014:

เรากำลังได้รับจำนวน n p = 0 0หน้า1 1 ... P K-1 K-1 เราต้องการจัดการผลรวมของปัจจัยของ n ซึ่งคือ (1 + p 0 + p 0 2 + ... + p 0 a 0 ) (1 + p 1 + p 1 2 + ... + p 1 a 1 ) ... (1 + p k-1 + p k-1 2 + ... + p k-1 a k-1 )

มันทำให้ใจฉันเห็นสิ่งนี้ ฉันไม่เคยคิดที่จะหาผลรวมหารด้วยวิธีนั้นและมันเป็นสูตรนี้มากกว่าสิ่งอื่นใดที่ทำให้การแก้ปัญหาการจับคู่จำนวนมากมายใน ECMAScript regex ดูเป็นไปได้

ในท้ายที่สุดแทนที่จะทดสอบหาผลของการบวกหรือการคูณเกิน N หรือการทดสอบที่ผลลัพธ์ดังกล่าวหารด้วย M เกิน N / M ฉันไปด้วยการทดสอบว่าผลลัพธ์ของการหารน้อยกว่า 1 ฉันมาถึงที่ เวอร์ชันทำงานแรกในวันที่ 7 เมษายน 2014

ประวัติที่สมบูรณ์ของการเพิ่มประสิทธิภาพกอล์ฟของฉันของ regex นี้อยู่ใน GitHub ณ จุดหนึ่งการเพิ่มประสิทธิภาพหนึ่งทำให้ regex ช้าลงมากดังนั้นจากจุดที่ฉันรักษาสองรุ่น พวกเขาคือ:

regex สำหรับการจับคู่อุดมสมบูรณ์ numbers.txt
regex สำหรับการจับคู่ตัวเลขมากมาย - shortest.txt

regexes เหล่านี้เป็นอย่างเข้ากันได้กับทั้ง ECMAScript และ PCRE แต่การเพิ่มประสิทธิภาพที่ผ่านมาเกี่ยวข้องกับการใช้กลุ่มจับอาจไม่ใช่การมีส่วนร่วม\14เพื่อให้การทำงานร่วมกันโดยการวาง PCRE และการเปลี่ยนแปลง\14?ที่จะ\14พวกเขาทั้งสองจะสามารถลดลง 1 ไบต์

นี่คือรุ่นที่เล็กที่สุดที่มีการปรับใช้ให้เหมาะสม (ทำให้เป็น ECMAScript เท่านั้น), จัดรูปแบบใหม่เพื่อให้พอดีกับบล็อกรหัส StackExchange ด้วย (ส่วนใหญ่) ไม่จำเป็นต้องเลื่อนแนวนอน:

# Match abundant numbers in the domain ^x*$ using only the ECMAScript subset of regex
# functionality. For the purposes of these comments, the input number = N.
^
# Capture the largest prime factor of N, and the largest power of that factor that is
# also a factor of N. Note that the algorithm used will fail if N itself is a prime
# power, but that's fine, because prime powers are never abundant.
(?=
  (                      # \1 = tool to make tail = Z-1
    (                    # Repeatedly divide current number by its smallest factor
      (?=(xx+?)\3+$)
      (x+)\4*(?=\4$)
    )+                   # A "+" is intentionally used instead of a "*", to fail if N
                         #  is prime. This saves the rest of the regex from having to
                         #  do needless work, because prime numbers are never abundant.
    (?!\3+$)             # Require that the last factor divided out is a different prime.
    (?=(xx(x*?))\5*$)    # \5 = the largest prime factor of N; \6 = \5-2
    x                    # An extra 1 so that the tool \1 can make tail = Z-1 instead of just Z
  )
  (x+)                   # Z = the largest power of \5 that is a factor of N; \7 = Z-1
)
# We want to capture Z + Z/\5 + Z/\5^2 + ... + \5^2 + \5 + 1 = (Z * \5 - 1) / (\5 - 1),
# but in case Z * \5 > N we need to calculate it as (Z - 1) / (\5 - 1) * \5 + 1.
# The following division will fail if Z == N, but that's fine, because no prime power is
# abundant.
(?=
  \1                     # tail = (Z - 1)
  (x(x*))                # \8   = (Z - 1) / (\5 - 1); \9 = \8-1
  # It is guaranteed that either \8 > \5-1 or \8 == 1, which allows the following
  # division-by-multiplication to work.
  (?=\8*$)
  \6\9+$
)
(?=
  (.*)                   # \10 = tool to compare against \11
  (                      # \11 = \8 * \5  =  (Z - 1) / (\5 - 1) * \5; later, \13 = \11+1
    (?=\8*$)
    \5\9+$
  )
)
# Calculate Q = \15{2} + Q_R = floor(2 * N / \13). Since we don't have space for 2*N, we
# need to calculate N / \13 first, including the fractional part (i.e. the remainder),
# and then multiply the result, including the fractional part, by 2.
(?=
  (x*?)(?=(x\11)+$)      # \12 = N % \13; \13 = \11 + 1
  (?=\12\10|(x))         # \14 = Q_R = floor(\12 * 2 / \13)
                         #     = +1 carry if \12 * 2 > \11, or NPCG otherwise
  (x(x*))                # \15 = N / \13; \16 = \15-1
  (?=\15*$)
  (?=\11+$)              # must match if \15 <  \13; otherwise doesn't matter
  \11\16+$               # must match if \15 >= \13; otherwise doesn't matter
)
# Calculate \17 = N / Z. The division by Z can be done quite simply, because the divisor
# is a prime power.
(?=
  (x(x*))                # \17 = N / Z; \18 = \17-1
  (?=\17*$)
  \7\18+$
)
# Seed a loop which will start with Q and divide it by (P^(K+1)-1)/(P-1) for every P^K
# that is a factor of \17. The state is encoded as \17 * P + R, where the initial value
# of R is Q, and P is the last prime factor of N to have been already processed.
#
# However, since the initial R would be larger than \17 (and for that matter there would
# be no room for any nonzero R since with the initial value of P, it is possible for
# \17 * P to equal N), treat it as a special case, and let the initial value of R be 0,
# signalling the first iteration to pretend R=Q. This way we can avoid having to divide Q
# and \17 again outside the loop.
#
# While we're at it, there's really no reason to do anything to seed this loop. To seed
# it with an initial value of P=\5, we'd have to do some multiplication. If we don't do
# anything to seed it, it will decode P=Z. That is wrong, but harmless, since the next
# lower prime that \17 is divisible by will still be the same, as \5 cannot be a factor
# of \17.

# Start the loop.
(
  (?=
    (                    # \20 = actual value of R
      x*?(?=\17+$)       # move forward by directly decoded value of R, which can be zero
      # The division by \17 can be done quite simply, because it is known that
      # the quotient is prime.
      (?=
        \17+?            # tail = \17 * (a prime which divides into \17)
        (?=
          (              # \21 = encoded value for next loop iteration
            (xx(x*))     # \22 = decoded value of next smaller P; \23 = (\22-1)-1
            (?=\18+$)    # iff \22 > \17, this can have a false positive, but never a false negative
            \22*$        # iff \22 < \17, this can have a false positive, but never a false negative
          )
        )
        # Find the largest power of \22 that is a factor of \17, while also asserting
        # that \22 is prime.
        (x+)             # \24 = the largest power of \22 that is a factor of \17
        .*(?=\17$)
        \24*(?=\24$)
        (?!
          (xx+)\25*
          (?!\22+$)
          \25$
        )
        \22+$
      )
      (
        (?=(x\7)+$)      # True iff this is the first iteration of the loop.
        \15{2}\14        # Potentially unset capture, and thus dependent on ECMAScript
                         # behavior. Change "\14" to "\14?" for compatibility with non-
                         # ECMAScript engines, so that it will act as an empty capture
                         # with engines in which unset backrefs always fail to match.
      |
      )
    )
  )
  # Calculate \30 = (\24 - 1) / (\22 - 1) * \22 + 1
  (?=
    .*(?=\24)x           # tail = \24 - 1
    (x(x*))              # \28 = (\24 - 1) / (\22 - 1); \29 = \28-1
    (?=\28*$)
    \23\29*$
  )
  (?=
    .*(x(                # \30 = 1 + \28 * \22 = (\28 - 1) / (\22 - 1) * \22 + 1; \31 = \30-1
      (?=\28*$)
      \22\29+$
    ))
  )
  # Calculate \33 = floor(\20 / \30)
  (
    .*(?!\30)\20         # if dividing \20 / \30 would result in a number less than 1,
                         # then N is abundant and we can exit the loop successfully
  |
    (?=
      .*?(?!x\20)(?=\30*$)
      (x(x*))            # \33 = \20 / \30; \34 = \33-1
      (?=\33*$)
      (?=\31+$)          # must match if \33 <  \30; otherwise doesn't matter
      \31\34+$           # must match if \33 >= \30; otherwise doesn't matter
    )
    # Encode the state for the next iteration of the loop, as \17 * \22 + \33
    .*(?=\33\21$)
  )
)+$

ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
DJMcMayhem


27

Python 2 , 41 40 ไบต์

n=k=j=input()
while~k<0:j-=1;k-=j>>n%j*n

เอาต์พุตคือรหัสทางออกดังนั้น0จึงเป็นจริงและ1เป็นเท็จ

ลองออนไลน์!

มันทำงานอย่างไร

หลังจากตั้งค่าทั้งหมดของn , k , และjเป็นอินพุตจาก STDIN เราจะเข้าสู่ลูปwhile กล่าวว่าวงจะแตกเร็วที่สุดเท่าที่-k - 1 = ~ k ≥ 0คือk ≤ -1 / k <0

ในแต่ละซ้ำเราลดลงครั้งแรกที่จะต้องพิจารณาตัวหารเท่านั้นที่เหมาะสมของn ถ้าเจเป็นตัวหารของn , n%jอัตราผลตอบแทน0และเจ >> n j% * n = J / 2 0 = Jได้รับการหักออกจากk แต่ถ้าเจไม่ได้แบ่งn , n%jเป็นบวกดังนั้นn%j*nอย่างน้อยn> เข้าสู่ระบบ2เจและเจ >> n j% * n = J / 2 n j% * n = 0ถูกลบออกจากk

สำหรับตัวเลขที่อุดมสมบูรณ์kจะถึงค่าลบก่อนหรือเมื่อเจกลายเป็น1เนื่องจากผลรวมของn 's หารที่เหมาะสมเป็นอย่างเคร่งครัดมากกว่าn ในกรณีนี้เราแยกออกจากwhile loop และโปรแกรมเสร็จสิ้นตามปกติ

แต่ถ้าnเป็นไม่อุดมสมบูรณ์ที่สุดก็มาถึง0 ในกรณีนี้ให้n%jโยนZeroDivisionErrorและโปรแกรมออกโดยมีข้อผิดพลาด


4
~k<0เป็นสิ่งที่แฟนซี แต่ฉันคิดว่า-1<kมันก็ใช้กลอุบายด้วยเช่นกัน)
Martin Ender




10

Mathematica ขนาด 17 ไบต์

Tr@Divisors@#>2#&

คำอธิบาย

Tr@                 The sum of the main diagonal of
   Divisors@         the list of divisors of
            #         the first argument
             >      is greater than
              2#      twice the first argument.
                &   End of function.

1
ฉันประหลาดใจที่ Mathematica ไม่ได้สร้างสิ่งนี้ ..
MrPaulch

1
@MrPaulch พิจารณาความยาวของโปรแกรมแม้ว่าบิวอินอาจจะยาวกว่าในชื่อ>.>
Conor O'Brien

1
@ ConorO'Brien ถ้ามันมีอยู่ก็อาจจะเป็นAbundantNumberQจึงจะบันทึกเป็นคู่ไบต์ :)
ngenisis


7

เรติน่า50 50ไบต์

^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$)

อินพุตเป็นunaryเอาต์พุต1สำหรับจำนวนที่มาก0มิฉะนั้น

ไม่มีอะไรที่เฉพาะเจาะจงเกี่ยวกับจอประสาทตาเกี่ยวกับโซลูชันนี้ ด้านบนเป็น regex บริสุทธิ์ NET ซึ่งตรงกับตัวเลขที่อุดมสมบูรณ์เท่านั้น

ลองออนไลน์! (ชุดทดสอบที่กรองอินพุตทศนิยมด้วย regex ด้านบน)


6

เรติน่า 34 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

M!&`(1+)$(?<=^\1+)
1>`¶

^(1+)¶1\1

อินพุตเป็นunaryเอาต์พุต1สำหรับจำนวนที่มาก0มิฉะนั้น

ลองออนไลน์!

คำอธิบาย

M!&`(1+)$(?<=^\1+)

เราเริ่มต้นด้วยการรับตัวหารทั้งหมดของอินพุต การทำเช่นนี้เรากลับ ( !) ทั้งหมดที่ทับซ้อนกัน ( &) การแข่งขัน ( M) ของ (1+)$(?<=^\1+)regex regex ตรงกับคำต่อท้ายบางส่วนของอินพุตโดยที่อินพุตทั้งหมดนั้นเป็นจำนวนมากของคำต่อท้ายนั้น (ซึ่งเรามั่นใจโดยพยายามไปให้ถึงจุดเริ่มต้นสำหรับสตริงโดยใช้สำเนาของคำต่อท้ายเท่านั้น) เนื่องจากวิธีที่เอ็นจิน regex ค้นหาการจับคู่สิ่งนี้จะส่งผลให้รายการตัวหารตามลำดับจากน้อยไปหามาก (คั่นด้วย linefeeds)

1>`¶

สเตจนั้นตรงกับ linefeeds ( ) และลบออก อย่างไรก็ตามการ1>จำกัด นั้นข้ามการแข่งขันครั้งแรก ดังนั้นสิ่งนี้จะรวมตัวหารทั้งหมดเข้าด้วยกันอย่างมีประสิทธิภาพยกเว้นอินพุตเอง เราลงท้ายด้วยอินพุตในบรรทัดแรกและผลรวมของตัวหารที่เหมาะสมทั้งหมดในบรรทัดที่สอง

^(1+)¶1\1

สุดท้ายเราพยายามจับคู่อย่างน้อยหนึ่งรายการ1ในบรรทัดที่สองมากกว่าที่เรามีในบรรทัดแรก หากเป็นกรณีนี้ผลรวมของตัวหารที่เหมาะสมเกินกว่าอินพุต Retina นับจำนวนการแข่งขันของ regex นี้ซึ่งจะเป็น1จำนวนที่มากและ0อย่างอื่น


1
มันทำให้ฉันประหลาดใจอยู่เสมอว่าคุณสามารถทำคณิตศาสตร์ในเรตินาได้อย่างไร ฉันชอบที่จะเห็นคำอธิบาย! :)
DJMcMayhem

1
@DJMcMayhem ขออภัยที่ลืมเพิ่มไปก่อนหน้า ทำ
Martin Ender

6

8086 การชุมนุม 23 28 25 24 ไบต์

8bc8 d1e9 33db 33d2 50f7 f158 85d2 7502 03d9 7204 e2f0 3bc3

แต่อย่างใด:

; calculate if N (1 < N <= 65535) is abundant
; input: N (mem16/r16)
; output: CF=1 -> abundant, CF=0 -> not abundant
ABUND   MACRO   N 
        LOCAL DIV_LOOP, CONT_LOOP, END_ABUND
        IFDIFI <N>,<AX> ; skip if N is already AX
    MOV  AX, N          ; AX is dividend
        ENDIF
    MOV  CX, AX         ; counter starts at N / 2
    SHR  CX, 1          ; divide by 2
    XOR  BX, BX         ; clear BX (running sum of factors)
DIV_LOOP:
    XOR  DX, DX         ; clear DX (high word for dividend)
    PUSH AX             ; save original dividend
    DIV  CX             ; DX = DX:AX MOD CX, AX = DX:AX / CX
    POP  AX             ; restore dividend (AX was changed by DIV)
    TEST DX, DX         ; if remainder (DX) = 0, it divides evenly so CX is a divisor
    JNZ  CONT_LOOP      ; if not, continue loop to next
    ADD  BX, CX         ; add number to sum
    JC   END_ABUND      ; if CF=1, BX has unsigned overflow it is abundant (when CX < 65536)
CONT_LOOP:
    LOOP DIV_LOOP
    CMP  AX, BX         ; BX<=AX -> CF=0 (non-abund), BX>AX -> CF=1 (abund)
END_ABUND:
        ENDM

ตัวอย่างโปรแกรมทดสอบทดสอบ N = [12..1000]:

    MOV  AX, 12         ; start tests at 12
LOOP_START:
    ABUND AX            ; call ABUND MACRO for N (in AX)
    JNC  LOOP_END       ; if not abundant, display nothing
    CALL OUTDECCSV      ; display AX as decimal (generic decimal output routine)
LOOP_END:
    INC  AX             ; increment loop counter
    CMP  AX, 1000       ; if less than 1000...
    JBE  LOOP_START     ; continue loop
    RET                 ; return to DOS

ผลผลิต [2..1000]

12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60, 66, 70, 72, 78, 80, 84, 88, 90, 96, 100, 102, 104, 108, 112, 114, 120, 126, 132, 138, 140, 144, 150, 156, 160, 162, 168, 174, 176, 180, 186, 192, 196, 198, 200, 204, 208, 210, 216, 220, 222, 224, 228, 234, 240, 246, 252, 258, 260, 264, 270, 272, 276, 280, 282, 288, 294, 300, 304, 306, 308, 312, 318, 320, 324, 330, 336, 340, 342, 348, 350, 352, 354, 360, 364, 366, 368, 372, 378, 380, 384, 390, 392, 396, 400, 402, 408, 414, 416, 420, 426, 432, 438, 440, 444, 448, 450, 456, 460, 462, 464, 468, 474, 476, 480, 486, 490, 492, 498, 500, 504, 510, 516, 520, 522, 528, 532, 534, 540, 544, 546, 550, 552, 558, 560, 564, 570, 572, 576, 580, 582, 588, 594, 600, 606, 608, 612, 616, 618, 620, 624, 630, 636, 640, 642, 644, 648, 650, 654, 660, 666, 672, 678, 680, 684, 690, 696, 700, 702, 704, 708, 714, 720, 726, 728, 732, 736, 738, 740, 744, 748, 750, 756, 760, 762, 768, 770, 774, 780, 784, 786, 792, 798, 800, 804, 810, 812, 816, 820, 822, 828, 832, 834, 836, 840, 846, 852, 858, 860, 864, 868, 870, 876, 880, 882, 888, 894, 896, 900, 906, 910, 912, 918, 920, 924, 928, 930, 936, 940, 942, 945, 948, 952, 954, 960, 966, 968, 972, 978, 980, 984, 990, 992, 996, 1000

เอาต์พุต [12500..12700]

12500, 12504, 12510, 12512, 12516, 12520, 12522, 12528, 12530, 12534, 12540, 12544, 12546, 12552, 12558, 12560, 12564, 12570, 12572, 12576, 12580, 12582, 12584, 12588, 12594, 12600, 12606, 12612, 12618, 12620, 12624, 12628, 12630, 12636, 12640, 12642, 12648, 12650, 12654, 12656, 12660, 12666, 12670, 12672, 12678, 12680, 12684, 12688, 12690, 12696, 12700

เอาต์พุต [25100..25300]

25100, 25104, 25110, 25116, 25120, 25122, 25128, 25130, 25134, 25140, 25144, 25146, 25152, 25158, 25160, 25164, 25168, 25170, 25172, 25176, 25180, 25182, 25188, 25194, 25200, 25206, 25212, 25216, 25218, 25220, 25224, 25228, 25230, 25232, 25236, 25240, 25242, 25245, 25248, 25254, 25256, 25260, 25266, 25270, 25272, 25278, 25280, 25284, 25290, 25296, 25300

ปรับปรุง:

  • แก้ไขสำหรับการล้นเกิน 16 บิต (+5 ไบต์) ขอบคุณ @deadcode สำหรับคำแนะนำ!
  • ตรรกะส่งกลับแบบง่าย (-3 ไบต์) ขอบคุณที่ช่วยจาก @deadcode อีกครั้ง
  • ใช้ TEST แทน CMP (-1 ไบต์) ขอบคุณที่ @ l4m2!

1
ฉันขอแนะนำให้แทนที่JLEด้วยJBEการเพิ่มช่วงของตัวเลขเป็นสองเท่าที่สามารถทดสอบได้ก่อนที่จะเกิดการล้นเกินทำให้เกิดการลบที่ผิดพลาด จากนั้นแทนที่จะเริ่มที่จะล้มเหลวที่ 12600 (จำนวนรวม 35760) มันจะเริ่มล้มเหลวที่ 25200 (จำนวนส่วนลงตัว 74744) ยิ่งไปกว่านั้นก็คือการตรวจจับธงพกและถือว่าเป็นจำนวนมากมายโดยไม่จำเป็นต้องคำนวณผลรวมจริง> 16 บิต
Deadcode

1
จับได้ดี @ รหัส ฉันได้อัปเดตรหัสสำหรับการกระโดดด้านล่างแทนการกระโดดน้อย ฉันเห็นสิ่งที่คุณหมายถึงการทำ JC หลังจาก ADD BX, CX จะจับล้นที่ไม่ได้ลงนามที่นั่นและทำให้มันถูกต้องจนถึง N = 65535 ซับซ้อนการทดสอบการตั้งค่าสถานะและการคืนค่าเล็กน้อยเนื่องจาก CF ก่อนหน้านี้มีความหมายว่าเป็นเท็จ อัปเดตพร้อมการแก้ไขด้วย
640KB

1
คุณสามารถบันทึกได้ 3 ไบต์โดยการย้อนกลับข้อมูลจำเพาะของค่าส่งคืนโดย CF จะถูกตั้งค่าหากมีความอุดมสมบูรณ์และชัดเจนหากไม่มี แต่ฉันขอแนะนำให้ทำการแก้ไขเพื่อแก้ไขเอกสารผลลัพธ์ก่อนดังนั้นจึงดูดีในประวัติการแก้ไข
Deadcode

1
นอกจากนี้เพื่อให้ง่ายข้อมูลจำเพาะควรเป็นว่าค่าส่งคืนอยู่ในสถานะพกพาและไม่มีความยุ่งยากกับธงอื่น ๆ ผู้โทรควรใช้JCหรือJNCดำเนินการว่ามีจำนวนมากหรือไม่
Deadcode

1
ขอบคุณมากสำหรับความช่วยเหลือและความคิดเห็นของคุณ ฉันได้อัปเดตเอกสารแบบอินไลน์แล้วและนำคำที่ไม่อัปโหลดออก สุจริตไม่เคยคิดมาก แต่ฉันเห็นประเด็นของคุณเกี่ยวกับเรื่องนี้เพราะมันไม่แตกต่างกับข้อยกเว้นของความคิดเห็นแบบอินไลน์ ยังเห็นด้วยเกี่ยวกับการสร้างธงผลตอบแทนที่ชัดเจนเช่นกัน จะทำงานกับมันในเวลาไม่นาน ขอบคุณสำหรับความสนใจและความช่วยเหลือ!
640KB


5

05AB1E , 4 ไบต์

ѨO‹

ลองออนไลน์!

มันทำงานอย่างไร

Ñ        #list of divisors
 ¨       #remove last element (i.e the input from the list of factors)
  O      #sum the list 
   ‹     #is this sum less than the input? 

ขออภัยที่โพสต์ในคำถามเก่าฉันเพิ่งจะผ่านการโพสต์เก่าสำหรับการปฏิบัติและสังเกตเห็นว่าการแก้ปัญหาของฉันสั้นกว่าโซลูชั่น 05AB1E ที่ดีที่สุดต่อไป


4
Sorry to post in old questionไม่ต้องกังวลกับมัน! ฉันมักจะมีความสุขที่จะเห็นคำตอบเกี่ยวกับความท้าทายเก่าของฉันและเป็นจริงได้รับการสนับสนุนรอบที่นี่ :)
DJMcMayhem


4

Java 8, 53 ไบต์ (มากขึ้นถ้าคุณรวมรหัสพิธีการ)

return IntStream.range(1,n).filter(e->n%e<1).sum()>n;

ลองออนไลน์

คำอธิบาย:

IntStream.range(1,n) \\ numbers from 1 to n-1
filter(e->n%e<1)     \\ filter in numbers that perfectly divide the number n
sum()>n              \\ sum and compare to original number

4
คำตอบที่ยอดเยี่ยม แต่ด้วย Java 8 คุณต้องรวมฟังก์ชั่นในจำนวนไบต์ของคุณ จากนั้นอีกครั้งคุณสามารถดรอปreturnถ้าฉันไม่ผิดดังนั้นมันจะสั้นกว่า: n->IntStream.range(1,n).filter(e->n%e<1).sum()>n(ไม่ใช่ 100% ถ้านี่ถูกต้องฉันแทบไม่เคยเขียนโปรแกรมใน Java 8) ยินดีต้อนรับสู่ PPCG!
Kevin Cruijssen

1
จำนวนที่ถูกต้องผ่านการนับมาตรฐานจะเป็นn->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n65 ไบต์ (สมมติว่าฉันได้รับแพคเกจทันทีที่ด้านบนของหัวของฉัน)
CAD97

4

Powershell, 51 49 ไบต์

param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i

ฉันหวังว่าฉันจะลบวงเล็บบางส่วนออกได้

-2 ขอบคุณ AdmBorkBork แทนที่จะไม่นับการป้อนข้อมูลในช่วงเริ่มต้นเราเพียงนำมาพิจารณาในการตรวจสอบขั้นสุดท้าย

ห่วงผ่านช่วงของการ1..ไป$input ลบ 1 หาที่ ( ?) แบบโมดูโลผกผันของการป้อนข้อมูลด้วยจำนวนปัจจุบันคือ$true(aka เพียง 0) - แล้ว-joinทั้งหมดของตัวเลขเหล่านั้นร่วมกับ+และiexสตริงที่เกิดขึ้นในการคำนวณมันแล้วดูว่า ผลรวมของส่วนเหล่านี้มีค่ามากกว่าอินพุต

PS C:\++> 1..100 | ? {.\abundance.ps1 $_}
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100

คุณสามารถบันทึกสองไบต์ด้วยการนับค่าสูงสุดและตรวจสอบว่ามีขนาดใหญ่กว่า 2x อินพุต -param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i
AdmBorkBork

3

MATL, 6 ไบต์

Z\sGE>

เอาท์พุท 1 สำหรับตัวเลขที่มีค่ามากเป็นอย่างอื่น 0

มันทำงานอย่างไร

Z\      % list the divisors of the implicit input
s       % add them
G       % push the input again
E       % double it
>       % compare
        % implicitly display result

3

QBICขนาด 22 ไบต์

:[a/2|~a%b|\p=p+b}?p>a

นี้คือการปรับตัวกับการทดสอบ Qbic primality แทนที่จะนับตัวหารและตรวจสอบว่ามันน้อยกว่าสามตัว การดำเนินการนี้จะมีเพียงครึ่งเดียวเท่านั้น1 to nที่การทดสอบเริ่มต้นดำเนินไป1 to nอย่างสมบูรณ์

คำอธิบาย:

:       Get the input number, 'a'
[a/2|   FOR(b=1, b<=(a/2), b++)
~a%b    IF a MOD b != 0  --> QBasic registers a clean division  (0) as false. 
        The IF-branch ('|') therefor is empty, the code is in the ELSE branch ('\')
|\p=p+b THEN add b to runnning total p
}       Close all language constructs: IF/END IF, FOR/NEXT
?p>a    Print '-1' for abundant numbers, 0 otherwise.

3

JavaScript (ES6), 33 ไบต์

let g =
x=>(f=n=>--n&&n*!(x%n)+f(n))(x)>x
<input type=number min=1 value=1 step=1 oninput="O.innerHTML=g(+value)"><br>
<pre id=O>false</pre>


ฉันแน่ใจว่าคำตอบแบบเรียกซ้ำจะดีที่สุด แต่ฉันไม่คิดว่ามันจะเป็นสิ่งที่ดี
Neil

3

Japt , 9 7 6 ไบต์

<Uâ1 x

บันทึก 2 ไบต์ด้วย ETHproductions บันทึก 1 ไบต์ขอบคุณ obarakon

ลองออนไลน์!


9 ตัวอักษร 10 ไบต์
Metoniem

@Metoniem ฉันแน่ใจว่าâมี 1 ไบต์ใน unicode อย่างน้อย (0xE2)
Tom

1
@Metoniem Japt ใช้การเข้ารหัส ISO-8859-1ซึ่งâเป็นไบต์เดียว
ETHproductions

หากâได้รับการโต้แย้งจริงมันจะลบจำนวนจริงออกจากรายการที่เหลือเพื่อให้คุณสามารถâ1 x >Uบันทึกสองไบต์ :-)
ETHproductions

@ TomDevs Nice! คุณสามารถทำได้<Uâ1 xเพื่อบันทึกไบต์ Japt เพิ่มUด้านหน้าของโปรแกรม
โอลิเวอร์

3

Cubix , 38 ไบต์

/..?%?(O;0I:^.<.>;rrw+s;rUO?-<...O0L.@

ลองที่นี่

      / . .
      ? % ?
      ( O ;
0 I : ^ . < . > ; r r w
+ s ; r U O ? - < . . .
O 0 L . @ . . . . . . .
      . . .
      . . .
      . . .

0I:- ตั้งค่าสแต็กด้วย 0, n, n (s, n, d)
^- เริ่มลูป )?- ลดค่า d และทดสอบสำหรับ 0 0 ออกจากลูป
%?- mod เทียบกับ n และทดสอบ 0 ทำให้เกิดการ;rrw+s;rUหมุน s ไปด้านบนและเพิ่ม d หมุน s ไปด้านล่างและเข้าร่วมลูป
;<- ล้างข้อมูลและเข้าร่วมลูปอีกครั้ง
เมื่อออกจากลูป
;<- ลบ d จากสแต็กและเปลี่ยนเส้นทาง
-?- ลบ n จาก s และทดสอบ, 0 LOU@เลี้ยวซ้าย, เอาต์พุตและออก, เนกาทีฟ0O@พุพองเป็นศูนย์, เอาต์พุตและออก บวก;Oลบความแตกต่างและเอาท์พุท เส้นทางจะผ่านไปทางเลี้ยวซ้ายซึ่งเปลี่ยนเส้นทางไปยัง@ทางออก


3

Pure Bash ขนาด 37 ไบต์

for((;k++<$1;s+=$1%k?0:k)){((s>$1));}

ขอบคุณ @Dennis สำหรับการจัดเรียงรหัสใหม่ - ประหยัด 6 ไบต์และกำจัดการส่งออกโดยไม่ตั้งใจไปยัง stderr

อินพุตถูกส่งผ่านเป็นอาร์กิวเมนต์

เอาต์พุตถูกส่งคืนในโค้ดทางออก: 0 สำหรับมากมาย, 1 สำหรับไม่บริบูรณ์

เอาต์พุตไปยัง stderr ควรถูกละเว้น

ทดสอบการทำงาน:

for n in {1..100}; do if ./abundant "$n"; then echo $n; fi; done 2>/dev/null
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100

คุณสามารถบันทึก 6 ไบต์ในขณะที่หลีกเลี่ยงเอาต์พุตเล็ดลอดไปยัง STDERR tio.run/nexus/bash#S04sUbBTSEwqzUtJzCtRsLFRUHf1d1P/…
เดนนิส


2

แบตช์ 84 ไบต์

@set/ak=%1*2
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@cmd/cset/a"%k%>>31

เอาท์พุท-1สำหรับจำนวนมากมาย0มิฉะนั้น ทำงานโดยการลบปัจจัยทั้งหมดจาก2nแล้วเลื่อนผลลัพธ์ 31 ตำแหน่งเพื่อแยกบิตเครื่องหมาย สูตรทางเลือกเช่น 84 ไบต์:

@set k=%1
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@if %k% lss -%1 echo 1

เอาต์พุต1สำหรับจำนวนมากมาย ทำงานโดยการลบปัจจัยทั้งหมดจากนั้นเปรียบเทียบผลที่ได้เพื่อn -n( set/aเป็นวิธีการทางคณิตศาสตร์แบบแบทช์เท่านั้นดังนั้นฉันจึงไม่สามารถปรับลูปได้อย่างง่ายดาย)


1
"(% 1 %%%% j)" โอ้แบทช์ :)
Bryan Boettcher

2

Perl 6, 72 24 ไบต์

{$_ <sum grep $_%%*,^$_}
  • อาร์กิวเมนต์ของโปรแกรม:
  • 1..aสร้างรายชื่อจาก
  • aใช้ตัวเลขทั้งหมดที่มีตัวหารของ
  • รวมพวกเขา
  • aตรวจสอบว่าผลรวมที่มากกว่า

ขอบคุณ @ b2gills


การเกิดขึ้น$^aหลังจากเหตุการณ์แรกทุกครั้งสามารถย่อให้สั้นลง$aได้ แต่มันจะยิ่งสั้นลงถ้าคุณเขียนเป็น{$_ <sum grep $_%%*,^$_}ยังดูรุ่นก่อนหน้าใช้[+](LIST)งานได้ (ไม่มีที่ว่าง)
Brad Gilbert b2gills

@ BradGilbertb2gills ขอบคุณ! :)
Ven

2

J, 19 ไบต์

ขอบคุณ Conor O'Brien ที่ตัดมันให้เหลือ 19 ไบต์!

<[:+/i.#~i.e.]%2+i.

ก่อนหน้า: (34 ไบต์)

f=:3 :'(+/((i.y)e.y%2+i.y)#i.y)>y'

ส่งคืน 1 ถ้ามันอุดมสมบูรณ์และ 0 ถ้าไม่ใช่

เอาท์พุท:

   f 3
0
   f 12
1
   f 11
0
   f 20
1

ยินดีต้อนรับสู่ PPCG! เราอนุญาตฟังก์ชั่นที่ไม่ระบุตัวตนเพื่อให้คุณสามารถลบผู้นำที่f=:เป็นส่วนหนึ่งของการนับไบต์ของคุณ นอกจากนี้คุณสามารถลงไปที่ 19 โดยแปลงเป็นคำกริยาโดยปริยาย:<[:+/i.#~i.e.]%2+i.
Conor O'Brien

ขอบคุณสำหรับคำแนะนำ! อย่างไรก็ตามคุณสามารถอธิบายคำกริยาหมวก ([:) และสวิตช์คำกริยา (~) ได้ไหม ฉันไม่ได้สิ่งที่พวกเขาควรจะทำในกริยานี้โดยปริยาย
บล็อก

~ สวิตช์ดังนั้นมันคือ # i แต่อะไรคือจุดประสงค์ของ [:
บล็อก

คุณรู้เรื่องส้อมเลยใช่ไหม (f g h) y' is the same as (fy) กรัม (HY) . When f` เป็นหมวกเป็นประมาณเช่นเดียวกับ([: g h) y g h yส่วน~นี้จะสลับอาร์กิวเมนต์ซ้ายและขวา สิ่งสำคัญคือต้องรู้ว่า~ไม่ใช่คำกริยา แต่เป็นคำวิเศษณ์ มันปรับเปลี่ยนคำกริยา 2 %~ 8ตัวอย่างเช่นเราอาจจะมีบางอย่างเช่น นี่~ปรับเปลี่ยนเพื่อสลับข้อโต้แย้งของตนเพื่อให้การแสดงออกเทียบเท่ากับ% 8 % 2
Conor O'Brien

ในฟอร์คโซ่#~ได้รับการประเมินหลังจากใช้คำกริยาไปทางขวาดังนั้นอาร์กิวเมนต์ที่เหลือจะกลายเป็นผลลัพธ์ทางด้านขวา
Conor O'Brien

2

Pyth, 11 ไบต์

>sPf!%QTS

เก่า:

L!%Qb>sPy#S

ฉันใช้!%เป็น pfn #ไม่ได้เพราะมันมีสองฟังก์ชั่น ทำให้ฉันเศร้า :(.


L!%Qb>sPy#SQ    Program's argument: Q
L!%Qb           Define a lambda y, that takes b as an argument
 !%Qb           Return true if Q is divisible by b
          S     Make a range 1..Q
        y#      Filter that range with the lambda (y)
       P        Remove the last element (Q itself)
      s         Sum them
     >     Q    Check if that sum is greater than the program's argument

ดูเหมือนจะไม่ได้กำหนดฟังก์ชั่นให้สั้นลง:>sPf!%QTS
FryAmTheEggman

2

k , 19 16 15 ไบต์

{x<+/&~(!x)!'x}

ส่งคืน1ค่าจริงและ0เท็จ

ลองออนไลน์!

{             } /function(x)
       (!x)     /{0, 1, ..., x-1}
            '   /for each n in {0, 1, ..., x-1}:
           ! x  /    do (x mod n)
      ~         /for each, turn 0 -> 1, * -> 0 (map not)
     &          /get indices of 1's
   +/           /sum (fold add)
 x<             /check if x < the sum



2

F #, 51 ไบต์

let f n=Seq.filter(fun x->n%x=0){1..n-1}|>Seq.sum>n

ลองออนไลน์!

กรองออกตัวเลขทั้งหมดที่ไม่ได้แบ่งอย่างเท่าเทียมกันในแล้วสรุปเปรียบเทียบพวกเขาและพวกเขากับnn

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.