Tạo một chuỗi


12

Một dãy số nguyên là một chuỗi nếu chênh lệch giữa hai số liên tiếp bất kỳ trong dãy này là -1 hoặc 1 và phần tử đầu tiên của nó là 0.

Chính xác hơn: a1, a2, ..., an là một chuỗi nếu:

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

Đầu vào

  • n - số phần tử trong chuỗi
  • s - tổng các phần tử trong chuỗi

Đầu ra

  • một tập hợp một chuỗi / danh sách / mảng / vv có độ dài nbằng tổng các phần tử s, nếu có thể
  • một tập hợp / danh sách / mảng / vv trống nếu không thể

Ví dụ

Đối với đầu vào 8 4, đầu ra có thể [0 1 2 1 0 -1 0 1]hoặc [0 -1 0 1 0 1 2 1]. Có thể có những khả năng khác.

Đối với đầu vào 3 5, đầu ra là trống [], vì nó không thể được thực hiện.

Quy tắc

Đây là một mã golf, câu trả lời ngắn nhất trong byte thắng. Đệ trình nên là một chương trình hoặc chức năng. Đầu vào / đầu ra có thể được đưa ra theo bất kỳ cách tiêu chuẩn nào .


Nhân tiện, tôi có một bằng chứng rằng tất cả các số có thể biểu diễn dưới dạng một chuỗi có độ dài l là tất cả các số giữa (l-1)*l/2-(l-1)*l/2có cùng mức tương đương với (l-1)*l/2.
tự hào

điều này có thể được sử dụng để tạo ra một thuật toán hiệu quả (O (n)) để tạo ra một chuỗi mong muốn
tự hào

Câu trả lời:


7

CJam, 56 47 44 34 byte

Rất nhiều phạm vi để cải thiện ở đây, nhưng đây là nỗ lực đầu tiên ở đây:

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

Tín dụng cho Dennis cho cách làm hiệu quả của { ... }%phần này.

In đại diện mảng nếu có thể, nếu không ""

Dùng thử trực tuyến tại đây


Tôi bối rối: Phần {}%mã của bạn trông không giống mã của tôi (chỉ là mã của @ PeterTaylor, thay thế dấu chấm bằng dấu gạch dưới). Nếu tôi đóng góp bất cứ điều gì vào mã của bạn, thì đó là {}=nhà điều hành ...
Dennis

Ban đầu tôi đã _{_W=)+}%\{_W=(+}%+có lần đầu tiên tạo hai bản sao, thêm 1 vào bản đầu tiên, trừ đi 1 bản khác. Ví dụ của bạn khiến tôi tìm ra cách để làm điều đó trong một { ... }%khối. Về việc { ... }=, tôi đã giảm nó rất nhiều trong thử nghiệm của mình, mặc dù chưa được đăng.
Trình tối ưu hóa

Tôi hiểu từ câu hỏi đưa ra đầu vào 3 5nên []và không""
Peter Taylor

1
@PeterTaylor "một tập hợp / danh sách / mảng / etc trống nếu không thể" - Vì vậy, tôi nghĩ rằng tôi chỉ cần làm cho nó rõ ràng ...
Trình tối ưu hóa

Thêm vào đó, []ptrong CJam chỉ cần xuất ra "". Vì vậy, làm thế nào ngôn ngữ đại diện cho mảng trống.
Trình tối ưu hóa

6

JavaScript (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

Không cần lực lượng vũ phu hoặc liệt kê của tất cả các bộ dữ liệu.

Xem một chuỗi có độ dài nn -1 bước, mỗi bước là tăng hoặc giảm.
Lưu ý, bạn chỉ có thể hoán đổi số gia tăng cho một số giảm, tổng thay đổi 2, vì vậy với bất kỳ độ dài nào, tổng luôn luôn là số chẵn hoặc luôn là số lẻ.
Có tất cả các số gia, chuỗi là 0, 1, 2, 3, ..., n-1 và chúng tôi biết tổng là (n-1) * n / 2
Thay đổi bước cuối cùng, tổng thay đổi 2, vì vậy Bước cuối cùng nặng 2.
Thay đổi bước tiếp theo đến bước cuối cùng, tổng thay đổi bằng 4, vì vậy bước cuối cùng nặng 4. Đó là vì bước kế tiếp được xây dựng dựa trên tổng một phần cho đến nay.
Thay đổi bước trước, tổng thay đổi bằng 6, vì vậy bước cuối cùng nặng 6 (không phải 8, không phải là số nhị phân).
...
Thay đổi bước đầu tiên cân (n-1) * 2

Thuật toán

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

Mã mã

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
}

Kiểm tra trong bảng điều khiển Firefox / FireBug

F(8,4)

Đầu ra

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

5

GolfScript ( 41 39 byte)

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

Bản demo trực tuyến

Cảm ơn Dennis vì 41-> 39.


Bạn có thể rút ngắn ,0=để ?. Một cổng đơn giản đến CJam sẽ ngắn hơn 5 byte:L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Dennis

@Dennis oooh, đó là cách thuận tiện để có được hai khối {}%. Tâm trí nếu tôi sử dụng nó?
Trình tối ưu hóa

@Optimizer: Tôi không, nhưng đó không thực sự là công việc của tôi.
Dennis

Tôi đã nói về { ... }%khối. Trong mã của tôi, tôi có hai cái, đang cố gắng giảm nó xuống còn 1. Như thuật toán thực sự, tôi nghĩ cả Peter và tôi đều đăng cùng một thuật toán gần như cùng một lúc.
Trình tối ưu hóa

3

Toán học, 73 byte

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

Giải pháp vũ phu đơn giản.

Tôi đang tạo ra tất cả các lựa chọn của các bước. Sau đó, tôi biến chúng thành các danh sách tích lũy để có được một chuỗi. Và sau đó tôi đang tìm kiếm cái đầu tiên có tổng bằng với tham số thứ hai. Nếu không có, giá trị mặc định là {}.


Mathematica chỉ chiếu sáng các vấn đề liên quan đến toán học / kết hợp, phải không? ;)
Trình tối ưu hóa

@Optimizer Tôi chắc chắn rằng CJam sẽ đánh bại nó. ;) Trên thực tế, thuật toán tương tự này không khó thực hiện trong CJam.
Martin Ender

1
Nó chắc chắn sẽ đánh bại nó, nhưng chỉ vì tên phương thức ngắn. Thuật toán sẽ không đơn giản như trước.
Trình tối ưu hóa

@Optimizer hả? Tôi nghĩ rằng nó đơn giản hơn với một vòng lặp và bộ lọc đơn giản hơn thành phần chức năng này.
Peter Taylor

3

Haskell, 56 byte

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

Giải trình:

  • Xây dựng danh sách với các hoán vị 1,-1và độ dài n-1: replicateM n-1[-1,1]
    Ví dụ:replicateM 2 [-1,1] ==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • Xây dựng một chuỗi trong số đó. scanlcó hiệu suất kém, nhưng nó làm đúng công việc ở đây.
  • Lọc tất cả các chuỗi có thể có độ dài ntrong đó tổng làs

1
một cải tiến đơn giản là thay đổi một hàm thành hàm. đây là một gợi ý cho một cải tiến không trực quan hơn: nhập Control.Monadchỉ để sử dụng replicateMđã quá lâu. bạn có thể sử dụng chức năng đơn âm nào khác để mô phỏng replicateM?
tự hào

Nhân tiện, bạn chỉ nên trả lại một giải pháp, vì vậy bạn nên thêm head$vào giải pháp của mình.
tự hào

headkhông trả lại []cho [] :: [[a]]- và tôi ghét lỗi.
Julian Kuhn

1
bởi vì một thời gian đã trôi qua, tôi sẽ nói cho bạn biết ý của tôi Bạn có thể sử dụng mapM(\x->[1,-1])[2..n]thay vì sequencereplicate.
tự hào

Hấp dẫn. Điều đó thậm chí còn ngắn hơn: P
Johannes Kuhn

2

Con trăn, 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 byte

Ngắn hơn so với giải pháp Mathicala của tôi, nhưng đó hầu hết là lỗi của tôi vì vẫn không sử dụng CJam đúng cách:

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

Đó thực sự là cùng một thuật toán: có được tất cả các n-1phần của {1, -1}. Tìm cái đầu tiên có tích lũy giống như s, trả trước a 0. In một mảng trống nếu không tìm thấy.



0

Hồng ngọc (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 ký tự

Kiểm tra mọi trình tự như nhiều câu trả lời khác. Sẽ cố gắng thực hiện một giải pháp O (n) ngắn hơ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*⍵),⊂⍬}

Thí dụ:

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

Điều này cũng như nhiều người khác chỉ cần vũ phu thông qua mọi sự kết hợp để tìm ra một kết hợp phù hợp, nếu không tìm thấy sẽ trả về không có gì. Trên thực tế, nó cố gắng một số kết hợp nhiều lần để làm cho mã ngắn hơn.

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.