Tìm tất cả các chuỗi Gozinta khác biệt


36

Chuỗi Gozinta

(Lấy cảm hứng từ Dự án Euler # 606 )

Chuỗi gozinta cho n là một chuỗi {1,a,b,...,n}trong đó mỗi phần tử phân chia chính xác phần tiếp theo. Ví dụ: có tám chuỗi gozinta khác nhau cho 12:

{1,12}, {1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}.

Các thách thức

Viết chương trình hoặc hàm chấp nhận số nguyên dương ( n > 1) và xuất hoặc trả về tất cả các chuỗi gozinta riêng biệt cho số đã cho.

  1. Thứ tự trong các chuỗi có vấn đề (tăng dần), thứ tự của các chuỗi không.
  2. Nếu không có cơ hội, bạn không thể sử dụng nội dung tích hợp để giải quyết thách thức.
  3. Đây là .

Chỉnh sửa: Loại bỏ 1như là một đầu vào tiềm năng.


4
Chào mừng đến với PPCG. Câu hỏi đầu tiên rất hay!
admBorkBork

5
"Nếu không có cơ hội, nó tồn tại [(nhìn vào bạn,
Mathicala

3
Như AdmBorkBork nói, cạnh trường hợp thường được thêm vào chỉ khi họ là quan trọng đối với cốt lõi của sự thách thức - nếu bạn muốn có một lý do duy nhất [[1]]tôi muốn nói rằng nếu [1,1]là một gozinta của 1sau đó [1,1,12]là một gozinta của 12như là [1,1,1,12]và bây giờ chúng ta có thể không còn "trả lại tất cả ..."
Jonathan Allan

4
Bạn nên làm cho chơi chữ rõ ràng trong câu hỏi cho những người không biết nó. 2|4được đọc "hai đi vào bốn" hay còn gọi là "hai gozinta bốn".
mbomb007

1
Hai tiếng rưỡi không đủ thời gian để hộp cát hoạt động. Xem Câu hỏi thường gặp về hộp cát .
Peter Taylor

Câu trả lời:


10

Python 3 , 68 65 byte

Chỉnh sửa: -3 byte nhờ @notjagan

f=lambda x:[y+[x]for k in range(1,x)if x%k<1for y in f(k)]or[[x]]

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

Giải trình

Mỗi chuỗi gozinta bao gồm số xở cuối chuỗi, có ít nhất một ước ở bên trái của chuỗi. Đối với mỗi ước kcủa xchuỗi [1,...,k,x]là khác nhau. Do đó chúng tôi có thể đối với từng ước ktất cả riêng biệt của nó chuỗi gozinta và append xđến hết trong số họ, để có được tất cả các biệt chuỗi gozinta với ktrực tiếp đến trái x. Này được thực hiện một cách đệ quy cho đến x = 1nơi [[1]]được trả lại, như tất cả các chuỗi gozinta bắt đầu với 1, có nghĩa là đệ quy đã chạm đáy.

Mã trở nên quá ngắn do sự hiểu biết danh sách Python cho phép lặp lại gấp đôi. Điều này có nghĩa là các giá trị được tìm thấy f(k)có thể được thêm vào cùng một danh sách cho tất cả các ước số khác nhau k.


đã cố gắng để làm điều này, quá muộn bây giờ = /
Rod

3
Câu trả lời này là cực kỳ nhanh so với những người khác cho đến nay.
ajc2000

-3 byte bằng cách loại bỏ danh sách không cần giải nén.
notjagan

7

Husk , 13 byte

ufo=ḣ⁰…ġ¦ΣṖḣ⁰

Một cách tiếp cận hơi khác so với H.PWiz , mặc dù vẫn bằng vũ lực. Hãy thử trực tuyến!

Giải trình

Ý tưởng cơ bản là nối tất cả các phần sau của [1,...,n] và chia kết quả thành các danh sách con trong đó mỗi phần tử phân chia phần tiếp theo. Trong số này, chúng tôi giữ những cái bắt đầu 1, kết thúc nvà không chứa bản sao. Điều này được thực hiện với tích hợp "rangify" . Sau đó, nó vẫn còn để loại bỏ các bản sao.

ufo=ḣ⁰…ġ¦ΣṖḣ⁰  Input is n=12.
           ḣ⁰  Range from 1: [1,2,..,12]
          Ṗ    Powerset: [[],[1],[2],[1,2],[3],..,[1,2,..,12]]
         Σ     Concatenate: [1,2,1,2,3,..,1,2,..,12]
       ġ¦      Split into slices where each number divides next: [[1,2],[1,2],[3],..,[12]]
 fo            Filter by
      …        rangified
   =ḣ⁰         equals [1,...,n].
u              Remove duplicates.

Tôi đoán nó không ngắn hơn để lọc các mảng trong tập quyền hạn nơi mỗi số chia số tiếp theo?
Sản phẩm ETH

@ETHproductions Không, đó là một byte dài hơn .
Zgarb

5

Thạch , 9 8 byte

ÆḌ߀Ẏ;€ȯ

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

Sử dụng một kỹ thuật tương tự như câu trả lời Japt của tôi , và do đó chạy rất nhanh trên các trường hợp thử nghiệm lớn hơn.

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

ÆḌ߀Ẏ;€ȯ    Main link. Argument: n (integer)
ÆḌ          Yield the proper divisors of n.
       ȯ    If there are no divisors, return n. Only happens when n is 1.
  ߀        Otherwise, run each divisor through this link again. Yields
            a list of lists of Gozinta chains.
    Ẏ       Tighten; bring each chain into the main list.
     ;€     Append n to each chain.

4

Toán học, 77 byte

FindPath[Graph@Cases[Divisors@#~Subsets~{2},{m_,n_}/;m∣n:>m->n],1,#,#,All]&

Hình thành một Graphnơi mà các đỉnh là Divisorsđầu vào #và các cạnh thể hiện sự phân chia thích hợp, sau đó tìm Allcác đường dẫn từ đỉnh 1đến đỉnh #.


1
Woah, điều này là khá thông minh!
JungHwan Min

3

Thạch , 12 byte

ŒPµḍ2\×ISµÐṀ

Một liên kết đơn âm chấp nhận một số nguyên và trả về một danh sách các danh sách số nguyên.

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

Làm sao?

Chúng tôi muốn tất cả các danh sách được sắp xếp của các số nguyên duy nhất giữa một và N sao cho đầu tiên là một, cuối cùng là N và tất cả các cặp chia. Mã đạt được bộ lọc này bằng cách kiểm tra các tiêu chí phân chia theo cặp được thỏa mãn đối với tập hợp sức mạnh của phạm vi được đề cập, nhưng chỉ chọn những tiêu chí có tổng số chênh lệch tăng dần (cả hai bắt đầu bằng một và kết thúc bằng N sẽ có tổng số chênh lệch gia tăng của N-1, những người khác sẽ có ít hơn).

ŒPµḍ2\×ISµÐṀ - Link: number N
ŒP           - power-set (implicit range of input) = [[1],[2],...,[N],[1,2],[1,3],...,[1,N],[1,2,3],...]
          ÐṀ - filter keep those for which the result of the link to the left is maximal:
  µ      µ   - (a monadic chain)
    2\       -   pairwise overlapping reduce with:
   ḍ         -     divides? (1 if so, 0 otherwise)
       I     -   increments  e.g. for [1,2,4,12] -> [2-1,4-2,12-4] = [1,2,8]
      ×      -   multiply (vectorises) (no effect if all divide,
             -                          otherwise at least one gets set to 0)
        S    -   sum         e.g. for [1,2,4,12] -> 1+2+8 = 11 (=12-1)

Chờ có giảm chồng chéo n-khôn? : o làm thế nào tôi không bao giờ thấy điều đó: PI đã sử dụng <slice>2<divisible>\<each>: P
HyperNeutrino

Sử dụng thay đổi mới nhất để nhanh chóng của Jelly, bạn có thể sử dụng Ɲthay vì `2` cho 11 byte .
Ông Xcoder

3

Japt , 17 byte

⬣ßX m+S+UR÷ª'1

Kiểm tra nó trực tuyến!

Thật kỳ lạ, việc tạo đầu ra dưới dạng một chuỗi dễ dàng hơn nhiều so với việc tạo ra nó dưới dạng một mảng ...

Giải trình

 ⬠£  ßX m+S+URà ·  ª '1
Uâq mX{ßX m+S+UR} qR ||'1   Ungolfed
                            Implicit: U = input number, R = newline, S = space
Uâ                          Find all divisors of U,
  q                           leaving out U itself.
    mX{         }           Map each divisor X to
       ßX                     The divisor chains of X (literally "run the program on X")
          m    R              with each chain mapped to
           +S+U                 the chain, plus a space, plus U.
                  qR        Join on newlines.
                     ||     If the result is empty (only happens when there are no factors, i.e. U == 1)
                       '1     return the string "1".
                            Otherwise, return the generated string.
                            Implicit: output result of last expression

Vì vậy, cách tiếp cận của bạn tránh tạo ra các chuỗi không hợp lệ sau đó lọc chúng, như các phương pháp khác làm gì?
Ô

@Umhima Không, nó chỉ tạo ra những cái hợp lệ, một ước số tại một thời điểm, do đó tại sao nó hoạt động nhanh như chớp ngay cả trong các trường hợp như 12000 :-)
ETHproductions

Rất sử dụng tốt đẹp của đệ quy :) Và tôi nicking rằng¬ lừa! : p
Xù xì

@Shaggy ¬là một trong những lý do tại sao tôi đã triển khai một loạt các hàm về cơ bản là "do X không có đối số hoặc Y đưa ra một đối số trung thực": P
ETHproductions

3

Toán học, 60 byte

Cases[Subsets@Divisors@#,x:{1,___,#}/;Divisible@@Reverse@{x}]&

Sử dụng hình thức đa đối số không có giấy tờ Divisible, trong đó Divisible[n1,n2,...]trả về Truenếu n2∣n1,n3∣n2 v.v., và Falsenếu không. Chúng tôi có tất cả Subsetscác danh sách Divisorscủa các đầu vào #, sau đó trả lại Casescó dạng {1,___,#}như vậy Divisiblecho Truecho Reversed chuỗi các ước.


Vì vậy, Divisiblevề cơ bản là một nội dung để xác minh chuỗi gozinta?
Ô

@Umhima Nó không kiểm tra tính phân chia thích hợp.
ngenisis

3

Haskell, 51 byte

f 1=[[1]]
f n=[g++[n]|k<-[1..n-1],n`mod`k<1,g<-f k]

Đệ quy tìm chuỗi gozinta của ước số phù hợp và nối thêm n.

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


Tôi cảm thấy nên có thêm tín dụng để xử lý đúng 1. Vì chúng tôi đã kết luận miễn trừ chung 1, bạn có thể lưu 10 byte bằng cách xóa trường hợp đó không?
Ô

@Umhima 1không phải là trường hợp đặc biệt cho thuật toán này, nó cần thiết như trường hợp cơ sở cho đệ quy. Về bản thân, phương trình xác định thứ hai chỉ có thể trả về danh sách trống.
Christian Sievers

Tôi hiểu rồi. Giải pháp của tôi (chưa được đăng) cũng sử dụng [[1]]làm cơ sở.
Ô

3

Haskell (Lambdabot), 92 85 byte

x#y|x==y=[[x]]|1>0=(guard(mod x y<1)>>(y:).map(y*)<$>div x y#2)++x#(y+1)
map(1:).(#2)

Cần Lambdabot Haskell kể từ khi được guardyêu cầu Control.Monadnhập khẩu. Hàm chính là một hàm ẩn danh, mà tôi đã nói là được phép và nó sẽ loại bỏ một vài byte.

Cảm ơn Laikoni vì đã tiết kiệm bảy byte.

Giải trình:

Monads rất tiện dụng.

x # y

Đây là chức năng đệ quy của chúng tôi thực hiện tất cả các công việc thực tế. xlà số chúng tôi tích lũy được (sản phẩm của các ước số còn lại trong giá trị) và ylà số tiếp theo chúng tôi nên thử chia thành số đó.

 | x == y = [[x]]

Nếu xbằng ythì chúng ta đã thực hiện đệ quy. Chỉ cần sử dụng xnhư là kết thúc của chuỗi gozinta hiện tại và trả lại nó.

 | 1 > 0 =

Haskell golf-ism cho "Đúng". Đó là, đây là trường hợp mặc định.

(guard (mod x y < 1) >>

Bây giờ chúng tôi đang hoạt động trong danh sách đơn nguyên. Trong danh sách đơn nguyên, chúng tôi có khả năng đưa ra nhiều lựa chọn cùng một lúc. Điều này rất hữu ích khi tìm thấy "tất cả có thể" của một cái gì đó do kiệt sức. Các guardtuyên bố nói "chỉ xem xét các lựa chọn sau đây nếu một điều kiện là đúng". Trong trường hợp này, chỉ xem xét lựa chọn sau nếu ychia x.

(y:) . map (y *) <$> div x y#2)

Nếu ykhông phân chia x, chúng ta có quyền lựa chọn thêm yvào chuỗi gozinta. Trong trường hợp này, đệ quy gọi (#), bắt đầu lại ở y = 2với xbằng x / y, vì chúng ta muốn "yếu tố out" mà ychúng ta vừa bổ sung vào chuỗi. Sau đó, bất kể kết quả từ cuộc gọi đệ quy này là gì, nhiều giá trị của nó do ychúng tôi chỉ cần đưa ra và thêm yvào chuỗi gozinta chính thức.

++

Hãy xem xét lựa chọn sau đây là tốt. Điều này chỉ đơn giản là thêm hai danh sách lại với nhau, nhưng về mặt đơn giản, chúng ta có thể nghĩ về nó như nói "chọn giữa làm việc này HOẶC điều này khác".

x # (y + 1)

Tùy chọn khác là chỉ cần tiếp tục đệ quy và không sử dụng giá trị y. Nếu ykhông phân chia xthì đây là lựa chọn duy nhất. Nếu ykhông chia xthì tùy chọn này sẽ được thực hiện cũng như tùy chọn khác và kết quả sẽ được kết hợp.

map (1 :) . (# 2)

Đây là chức năng gozinta chính. Nó bắt đầu đệ quy bằng cách gọi (#)với đối số của nó. A 1được thêm vào mỗi chuỗi gozinta, bởi vì (#)hàm không bao giờ đặt các chuỗi vào chuỗi.


1
Giải thích tuyệt vời! Bạn có thể lưu một số byte bằng cách đặt tất cả các mẫu bảo vệ trong một dòng. mod x y==0có thể rút ngắn thành mod x y<1. Vì các chức năng ẩn danh được cho phép, chức năng chính của bạn có thể được viết miễn phí dưới dạng map(1:).(#2).
Laikoni

3

Haskell, 107 100 95 byte

f n=until(all(<2).map head)(>>=h)[[n]]
h l@(x:_)|x<2=[l]|1<2=map(:l)$filter((<1).mod x)[1..x-1]

Có lẽ có một điều kiện chấm dứt tốt hơn (đã thử một cái gì đó như

f n=i[[n]]
i x|g x==x=x|1<2=i$g x
g=(>>=h)

nhưng nó dài hơn). Việc kiểm tra 1có vẻ thận trọng vì việc lặp lại 1s hoặc trùng lặp ( nubkhông phải Prelude) là nhiều byte hơn.

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


3
(>>=h)cho(concatMap h)
Michael Klein


Chúa u
ơi,

3

JavaScript (Firefox 30-57), 73 byte

f=n=>n>1?[for(i of Array(n).keys())if(n%i<1)for(j of f(i))[...j,n]]:[[1]]

Thuận tiện n%0<1là sai.


2

Thạch , 17 byte

ḊṖŒP1ppWF€ḍ2\Ạ$Ðf

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


Đó là ấn tượng nhanh chóng. Kết quả của bạn 1là bất ngờ, mặc dù. Tôi đã không quản lý để tìm thấy một kết quả cuối cùng cho 1, nhưng tôi cho rằng nó là [[1]]. Tôi không thể nói chắc chắn rằng điều đó [1,1]là không chính xác, ngoại trừ tất cả các kết quả khác đang tăng trình tự. Suy nghĩ?
Ô

@Umhima Bạn có thể muốn để câu trả lời làm bất cứ điều gì cho 1.
Ông Xcoder

@Umhima Nếu đó là sự cố tôi có thể khắc phục cho +2 (thay thế ;€bằng ;Q¥€).
Erik the Outgolfer

2

Toán học, 104 byte

(S=Select)[Rest@S[Subsets@Divisors[t=#],FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&],First@#==1&&Last@#==t&]&

FreeQ[...]có thể trở thànhAnd@@BlockMap[#∣#2&@@#&,#,2,1]
JungHwan Min

rất đẹp! nhưng tôi nhận được một thông báo thêm DeveloperPhân vùng Bản đồ :: nlen: - Không tìm thấy văn bản tin nhắn - >> `tại sao vậy?
J42161217

BlockMapsử dụng Developer`PartitionMapchức năng bên trong, nhưng vì nó là chức năng của nhà phát triển nên nó không có thông báo lỗi. Lỗi xảy ra do các danh sách có 1 hoặc 0 phần tử mà bạn không thể tạo 2 phân vùng.
JungHwan Min

2

Toán học, 72 byte

Cases[Subsets@Divisors@#,{1,___,#}?(And@@BlockMap[#∣#2&@@#&,#,2,1]&)]&

Giải trình

Divisors@#

Tìm tất cả các ước của đầu vào.

Subsets@ ...

Tạo tất cả các tập hợp con của danh sách đó.

Cases[ ... ]

Chọn tất cả các trường hợp khớp với mẫu ...

{1,___,#}

Bắt đầu bằng 1 và kết thúc bằng <input>...

?( ... )

và thỏa mãn điều kiện ...

And@@BlockMap[#∣#2&@@#&,#,2,1]&

Phần tử bên trái chia phần tử bên phải cho tất cả 2 phân vùng của danh sách, bù 1.


2

TI-BASIC, 76 byte

Input N
1→L1(1
Repeat Ans=2
While Ans<N
2Ans→L1(1+dim(L1
End
If Ans=N:Disp L1
dim(L1)-1→dim(L1
L1(Ans)+L1(Ans-(Ans>1→L1(Ans
End

Giải trình

Input N                       Prompt user for N.
1→L1(1                        Initialize L1 to {1}, and also set Ans to 1.

Repeat Ans=2                  Loop until Ans is 2.
                              At this point in the loop, Ans holds the
                              last element of L1.

While Ans<N                   While the last element is less than N,
2Ans→L1(1+dim(L1              extend the list with twice that value.
End

If Ans=N:Disp L1              If the last element is N, display the list.

dim(L1)-1→dim(L1              Remove the last element, and place the new
                              list size in Ans.

L1(Ans)+L1(Ans-(Ans>1→L1(Ans  Add the second-to-last element to the last
                              element, thereby advancing to the next
                              multiple of the second-to-last element.
                              Avoid erroring when only one element remains
                              by adding the last element to itself.

End                           When the 1 is added to itself, stop looping.

Tôi có thể lưu thêm 5 byte nếu nó được phép thoát với một lỗi thay vì duyên dáng, bằng cách xóa kiểm tra Ans> 1 và điều kiện vòng lặp. Nhưng tôi không tự tin rằng điều đó được cho phép.


Bạn đã gõ nó vào máy tính của bạn? Bởi vì đó là bất ngờ và có phần ấn tượng.
Ô

Vâng! Phần khó khăn về TI-BASIC là chỉ có các biến toàn cục, vì vậy tôi đã phải sử dụng hiệu quả chính danh sách này như ngăn xếp đệ quy của mình.
calc84maniac

2

Toán học 86 77 byte

Select[Subsets@Divisors@#~Cases~{1,___,#},And@@BlockMap[#∣#2&@@#&,#,2,1]&]&

Lực lượng vũ phu theo định nghĩa.

Mong muốn có một cách ngắn hơn để thực hiện so sánh yếu tố tuần tự theo cặp của một danh sách.

Cảm ơn @Jenny_mathy và @JungHwanMin vì đã gợi ý tiết kiệm 9 byte


1
bạn có thể sử dụng FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&](làm đối số thứ hai) để chuyển đến 82 byte
J42161217

@Jenny_mathy Hoặc tốt hơn,And@@BlockMap[#∣#2&@@#&,#,2,1]
JungHwan Min

1

Husk , 17 16 byte

-1 byte, nhờ Zgarb

foEẊ¦m`Je1⁰Ṗthḣ⁰

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


Ngắn, nhưng chậm. Tôi 50nhập dữ liệu vào và hết thời gian. Ý chính của cách tiếp cận của bạn là gì?
Ô

Về cơ bản, nó cố gắng thử tất cả các chuỗi có thể và chọn chuỗi phù hợp với thông số kỹ thuật
H.PWiz

@Umhima TIO có thời gian chờ 60 giây, đó không phải là lỗi của chương trình.
Erik the Outgolfer

o`:⁰:1có thể`Je1⁰
Zgarb

@Zgarb Một lần nữa ...
H.PWiz

0

PHP 147 141

Đã chỉnh sửa để xóa bài kiểm tra dự phòng

function g($i){$r=[[1]];for($j=2;$j<=$i;$j++)foreach($r as$c)if($j%end($c)<1&&$c[]=$j)$r[]=$c;foreach($r as$c)end($c)<$i?0:$R[]=$c;return$R;}

Giải thích:

function g($i) {

15 ký tự của nồi hơi :(

    $r = [[1]];

Ban đầu kết quả được đặt thành [[1]]khi mọi chuỗi bắt đầu bằng 1. Điều này cũng dẫn đến hỗ trợ cho 1 làm đầu vào.

    for ($j = 2; $j <= $i; $j++) {
        foreach ($r as $c) {
            if ($j % end($c) < 1) {
                $c[] = $j;
                $r[] = $c;
            }
        }
    }

Đối với mỗi số từ 2 đến $i, chúng tôi sẽ mở rộng mỗi chuỗi trong tập hợp của chúng tôi theo số hiện tại nếuđi , sau đó, thêm chuỗi mở rộng vào tập kết quả của chúng tôi.

    foreach ($r as $c) {
        end($c) < $i ? 0 : $R[] = $c;
    }

Lọc ra các chuỗi trung gian của chúng tôi đã không làm được $i

    return $R;
}

10 ký tự của nồi hơi :(


-1

Toán học

f[1] = {{1}};
f[n_] := f[n] = Append[n] /@ Apply[Join, Map[f, Most@Divisors@n]]

Trả lời được lưu trữ cho các cuộc gọi bổ sung.


1
Chào mừng đến với trang web! Đây là một môn đánh gôn, vì vậy bạn nên bao gồm số byte của mình và ngoài ra còn cố gắng loại bỏ tất cả các khoảng trắng thừa, mà tôi nghi ngờ bạn có một số.
Thuật sĩ lúa mì
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.