Skolem 시퀀스 생성


10

스코 렘 시퀀스

Skolem 서열 의 서열이다 2n모든 숫자 번호 i사이 1그리고 n정확히 두 번 발생하고, 두 발생 사이의 거리를 i정확히 i단계. Skolem 시퀀스의 예는 다음과 같습니다.

1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5

다음 시퀀스는 Skolem 시퀀스가 아닙니다 .

1 2 1 2      (The distance between the 1's is 2, not 1)
3 1 1 3      (The number 2 is missing)
1 1 2 1 1 2  (There are four 1's)

객관적인

주어진 길이의 모든 Skolem 시퀀스 수를 계산하는 프로그램, 함수 또는 표현식을 작성하십시오. 보다 명확하게, 입력 값은 정수 n이고 출력값은 length의 Skolem 시퀀스 수입니다 2n. 이 순서에는 OEIS 항목이 있습니다. 의 경우 또는을 n = 0반환 할 수 있습니다 . 에서 시작하는 처음 몇 값 은010

0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768

규칙과 득점

이것은 코드 골프입니다. 출력 형식이 이유 내에서 느슨합니다.


궁금한 0, 1, 0, 0, 6...점이 있지만 질문에 무엇이 있습니까? 코드 스 니펫이라면 어떤 언어입니까?
PhiNotPi

2
왜 출력의 첫 번째 항목 0입니까? 0유효한 입력 으로 인정 하려면 출력은이어야합니다 1.
피터 테일러

1
일부 (내 코드 포함)에는 빈 시퀀스가 ​​없다고 생각합니다. 1이 기분이 좋아지면 돌려주십시오.
boothby 2016 년

2
모든 상황 에서 AFAIK는 하나의 빈 시퀀스 / null 객체 / 빈 세트 등 / 함수-/ 빈 세트 / 빈 그래프 / 그 밖의 다른 것이 있다고 가정합니다.
Bakuriu

1
@boothby, 방금 Knuth를 바보라고 했습니까?
피터 테일러

답변:


8

GolfScript, 48 46 자

:b,1,{)2\?){{.2$&!{.2$|@@}*.+.4b?<}do;;}+%}@/,

더 빠른 버전 ( 온라인 시도 )-합리적인 속도로 실행됩니다 (예 : n=8약 2 초 소요). 그리고 선택한 접근법은 실제로 문자가 거의 없습니다.

이 버전은 비트 마스크에서도 작동합니다. 가능한 결과 배열을 1 이상으로 빌드합니다 n=3.

1: 000011        000110 001100 011000 110000
2: 010111 101011 101110        011101 110101 111010

일부 결과 (예 : 000011)에는 두 가지 가능한 연속성이 있지만 다른 결과 (예 : 001100)에는 결과 배열에서 제거되지 않고 제거됩니다.

코드 설명 :

:b           # save the input into variable b for later use
,            # make the list 0..b-1 (the outer loop)
1,           # puts the list [0] on top of the stack - initially the only possible
             # combination
{)           # {...}@/ does the outer loop counting from i=1 to b
  2\?)       # computes the smalles possible bit mask m=2^i+1 with two bits set 
             # and distance of those equal to i (i.e. i=1: 11, i=2: 101, ...)
  {          # the next loop starts with this bitmask (prepended to code via
             # concatination {...}+
             # the loop itself iterates the top of the stack, i.e. at this point 
             # the result array                 
             # stack here contains item of result array (e.g. 00000011)
             # and bitmask (e.g. 00000101)
    {        # the inner-most loop tries all masks with the current item in the result set
      .2$&!  # do item and result set share not single bit? then - {...}*
      {
        .2$| # then generate the new entry by or-ing those two
        @@   # push it down on the stack (i.e. put working items to top)
      }*
      .+     # shift the bit mask left by one
      .4b?<  # if still in the range loop further
    }do;;    # removes the remainders of the loop (i.e. item processed and mask)
  }+%        # stack now contains the new result array
}@/
,            # length of result array, i.e. the number of Skolem sequences

더 빠른 묶음 솔루션 수용
boothby

6

J 식, 47 자

 +/*/"1((=&{:+.2-#@])#;.2)\"1~.(i.!+:y)A.,~>:i.y

예:

    y=:5
    +/*/"1((=&{:+.2-#@])#;.2)\"1~.(i.!+:y)A.,~>:i.y
10

y=:5내 컴퓨터에서 약 30 초가 걸립니다 .

알고리즘은 다음과 같이 느립니다.

  • ~.(i.!+:y)A.,~>:i.y모든 순열을 생성 1 2 .. y 1 2 .. y하고 중복 항목을 제거합니다.
  • ((=&{:+.2-#@])#;.2)\"1 계산 :
    • (...)\"1 모든 행의 모든 ​​접두사에 대해
      • #;.2 마지막 요소가 발생할 때마다 요소를 계산합니다.
      • #@] 카운트 수 (즉, 마지막 요소의 발생 횟수)
      • =&{: 카운트 목록과 원래 목록의 "평등" "마지막 요소"를 결정합니다.
      • +.논리 OR입니다. =&{:+.2-#@]"카운트 목록과 원본 목록의 마지막 요소가 같거나 [카운트 목록에] 두 개가 아닌 하나의 요소 만 있음"을 읽습니다.
  • */"1 조건 테이블의 행에 곱 (논리 AND)하여 Skolem 시퀀스 인 순열을 결정합니다.
  • +/ 1과 0을 합산합니다.

6

GolfScript (46 자)

:&1,\,{0,2@)?)2&*{2${1$^}%@+\2*}*;+}/{4&?(=},,

스택에서 입력을받는 표현식입니다. stdin에서 입력을받는 전체 프로그램으로 바꾸려면 prepend~

상당히 비효율적입니다. 골프를 타지 않은 56 문자에서 골프를 타면서 절약 한 대부분의 비용 절감은 잘못된 결과를 나타내지 않고 폐기물 계산을 수행하는 방식으로 루프 범위를 확장하는 것입니다.

이 방법은 데카르트 제품의 비트 단위 마스킹입니다. 예를 들어 n=4, ungolfed 코드에 대해 (마스크에 이진 사용) 는 직교 곱에있는 각 요소의 xor를 계산합니다 [00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]. 8 비트의 결과는 겹치지 않는 마스크로만 달성 할 수 있습니다.

속도가 아닌 크기를 최적화하기 위해이 코드는 부분 곱 ( S1 u S1xS2 u S1xS2xS3 ...)을 누적 하고 각 제품 을 실제로 유효한 시퀀스에 기여할 수 2n있는 요소가 아닌 요소로 만듭니다 2n-1-i.

속도

골프 버전은 n=5내 컴퓨터에서 10 초 동안, 5 분 이상 동안 실행됩니다 n=6. 원래 ungolfed 버전은 1 n=5초 이내에, n=6약 1 분 안에 계산 됩니다 . 중간 결과에 대한 간단한 필터를 사용하면 n=830 초 안에 계산할 수 있습니다 . 루프를 최대한 제한하고 중간 충돌을 필터링하는 동안 66 문자 (프로그램-식으로 65 문자)로 골프를 쳤습니다.

~:&1,\,{0,\).2\?)2&*@-{.{[\].~^.@~+<{;}*}+3$%@+\2*}*;\;}/{4&?(=},,

제길. 48char J 솔루션이 게시하기에 충분하다고 생각했을 때.
John Dvorak

제길. 47 자 넥타이는 오래 가지 못했습니다. +1
John Dvorak 2016 년

5

GolfScript, 49 자

~:/..+?:d(,{d+/base(;:w;/,{.w?)w>1$?=},,/=},,/1=+

nSTDIN 의 숫자 를 예상합니다 . 이것은 코드 골프입니다-5 n보다 큰 코드를 사용하지 마십시오 .


아야, 5보다 크지 않은가?
boothby

@boothby 첫 번째 직접 시도였습니다. 우리는 종종 결정 속도 대 크기를 가져와야하며 코드 골프는 크기에 관한 것입니다. 그래서 빠른 버전도 추가했습니다. 원래는 훨씬 길었지만 지금은 더 짧습니다.
Howard

0

세이지, 70

이것은 내 원본보다 약간 짧습니다.

sum(1for i in DLXCPP([(i-1,j,i+j)for i in[1..n]for j in[n..3*n-i-1]]))

작동 방식 :

0/1 행렬이 주어지면 해당 행렬의 정확한 표지 문제는 모든 1 벡터에 (정수로) 합되는 행의 하위 집합을 찾는 것입니다. 예를 들어

11001
10100
01001
00011
00010

해결책이있다

10100
01001
00010

문제에 대한 내가 가장 좋아하는 접근 방식은 문제를 정확한 표지 문제로 변환하는 것입니다. Skolem 시퀀스는이를 효율적으로 촉진합니다. 나는 솔루션이 길이의 Skolem 시퀀스로 bijection되는 정확한 커버 문제를 만듭니다 2n. 예를 들어, 문제의 행 n=6

  a   |  b  
001000|001001000000 # S[b] = S[b+a+1] = a

위치 1은 a < n기호 a가 사용됨을 의미합니다 . 나머지 위치는 시퀀스의 실제 위치에 해당합니다. 정확한 표지는 각 기호가 정확히 한 번 사용되고 각 위치가 정확히 한 번 채워지는 것에 해당합니다. 구성 k에 따라 위치의 모든 기호 k는 파트너와 떨어져 있습니다.

Sage에서는 DLXCPP"춤추는 링크"구현입니다. 이는 엄청나게 우아한 방식으로 정확한 표지 문제를 해결합니다. 그것은 내가 가장 좋아하는 알고리즘 중 하나이며 Sage의 표면에 있으면 조합 열거가 기쁨이됩니다.


와, 춤 링크. 사용 len(list(...))하면 4 문자가 절약됩니다.
Ray

@Ray len(list(...))n = 16으로 계산하면 내 컴퓨터는 단순히 죽을 것 입니다. 그리고 그것은 완전히 런타임을 죽일 것입니다.
boothby 2016 년

생성기를 목록으로 변환하는 데 많은 메모리가 필요하기 때문에 그렇습니다.
Ray
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.