Drop of Chaos (Xây dựng chuỗi tuần hoàn tối thiểu)


9

Ý tưởng ở đây là sản xuất một mô hình gần như lặp lại. Đó là, trình tự đang được xây dựng thay đổi vào thời điểm cuối cùng để tránh sự lặp lại của một số sau đó. Phải tránh các hậu quả của loại AA và ABA (trong đó B không dài hơn A).

Ví dụ:

Tôi sẽ tiếp tục và bắt đầu bằng cách liệt kê tất cả các ví dụ nhỏ để làm cho mô tả của tôi rõ ràng hơn. Hãy bắt đầu với 0.

Hợp lệ: 0

Không hợp lệ: 00 (mẫu AA)
Hợp lệ: 01

Không hợp lệ: 010 (mẫu ABA)
Không hợp lệ: 011 (mẫu AA)
Hợp lệ: 012

Hợp lệ: 0120
Không hợp lệ: 0121 (mẫu ABA)
Không hợp lệ: 0122 (mẫu AA)

Không hợp lệ: 01200 (mẫu AA)
Không hợp lệ: 01201 (mẫu ABA; 01-2-01)
Không hợp lệ: 01202 (mẫu ABA)
Hợp lệ: 01203

Bây giờ, tôi tin tưởng mạnh mẽ rằng 4không bao giờ cần thiết, mặc dù tôi không có bằng chứng, bởi vì tôi đã dễ dàng tìm thấy chuỗi hàng trăm ký tự chỉ sử dụng 0123. (Có lẽ nó liên quan chặt chẽ đến việc chỉ cần ba ký tự để có các chuỗi vô hạn không có bất kỳ mẫu AA nào. Có một trang Wikipedia về điều này.)

Đầu ra đầu vào

Đầu vào là một số nguyên duy nhất, dương, khác không n. Bạn có thể cho rằng n <= 1000.

Đầu ra là một nchuỗi -character không có chuỗi con nào khớp với mẫu bị cấm (AA hoặc ABA).

Đầu vào và đầu ra mẫu

>>> 1
0

>>> 2
01

>>> 3
012

>>> 4
0120

>>> 5
01203

>>> 50
01203102130123103201302103120132102301203102132012

Quy tắc

  • Chỉ 0123cho phép các nhân vật .
  • B không dài hơn A. Điều này là để tránh tình huống 012345phải theo sau bởi 60123451có : 1-2345-1. Nói cách khác, trình tự sẽ là tầm thường và không thú vị.
  • ncó thể được nhập thông qua bất kỳ phương pháp nào mong muốn, ngoại trừ mã hóa cứng.
  • Đầu ra có thể là một danh sách hoặc một chuỗi, tùy thuộc vào cái nào dễ hơn.
  • Không có lực lượng vũ phu ; thời gian chạy nên theo thứ tự phút, nhiều nhất là một giờ trên máy thực sự chậm n=1000. (Điều này nhằm loại bỏ các giải pháp chỉ lặp qua các nhoán vị toàn phần {0,1,2,3}, do đó, mánh khóe và các thủ thuật tương tự không được phép.)
  • Các sơ hở tiêu chuẩn không được phép, như thường lệ.
  • Ghi điểm được tính bằng byte. Đây là , vì vậy bài dự thi ngắn nhất sẽ thắng (có thể - xem phần thưởng).
  • Tiền thưởng: chọn chữ số thấp nhất được phép ở mỗi bước. Nếu 13là các lựa chọn có thể cho chữ số tiếp theo trong chuỗi, hãy chọn 1. Trừ 5 byte từ điểm số của bạn. Tuy nhiên, hãy lưu ý các lưu ý dưới đây.

Ghi chú!

Kết thúc là có thể. Chương trình hoặc chức năng của bạn phải tránh những điều này. Đây là một ví dụ:

Stump: 012031021301011010010130210312013232
Stump: 012031021301011010010130210312013232
Stump: 0120310213012310320130210301
Stump: 012031021301011010010130210312013232

Mỗi chuỗi này không thể được mở rộng thêm nữa (không sử dụng a 4). Nhưng cũng lưu ý rằng có một sự khác biệt quan trọng giữa hai đầu tiên và hai thứ hai. Tôi sẽ thay thế phần tiếp theo ban đầu được chia sẻ bằng một Xđể làm cho điều này rõ ràng hơn.

Gốc cây: X2130120
Gốc cây: X2130123
Gốc cây: X320
Gốc cây: X321301203102130

Hai chữ số cuối cùng X10, vì vậy các lựa chọn khả dĩ duy nhất cho chữ số tiếp theo là 23. Lựa chọn 2dẫn đến một tình huống trong đó trình tự phải chấm dứt. Thuật toán tham lam sẽ không hoạt động ở đây. (Dù sao, không phải không quay lại.)


Người ta có thể sử dụng chiến lược vũ phu để kiểm tra mọi chuỗi có thể, ngay cả khi nó không cho đầu ra trong thời gian thực không? Bạn có biết có một giải pháp cho tất cả n? Nếu ai đó đưa ra một thuật toán bán tham lam heuristic, làm thế nào bạn sẽ kiểm tra xem nó không gặp vấn đề trong một thời gian rất lớn? Vấn đề chung là một vấn đề thú vị và tôi không thể tìm thấy bất cứ điều gì về việc tránh mẫu mà chúng tôi giới hạn độ dài của một phần của mẫu. Nếu ai đó có thể tạo ra một công thức chung, tôi hy vọng đó là cách tiếp cận tốt nhất.
xnor

Tôi tin rằng tôi không cho phép vũ phu trong các quy tắc. Tôi có lẽ nên làm nổi bật điều đó. Tôi không có bằng chứng cho thấy có tồn tại một giải pháp cho tất cả n, nhưng cho rằng các gốc cây mà chương trình của tôi tìm thấy có xu hướng dài hơn trung bình 10 chữ số mỗi lần, tôi rất chắc chắn rằng một chuỗi vô hạn tồn tại. Tôi không chắc làm thế nào một thuật toán nửa tham lam có thể được kiểm tra cho các chuỗi lớn tùy ý. Tôi có thể hạn chế các yêu cầu để n= 1000 và chỉ không lo lắng về cao n.
El'endia Starman

4
Tôi cho rằng AAthực sự gõ ABAnơi Btrống. Điều này có lẽ có thể giúp hợp lý hóa một số giải pháp.
mathmandan

Câu trả lời:


6

Võng mạc , 86 byte - 5 = 81

$
_
(r`^(?<-2>.)+_((.)+)\b$
$1!
\b$
0
3#
#
0#
1
1#
2
2#
3
)r`\1(?<-2>.)*((.)+)$
$0#
!
<empty>

Trường hợp <empty>đại diện cho một dòng dấu trống. Bạn có thể chạy mã trên từ một tệp duy nhất có -scờ.

Đầu vào nên được đưa ra trong unary , ví dụ 111111. Tôi đã không kiểm tra nó cho đầu ra theo thứ tự hàng ngàn - hai trong số các regex có thể hơi chậm sau một thời gian - nhưng nó có thể dễ dàng xử lý vài trăm trong vài giây.

Giải trình

Đây là một giải pháp quay lui đơn giản.

  1. Nối a 0.
  2. Mặc dù trình tự hiện tại không hợp lệ, hãy xóa tất cả các dấu 3 và tăng số không cuối cùng 3.
  3. Lặp lại cho đến khi chúng ta có một chuỗi hợp lệ của độ dài mong muốn.

Việc quay lại này được thực hiện bằng một vòng lặp thay thế regex sẽ hủy bỏ khi chuỗi không thay đổi qua một lần lặp.

$
_

Điều này nối thêm một _đầu vào, được sử dụng để tách đầu vào đơn nguyên khỏi chuỗi chúng ta đang xây dựng.

(r`^(?<-2>.)+_((.)+)\b$
$1!

Đây là sự thay thế đầu tiên trong vòng lặp (được chỉ định bởi hàng đầu (). Regex khớp với nếu a) có một ký tự từ (nghĩa là một chữ số) ở cuối chuỗi (có nghĩa là chuỗi hợp lệ - chúng ta sẽ thấy bên dưới các chuỗi không hợp lệ được đánh dấu bằng một dấu #) và b) có ít nhất có nhiều ký tự trong chuỗi như trong đầu vào (điều này được kiểm tra bằng cách sử dụng các nhóm cân bằng ). Nếu đó là trường hợp, chúng tôi loại bỏ đầu vào và nối thêm a !. Điều này !phục vụ để làm cho tất cả các biểu thức trong vòng lặp thất bại, do đó nó chấm dứt.

\b$
0

Nếu có một ký tự từ ở cuối (nghĩa là chuỗi hợp lệ và vòng lặp không bị chấm dứt bởi bước trước đó), hãy nối thêm a 0.

3#
#

Nếu (thay vào đó) chuỗi đã được đánh dấu không hợp lệ và kết thúc 3, chúng tôi sẽ xóa 3chuỗi đó (nhưng để lại chuỗi đó là không hợp lệ, vì không có khả năng tiếp tục cho tiền tố hiện tại ... vì vậy ký tự tiếp theo cũng cần được quay lại).

0#
1
1#
2
2#
3

Nếu dãy được đánh dấu không hợp lệ và bất kỳ chữ số nào khác 3ở cuối, chúng tôi sẽ tăng chữ số và xóa điểm đánh dấu.

)r`\1(?<-2>.)*((.)+)$
$0#

Sự thay thế cuối cùng trong vòng lặp (như được chỉ định bởi )). Nó kiểm tra xem chuỗi kết thúc ở ABAđâu (nơi Bkhông dài hơn Anhưng có khả năng trống). Độ dài tương đối ABđược kiểm tra lại bằng cách sử dụng các nhóm cân bằng và sự lặp lại của Ađược kiểm tra với độ phản hồi đơn giản.

Nếu regex này khớp, chúng tôi đánh dấu chuỗi không hợp lệ bằng cách nối thêm #.

!
<empty>

Khi vòng lặp kết thúc, tất cả những gì chúng ta cần làm là loại bỏ !và sau đó được để lại với đầu ra mong muốn.


2

Python 2, 175 - 5 = 170 byte

n=input();s='';u=j=-1
while n>len(s):
 while u>2:u=int(s[0]);s=s[1:]
 u+=1;t=`u`+s;m=c=0
 while t[c:]*0**m:c+=1;i=t[c:].find(t[:c]);m=j<i<=c
 if c>=len(t):s=t;u=j
print s[::j]

Đây là thuật toán tham lam với quay lui. Tôi ước nó ngắn hơn. Tôi hy vọng nó đúng (xem bên dưới).

Nó xây dựng chuỗi một chữ số tại một thời điểm. Với một chuỗi các dchữ số mà nó đã tìm thấy rồi, nó cố gắng để nối thêm một 0như các (d+1)chữ số st. Nếu nó không hoạt động, thì nó cố gắng a 1, sau đó a 2, sau đó a 3. Nếu không có cái nào trong số này hoạt động, thì nó sẽ quay trở lại dchữ số thứ và tăng nó (nếu nhỏ hơn 3) hoặc loại bỏ nó (nếu bằng 3, trong trường hợp đó, nó sẽ tăng số trước đó, v.v.).

Kiểm tra tính hợp lệ là dòng có .findtrong đó. Trong trường hợp bất kỳ ai quyết định đọc mã của tôi, tôi nên nói rằng chương trình này thực sự đang lưu trữ chuỗi ngược, nghĩa là nó thêm chữ số vào phía trước . Vì vậy, kiểm tra liên quan đến việc tìm kiếm các vị trí mà các chữ số đầu tiên c xuất hiện lại sau đó trong chuỗi (bất kỳ vị trí nào sau các cchữ số đầu tiên ) và nếu có bất kỳ vị trí nào như vậy, liệu độ dài can thiệp có nhiều nhất hay không c.

(Tất nhiên nó đảo ngược chuỗi trước khi in.)

Nó cũng có thể dễ dàng nhanh hơn; Ban đầu tôi đã có nó thoát khỏi các vòng lặp khác nhau sớm để đạt hiệu quả, nhưng chi phí đó là các byte quý giá. n=1000Mặc dù vậy, nó vẫn ổn trong phạm vi .

Dù sao, chương trình dường như thể hiện một ưu tiên cho các chữ số nhỏ hơn, nhưng nó không phải là một ưu tiên rất mạnh. Ví dụ, chạy nó với n=2000cho tôi một chuỗi với 523số không, số 502một, 497twos và 478threes, kết thúc bằng 30210312013021. Vì vậy, nếu bất cứ ai khác đang làm việc trên một thuật toán tham lam, có lẽ họ có thể xác nhận kết quả này. Hoặc với n=1000tôi đã [263, 251, 248, 238]cho số đếm bằng chữ số.

Cuối cùng, tôi sẽ đề cập rằng các số đếm này là loại gợi ý về tính đối xứng, gần như (mặc dù không chính xác) như thể chúng ta đã bắt đầu với một phân phối thống nhất và sau đó chuyển đổi một số 3'thành 0' và một vài trong số 2'thành 1' S. Nhưng rõ ràng đó chỉ có thể là sự trùng hợp. Tôi không có ý kiến!


1

Haskell, 115 (120 byte - 5 phần thưởng)

x?_|or[t x==t(drop i x)|i<-[1..length x],t<-[take$div(i+1)2]]=[]
x?0=[x]
x?n=(?(n-1)).(:x)=<<"0123"
f=reverse.head.([]?)

Chạy trực tuyến tại Ideone

Chạy ví dụ:

*Main> f 40
"0120310213012310320130210312013210230120"
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.