Sắp xếp một chuỗi nối


17

Xem xét một chuỗi dựa trên quan hệ tái phát f(n) = f(n-1)+f(n-2), bắt đầu bằng f(1) = x1, f(2) = x2. Đối với x1 = 2, x2 = 1, trình tự bắt đầu như thế này:

2  1  3  4  7  11  18  29  47  76  123  199  322  521  843

Nối chuỗi này thành một chuỗi sẽ cho:

213471118294776123199322521843

Bây giờ, chia danh sách này thành các số nhỏ nhất có thể cung cấp y(n) > y(n-1). Bắt đầu với số đầu tiên, sau đó là số thứ hai, vv Số đầu ra đầu tiên phải luôn là một chữ số. Pad số cuối cùng với số không cần thiết.

2 13 47 111 829 4776 12319 93225 218430

Bạn sẽ nhận được hai số, (x1, x2)làm đầu vào, trên bất kỳ định dạng thuận tiện nào, và thách thức là xuất ra danh sách đã sắp xếp.

Quy tắc:

  • Chức năng và chương trình đều ổn
  • Chuỗi ban đầu sẽ có chính xác 15 số (Số cuối cùng là f(15)).
  • x1x2không âm (không có thể có).
  • Đầu ra có thể ở bất kỳ định dạng thuận tiện
  • Các vector đầu ra yphải được tạo ra sao cho y2 > y1.
    • Đầu tiên nhỏ nhất có thể y1, sau đó nhỏ nhất có thể y2, sau đó y3và như vậy.
  • Nếu x1 = x2 = 0sau đó xuất 15 số không (trên cùng định dạng với đầu ra khác, nghĩa là không 000000000000000).

Ví dụ :

Input: 1 1
Output: 1  12  35  81  321  345  589  1442  3337 7610

Input: 3 2
Output: 3  25  71  219  315  0811 3121  23435 55898 145300
                             |
                             Optional leading zero 
Input: 0 0
Output: 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

Mã ngắn nhất tính bằng byte thắng. Vui lòng bao gồm một liên kết đến một thông dịch viên trực tuyến nếu có thể.


Chính xác ý bạn là gì bởi "những con số nhỏ nhất có thể"? Trung bình nhỏ nhất? Nhỏ nhất tối đa? Thứ gì khác?
isaacg

@isaacg Vì vậy, số thứ n lớn hơn (n-1) th.
nicael

1
Để làm rõ câu hỏi của tôi, sự phân chia thích hợp 5467sẽ là gì? 54 67? 5 46 70?
isaacg


3
Điều 0 có vẻ như là một ngoại lệ khá khó chịu và không cần thiết.
Martin Ender

Câu trả lời:


1

Bình thường, 56 byte

LsgM.:sMb2?sQsM.WyHX_1Z`0u?yGX_1GHaGHjkhM.u,eNsN14QYmZ15

Bộ kiểm tra

Giải trình:

Đầu tiên, chúng tôi kiểm tra xem đầu vào là chính xác 0, 0. Nếu vậy, in 15 số không.

Nếu không, chúng tôi sản xuất trình tự, với jkhM.u,eNsN14Q. Điều này tương tự như thuật toán Pyth tiêu chuẩn cho chuỗi Fibonacci.

Tiếp theo, chúng tôi giảm qua chuỗi này. Bộ tích lũy là một danh sách các chuỗi, đại diện cho mỗi số trong chuỗi được chia. Ở mỗi bước giảm, chúng ta lấy ký tự tiếp theo và kiểm tra xem bộ tích lũy có theo thứ tự hay không, sử dụng hàm trợ giúp y, được xác định với LsgM.:sMb2, đó là sự thật nếu đầu vào không đúng thứ tự. Nếu theo thứ tự, chúng tôi sẽ thêm ký tự tiếp theo vào danh sách dưới dạng số riêng của nó. Nếu không, chúng ta thêm ký tự tiếp theo vào cuối chuỗi cuối cùng. Điều này được thực hiện với u?yGX_1GHaGH ... Y.

Tiếp theo, chúng tôi thực hiện một vòng lặp while chức năng. Vòng lặp tiếp tục cho đến khi danh sách đang chạy theo thứ tự, sử dụng lại chức năng của trình trợ giúp. Ở mỗi bước, a 0được thêm vào cuối chuỗi cuối cùng trong danh sách. Điều này được thực hiện với .WyHX_1Z`0.

Cuối cùng, các chuỗi được chuyển đổi thành số nguyên, với sMvà in.


Bình thường, 51 byte

LsgM.:sMb2?sQsM.WyHX_1Z`0hf!yT_./jkhM.u,eNsN14QmZ15

Tôi tin rằng điều này hoạt động, nhưng nó quá chậm để kiểm tra - đó là một giải pháp vũ lực để phân chia chuỗi.


Tôi sẽ thực hiện một số cải tiến cho Xchức năng, nhưng đoạn mã trên hoạt động trong phiên bản Pyth gần đây nhất khi câu hỏi được đăng.


5

JavaScript ES6, 127 135

(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

Kiểm tra

F=(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

// less golfed

U=(a,b)=>{
  for(n=r=[], o=a+n+b, v=13; v--; a=b, b=t)
    o+= t= b+a;
  for(d of o+'0'.repeat(99))
    if ((n+=d) > +v)
      r.push(v=n), n='';
  return +v ? r : [...o]
}

function test(){
  var i = I.value.match(/\d+/g)
  O.textContent = i.length > 1 ? F(+i[0],+i[1]) : ''
}
test()
A,B : <input id=I value='0 1' oninput='test()'>
<pre id=O></pre>


Có lỗi cho x1 = 0, x2> 0, ví dụ: "0 1".
flornquake

@flornquake cố định. Số lượng byte vẫn giữ nguyên, đã giảm một chút mã điền 0
edc65

2

JavaScript ES6, 187 180 187 184 182 179 175 172 165 160 155 154 byte

(a,b)=>eval('d=""+a+b;for(i=-12,j=1;++i<99;)i<2?(c=b,d+=b=a+b,a=c,r=a?[d[0]]:"0,".repeat(15)):(f=+d.slice(j,i))>r[r.length-1]?(r.push(f),j=++i-1):d+=0;r')

Tôi nhận được kết quả tương tự khi chạy nó cho 1,13,2trường hợp thử nghiệm. 0,0đã lấy quá 26 byte ...

De-golf + được chuyển đổi thành ES5 + demo:

function s(a, b) {
  d = "" + a + b;
  for (i = -12, j = 1; ++i < 99;)
    i < 2 ?
      (c = b, d += b = a + b, a = c, r = a ? [d[0]] : "0,".repeat(15))
    : (f = +d.slice(j, i)) > r[r.length - 1] ?
      (r.push(f), j = ++i - 1)
      : d += 0;
  return r
}
document.write(
   s(1,1)+"<br>"+
   s(3,2)+"<br>"+
   s(0,0)
)


Tại sao nó tạo ra nhiều số hơn? Và nó không phải là dễ dàng để sửa chữa? Yêu cầu là n <= 15.
Stewie Griffin

@Stewie Nhưng này, cái đầu tiên tạo ra 12 và thứ hai 11. Nó nhỏ hơn 15.
nicael

Chuỗi ban đầu f(n) = f(n-1)+f(n-2)có giá trị tối đa chính xác là 15. Số lượng giá trị đầu ra được xác định dựa trên thuật toán, không có gì khác.
Stewie Griffin

@Stewie ok, vậy nó phải chính xác là 15, phải không? Sau đó, bởi n <= 15 bạn có nghĩa là các số đầu vào nhỏ hơn 15?
nicael

Số lượng giá trị trong chuỗi ban đầu là 15. Các giá trị bắt đầu f(1)=x1f(2)=x2có thể cao hơn 15. Số lượng giá trị đầu ra được xác định dựa trên các giá trị đầu vào. Đối với 3 2nó sẽ là 10.
Stewie Griffin

1

JavaScript (ES6), 162 byte

(a,b)=>(k=[...Array(15).keys(y="")],p=-1,z=k.map(_=>0),a|b?[...k.map(f=n=>n--?n?f(n)+f(n-1):b:a).join``,...z].map(d=>+(y+=d)>p?(p=y,y=" ",p):"").join``:z.join` `)

Giải trình

(a,b)=>(
  k=[...Array(15).keys(y="")],     // k = array of numbers 0 to 14, initialise y
  p=-1,                            // initialise p to -1 so that 0 is greater than p
  z=k.map(_=>0),                   // z = array of 15 zeroes
  a|b?[                            // if a and b are not 0
      ...k.map                     // for range 0 to 14
      (f=n=>n--?n?f(n)+f(n-1):b:a) // recursive sequence function (0 indexed)
      .join``,                     // join result of f(0) to f(14) as a string
      ...z                         // append zeroes for padding
    ].map(d=>                      // for each digit of concatenated result
      +(y+=d)                      // append the digit to the current number y
      >p?(                         // if the current number is greater than the previous p
        p=y,                       // set previous to the current number
        y=" ",                     // reset y (with space as a separator)
        p                          // output the current number (with space at the start)
      ):""                         // else add nothing to the output
    )
    .join``                        // return the output as a string
  :z.join` `                       // return a bunch of zeroes if a and b are 0
)

Kiểm tra


1

Toán học, 192 byte

f[{0,0}]:=0~Table~15
f@l_:=(t=0;q={};If[#>0,q~Join~{10^⌈Log10[t/#]⌉#},q]&[Last@#]&@FoldList[If[#>t,AppendTo[q,t=#];0,#]&[10#+#2]&,0,Flatten@IntegerDigits@SequenceFoldList[#+#2&,l,Range@13]])

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

f[{2, 1}]
(* {2, 13, 47, 111, 829, 4776, 12319, 93225, 218430} *)
f[{3, 2}]
(* {3, 25, 71, 219, 315, 811, 3121, 23435, 55898, 145300} *)
f[{0, 0}]
(* {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

Độ dài của các tên hàm đang giết chết tôi.


1

Haskell, 165 159 152 142 141 byte

w=take 15
x#y=x:scanl(+)y(x#y)
0%0=w[0,0..]
x%y=g(-1)(w(x#y)++0%0>>=show)(-1)
g _""_=[]
g b l@(h:t)a|b>a=b:g 0l b|1<2=g(max 0b*10+read[h])t a

Ví dụ sử dụng: 3 % 2-> [3,25,71,219,315,811,3121,23435,55898,145300].

Bản demo trực tuyến (có maintrình bao bọc).

Làm thế nào nó hoạt động:

w=take 15
x#y=x:scanl(+)y(x#y)              -- fibonacci sequence generator for x and y

0%0=w[0,0..]                      -- special case 0%0
x%y=g(-1)(w(x#y)++0%0>>=show)(-1) -- calculate fib sequence, add some extra 0 and
                                  -- flatten all digits into a single string.
                                  -- start calculating the resulting sequence

g _""_=[]                         -- if we don't have digits left, stop.
                                  -- the final 0 in the second parameter is ignored.
g b l@(h:t)a
  |b>a=b:g 0l b                   -- if the current number is greater than the
                                  -- previous one, take it and start over.
  |1<2=g(max 0b*10+read[h])t a    -- otherwise add the next digit and retry.
                                  -- The "max" fixes the initial call with -1.

0

PowerShell, 167 166 byte

param($x,$w)if($w-lt($x-eq0)){"0`n"*15;exit}[char[]]("$x"+-join(0..13|%{$w;$w=$x+($x=$w)}))|%{$z+="$_";if(+$z-gt$y){($y=$z);$z=""}};if($z){while(+$z-lt$y){$z+="0"}$z}

Đã lưu một byte bằng cách loại bỏ $sbiến và chỉ cung cấp trực tiếp vòng lặp đầu ra.

Ungolfed và bình luận:

param($x,$w)           # Take input parameters as x and w
if($w-lt($x-eq0)){     # If x=0, ($x-eq0)=1, so $w-lt1 implies w=0 as well
  "0`n"*15             # Print out 15 0's separated by newlines
  exit                 # And exit program
}                      # otherwise ...
[char[]](              # Construct the sequence string as a char-array
"$x"+-join(            # Starting with x and concatenated with a joined array
  0..13|%{             # Loop
    $w                 # Add on w
    $w=$x+($x=$w)      # Recalculate for next loop iteration
  }
))|%{                  # Feed our sequence as a char-array into a loop
  $z+="$_"             # z is our output number, starts with the first digit
  if(+$z-gt$y){        # If z is bigger than y (initialized to 0)
    ($y=$z)            # Set y equal to z and print it
    $z=""              # Reset z to nothing to start building the next number
  }
}
if($z){                # If there is remaining digits, we need to pad zeroes
  while(+$z-lt$y){     # Until z is bigger than y
    $z+="0"            # Tack on a zero
  }
  $z                   # Print the final number
}

0

Perl 6 , 107 byte

{$_=@=(|@_,*+*...*)[^15].join.comb;.sum??[.shift,{last if !@$_;until (my$a~=.shift//0)>$^b {};$a}...*]!!$_} # 107

Sử dụng:

# give it a lexical name for ease of use
my &code = {...}

# use 「eager」 because the anonymous block returns a lazy array
# and 「say」 doesn't ask it to generate the values
say eager code 2, 1;
# [2 13 47 111 829 4776 12319 93225 218430]
say eager code 1, 1;
# [1 12 35 81 321 345 589 1442 3337 7610]
say eager code 3, 2;
# [3 25 71 219 315 0811 3121 23435 55898 145300]
say eager code 0, 0;
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
say eager code 0, 1;
# [0 1 12 35 81 321 345 589 1442 3337 7000]

Giải trình

tạo một chuỗi giống như Fibonacci, bắt đầu bằng các đối số ( @_) trượt ( |) trong

|@_,*+*...*

lấy 15 phần tử đầu tiên của chuỗi đó

(…)[^15]

kết hợp chuỗi đó thành một chuỗi đơn ( .join), chia nó thành một chuỗi các ký tự riêng lẻ ( .comb) và lưu trữ trong vô hướng "mặc định" ( $_) sau khi ép chuỗi đó thành một mảng có thể thay đổi, trước tiên lưu trữ nó trong một mảng ẩn danh ( @)

$_=@=(…)[^15].join.comb;

nó tìm thấy tổng các giá trị trong vô hướng mặc định và nếu đó là 0 trả về vô hướng mặc định, nó sẽ chứa một mảng gồm 15 số không

.sum??  !!$_

nếu tổng không bằng 0, nó sẽ tạo một danh sách bằng cách trước tiên chuyển phần tử đầu tiên trong vô hướng mặc định

.shift,  

tiếp theo bằng cách tạo phần còn lại của các giá trị, kiểm tra nó với giá trị trước đó ( $^b)
nếu vô hướng mặc định hết giá trị, sử dụng 0 thay thế ( //0)

…,{  ;until (my$a~=.shift//0)>$^b {};$a}...*

dừng lại khi không còn phần tử nào trong vô hướng mặc định

…,{last if !@$_;  }...*

Tại sao phải có một không gian trong until (my$a...? Không phải là (một dấu phân cách đặc biệt?
mèo

@cat đó sẽ là một cuộc gọi đến chương trình con có tên until, không tồn tại.
Brad Gilbert b2gills
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.