คำนวณปัจจัยสำคัญ


27

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

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่รับอินพุตเป็นจำนวนเต็มมากกว่า 1 และส่งออกหรือส่งกลับรายการปัจจัยหลัก

กฎระเบียบ

  • อินพุตและเอาต์พุตอาจกำหนดโดยวิธีมาตรฐานและในรูปแบบมาตรฐานใด ๆ
  • ปัจจัยที่ซ้ำกันต้องรวมอยู่ในผลลัพธ์
  • ผลลัพธ์อาจอยู่ในลำดับใดก็ได้
  • อินพุตจะต้องไม่น้อยกว่า 2 หรือมากกว่า 2 31 - 1
  • อนุญาตให้มีบิวด์อิน แต่อนุญาตให้รวมโซลูชันที่ไม่ใช่บิลด์ไว้

กรณีทดสอบ

2 -> 2
3 -> 3
4 -> 2, 2
6 -> 2, 3
8 -> 2, 2, 2
12 -> 2, 2, 3
255 -> 3, 5, 17
256 -> 2, 2, 2, 2, 2, 2, 2, 2
1001 -> 7, 11, 13
223092870 -> 2, 3, 5, 7, 11, 13, 17, 19, 23
2147483646 -> 2, 3, 3, 7, 11, 31, 151, 331
2147483647 -> 2147483647

เกณฑ์การให้คะแนน

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


2
คงจะดีกว่านี้มากถ้าคุณไม่อนุญาตให้ใช้บิวด์อิน
บัฟเฟอร์อ่านมากกว่า

2
@TheBitByte ความท้าทายที่ไม่อนุญาตให้ใช้บิวด์อินมักจะถูกมองว่าเป็นDo X โดยไม่มีความท้าทายYโดยเฉพาะอย่างยิ่งเนื่องจากบางครั้งก็ยากที่จะบอกได้ว่าโซลูชันในตัวเป็นเทคนิคในตัวหรือไม่
ETHproductions

1
ถ้างั้นก็สนุกไปกับการไหลเข้าของ <5 ไบต์โซลูชั่น! ขณะที่ฉันเขียนสิ่งนี้ Pyth ก็ทำมันด้วย 1 ไบต์
บัฟเฟอร์อ่านมากกว่า

2
@TheBitByte คิดว่ามันเป็นความท้าทายด้านภาษาต่อภาษาเป็นหลัก พยายามเอาชนะวิธีแก้ปัญหาของ Python หรือภาษาอื่นโดยไม่ต้องใช้ภาษาในตัว
isaacg

1
@isaacg เอาละการใช้ภาษาเป็นวิธีที่ดีกว่าในการมองมันฉันเห็นด้วย
บัฟเฟอร์อ่านมากกว่า

คำตอบ:




10

Python 2, 53 ไบต์

f=lambda n,i=2:n/i*[f]and[f(n,i+1),[i]+f(n/i)][n%i<1]

พยายามที่แต่ละตัวหารที่มีศักยภาพiในการเปิด ถ้าiเป็นตัวหาร prepends n/iมันและเริ่มต้นใหม่กับ อื่นลองตัวหารถัดไปสูงสุด เนื่องจากตัวหารถูกตรวจสอบตามลำดับที่เพิ่มขึ้นจะพบเฉพาะตัวที่ดีที่สุดเท่านั้น

ในฐานะโปรแกรม 55 ไบต์:

n=input();i=2
while~-n:
 if n%i:i+=1
 else:n/=i;print i

8

Mathematica, 38 30 ไบต์

ขอบคุณ @MartinEnder สำหรับ 8 ไบต์!

Join@@Table@@@FactorInteger@#&

แล้วไงFactorInteger[#][[All, 1]]&ล่ะ 26 ไบต์
David G. Stork

@ DavidG.Stork ที่ไม่ทำงานเพราะมันจะไม่ทำซ้ำปัจจัยสำคัญหากพลังมากกว่า 1
JungHwan Min



4

JavaScript (ES6), 44 ไบต์

f=(n,x=2)=>n-1?n%x?f(n,x+1):[x,...f(n/x)]:[]

ไม่มีประสิทธิภาพอย่างน่ากลัวเนื่องจากความจริงที่ว่ามันซ้ำจาก 2 ถึงทุกปัจจัยที่สำคัญรวมถึงสุดท้าย คุณสามารถลดความซับซ้อนของเวลาได้อย่างมากด้วยราคา 5 ไบต์:

f=(n,x=2)=>x*x>n?[n]:n%x?f(n,x+1):[x,...f(n/x,x)]


3

ที่จริงแล้ว 6 ไบต์

w`in`M

ลองออนไลน์!

คำอธิบาย:

w`in`M
w       factor into primes and exponents
 `in`M  repeat each prime # of times equal to exponent

คุณอาจจะสามารถใช้oตอนนี้ใช่มั้ย
Oliver

@Oliver ใช่ แต่โดยปกติฉันจะไม่อัปเดตคำตอบเก่า ๆ ด้วย builtins
Mego




2

tone-deaf , 3 ไบต์

ภาษานี้ค่อนข้างอ่อนเยาว์และยังไม่พร้อมสำหรับสิ่งสำคัญ แต่สามารถแยกตัวประกอบเฉพาะออกได้:

A/D

สิ่งนี้จะรอการป้อนข้อมูลของผู้ใช้จากนั้นออกรายการปัจจัยหลัก



1

Bash + coreutils, 19 ไบต์

factor|sed s/.*:.//

ลองออนไลน์!


factor|sed s/.*://คุณสามารถโกนไบต์ถ้าช่องว่างไม่ได้เรื่องในการส่งออกโดยใช้ นอกจากนี้factor|cut -d: -f2(หรือfactor|cut -d\ -f2เพื่อให้ตรงกับเอาต์พุตปัจจุบันของคุณ) มีความยาวไบต์เดียวกัน แต่จะทำงานได้เร็วขึ้นและใช้โอเวอร์เฮดของหน่วยความจำน้อยลง
Caleb

ฉันจะถาม OP เกี่ยวกับช่องว่าง น่าเศร้าที่ฉันต้องfactor|cut -d\ -f2-กำจัดพื้นที่ชั้นนำซึ่งมีความยาวหนึ่งไบต์
เดนนิส



1

Hexagony , 58 ไบต์

ยังไม่เล่นกอล์ฟ แต่ @MartinEnder น่าจะสามารถทำลายสิ่งนี้ได้

พิมพ์ปัจจัยคั่นด้วยช่องว่างพร้อมช่องว่างต่อท้าย

แข็งแรงเล่นกอล์ฟ:

2}\..}$?i6;>(<...=.\'/})."@...>%<..'':\}$"!>~\{=\)=\}&<.\\

ออกวาง:

     2 } \ . .
    } $ ? i 6 ;
   > ( < . . . =
  . \ ' / } ) . "
 @ . . . > % < . .
  ' ' : \ } $ " !
   > ~ \ { = \ )
    = \ } & < .
     \ \ . . .

คำอธิบายมาในภายหลัง




1

C, 92 ไบต์

int p(int n){for(int i=2;i<n;i++)if(n%i==0)return printf("%d, ",i)+p(n/i);printf("%d\n",n);}

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

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int prime(int number) {
    for (int i = 2; i < number; i++) {
        if (number % i == 0) {
            printf("%d, ", i);
            return prime(number / i); //you can golf away a few bytes by returning the sum of your recursive function and the return of printf, which is an int
        }                             //this allow you to golf a few more bytes thanks to inline calls
    }
    printf("%d\n", number);
}

int main(int argc, char **argv) {
    prime(atoi(argv[1]));
}




0

Perl 6 , 77 64ไบต์  

{my$a=$_;.is-prime??$_!!map ->\f{|({$a%f||($a/=f)&&f}...^*!= f)},(2... *>$a)}

ลองมัน

{my$a=$_;map ->\f{|({$a%f||($a div=f)&&f}...^ f>*)},(2... *>$a)}

ลองใช้ (หมายเหตุ: ใช้เวลาไม่พอที่จะทำให้เสร็จ)


เวอร์ชันที่มีประสิทธิภาพมากขึ้นจะยาวกว่าที่ 100 ไบต์เล็กน้อย

{my$a=$_;map ->\f{|({$a.is-prime??($/=$a)&&($a=0)||$/!!($a%f||($a div=f)&&f)}...^ f>*)},(2... *>$a)}

ลองมัน


ขยาย: (รุ่น 64 ไบต์)

{
  my $a = $_;  # the input 「$_」 is read-only by default
  map
    -> \f {
      |(              # slip ( flattens into outer list )

        # generate sequence of 0 or more 「f」s
        {
          $a % f      # is it not evenly divisible

          ||          # if it is evenly divisible
          ($a div=f)  # divide it
          &&          # and
          f           # return 「f」
        }
        ...^   # keep doing that until
        f > *  # 「f」 is bigger
      )

    },

    # do that over the following list

    (2 ... * > $a) # generate a sequence from 2
                   # up to whatever the value of $a
                   # is at the time of the check
}

0

VB.NET, 86 ไบต์

มีสิ่งนี้เกิดขึ้นจากโปรแกรม Project Euler หรือไม่ นำการเพิ่มประสิทธิภาพออกไปเพื่อผลประโยชน์ของความบกพร่องและนี่คือผลลัพธ์ โดยธรรมชาติแล้ว VB นั้นมีความละเอียดมากดังนั้นจึงค่อนข้างยาว ฉันไม่นับช่องว่างชั้นนำ สามารถละไว้ได้ แต่อ่านง่ายกว่า

สิ่งนี้จะใช้จำนวนเต็มเป็นพารามิเตอร์และพิมพ์ปัจจัยหลักด้วยเครื่องหมายจุลภาคหลังจาก มีเครื่องหมายจุลภาคต่อท้ายในตอนท้าย

Sub A(a)
    For i=2To a ' VB re-evaluates a each time, so the /= at the end of the loop shortens this
        While a Mod i=0 ' this is a factor. We've grabbed primes before this, so this must be a prime factor
            Console.Write(i &",") ' output
            a/=i ' "mark" the prime as "used"
        End While
    Next
End Sub


0

Java (OpenJDK)ขนาด 259 ไบต์

import java.util.*;interface g{static void main(String[]z){int a=new Scanner(System.in).nextInt();int b=0;int[]l={};for(int i=2;i<=a;i++){for(;a%i<1;l[b-1]=i){l=Arrays.copyOf(l,b=l.length+1);a/=i;}}for(int i=0;i<b;i++)System.out.print(l[i]+(i<b-1?", ":""));}}

ลองออนไลน์!


อ้างถึงกระทู้นี้เพื่อดูวิธีการส่งนี้สามารถ golfed เพิ่มเติม: gist.github.com/kritixilithos/fde37dc5a8ae54852aa134a6e70ea495 หากคุณต้องการที่จะชี้แจงสิ่งที่รู้สึกอิสระที่จะ ping ฉันที่ไบต์ที่ 19 :)
Kritixi Lithos

0

Ruby, 61 ไบต์

require'prime';->x{x.prime_division.flat_map{|x|[x[0]]*x[1]}}

บิวด์อินที่สั้นที่สุดที่ฉันนึกได้


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