모든 고진 타 체인 찾기


36

고진 타 체인

( 프로젝트 오일러 # 606에서 영감을 얻음 )

n에 대한 고진 타 체인은 {1,a,b,...,n}각 요소가 다음 요소를 올바르게 나누는 시퀀스 입니다. 예를 들어 12 개의 8 개의 고진 타 체인이 있습니다.

{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}.

도전

양의 정수 ( n > 1) 를 받아들이고 주어진 숫자에 대한 모든 고진 타 체인을 출력하거나 반환 하는 프로그램이나 함수를 작성하십시오 .

  1. 체인의 순서는 중요합니다 (오름차순). 체인의 순서는 중요하지 않습니다.
  2. 오프 기회에는 해당 문제를 해결하는 내장 기능을 사용할 수 없습니다.
  3. 이것은 입니다.

편집 : 1잠재적 인 입력으로 제거 .


4
PPCG에 오신 것을 환영합니다. 좋은 첫 질문!
AdmBorkBork

5
"오프 기회에 [(당신을보고, Mathematica!)]"
Outgolfer Erik

3
당신은 단지에 대한 이유를 원하는 경우 - AdmBorkBork 말했듯이, 가장자리의 경우는 일반적으로 그들은 문제의 핵심에 중요한 경우에만 추가 [[1]]나는 경우 말 것 [1,1]의 gozinta입니다 1다음은 [1,1,12]의 gozinta입니다 12있는 그대로 [1,1,1,12]지금 우리는 할 수 더 이상 "모두 반환하지 않습니다"
Jonathan Allan

4
당신은 그것을 모르는 사람들을 위해 질문에서 말장난을 분명히해야합니다. 2|4"2는 4로 간다", 일명 "2는 gozinta 4"로 읽습니다.
mbomb007

1
샌드 박스가 작동하는 데 2 ​​시간 반이 충분하지 않습니다. 샌드 박스 FAQ를 참조하십시오 .
피터 테일러

답변:


10

파이썬 3 , 68 65 바이트

편집 : @ notjagan 덕분에 -3 바이트

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

온라인으로 사용해보십시오!

설명

gozinta 사슬사슬x 의 끝에 숫자 가 있고 그 왼쪽에 적어도 하나의 제수가 있습니다. 사슬 k의 각 제수마다 다릅니다. 따라서 우리는 각 제수마다 고유 한 고진 타 사슬을 모두 찾아서 끝에 추가 하여 모든 고진 타 사슬 을 왼쪽으로 직접 가져올 수 있습니다. 때까지 반복적으로 수행되는 경우 반환되는 모든으로, gozinta 체인이 1로 시작하는 재귀가 밖으로 바닥을 의미합니다.x[1,...,k,x]kxkxx = 1[[1]]

파이썬 반복 이해로 인해 코드가 너무 짧아 이중 반복이 가능합니다. 이것은에서 찾은 값 f(k)을 모든 다른 제수에 대해 동일한 목록에 추가 할 수 있음을 의미합니다 k.


너무 늦었 어, 이렇게하려고
Rod

3
이 답변은 지금까지 다른 답변에 비해 엄청나게 빠릅니다.
ajc2000

불필요한 목록 압축 풀기를 제거하여 -3 바이트 .
notjagan

7

껍질 , 13 바이트

ufo=ḣ⁰…ġ¦ΣṖḣ⁰

H.PWiz 와는 약간 다른 접근 방식 이지만 여전히 무차별 대입입니다. 온라인으로 사용해보십시오!

설명

기본 아이디어는 모든 하위 시퀀스를 연결 [1,...,n]하고 결과를 하위 요소로 분할하여 각 요소가 다음 요소를 나누는 것입니다. 이들 중, 우리는 시작하는 것과 유지 1와 끝을, n더 중복을 포함하지 않습니다. 이것은 "rangify"내장으로 수행됩니다 . 그런 다음 중복을 버립니다.

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.

각 숫자가 다음 숫자를 나누는 powerset의 배열을 필터링하는 것이 더 짧지 않다고 생각합니다.
ETHproductions

@ETHproductions 아니요, 1 바이트 더 깁니다 .
Zgarb

5

젤리 , 9 8 바이트

ÆḌ߀Ẏ;€ȯ

온라인으로 사용해보십시오!

Japt answer 와 유사한 기술을 사용 하므로 더 큰 테스트 사례에서 매우 빠르게 실행됩니다.

작동 원리

ÆḌ߀Ẏ;€ȯ    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

Mathematica, 77 바이트

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

Graph정점이 Divisors입력 의 정점 인 a를 형성 #하고 모서리는 적절한 분할 성을 나타내고 All정점에서 정점 1까지의 경로 를 찾습니다 #.


1
우와, 이건 정말 영리 해요!
JungHwan Min

3

젤리 , 12 바이트

ŒPµḍ2\×ISµÐṀ

정수를 받아들이고 정수 목록을 리턴하는 모나드 링크.

온라인으로 사용해보십시오!

어떻게?

첫 번째는 1이고, 마지막은 N이며, 모든 쌍이 나누도록 하나와 N 사이의 고유 한 정수 목록을 모두 원합니다. 이 코드는 해당 범위의 거듭 제곱에 대해 페어 단위 나누기 기준이 충족되는지 확인하여이 필터를 달성하지만 최대 증분 차이의 합을 최대로 선택하는 것만 선택합니다 (하나로 시작하고 N으로 끝나는 것만 N-1의 증분 차이의 합, 다른 것들은 적을 것입니다).

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

n와 겹치는 감소가있을 때까지 기다 립니까? : PI 사용되었다 : o를 어떻게 결코 보지 않았다 <slice>2<divisible>\<each>P :
HyperNeutrino

Jelly 's quicks의 최신 변경 사항을 사용하면 11 바이트Ɲ 에`2` 대신 사용할 수 있습니다 .
Mr. Xcoder

3

Japt , 17 바이트

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

온라인으로 테스트하십시오!

이상하게도 출력을 문자열로 생성하는 것이 배열의 배열로 생성하는 것보다 훨씬 쉽습니다 ...

설명

 ⬠£  ß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

그렇다면 다른 접근 방식과 마찬가지로 잘못된 접근 방식을 생성 한 다음 필터링하지 않습니다.
우산

@Umbrella Nope, 한 번에 하나의 제수 만 유효한 것만 생성하므로 12000 :-) 와 같은 경우에도 번개처럼 빠르게 작동하는 이유
ETHproductions

재귀의 아주 좋은 사용 :) 그리고 나는 그 ¬트릭을 닉네 ! : p
Shaggy

@Shaggy ¬는 기본적으로 "X는 인수가 없거나 X는 진실한 인수를하는"기능을 구현 한 이유 중 하나입니다. : P
ETHproductions

3

Mathematica, 60 바이트

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

용도의 문서화되지 않은 다중 인수 형태 Divisible, Divisible[n1,n2,...]반환 True하는 경우 n2∣n1, n3∣n2등, 그리고 False그렇지. 입력 Subsets의 모든 목록 을 취한 다음 d 시퀀스의 제수 를 제공 하는 형식의 형식 을 반환합니다 .Divisors#Cases{1,___,#}DivisibleTrueReverse


그래서, Divisiblegozinta 체인을 확인하기위한 내장은 기본적으로?
우산

@Umbrella 적절한 나누기를 확인하지 않습니다.
ngenisis

3

하스켈, 51 바이트

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

재귀 적으로 적절한 제수의 gozinta 사슬을 찾아서 추가하십시오 n.

온라인으로 사용해보십시오!


제대로 처리하면 추가 크레딧이 필요하다고 생각합니다 1. 우리는 총괄적으로 면제하기로 결정 했으므로 1해당 사례를 제거하여 10 바이트를 절약 할 수 있습니까?
우산

@Umbrella 1는이 알고리즘의 특별한 경우가 아니며 재귀의 기본 사례로 필요합니다. 자체적으로 두 번째 정의 방정식은 빈 목록 만 반환 할 수 있습니다.
Christian Sievers

내가 참조. 내 솔루션 (아직 게시되지 않음) [[1]]도 기본으로 사용 됩니다.
우산

3

하스켈 (Lambdabot), 92 85 바이트

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)

가져와야하므로 Lambdabot Haskell이 guard필요 Control.Monad합니다. 주요 기능은 익명의 기능으로, 허용되며 몇 바이트를 깎습니다.

7 바이트를 절약 한 Laikoni에게 감사합니다.

설명:

모나드는 매우 편리합니다.

x # y

이것은 모든 실제 작업을 수행하는 재귀 함수입니다. x우리가 누적하고있는 숫자 (값에 남아있는 제수의 곱)이고 그 다음에 나눠야하는 y숫자입니다.

 | x == y = [[x]]

경우 x등호 y우리는 완료 재귀입니다. 그냥 사용하는 x현재의 gozinta 체인의 끝으로 그것을 돌려줍니다.

 | 1 > 0 =

"참"에 대한 Haskell 골프주의. 즉, 이것이 기본 경우입니다.

(guard (mod x y < 1) >>

우리는 지금리스트 모나드 안에서 작동하고 있습니다. 리스트 모나드 내에서 동시에 여러 선택을 할 수 있습니다. 이것은 피로로 "가능한 모든 것"을 찾을 때 매우 유용합니다. guard문은 "조건에 해당하는 경우에만 다음과 같은 선택을 고려"말했다. 이 경우 y나누는 경우에만 다음 선택을 고려하십시오 x.

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

경우 y분할을하지 x, 우리는 추가 선택이 ygozinta 체인을. 이 경우, 체인에 추가 한 것을 "요소 화"하기 위해 와 같음으로 (#)시작하여 재귀 적으로 호출 합니다. 그런 다음이 재귀 호출의 결과에 관계없이 방금 인수 하여 고진 타 체인에 공식적으로 추가 합니다.y = 2xx / yyyy

++

다음 선택도 고려하십시오. 이것은 단순히 두리스트를 합친 것입니다.

x # (y + 1)

다른 옵션은 단순히 재귀를 계속하고 값을 사용하지 않는 것 y입니다. 경우 y분할하지 않습니다 x다음이 유일한 옵션입니다. 경우 y분할을 수행 x한 후이 옵션은 물론 다른 옵션으로로 간주되며, 그 결과가 결합됩니다.

map (1 :) . (# 2)

이것이 주요 고진 타 기능입니다. (#)인수와 함께 호출하여 재귀를 시작합니다 . 함수는 체인에 체인을 넣지 1않기 때문에 모든 고진 타 체인 앞에 A 가 붙습니다 (#).


1
좋은 설명! 패턴 가드를 모두 한 줄에 배치하여 일부 바이트를 절약 할 수 있습니다. mod x y==0로 단축 할 수 있습니다 mod x y<1. 익명 함수가 허용되므로 기본 함수를로 포인트없이 작성할 수 있습니다 map(1:).(#2).
Laikoni

3

하스켈, 107 (100) 95 바이트

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]

아마도 더 나은 종료 조건이있을 수 있습니다 (

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

그러나 더 길다). 1반복 문지르 기 1또는 중복 ( nubin이 Prelude아님)이 더 많은 바이트이므로 확인이 신중한 것으로 보입니다 .

온라인으로 사용해보십시오.


3
(>>=h)대한(concatMap h)
마이클 클라인


이런 멍청한 짓에 대해 바보입니다 u...
Leif Willerts

3

자바 스크립트 (Firefox 30-57), 73 바이트

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

편리하게 n%0<1거짓입니다.


2

젤리 , 17 바이트

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

온라인으로 사용해보십시오!


정말 빨랐습니다. 1그러나 결과 는 예기치 않습니다. 에 대한 결정적인 결과를 찾지 1못했지만 그 결과는 이라고 가정했습니다 [[1]]. [1,1]다른 모든 결과가 시퀀스를 증가시키는 것을 제외하고는 그것이 틀렸다는 것을 확실히 말할 수는 없습니다 . 생각?
우산

@Umbrella 당신은 답이 1을 위해 무엇이든하도록 할 수 있습니다.
Mr. Xcoder

@Umbrella은 문제가 있다면 나는 (대체이 그것을 해결할 수 ;€;Q¥€).
Outgolfer Erik

2

수학, 104 바이트

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

FreeQ[...]될 수 있습니다And@@BlockMap[#∣#2&@@#&,#,2,1]
JungHwan 분에게

아주 좋아요! 하지만 추가 메시지 DeveloperPartitionMap :: nlen :-메시지 텍스트를 찾을 수 없습니다->>`왜 그럴까요?
J42161217

BlockMap용도 Developer`PartitionMap내부적으로 기능을하지만, 개발자의 기능이기 때문에, 그것은 오류 메시지가 없습니다. 이 오류는 1 또는 0 개의 요소가있는 목록으로 인해 발생하며 2 개의 파티션으로 만들 수 없습니다.
JungHwan Min

2

Mathematica, 72 바이트

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

설명

Divisors@#

입력의 제수를 모두 찾으십시오.

Subsets@ ...

해당 목록의 모든 서브 세트를 생성하십시오.

Cases[ ... ]

패턴과 일치하는 모든 사례를 선택하십시오.

{1,___,#}

1로 시작하고 끝나는 <input>...

?( ... )

그리고 조건을 만족시킵니다 ...

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

왼쪽 요소는 목록의 모든 두 파티션에 대한 오른쪽 요소를 오프셋 1로 나눕니다.


2

TI-BASIC, 76 바이트

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

설명

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.

Ans> 1 검사 및 루프 조건을 제거하여 정상적으로 대신 오류없이 종료 할 수 있다면 다른 5 바이트를 절약 할 수 있습니다. 그러나 나는 그것이 허용 된 확신하지 않습니다.


이것을 계산기에 입력 했습니까? 예상치 못하고 다소 인상적이기 때문입니다.
우산

네! TI-BASIC의 까다로운 부분은 전역 변수 만 있다는 것이므로 목록 자체를 내 재귀 스택으로 효과적으로 사용해야했습니다.
calc84maniac

2

Mathematica 86 77 바이트

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

정의에 의한 무차별 대입.

리스트의 페어 단위 순차 요소 비교를 수행하는 더 짧은 방법이 있었으면 좋겠다.

9 바이트 절약 제안에 대해 @Jenny_mathy와 @JungHwanMin에게 감사합니다.


1
당신이 사용할 수있는 FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&]82 바이트로 이동합니다 (두 번째 인수로)
J42161217

@Jenny_mathy 또는 더 나은,And@@BlockMap[#∣#2&@@#&,#,2,1]
JungHwan Min

1

껍질 , 17 16 바이트

Zgarb 덕분에 -1 바이트

foEẊ¦m`Je1⁰Ṗthḣ⁰

온라인으로 사용해보십시오!


짧지 만 느립니다. 나는 넣어 50입력과 그 시간이 초과되었습니다. 당신의 접근 방식의 요지는 무엇입니까?
우산

그것은 본질적으로 가능한 모든 체인을 시도하고 사양과 일치하는 체인을 선택합니다
H.PWiz

@Umbrella TIO의 타임 아웃 시간은 60 초이며 프로그램의 결함이 아닙니다.
Outgolfer Erik

o`:⁰:1할 수 있습니다`Je1⁰
Zgarb에게

@Zgarb 다시 한번 ...
H.PWiz

0

PHP 147 141

중복 테스트를 제거하도록 편집

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

설명 :

function g($i) {

상용구 15 자 :(

    $r = [[1]];

[[1]]모든 체인이 1로 시작 하면 결과 세트를 초기화하십시오 . 또한 입력으로 1을 지원합니다.

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

2에서 모든 숫자를 들어 $i, 우리는 현재의 수에 의해 우리의 세트에 각 체인을 확장 할거야 경우gozinta , 다음, 우리의 결과 집합에 확장 된 체인을 추가 할 수 있습니다.

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

하지 않은 중간 체인을 걸러냅니다 $i

    return $R;
}

상용구 10 자 :(


-1

매스 매 티카

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

추가 통화에 대한 응답이 캐시됩니다.


1
사이트에 오신 것을 환영합니다! 이것은 코드 골프 이므로 바이트 수를 포함해야하며 추가 공백을 모두 제거해야합니다.
밀 마법사
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.