길이 n의 매직 시퀀스


11

마법의 순서는 음이 아닌 정수의 순서입니다 x[0..n-1]정확히가되도록 x[i]의 인스턴스i

예를 들어, 6,2,1,0,0,0,1,0,0,0은 6 0, 2 1 등이 있으므로 마술 순서입니다.

n이 주어지면 길이 n의 모든 매직 시퀀스를 출력하는 함수를 작성하십시오.


10 초 내에 n의 최고 값에 대한 올바른 출력을 생성 할 수있는 프로그램이 승리합니다. (그러나 모든 프로그램은 환영합니다)

예를 들어, Alice의 프로그램은 10 초 이내에 n = 15까지 처리 할 수 ​​있고 Bob은 동시에 n = 20까지 처리 할 수 ​​있습니다. 밥이 이긴다.

플랫폼 : Linux 2.7GHz @ 4 CPU


5
PPCG에 오신 것을 환영합니다! 이것은 큰 도전이지만이기는 기준이 필요합니다. 예를 들어, 우승자가 가장 짧은 프로그램이라고 말할 수 있습니다.
Ypnypn


2
답변이 게시 된 후 당첨 기준을 변경하지 마십시오. 또한 이것은 적어도 내 의견으로는 가장 빠른 코드보다 코드 골프만큼 훨씬 낫습니다.
Alex A.

2
@xnor n의 정수 파티션을 생성하고 자체 설명이 가능한지 확인하여 시작할 수 있습니다.
마틴 엔더

2
n>5형태가 아닌 솔루션으로 가장 작은 것은 무엇입니까 [n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]? 나는 n=20하나를 찾아 보지 못했고 오류가 있는지 궁금합니다.
xnor

답변:


19

파이썬, n≈10 8

def magic_sequences(n):
    if n==4:
        return (1, 2, 1, 0),(2, 0, 2, 0) 
    elif n==5:
        return (2, 1, 2, 0, 0),
    elif n>=7:
        return (n-4,2,1)+(0,)*(n-7)+(1,0,0,0),
    else:
        return ()

이것은 내가 증명할 사실을 사용하여 길이의 유일한 매직 시퀀스 n는 다음과 같습니다.

  • [1, 2, 1, 0][2, 0, 2, 0]에 대한n=4
  • [2, 1, 2, 0, 0] ...에 대한 n=5
  • [n-4, 2, 1, 0, 0, ..., 0, 0, 1, 0, 0, 0] ...에 대한 n>=7

따라서, n>=7큰 튜플 만 반환하면됩니다. n=10^8랩톱에서 최대 약이 작업을 수행 할 수 있으며 메모리에 의해 제한 될 수 있습니다. 더 이상 얼어 붙습니다. (목록이 아닌 튜플을 사용한다는 아이디어에 대해 trichoplax에 감사합니다.) 또는 0이 아닌 항목의 사전을 대신 인쇄 {0:n-4, 1:2, 2:1, (n-4):1}할 수 있다면 엄청난 양의 작업을 수행 할 수 있습니다 n.

나는 독창성을 증명한다 n>=7. 다른 것들은 무차별적인 힘이나 사건으로 확인할 수 있습니다.

항목의 합계는 l목록의 모든 숫자의 총 개수이며 길이 n입니다. 이 목록에는 l[0]0 n-l[0]이 있으므로 0이 아닌 항목이 있습니다. 그러나 정의 l[0]제로이거나 우리는 모순을 얻고, 다른 제로의 각 항목이 이미의 합을 차지 적어도 1이다 l[0] + (n-l[0]-1)*1 = n-1의 전체 합계 중 n. 따라서 계산하지 않으면 l[0]최대 2 개가 있고 2보다 큰 항목은 없습니다.

그러나 이는 0이 아닌 유일한 항목은 l[0], l[1], l[2], and l[l[0]]값이 최대 l[0]이고 순열은 1,1,2최대 합을 의미 l[0]+4합니다. 이 합이기 때문에 n, 우리가 적어도 7 인 l[0]>=3l[l[0]]=1. 이제 적어도 하나 거기 1수단 l[1]>=1만하면 l[1]==1그건 또 다른 1, 그래서 l[1]>=2, 의미있는 l[1]외로운입니다 2. 이렇게하면 l[2]=1나머지 항목은 모두 0이므로 l[0]=n-4솔루션이 완성됩니다.


그리고 언어는 ...?
edc65

@ edc65 파이썬처럼 보입니다. 그러나 나는 확실하지 않다.
Ismael Miguel

4

파이썬 3, n≈40

def plausible_suffix(l,N):
    if sum(l)>N:
        return False

    pairs = [(N-1-i,l[i]) for i in range(len(l))]

    if sum(i*x for i,x in pairs)>N:
        return False

    num_remaining = N - len(l)

    for index, desired_count in pairs:
        count = l.count(index)
        more_needed = desired_count - count
        if more_needed<0: 
            return False
        num_remaining -= more_needed
        if num_remaining<0:
            return False
    return True

plausible_func = plausible_suffix

def generate_magic(N):
    l=[0]
    while l:
        extend = False
        if plausible_func(l,N):
            if len(l)==N:
                yield l[::-1]
            else:
                extend = True
        if extend:
            l.append(0)
        else:
            while l[-1]>=N-2:
                l.pop(-1)
                if not l:raise StopIteration
            l[-1]+=1

n=40 #test parameter

if n>0:
    for x in generate_magic(n):
        print(n,x)

가능한 목록에 대한 폭 넓은 우선 검색을 수행하여 오른쪽에서 왼쪽으로 항목을 채우고 접미사에서 검색을 중지 할 수없는 접미사에서 검색을 중지하면 다음과 같은 경우에 발생할 수 있습니다.

  • 접미사 항목의 합계가 초과합니다 n(전체 목록의 합계는이어야 함 n).
  • i*l[i]접미사에서 가중 합이 초과됩니다 n(전체 목록의 합은이어야 함 n)
  • 접미사에 숫자가 여러 번 표시되면 접미사가
  • 채워지지 않은 남은 반점의 수가 너무 적어서 더 많은 시간이 필요한 모든 숫자를 설명 할 수 없습니다.

원래 테스트 된 접두사를 왼쪽에서 오른쪽으로 사용했지만 더 느리게 진행되었습니다.

출력 n=30은 다음과 같습니다.

4 [1, 2, 1, 0]
4 [2, 0, 2, 0]
5 [2, 1, 2, 0, 0]
7 [3, 2, 1, 1, 0, 0, 0]
8 [4, 2, 1, 0, 1, 0, 0, 0]
9 [5, 2, 1, 0, 0, 1, 0, 0, 0]
10 [6, 2, 1, 0, 0, 0, 1, 0, 0, 0]
11 [7, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0]
12 [8, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]
13 [9, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
14 [10, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
15 [11, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
16 [12, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
17 [13, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
18 [14, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
19 [15, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
20 [16, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
21 [17, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
22 [18, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
23 [19, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
24 [20, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
25 [21, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
26 [22, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
27 [23, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
28 [24, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
29 [25, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
30 [26, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

처음 세 개의 목록을 제외하고 [1, 2, 1, 0], [2, 0, 2, 0], [2, 1, 2, 0, 0]각 길이의 목록은 정확히 하나이며 n>6형식이 [n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]있습니다. 이 패턴은 적어도 지속됩니다 n=50. 나는 그것이 영원히 보유하고 있다고 생각하는데,이 경우 엄청난 수의 결과를 출력하는 것은 사소한 일입니다. 그렇지 않더라도 가능한 솔루션에 대한 수학적 이해는 검색 속도를 크게 향상시킵니다.


@Ypnypn 특별한 경우가 n=0있습니다. n카운트 업하지 않고 단일 결과를 반환하는 것을 놓쳤 습니다 n. 이것은 나를 최대로 가져옵니다 n=40.
xnor

0

Pyth-15 바이트

가능한 모든 len 순서의 n필터에 의해 무차별 대입을 사용 합니다.

f.A.eq/TkYT^UQQ

자세한 설명은 곧 제공 될 예정입니다.

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


2
참고로 OP는 승리 기준을 가장 빠른 코드로 변경했습니다.
Alex A.

2
우승 기준에 관계없이 다음은 3 바이트 골프입니다.`fqm / TdQT ^ UQQ`
Jakube

0

K, 26 바이트

{f@&{x~(+/x=)'!#x}'f:!x#x}

Maltysen의 접근 방식과 마찬가지로 무차별 대입. 프로그램의 핵심은 주어진 벡터가 "매직"인지 테스트하는 술어입니다.

{x~(+/x=)'!#x}

입력 벡터 ( !#x) 만큼 iota 벡터를 만들고 각 숫자의 발생 횟수를 세고 ( (+/x=)') 결과를 입력 벡터 ( x~) 와 비교하십시오 . 일치하는 항목이 있으면 마술 순서입니다.

불행하게도,이 첫 번째 찌르기는 꽤 느리게 보입니다. 랩톱에서 Kona를 사용하여 테스트하면 n = 7을 처리하는 데 약 12 ​​초가 걸립니다. 나는 이것을 조금 더 생각할 필요가있다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.