하나의 시퀀스 만들기


12

이 시퀀스에서 연속 된 두 숫자의 차이가 -1 또는 1이고 첫 번째 요소가 0 인 경우 정수 시퀀스는 1 시퀀스입니다.

보다 정확하게는 다음과 같은 경우 a1, a2, ..., a는 하나의 순서입니다.

For any k (1 ≤  k < n): |a[k] - a[k+1]|=1, 
a[1]=0

입력

  • n -시퀀스의 요소 수
  • s -시퀀스의 요소 합

산출

  • 가능한 경우, n요소의 합을 가지는 길이의 1 순서 세트 /리스트 / 배열 / 등s
  • 가능하지 않은 경우 빈 세트 / 목록 / 배열 등

입력의 8 4경우 출력은 [0 1 2 1 0 -1 0 1]또는 일 수 있습니다 [0 -1 0 1 0 1 2 1]. 다른 가능성이있을 수 있습니다.

입력의 3 5경우 출력을 []수행 할 수 없으므로 출력이 비어 있습니다.

규칙

이것은 코드 골프이며 바이트 단위의 최단 답변입니다. 제출물은 프로그램 또는 기능이어야합니다. 입력 / 출력은 표준 방법 중 하나로 제공 될 수 있습니다 .


그건 그렇고, 나는 길이 l의 한 시퀀스로 표현할 수있는 모든 숫자가 사이에 (l-1)*l/2있고와 -(l-1)*l/2동일한 패리티를 갖는 모든 숫자라는 증거 를 가지고 있습니다 (l-1)*l/2.
자랑스런 Haskeller

이것은 하나의 시퀀스 원하는 있도록 효율적인 알고리즘 (O (N))하기 위해 사용될 수있다
자랑 haskeller

답변:


7

CJam, 56 47 44 34 바이트

여기에는 개선의 여지가 많지만 여기에 첫 번째 시도가 있습니다.

L0aa{{[~_(]_)2++}%}l~:N;(*{:+N=}=p

효율적인 작업 수행 방법으로 Dennis에게 감사의 뜻을 전합니다 { ... }%.

가능하면 배열 표현을 인쇄합니다. 그렇지 않으면 ""

여기에서 온라인으로 사용해보십시오


혼란 스러워요 : {}%코드 의 일부는 내 것과 비슷합니다 (@PeterTaylor의 코드이며 점을 밑줄로 바꿉니다). 내가 당신의 코드에 무엇이든 기여했다면, 그것은 {}=운영자입니다.
Dennis

나는 처음에 _{_W=)+}%\{_W=(+}%+두 개의 사본을 만들고 처음 에 1을 더하고 다른 것에서 1을 뺀 것을 가지고있었습니다 . 귀하의 예를 통해 한 { ... }%블록 에서 그 방법을 알아 냈습니다 . 에 관해서 { ... }=는 아직 게시하지는 않았지만 실험에서 이미 많이 줄였습니다.
Optimizer

나는 주어진 입력하는 질문에서 이해 3 5출력이해야 []하지""
피터 테일러

1
@PeterTaylor "가능한 경우 빈 세트 / 목록 / 배열 / 등"-그래서 나는 그것을 명확히해야한다고 생각합니다.
Optimizer

또한 []pCJam 에서는 로 출력됩니다 "". 언어가 빈 배열을 나타내는 방식입니다.
Optimizer

6

자바 스크립트 (E6) 79 82

F=(n,t,
  d=n+n*~-n/4-t/2,
  l=1,
  q=[for(x of Array(n))d<n--?++l:(d+=~n,--l)]
)=>d?[]:q

모든 튜플을 무차별 적으로 열거하거나 열거 할 필요가 없습니다.

n -1 단계 로 길이 n 의 시퀀스를 참조 하십시오. 각 단계는 증가 또는 감소합니다. 감소에 대해서만 증분을 교환 할 수 있으며 합계는 2 씩 변하므로 주어진 길이에 대해 합계는 항상 짝수이거나 항상 홀수입니다. 모든 증분이 있으면 시퀀스는 0, 1, 2, 3, ..., n-1이고 합은 (n-1) * n / 2임을 알 수 있습니다 . 마지막 단계를 변경하면 합은 2 씩 변경되므로 마지막 단계의 무게는 2입니다. 마지막 단계 의 다음 단계를 변경하면 합계가 4 씩 변경되므로 마지막 단계의 무게는 4입니다. 이는 연속 단계가 지금까지 부분 합계를 기반으로하기 때문입니다. 이전 단계를 변경하면 합계가 6 씩 변경되므로 마지막 단계의 무게는 6입니다 (8이 아니라 이진수가 아님). ... 첫 단계 변경 무게 (n-1) * 2






연산

Find the max sum (all increments)  
Find the difference with the target sum (if it's not even, no solution)  
Seq[0] is 0  
For each step  
  Compare current difference with the step weight
  if is less 
     we have an increment here, seq[i] = seq[i-1]+1 
  else 
     we have a decrement here, seq[i] = seq[i-1]-1.  
     Subtract we current weight from the current diff.
If remaining diff == 0, solution is Seq[]. Else no solution

Ungolfed 코드

F=(len,target)=>{
  max=(len-1)*len/2
  delta = max-target
  seq = [last=0]
  sum = 0
  weight=(len-1)*2
  while (--len > 0)
  {
    if (delta >= weight)
    {
      --last
      delta -= weight;
    }
    else
    {
      ++last
    }  
    sum += last
    seq.push(last);
    weight -= 2;
  }  
  if (delta) return [];
  console.log(sum) // to verify

  return seq
}

Firefox / FireBug 콘솔에서 테스트

F(8,4)

산출

[0, -1, 0, -1, 0, 1, 2, 3]

5

GolfScript ( 41 39 바이트)

[][1,]@~:^;({{.-1=(+.)))+}%}*{{+}*^=}?`

온라인 데모

41-> 39의 Dennis 에게 감사합니다 .


을 (를) 단축 ,0=할 수 있습니다 ?. CJam에 대한 간단한 포트는 5 바이트가 짧습니다.L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Dennis

@Dennis oooh, 두 개의 {} % 블록을 타는 편리한 방법입니다. 내가 사용하면 마음?
Optimizer

@Optimizer : 나는하지 않지만 실제로는 내 일이 아닙니다.
Dennis

나는 { ... }%블록 에 대해 이야기하고있었습니다 . 내 코드에는 두 개가 있었고 그것을 1로 줄이려고했습니다. 실제 알고리즘이 진행되는 것처럼 Peter와 나는 같은 알고리즘을 거의 동시에 게시했다고 생각합니다.
Optimizer

3

수학, 73 바이트

f=FirstCase[{0}~Join~Accumulate@#&/@Tuples[{-1,1},#-1],l_/;Tr@l==#2,{}]&;

간단한 무차별 대입 솔루션.

모든 단계를 선택하고 있습니다. 그런 다음 그것들을 누적 된 목록으로 바꾸어 하나의 시퀀스를 얻습니다. 그런 다음 합계가 두 번째 매개 변수와 같은 첫 번째 것을 찾고 있습니다. 없는 경우 기본값은 {}입니다.


Mathematica는 수학 / 조합 관련 문제를 해결하기 위해 노력하고 있습니다. ;)
Optimizer

@Optimizer 그럼에도 불구하고 CJam이 이길 것이라고 확신합니다. ;) 사실이 같은 알고리즘은 CJam에서 어렵지 않아야합니다.
Martin Ender

1
메서드 이름이 짧기 때문에 확실히 이길 것입니다. 알고리즘은 간단하지 않습니다.
Optimizer

@ 옵티 마이저? 이 함수 구성보다 간단한 루프 및 필터를 사용하는 것이 더 간단하다고 생각합니다.
피터 테일러

3

하스켈, 56 바이트

n%s=[x|x<-scanl(+)0`map`mapM(\_->[1,-1])[2..n],s==sum x]

설명:

  • 1,-1길이 n-1 의 순열을 사용하여 목록을 작성하십시오 . replicateM n-1[-1,1]
    예 : replicateM 2 [-1,1]==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • 그것으로부터 하나의 순서를 만드십시오. scanl성능이 좋지 않지만 여기에서 올바른 작업을 수행합니다.
  • n합계가 있는 길이 로 가능한 모든 시퀀스를 필터링합니다.s

1
간단한 개선은 a를 infix 함수로 변경하는 것입니다. 다음은보다 직관적 인 개선을위한 힌트 Control.Monad입니다. 사용하기위한 가져 오기 replicateM가 이미 너무 깁니다. 다른 어떤 모나 딕 함수를 사용하여 시뮬레이션 할 수 replicateM있습니까?
자랑스런 Haskeller

그건 그렇고, 당신은 하나의 솔루션 만 반환해야하므로 솔루션에 추가 head$해야합니다.
자랑스런 Haskeller

head[]대한 반환하지 않습니다 [] :: [[a]]-그리고 나는 오류가 싫어.
Johannes Kuhn

1
시간이 지났기 때문에 내가 의미하는 바를 알려 드리겠습니다. 및 mapM(\x->[1,-1])[2..n]대신에 사용할 수 있습니다 . sequencereplicate
자랑스러운 haskeller

흥미 롭군 즉, 심지어 짧은 : P
요하네스 쿤

2

파이썬, 138

from itertools import*
def f(n,s):
 for i in[list(accumulate(x))for x in product([-1,1],repeat=n-1)]:
  if sum(i)==s:return[0]+i
 return[]

0

CJam, 65 58 54 바이트

내 Mathematica 솔루션보다 약간 짧지 만 여전히 CJam을 올바르게 사용하지 않는 것은 내 잘못입니다.

0]]l~:S;({{_1+\W+}%}*{0\{+_}%);}%_{:+S=}#_@\i=\0>\[]?p

문자 그대로 동일한 알고리즘 n-1입니다 {1, -1}.의 모든 튜플을 가져옵니다 . 누적이와 (과 s) 같은 첫 번째 것을 찾으십시오 0. 빈 배열이 없으면 인쇄하십시오.


0

CJam, 40

CJam의 또 다른 접근법.

ri,W%)\_:+ri-\{2*:T1$>1{T-W}?2$+\}/])!*p

0

루비 (136)

def one_sequences(n)
  n.to_s.chars.map(&:to_i).each_cons(2).to_a.select{|x|x[0] == 0 && (x[1] == 1 || x[1]
  == -1)}.count
end

0

J, 47 자

다른 많은 답변과 마찬가지로 모든 시퀀스를 확인합니다. 더 짧은 O (n) 솔루션을 만들려고합니다.

   f=.4 :'(<:@#}.])(|:#~y=+/)+/\0,|:<:2*#:i.2^<:x'

   8 f 4
0 1 2 1 0 1 0 _1

   3 f 5
[nothing]

0

APL 38

{⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}

예:

     4 {⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}8
0 1 2 1 0 1 0 ¯1

이것은 많은 다른 사람들이 모든 조합을 통해 무차별적인 힘을 발휘하여 발견되지 않으면 아무 것도 반환하지 않는 일치하는 것을 찾습니다. 실제로 코드를 짧게 만들기 위해 몇 가지 조합을 두 번 이상 시도합니다.

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