Biểu diễn ngắn nhất của số Underload


13

Hương vị văn bản

Ngăn xếp dựa trên esolang không sắp xếp có một số mối quan hệ thú vị để lập trình chức năng. Một trong số đó là cách xử lý của kiểu dữ liệu số như tính toán lambda, bạn biểu diễn số tự nhiên N bằng một hàm thực hiện một hành động N lần.

Để làm cho mọi thứ đơn giản, chúng tôi sẽ chỉ xem xét tập hợp con sau của các lệnh Underload:

  • : - Lệnh này sao chép mục trên cùng trên ngăn xếp.
  • * - Lệnh này ghép hai mục trên cùng vào ngăn xếp thành một mục duy nhất.

Chúng tôi định nghĩa một số Underload N là một chuỗi :*khi được thực thi sẽ tiêu thụ mục trên cùng trên ngăn xếp và tạo ra N bản sao của mục đó được nối với nhau. Vài ví dụ:

  • Không có số dưới tải 0, -1, 1/2, π.
  • Chuỗi rỗng là số Underload 1, vì nó không để lại ngăn xếp.
  • :*là chữ số Underload 2, vì nó sao chép mục trên cùng và sau đó ghép hai bản sao đó lại với nhau thành một mục duy nhất: (A):*= (A)(A)*= (AA).
  • ::**là số Underload 3: (A)::**= (A)(A):**= (A)(AA)*= (AAA).
  • :::*** là số dưới 4.
  • :*:*cũng là số Underload 4: (A):*:*= (AA):*= (AA)(AA)*= (AAAA).

Nói chung, bạn sẽ thấy rằng, nếu MNlà các chữ số Underload M và N, thì đó :N*là chữ số N + 1 và MNlà chữ số M × N.

Các thách thức

Nhiệm vụ của bạn là viết chương trình ngắn nhất (lấy đầu vào trên STDIN) hoặc hàm (lấy đầu vào thông qua đối số) để tạo ra biểu diễn ngắn nhất của số Underload cho đầu vào dưới dạng chuỗi. Điều đó có nghĩa là, nếu đầu vào là số tự nhiên dương N> 1, bạn phải tạo ra một chữ số Underload N có độ dài bằng ký tự nhỏ hơn hoặc bằng với mọi chữ số Underload N khác.

Mẫu đầu vào và đầu ra: ("Đầu vào - OUTPUT.")

  • 1 - .
  • 2 - :*.
  • 5 - ::*:**(2 × 2 + 1).
  • 7 - ::*::***(2 × 3 + 1) hoặc :::**:**(3 × 2 + 1).
  • 33 - ::*:*:*:*:**(2 × 2 × 2 × 2 × 2 + 1).
  • 49 - ::*:*:*:*::***(16 × 3 + 1, dài 14) nhưng không ::*::***::*::***(7 × 7, dài 16).

Nếu đầu vào không phải là số tự nhiên dương, bạn có thể trả lại lỗi, tạo ra hành vi không xác định hoặc thậm chí không thể chấm dứt. Một lời giải thích về phương pháp tìm câu trả lời của bạn được đánh giá cao.

Hạn chế kẽ hở tiêu chuẩn áp dụng: không phải trả thêm đầu vào, không có yêu cầu web, giá trị sản lượng / lợi nhuận phải được chính xác câu trả lời và không phải là một dòng ngẫu nhiên vô hạn của :*vv


@Geobits Tôi đã không nói gì về thời gian thực hiện, miễn là bạn có thể chứng minh rằng cuối cùng họ sẽ trả lời đúng, bạn vẫn ổn.
thuật toán

2
Vấn đề này liên quan đến chuỗi bổ sung; cụ thể, độ dài của câu trả lời đúng cho đầu vào x2*A117498(x)nơi A117498 đưa ra sự kết hợp tối ưu giữa các phương pháp nhị phân và yếu tố để tìm chuỗi bổ sung.
Peter Taylor

Câu trả lời:


4

GolfScript ( 61 60 55 54 53 ký tự)

~:X'']({:A{.'.+'\*A{2$+}%~}%}*{,}${1\~X=}?{44/'*:'=}%

Đây là ít khó khăn hơn so với phiên bản trước của tôi và có một cách tiếp cận hơi khác, nhưng nó vẫn còn mạnh mẽ. Chúng tôi biết rằng đó ':'X*'*'X*+là một giải pháp ứng cử viên, vì vậy nếu chúng tôi tạo ra tất cả các chuỗi cân bằng tốt cho đến độ dài đó và lấy chuỗi ngắn nhất để đánh giá đúng thì chúng tôi có thể chắc chắn tìm thấy một chuỗi.

# Evaluate input and store the target number in X
~:X
# Seed the generator with the empty string
'']
# X times...
({
    # Store the array of strings so far into A
    :A
    # Generate A' by mapping each element
    {
        # Dup: this leaves an untouched copy of the current string
        .
        # Wrap the duplicate in .+
        '.+'\*
        # For each element in A, generate that element suffixed with the current string
        A{2$+}%~
    }%
}*
# Order by length
{,}$
# Find the first element which evaluates to X
{1\~X=}?
# tr .+ :*
{44/'*:'=}%

Cảm ơn Howard, từ giải pháp mà tôi đã đánh cắp một vài điều chỉnh 1 char.


Haha, một đầu vào 3 mất hơn ba giây để thực thi trên trình thông dịch web. Chơi golf tốt nhất của nó.
thuật toán

@alerskymshark, bạn có thể tăng tốc nó lên một chút với một điểm trùng lặp. Chèn .&ngay sau vòng lặp bên trong (tức là giữa ~}%}*.
Peter Taylor

4

GolfScript ( 54 53 ký tự)

Đây là một cách tiếp cận theo tinh thần của Howard (xây dựng các chuỗi đánh giá đúng giá trị và chọn ngắn nhất, thay vì dùng vũ lực thông qua các chuỗi ứng cử viên để tìm ra các chuỗi đánh giá đúng giá trị), nhưng tôi nghĩ đủ khác nó thuộc về một câu trả lời riêng

~.''':*':s@,{):x,2>{:^~$x^/~$+{s\*}x^%*}%{,}$0=}/]((=

Bản demo trực tuyến không khả dụng vì nó chạy phiên bản lỗi của trình thông dịch.

# Let <N> denote the string which evaluates to N
# We want to enter the main loop with three values on the stack: <0> <1> <2>
# However, we'll never use <0>, so we can actually replace that with any value at all.
# Getting the input from underneath 3 items would normally use two stack manipulations.
# Trick: let's use the input value for <0>! (This gives a further bonus later).
# NB We store the value of <2> in the variable s
~.''':*':s@
# for x=1 to input_value ...
,{):x
    # for ^=2 to x-1 ...
    ,2>{:^
        # Use negative stack offsets to index the stack from the start
        # I.e. -1$ gets the first item on the stack, which is <0>
        # -2$ gets the second item on the stack, which is <1>
        # In general, val~$ gets <val>
        ~$x^/~$+
        # We have the string <^><x / ^> on the stack.
        # Increment it (x % ^) times to get a candidate <x>.
        {s\*}x^%*
    }%
    # Select a shortest string.
    {,}$0=
}/
# Group the stack into one array and select the appropriate offset,
# reusing that hacky <0> substitute for the offset.
]((=

Có thể cạo một cái bằng cách thay thế 3+bằng )(khai thác thực tế là []0=không để lại gì trên ngăn xếp) nếu nó không []2>dẫn đến lỗi.
Peter Taylor

[]2>năng suất []không có lỗi.
Howard

@Howard, ah, golfscript.apphb.com phải chạy phiên bản cũ. Nhưng hóa ra tôi đã sai, vì sự thay thế đó dẫn đến việc đầu ra sai cho đầu vào '1'.
Peter Taylor

Mà bạn có thể sửa chữa với ((=thay vì -1=.
Howard

Và golfscript.apphb.com thực sự chạy một phiên bản cũ, ví dụ các vòng lặp lồng nhau không hoạt động.
Howard

4

Con trăn 2.7 - 87 84 92

u=lambda n:n>1and min([u(i)+u(n/i)for i in range(2,n)if n%i<1]+[':'+u(n-1)+'*'],key=len)or''

Giải thích:
Đây là một giải pháp khá đơn giản. Nó kiểm tra đệ quy tất cả các biểu diễn có thể có của n là tích của hai số hoặc dưới dạng :(n-1)*, sau đó tìm ra giải pháp độ dài tối thiểu. phạm vi (2, n) là cần thiết để đệ quy có độ sâu giới hạn và n <2 đưa ra trường hợp cơ sở.

Lưu ý:
i và n / i là hai yếu tố của n. Việc thay thế ... và ... hoặc ... thay thế cho ... nếu ... khác ... không hoạt động vì '' đánh giá là sai. min của chuỗi cho một trong những chuỗi ngắn nhất. Python 2.7 lưu 1 ký tự bằng cách sử dụng / thay vì //.

Chỉnh sửa: Di chuyển trường hợp cơ bản vào mặt sau của biểu thức, cho phép tôi sử dụng ... và ... hoặc ... và cạo một vài khoảng trắng.

Các trường hợp thử nghiệm:

u(1)
''
u(5)
'::*:**'
u(49)
'::*:*:*:*::***'

1
" Min chuỗi cho một trong những chuỗi ngắn nhất " không đúng trừ khi bạn cung cấp đối số tùy chọn key=len. Nó cung cấp cho chuỗi từ vựng sớm nhất. ( Ví dụ ). Vì '*' < ':'điều này có nghĩa là bạn có thành kiến ​​đối với các giải pháp liên quan đến quyền hạn của 2, nhưng chúng luôn luôn là ngắn nhất?
Peter Taylor

1
Trả lời: thực sự sai lệch phức tạp hơn, nhưng không phải lúc nào cũng đưa ra câu trả lời đúng. Ví dụ nhỏ nhất là u(33), trong đó việc sắp xếp từ vựng cho 14-char ::**::*::*:***nhưng sắp xếp theo chiều dài sẽ cho 12-char::*:*:*:*:**
Peter Taylor

1
Tôi không bao giờ biết rằng về so sánh chuỗi Python. Tôi đã cập nhật câu trả lời của tôi.
isaacg

3

GolfScript, 63 58 56 ký tự

~n./\{:v~[':*'1$*v,,2>{v,\%!},{.v=v,@/v=+}/]{,}$0=]}*-2=

Mã nhận đầu vào trên STDIN và in kết quả.

Ví dụ:

> 49
:::**:*:*:*:**

> 1234
::::*:*:*:**:*:*:**::**::***

Bạn có thể kiểm tra trường hợp của riêng bạn trực tuyến .


Wow, tôi nghĩ rằng một cách tiếp cận dựa trên bao thanh toán sẽ dài hơn một chút so với cách tiếp cận vũ phu.
Peter Taylor

@PeterTaylor Tôi cũng nghĩ vậy nhưng hóa ra không phải vậy. Hơn nữa, giải pháp vũ phu của tôi dài hơn bạn một chút ;-)
Howard

Bạn có thể giải thích những gì từng phần? Tôi chỉ có thể theo dõi cho đến khi :x(=bit. Ngoài ra, +1 để có thể chạy 49 trong một khoảng thời gian hợp lý.
thuật toán

@alerskymshark Tôi vẫn đang nghiên cứu giải pháp nên nó vẫn có thể thay đổi rất nhiều (như nó đã làm). Chủ yếu, phần x,2>{x\%!},cung cấp cho tất cả các ước số thực sự x, {.v=x@/v=+}/sau đó kết hợp các giải pháp cho dx/dcho tất cả các ước d. {,}$sắp xếp chúng theo chiều dài và 0=mất thời gian ngắn nhất (cộng với :(x-1)*trường hợp ban đầu ).
Howard

2

Brachylog 2 , 30 (có thể cuối cùng là 26) byte, thách thức ngôn ngữ

Đây là một chức năng hoạt động với triển khai Brachylog 2 hiện tại (và trả về danh sách mã ký tự vì việc triển khai hiện tại có một số vấn đề với xử lý chuỗi):

∧.l∧?{ḋp~c×ᵐ{-₁↰₁:[42,58]c↻}ᵐc}

Hãy thử trực tuyến!

Ngôn ngữ vẫn còn rất mới. Đây là phiên bản 26 byte của chương trình sẽ hoạt động theo đặc điểm kỹ thuật, nhưng sử dụng một số tính năng chưa được thực hiện và do đó chưa hợp lệ, nhưng có thể sẽ có trong tương lai (thậm chí còn kém hiệu quả hơn):

{ḋp~c×ᵐ{-₁↰₁:"*:"c↻}ᵐc}ᶠlᵒh

Giải trình

∧.l∧?{ḋp~c×ᵐ{-₁↰₁:[42,58]c↻}ᵐc}
∧.l∧?                            Evaluation hint: try shortest outputs first
     {                        }  Define an inner function
      ḋ                          Prime factor decomposition of the input
       p                         Find a permutation
        ~c                       Find an inverse concatenation (i.e. partition)
          ×ᵐ                     Take the product of each set inside the partition
      ḋp~c×ᵐ                     Find a decomposition into factors ≥ 2
            {              }ᵐ    For each of those factors:
             -₁                  Decrement it
               ↰₁                Call the inner function recursively
                 :[42,58]c       Append "*:" (as character codes)
                          ↻      Move the last element to the start
                             c   Append the results together

Ý tưởng cơ bản khá đơn giản: chúng tôi xen kẽ giữa việc phân tách số thành các yếu tố (1 hoặc nhiều hơn) (không nhất thiết là các thừa số, nhưng các yếu tố 1 không được phép) và biểu thị từng yếu tố là 1 + (một đại diện thu được từ đệ quy gọi). Điều này được đảm bảo để tìm kiếm tất cả các biểu diễn Underload có thể của số (chúng ta có thể áp dụng giai đoạn nhân "hai lần liên tiếp" bằng cách nhân nhiều hơn 2 số và một giai đoạn tăng hai lần liên tiếp bằng cách tách chúng với giai đoạn nhân cùng nhau chỉ một số). Chúng ta không cần một trường hợp cơ sở rõ ràng, bởi vì việc phân tách 1 thành các thừa số nguyên tố cung cấp cho chúng ta một danh sách trống và do đó chúng ta xây dựng nó với một giai đoạn nhân để nhân các số 0 với nhau.

Chương trình này khá kém hiệu quả, đặc biệt là vì gợi ý thứ tự đánh giá mà tôi đã đưa ra (tạo ra các câu trả lời ngắn nhất đến dài nhất về quy mô của đầu ra cuối cùng), trong khi giải quyết phần "ngắn nhất" của câu hỏi, không phải là tuyệt vời về mặt thực sự làm cho chương trình hoàn thành nhanh chóng (một gợi ý hữu ích hơn nhiều sẽ là "chỉ tạo ra câu trả lời ngắn nhất ở mỗi giai đoạn đệ quy", nhưng phải mất nhiều byte byte hơn). Ngoài ra, ḋp~c×ᵐcó thể tạo các phân vùng nhân nhiều lần, khiến chương trình thực hiện rất nhiều công việc dư thừa.


0

J - 81 char

Đối với hậu thế, đây là điều tốt nhất mà tôi có thể làm ở J.

_2{::(0&(][,0{<@;"1@({~#(#~]-:"1<.)@(],.%)2}.i.@#)(/:#&>)@,':'<@,'*',~>@{:),~)&a:

Chúng tôi tạo một danh sách kết quả, bắt đầu bằng hai chuỗi trống (đó là ,~a:) đại diện cho 0 (không bao giờ được sử dụng) và 1, sau đó lặp lại một động từ trên chúng (sử dụng lén các móc, xe lửa và &) nối thêm đại diện ngắn nhất của số tiếp theo.

Động từ thực tế mà chúng tôi lặp lại sử dụng độ dài của danh sách làm chỉ số cho số chúng tôi đang hoạt động. Đầu tiên, chúng tôi tính số này thành các cặp nhân tố ( #(#~]-:"1<.)@(],.%)2}.i.@#) và truy xuất từng cặp bằng cách kéo từ mảng ( {~). Chúng tôi biến mỗi cặp đó (có thể có 0 trong số chúng nếu số đó là số nguyên tố) thành chuỗi đơn ( <@;"1).

Sau đó, chúng tôi sẽ thêm vào danh sách đó mục nhập cho kết quả trước đó được đặt trong ngoặc :*và sắp xếp danh sách này theo độ dài ( (/:#&>)). Cuối cùng, chúng tôi lấy kết quả đầu tiên từ danh sách này ( 0{) và nối nó vào cuối mảng cơ sở ( [,). Khi vòng lặp được lặp lại xong, chúng ta có một danh sách có độ dài hơn 2 lần so với đầu vào, bắt đầu từ 0. Vì vậy, cái chúng ta phải trả về là chuỗi tiếp theo ( _2{::).

   un =: _2{::(0&(][,0{<@;"1@({~#(#~]-:"1<.)@(],.%)2}.i.@#)(/:#&>)@,':'<@,'*',~>@{:),~)&a:
   un 49
::*:*:*:*::***
   un 1234
:*::*:*:*::*::***::*::*:****
   un 10010
:*::*:*::***::*:*:*:*:*:*:*::***
   2 * (1 + 3 * 2^2) * (1 + 3 * 2^7)
10010
   6!:2 'un 10010'   NB. time in seconds
19.5539

0

Jelly , 33 byte, thách thức ngôn ngữ postdates

ÆḌḊµ⁹÷Ñ;Ñð€
’ß”:;;”*W;ÇLÞḢµ“”>1$?

Hãy thử trực tuyến!

Một giải pháp vũ phu đơn giản.

Giải trình

Chương trình chính

’ß”:;;”*W;ÇLÞḢµ“”>1$?
              µ  >1$?  If input is greater than 1, then:
’ß                       Run recursively on the input - 1
  ”:;                    Prepend a colon
     ;”*                 Append an asterisk
        W;               Cons to:
          Ç                the result of the helper, on {the original input}
           LÞ            Sort by length
             Ḣ           Take the first (i.e. shortest) result
               “”      Otherwise, return an empty string

Chương trình chính sử dụng hàm trợ giúp để liệt kê tất cả các cách có thể để tạo ra giá trị thông qua phép nhân, sau đó thử tạo ra giá trị bằng cách thêm và trả về khả năng ngắn nhất. Nó cũng xử lý trường hợp cơ sở (một đầu vào của 1).

Chức năng trợ giúp

ÆḌḊµ⁹÷Ñ;Ñð€
ÆḌ µ     ð€            For all proper factors of the input
  Ḋ                    except the first (i.e. 1):
    ⁹÷                   Divide it into the input;
      Ñ                  Run the main program on it;
       ;                 Append the result of:
        Ñ                  the main program run on {the factor}

Hàm trợ giúp thử tất cả các phương thức có thể để biểu thị đầu vào dưới dạng phép nhân của hai số và gọi đệ quy lẫn nhau chương trình chính để có được các biểu diễn ngắn nhất của chúng.


0

GNU Prolog, 96 byte

v(N)-->{N#=1};{N#=A*B,A#<B,B#<N},v(A),v(B);{N#=M+1},":",v(M),"*".
s(N,S):-length(S,_),v(N,S,[]).

Dòng đầu tiên là một ngữ pháp thực hiện đánh giá Underload và hoạt động theo hướng ngược lại (thực ra, nó không hoạt động theo hướng thuận do A#<Bràng buộc; thay đổi điều này thành A#<Nmột chương trình chậm hơn, hoạt động cả hai chiều). Dòng thứ hai định nghĩa vị từ giống như hàm s(là hàm được triển khai như một giải pháp cho chương trình này), tìm chuỗi ngắn nhất có thể đánh giá số được đưa ra làm đầu vào (điều này gây khó chịu cho một nhiệm vụ tương đối đơn giản, nhưng đó là Prolog cho bạn.

Chương trình nên khá tự giải thích, vì nó ít nhiều là một bản dịch trực tiếp của đặc tả sang ngữ pháp, và sau đó là cú pháp Prolog; định nghĩa vnói Nlà 1 trong một chuỗi rỗng, hoặc NA× B(với Aít hơn Bít hơn N) và chuỗi là nối của v(A)v(B), hoặc NM1 và chuỗi được :nối với v(M)nối với *. Dòng thứ hai là một chút tinh tế;length(S,_) có nghĩa là "S có một số độ dài", nhưng chỉ định đây là điều đầu tiên trên dòng đóng vai trò là một gợi ý cho việc triển khai Prolog rằng nó sẽ kiểm tra độ dài ngắn nhất trước (có nghĩa là chúng ta sẽ có độ dài ngắn nhất có thể cho giá trị trả về) .

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.