Đếm bán nguyệt không vuông


8

Định nghĩa

Một nửa số không vuông là một số tự nhiên là tích của hai số nguyên tố riêng biệt.

Nhiệm vụ

Cho một số tự nhiên n, đếm tất cả các bán kết không vuông nhỏ hơn hoặc bằng n.

Chi tiết

Vui lòng viết một hàm hoặc thủ tục chấp nhận một tham số nguyên duy nhất và đếm tất cả các nửa số không có bình phương nhỏ hơn hoặc bằng tham số của nó. Số đếm phải là giá trị trả về của lệnh gọi hàm hoặc được in thành STDOUT.

Chấm điểm

Câu trả lời với số lượng nhân vật ít nhất sẽ thắng.

Trong trường hợp hòa, các tiêu chí sau sẽ được sử dụng theo thứ tự:

  1. Người cao nhất

  2. Độ phức tạp thời gian tốt nhất

  3. Không gian phức tạp nhất

Ví dụ

f(1)     = 0
f(62)    = 18
f(420)   = 124
f(10000) = 2600


Rất tiếc, xin lỗi, nhưng không có chuỗi đó không hoàn toàn đúng do hạn chế đồng quy (ví dụ: 35 = 5 * 7 và 55 = 5 * 11 không được bao gồm). Tôi sẽ thêm một vài giải pháp ví dụ cho vấn đề đặc biệt này trong giây lát.
ardew


Điều gì xảy ra nếu một ngôn ngữ không có STDOUT (như javascript)? Sử dụng console.log?
Bọ rùa

@Inkorms không javascript có khả năng trả về giá trị từ một hàm?
ardew

Câu trả lời:


7

J, 50 40 38 37 ký tự

f=:3 :'+/y<:}.~.,(~:/**/)~p:i._1&p:y'

Sử dụng:

   f 1
0
   f 62
18
   f 420
124
   f 10000
2600

Cảm ơn FUZxxl .

Kiểm tra hiệu suất

   showtotal_jpm_ ''[f 1[start_jpm_ ''
 Time (seconds)
┌───────┬──────┬────────┬────────┬─────┬────┬───┐
│name   │locale│all     │here    │here%│cum%│rep│
├───────┼──────┼────────┼────────┼─────┼────┼───┤
│f      │base  │0.000046│0.000046│100.0│100 │1  │
│[total]│      │        │0.000046│100.0│100 │   │
└───────┴──────┴────────┴────────┴─────┴────┴───┘
   showtotal_jpm_ ''[f 1[f 62[start_jpm_ ''
 Time (seconds)
┌───────┬──────┬────────┬────────┬─────┬────┬───┐
│name   │locale│all     │here    │here%│cum%│rep│
├───────┼──────┼────────┼────────┼─────┼────┼───┤
│f      │base  │0.000095│0.000095│100.0│100 │2  │
│[total]│      │        │0.000095│100.0│100 │   │
└───────┴──────┴────────┴────────┴─────┴────┴───┘
   showtotal_jpm_ ''[f 1[f 62[f 420[start_jpm_ ''
 Time (seconds)
┌───────┬──────┬────────┬────────┬─────┬────┬───┐
│name   │locale│all     │here    │here%│cum%│rep│
├───────┼──────┼────────┼────────┼─────┼────┼───┤
│f      │base  │0.000383│0.000383│100.0│100 │3  │
│[total]│      │        │0.000383│100.0│100 │   │
└───────┴──────┴────────┴────────┴─────┴────┴───┘
   showtotal_jpm_ ''[f 1[f 62[f 420[f 10000[start_jpm_ ''
 Time (seconds)
┌───────┬──────┬────────┬────────┬─────┬────┬───┐
│name   │locale│all     │here    │here%│cum%│rep│
├───────┼──────┼────────┼────────┼─────┼────┼───┤
│f      │base  │0.084847│0.084847│100.0│100 │4  │
│[total]│      │        │0.084847│100.0│100 │   │
└───────┴──────┴────────┴────────┴─────┴────┴───┘
   showtotal_jpm_ ''[f 1[f 62[f 420[f 10000[f 50000[start_jpm_ ''
 Time (seconds)
┌───────┬──────┬────────┬────────┬─────┬────┬───┐
│name   │locale│all     │here    │here%│cum%│rep│
├───────┼──────┼────────┼────────┼─────┼────┼───┤
│f      │base  │5.014691│5.014691│100.0│100 │5  │
│[total]│      │        │5.014691│100.0│100 │   │
└───────┴──────┴────────┴────────┴─────┴────┴───┘

Tôi không phải là nhà lý thuyết như đã thấy ở đây trong quá khứ, nhưng tôi nghĩ rằng độ phức tạp thời gian là một cái gì đó giống như O (n p 2 ) trong đó n p là số lượng các số nguyên tố lên đến và bao gồm cả số đầu vào n. Điều này dựa trên giả định rằng độ phức tạp của phương thức của tôi (tạo bảng nhân rất lớn) vượt xa độ phức tạp của hàm tạo nguyên tố được xây dựng trong J.

Giải trình

f=:3 :'...'tuyên bố một động từ (monadic) (chức năng). Đầu vào của động từ được thể hiện bởi ytrong định nghĩa động từ.

p:i._1&p:yCác p:động từ là số nguyên tố đa mục đích động từ, và nó được sử dụng theo hai cách khác nhau ở đây: _1&p:ytrả về số nguyên tố ít hơn ysau đó p:i.tạo ra mỗi một trong số họ. Sử dụng 10 làm đầu vào:

   p:i._1&p:10
2 3 5 7

(~:/**/)~tạo bảng tôi đã nói trước đó. */tạo bảng nhân, ~:/tạo bảng không bằng nhau (để loại bỏ các ô vuông) và cả hai bảng này được nhân với nhau. Sử dụng đầu ra trước đây của chúng tôi làm đầu vào:

   */~2 3 5 7
 4  6 10 14
 6  9 15 21
10 15 25 35
14 21 35 49

   ~:/~2 3 5 7
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0

   (~:/**/)~2 3 5 7
 0  6 10 14
 6  0 15 21
10 15  0 35
14 21 35  0

}.~.,bây giờ chúng ta biến các số thành một danh sách ,lấy các giá trị duy nhất ~.và xóa 0 khi bắt đầu}.

   }.~.,(~:/**/)~2 3 5 7
6 10 14 15 21 35

y<: so sánh với đầu vào ban đầu để kiểm tra giá trị nào là hợp lệ:

   10<:6 10 14 15 21 35
1 1 0 0 0 0

+/ và sau đó tổng hợp để có được câu trả lời.

   +/1 1 0 0 0 0
2

Bạn có phiên bản giả mạo của chương trình này (giả mạo trái ngược với ngầm)? 13 không phải lúc nào cũng đưa ra mã ngầm hiệu quả nhất.
FUZxxl

Không, tôi đã không sử dụng 13 trong trường hợp này - mặc dù tôi nghĩ có lẽ tôi đã làm những gì nó đã làm nếu tôi đã thử. Mã về cơ bản là: +/-.x<}.~.,(~:/~*[*/])p:i._1&p:[x=.ntrong đó n là đầu vào.
Gareth

1
Tại sao không chỉ f=:3 :'+/-.y<}.~.,(~:/~*[*/])p:i._1&p:y'cho 40 ký tự?
FUZxxl

Cảm ơn, tôi thậm chí chưa bao giờ cân nhắc sử dụng3 :'...'
Gareth

Bạn có công bố một số kết quả về thời gian để chúng tôi có thể đánh giá hiệu quả của chương trình không?
DavidC

5

Toán học 65 64 55 51 47 39

Sau đây đếm số lượng bán kết không vuông nhỏ hơn hoặc bằng n:

FactorInteger@Range@n~Count~{a={_,1},a}

Bất kỳ yếu tố bán chính không vuông nào thành một cấu trúc của biểu mẫu: {{p,1}{q,1}} Ví dụ:

FactorInteger@221
(* out *)
{{13, 1},{17, 1}}

Thói quen chỉ đơn giản là đếm các số trong phạm vi mong muốn có cấu trúc các yếu tố này.


Sử dụng

n=62;
FactorInteger@Range@n~Count~{a={_,1},a}

(* out *)
18

Thời gian: Tất cả các ví dụ đã cho

FactorInteger@Range@#~Count~{a = {_, 1}, a} & /@ {1, 62, 420, 10^4} // Timing

(* out *)
{0.038278, {0, 18, 124, 2600}}

Thời gian: n = 10 ^ 6

Phải mất dưới bốn giây để đếm số lượng các số nguyên tố bán tự do vuông nhỏ hơn hoặc bằng một triệu.

n=10^6;
FactorInteger@Range@n~Count~{a = {_, 1}, a}//Timing
(* out *)
{3.65167, 209867}

Giải pháp tuyệt vời, súc tích
ardew

@ardnew Cảm ơn. Tôi rất thích thử thách.
DavidC

Đẹp! Câu hỏi: những ký tự không gian xung quanh =và sau khi ,thực sự cần thiết về mặt cú pháp?
Todd Lehman

@ToddLehman, Bạn nói đúng. Tôi loại bỏ chúng. (Chúng chưa được tính nên số byte vẫn giữ nguyên.)
DavidC

4

Con trăn, 115

r=range
p=lambda x:all(x%i for i in r(2,x))
f=lambda x:sum([i*j<=x and p(j)and p(i)for i in r(2,x)for j in r(2,i)])

f=lambda x:sum([(i*j<=x)&p(j)&p(i)for i in r(2,x)for j in r(2,i)])lưu 5 ký tự.
beary605

@ beary605: Cảm ơn, nhưng tôi nghĩ rằng nó sẽ diễn ra quá lâu mà không bị đoản mạch.
grc

bỏ phiếu cho bạn quá nhiều suy nghĩ itertoolstrong đầu tôi
Ev_genus

4

Thạch , 7 byte

ŒcfÆf€L

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ŒcfÆf€L  Main link. Argument: n

Œc       Generate all 2-combinations of [1, ..., n], i.e., all pairs [a, b] such
         that 1 ≤ a < b ≤ n.
   Æf€   Compute the prime factorization of each k in [1, ..., n].
  f      Filter; keep only results that appear to the left and to the right.
      L  Take the length.

Wow, bạn đã làm cho nỗ lực của tôi trông xấu hổ. Cảm ơn các ý tưởng!
Harry

3

Con trăn (139)

from itertools import*;s=lambda n:sum(x*y<=n and x<y for x,y in product(filter(lambda x:all(x%i for i in range(2,x)),range(2,n)),repeat=2))

Vui lòng cung cấp một số kết quả mẫu để các đối thủ cạnh tranh có thể kiểm tra chương trình của họ.


Hãy xem, bạn thậm chí không cần các ví dụ! : ^)
ardew


2

Con trăn 139

def f(n):
 p=[];c=0
 for i in range(2,n+1):
    if all(i%x for x in p):p+=[i]
    c+=any((0,j)[i/j<j]for j in p if i%j==0 and i/j in p)
 return c

2

Golf 64

~:ß,{:§,{)§\%!},,2=},0+:©{©{1$}%\;2/}%{+}*{..~=\~*ß>+\0?)+!},,2/

Demo trực tuyến tại đây

Lưu ý: Trong bản demo ở trên tôi đã loại trừ các trường hợp 42010000thử nghiệm. Do thử nghiệm tính nguyên thủy cực kỳ kém hiệu quả, không thể để chương trình thực thi các đầu vào này trong vòng chưa đầy 5 giây.


2

Vỏ, 40

#! / thùng / sh

seq $ 1 | yếu tố | awk 'NF == 3 && $ 2! = $ 3' | wc -l

#old, 61
#seq $ 1 | yếu tố | awk 'BEGIN {a = 0} NF == 3 && $ 2! = $ 3 {a ++} END {in a}'

Sử dụng:

$ ./ đếm 1
0
$ ./ đếm 420
124
$ ./ đếm 10000
2600
$ thời gian ./cnt.sh 1000000
209867

số 0m23.956 thực
người dùng 0m23.601s
sys 0m0.404s

2

Thạch , 14 13 byte

RÆEḟ0⁼1,1$Ɗ€S

Hãy thử trực tuyến!

RÆEḟ0⁼1,1$Ɗ€S    main function:
RÆE             get the prime factorization Exponents on each of the Range from 1 to N,
          Ɗ€    apply the preceding 1-arg function composition (3 funcs in a row) to each of the prime factorizations:
                (the function is a monadic semiprime checker, as per DavidC's algorithm)
    ḟ0          check if the factors minus the zero exponents...
      ⁼1,1$      ...are equal to the list [1,1]
             S   take the Sum of those results, or number of successes!

Phê bình xây dựng hoan nghênh!


2
Sự kết hợp này Scó thể được chuyển thành sử dụng ċ(Đếm). Bạn có thể nhận được tới 10 byte bằng cách sử dụng nó. Tôi sẽ để bạn giải quyết nó!
Lynn

2

Python 2/3 , 95 94 byte

lambda n:sum(map(F,range(n+1)))
F=lambda x,v=2:sum(x%i<1and(F(i,0)or 3)for i in range(2,x))==v

Hãy thử trực tuyến!

Được đăng trong một thử thách 6 năm tuổi vì nó thiết lập một bản ghi Python mới, IMO là một cách tiếp cận khá thú vị.

Giải trình

lambda n:sum(map(F,range(n+1)))           # Main function, maps `F` ("is it a semiprime?")
                                          #  over the range [0, n]
F=lambda x,v=2:                           # Helper function; "Does `x` factor into `v`
                                          #  distinct prime numbers smaller than itself?"
  sum(                                    # Sum over all numbers `i` smaller than `x`
    x%i<1                                 # If `i` divides `x`,
    and                                   #  then
    (F(i,0)                               #  add 1 if `i` is prime (note that `F(i,0)`
                                          #  is just a primality test for `i`!)
    or 3)                                 #  or `3` if `i` is not prime (to make `F`
                                          #  return `False`)
  for i in range(2,x))
  ==v                                     # Check if there were exactly `v` distinct prime
                                          #  factors smaller than `x`, each with
                                          #  multiplicity 1

Python 2/3 (PyPy) , 88 82 81 byte

lambda n:sum(sum(x%i<1and(x/i%i>0or 9)for i in range(2,x))==2for x in range(n+1))

Hãy thử trực tuyến!

Dựa trên một golf 92 byte của Value Ink. PyPy là cần thiết để giải thích chính xác 0or, bởi vì Python tiêu chuẩn xem đây là một nỗ lực tại một số bát phân.



1

Stax , 8 byte

ߺ@N¬Që↔

Chạy và gỡ lỗi nó

Giải nén, không được chỉnh sửa và nhận xét, nó trông như thế này.

F       for 1..n run the rest of the program
  :F    get distinct prime factors
  2(    trim/pad factor list to length 2
  :*    compute product of list
  _/    integer divide by initial number (yielding 0 or 1)
  +     add to running total

Chạy cái này




0

Võng mạc , 58 byte

_
¶_$`
%(`$
$"
,,`_(?=(__+)¶\1+$)
¶1$'
)C`1(?!(__+)\1+¶)
2

Hãy thử trực tuyến!

Mất như là đầu vào unary với _ dấu kiểm đếm

Giải trình

Một số là một bán nguyên tố không vuông nếu hệ số lớn nhất và nhỏ nhất của nó, ngoại trừ chính nó và 1, đều là các số nguyên tố.

_
¶_$`

Lấy đầu vào và tạo mỗi số đơn nguyên nhỏ hơn hoặc bằng số đó, mỗi số trên một dòng riêng

%(`

Sau đó, cho mỗi số ...

$
$"
,,`_(?=(__+)¶\1+$)
¶1$'

Tìm hệ số nhỏ nhất và lớn nhất của nó, ngoại trừ chính nó 1 ...

)C`1(?!(__+)\1+¶)

và đếm số lượng của chúng là số nguyên tố. Vì yếu tố nhỏ nhất phải là số nguyên tố, điều này trả về 1 hoặc 2

2

Đếm tổng số 2



0

Ruby -rprime , 64 byte

Tôi biết rằng có một giải pháp Ruby khác ở đây, nhưng tôi không muốn đưa ra nhận xét vì nó đã được trả lời vào năm 2012 ... và khi nó bật ra, sử dụng cờ chương trình sẽ coi đó là một ngôn ngữ khác , vì vậy tôi đoán điều này về mặt kỹ thuật không phải là "Ruby".

Hãy thử trực tuyến!

Giải trình

->n{(1..n).count{|i|m=i.prime_division;m.size|m.sum(&:last)==2}}
->n{                                    # Anonymous lambda
    (1..n).count{|i|                    # Count all from 1 to `n` that match
                                        # the following condition
                m=i.prime_division;     # Get the prime factors of `i` as
                                        #  base-exponent pairs (e.g. [2,3])
                m.size                  # Size of factors (# of distinct primes)
                      |                 # bit-or with...
                       m.sum(&:last)    # Sum of the last elements in the pairs
                                        #  (the sum of the exponents)
                                    ==2 # Check if that equals 2 and return.
                                        # Because 2 is 0b10, the bit-or means
                                        #  that the condition is true iff both
                                        #  are either 2 or 0, but because this
                                        #  is a prime factorization, it is
                                        #  impossible to have the number of
                                        #  distinct primes or the sum of the
                                        #  exponents to equal 0 for any number
                                        #  > 1. (And for 1, size|sum == 0.)
    }                                   # End count block
}                                       # End lambda

0

APL (NARS), ký tự 26, byte 52

{≢b/⍨{(⍵≡∪⍵)∧2=≢⍵}¨b←π¨⍳⍵}

kiểm tra:

  f←{≢b/⍨{(⍵≡∪⍵)∧2=≢⍵}¨b←π¨⍳⍵}
  f 1
0
  f 9
1
  f 62
18
  f 420
124
  f 1000
288
  f 10000
2600
  f 100000
23313

đây là một thay thế dài hơn (59 ký tự mà tôi muốn)

r←h w;n;t
n←4⋄r←0
n+←1⋄→0×⍳w<n⋄→2×⍳(2≠≢t)∨2≠≢∪t←πn⋄r+←1⋄→2

kiểm tra:

  h 1000000
209867
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.