Tái thiết một chuỗi số học


23

Đưa ra một chuỗi số học hữu hạn của các số nguyên dương với một số thuật ngữ được loại bỏ ở giữa, xây dựng lại toàn bộ chuỗi.

Nhiệm vụ

Xem xét một chuỗi số học: một danh sách các số nguyên dương trong đó sự khác biệt giữa hai yếu tố kế tiếp là như nhau.

2 5 8 11 14 17

Bây giờ, giả sử một hoặc nhiều số nguyên bị xóa khỏi chuỗi, tuân theo các ràng buộc sau:

  • Các số nguyên bị loại bỏ sẽ là các điều khoản liên tiếp của chuỗi.
  • Các số nguyên đầu tiên và cuối cùng trong chuỗi sẽ không bị xóa.
  • Ít nhất ba số nguyên sẽ vẫn còn trong chuỗi.

Đối với trình tự trên, có thể loại bỏ bao gồm:

2 5 8 14 17  (removed 11)
2 5 17       (removed 8 11 14)
2 14 17      (removed 5 8 11)

Nhiệm vụ của bạn: Đưa ra một trong các chuỗi một phần này, xây dựng lại chuỗi đầy đủ ban đầu.

Chi tiết

Bạn có thể cho rằng đầu vào là hợp lệ (có giải pháp) và thiếu ít nhất một thuật ngữ. Tất cả các số trong chuỗi sẽ là số nguyên dương (> 0). Trình tự có thể có sự khác biệt tích cực hoặc tiêu cực giữa các điều khoản (nghĩa là nó có thể tăng hoặc giảm). Nó sẽ không phải là một chuỗi liên tục (ví dụ 5 5 5).

Giải pháp của bạn có thể là một chương trình đầy đủ hoặc một chức năng . Bất kỳ phương thức nhập và xuất mặc định nào đều được chấp nhận.

Đầu vào và đầu ra của bạn có thể là một chuỗi (với bất kỳ dấu phân cách hợp lý nào), danh sách các chuỗi hoặc danh sách các số. Bạn có thể đại diện cho các số trong bất kỳ cơ sở nào thuận tiện cho ngôn ngữ của bạn.

Vui lòng đề cập đến bất kỳ phương thức / định dạng I / O bất thường nào trong bài gửi của bạn, để những người khác sẽ có thể kiểm tra mã của bạn dễ dàng hơn.

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

In: 2 5 8 14 17
Out: 2 5 8 11 14 17
In: 2 5 17
Out: 2 5 8 11 14 17
In: 2 14 17
Out: 2 5 8 11 14 17
In: 21 9 6 3
Out: 21 18 15 12 9 6 3
In: 10 9 5
Out: 10 9 8 7 6 5
In: 1 10 91 100
Out: 1 10 19 28 37 46 55 64 73 82 91 100

Đây là ; câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng.



Sẽ rất thú vị khi có đầu vào ở dạng2 5 ... 17
schnaader

Câu trả lời:


9

Haskell , 63 byte

f(a:b:c)|s<-[a,b..last c],all(`elem`s)c=s
f a=r$f$r a
r=reverse

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

Về cơ bản hoạt động bằng cách cố gắng xây dựng kết quả từ phía trước và, nếu thất bại, từ phía sau. Điều này sử dụng thực tế là các thành viên đầu tiên và cuối cùng của đầu vào sẽ luôn luôn chính xác, thực tế là các thành viên bị xóa phải liên tiếp và thực tế là sẽ luôn có ít nhất ba mục trong đầu vào. Tất cả những gì tôi phải làm là giả định rằng các thành viên thứ hai hoặc thứ hai đến cuối cùng là chính xác và kiểm tra xem nó có hoạt động không. May mắn thay, Haskell có cú pháp thực sự đẹp để tạo ra chuỗi số học.

EDIT: cảm ơn @xnor đã chỉ ra một lỗi và cung cấp giải pháp!


5
Mặc dù điều này là đẹp, nhưng có vẻ như nó không luôn luôn hoạt động: [1,3,4,5]cho [1,3,5].
xnor

1
Và tôi nghĩ all(`elem`s)cnên sửa nó với cùng số byte.
xnor

6

05AB1E , 9 8 byte

Ÿs¥¿Äô€н

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

Giải trình

  • Xây dựng phạm vi [đầu tiên, ..., cuối cùng] với chênh lệch +/- 1
  • Tính toán đồng bằng của đầu vào
  • Lấy giá trị tuyệt đối của gcd của đồng bằng châu thổ
  • Chia phạm vi đầy đủ trong khối có kích thước đó
  • Lấy phần tử đầu tiên của mỗi đoạn

Đã lưu 1 byte bằng cách sử dụng gcd of deltasthay vì min delta, lấy cảm hứng từ user202729


5

Brachylog v2, 9 byte

⊆.s₂ᵇ-ᵐ=∧

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

Đây là một đệ trình chức năng. Trình thông dịch Brachylog có thể được tạo để đánh giá một hàm như thể nó là một chương trình đầy đủ bằng cách đưa nó Zlàm đối số dòng lệnh; trong trường hợp này, đầu vào được chỉ định theo định dạng, ví dụ, [1, 2, 4]và đầu ra được trả về ở định dạng tương tự, ví dụ Z = [1, 2, 3, 4]. (Tất nhiên, để gửi chức năng, đầu vào và đầu ra không ở bất kỳ định dạng nào cả; chúng chỉ là danh sách.)

Điều này thực sự giải quyết được một vấn đề khó hơn so với vấn đề mà OP yêu cầu: nó giải quyết chuỗi số nguyên ngắn nhất có chứa các giá trị được chỉ định theo thứ tự đã chỉ định, bất kể việc xóa có liên tiếp hay không. Bởi vì nó sử dụng sức mạnh vũ phu, nó có thể rất chậm nếu nhiều giá trị bị xóa.

Giải trình

Chương trình có ba phần chính.

tìm thấy một kết quả của đầu vào (tức là một chuỗi có đầu vào là một chuỗi con). Khi có nhiều hơn một đầu ra có thể từ một chương trình Brachylog, đầu ra được chọn là đầu ra đầu tiên theo thứ tự tiebreak và thứ tự tiebreak được xác định bởi lệnh đầu tiên trong chương trình có ý kiến ​​về nó; trong trường hợp này, chỉ định một đơn đặt hàng ưu tiên các đầu ra ngắn hơn các đầu ra dài. Vì vậy, đầu ra chúng ta sẽ nhận được sẽ là kết quả ngắn nhất của đầu vào tuân theo các hạn chế trong phần còn lại của chương trình.

.... được sử dụng để sản xuất các giá trị mà họ coi là đầu vào (tức là supersequence trong trường hợp này), nhưng cũng khẳng định rằng một điều kiện cụ thể giữ trên đó. Nói cách khác, chúng tôi đưa ra kết quả siêu ngắn nhất tuân theo một điều kiện cụ thể (và bỏ qua mọi kết quả trung gian được sử dụng để xem liệu nó có tuân theo điều kiện đó không).

Cuối cùng, chúng ta có s₂ᵇ-ᵐ =, tức là "tất cả các vùng đồng bằng của chuỗi đều bằng nhau", điều kiện chúng ta áp dụng cho đầu ra. (Giá trị trả về từ này là danh sách các vùng đồng bằng, chứ không phải là supersequence bản thân, đó là lý do tại sao chúng ta cần các .... để đảm bảo rằng đúng là đầu ra.)

Brachylog được giữ lại ở đây bằng cách không có bất kỳ nội dung nào có thể xử lý việc tính toán đồng bằng, áp dụng một thao tác cho các cặp chồng chéo từ danh sách hoặc tương tự. Thay vào đó, chúng ta phải nói rõ ý của chúng tôi: s₂ᵇtìm tất cả ( ) các chuỗi con ( s) có độ dài 2 ( ) (việc sử dụng là bắt buộc để giữ một liên kết giữa các ẩn số trong các chuỗi con và trong siêu kết quả; việc sử dụng phổ biến hơn sẽ phá vỡ điều này liên kết). Sau đó -ᵐthực hiện phép trừ trên mỗi cặp này để tạo ra một delta. Thật khó chịu khi phải viết ra năm byte s₂ᵇ-ᵐcho một thứ mà hầu hết các ngôn ngữ golf hiện đại đều có sẵn, nhưng đó là cách mà codegolf đôi khi đi, tôi đoán vậy.


4

Python 2, 104 97 89 83 71 67 60 byte

Cảm ơn Chas Brown đã lưu 4 byte.
Cảm ơn ovs đã tiết kiệm 7 byte.

Nhập danh sách bằng các đối số.

lambda a,b,*c:range(a,c[-1],min(b-a,c[0]-b,key=abs))+[c[-1]]

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

Giải trình:

Vì việc loại bỏ là liên tiếp, nên đủ để kiểm tra sự khác biệt giữa hai cặp yếu tố liên tiếp.


Bạn có thể lưu 3 byte bằng cách thay thế b if b%c else cbằng [c,b][b%c>0].
Chas Brown

@ChasBrown Cảm ơn, mặc dù tôi đã sớm đưa ra một cách tiếp cận tốt hơn.
Colera Su

1
Đẹp với key=abs! Dường như ở đây, mọi người thường bỏ qua f=phần trừ khi sử dụng hàm đệ quy; vì vậy bạn có thể tiết kiệm 2 byte theo cách đó.
Chas Brown

1
Ngoài ra, thay thế a[-1]-a[-2]bằng a[2]-a[1]- logic là như nhau và bạn nhận được 2 byte khác.
Chas Brown


4

Bình thường , 11 byte

%hS.+SQ}hQe

Hãy thử nó ở đây!

Cảm ơn Steven H. vì đã tiết kiệm một byte!

Bình thường , 12 byte

%.aiF.+Q}hQe

Hãy thử nó ở đây!

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

% .aiF. + Q} hQe ~ Chương trình đầy đủ.

     . + Q ~ Nhận đồng bằng.
   iF ~ Giảm theo GCD.
 .a ~ Giá trị tuyệt đối.
% ~ Mô-đun. Nhận mọi yếu tố thứ n của ...
        } ~ Phạm vi số bao gồm giữa ...
         hQ ~ Yếu tố đầu tiên và ...
           e ~ Yếu tố cuối cùng.

Presort Qđể bạn có thể sắp xếp và lấy phần tử đầu tiên thay vì abs(GCD(Q))như trong %hS.+SQ}hQe11 byte. Bộ thử nghiệm
Steven H.

3

Thạch , 8 byte

ṂrṀmIg/$

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

Ghi chú:

  • Chỉ hoạt động trên một số phiên bản cũ của Jelly. ( ví dụ như cam kết này ) (trong đó gsử dụng fractions.gcd, có kết quả ký giống như dấu đầu vào, thay vì math.gcd, luôn trả về giá trị dương).

  • Liên kết TIO ở trên là liên kết TIO của Python 3, mã Python bao gồm mã nguồn Jelly từ cam kết mà tôi đã đề cập ở trên, ngoại trừ mọi thứ (3 tệp) được đóng gói vào cùng một tệp (để TIO chạy) và dictionary.pyđã được rút gọn thành chỉ một số dòng. Tuy nhiên dictionary.pykhông liên quan đến câu trả lời này, vì nó không sử dụng chuỗi nén. ( “...»cấu trúc)

Giải trình:

Đầu tiên, vì một phân đoạn liên tục bị xóa và vẫn còn ít nhất 3 yếu tố, nên vẫn còn hai số liên tiếp trong danh sách cũ và tất cả các đồng bằng sẽ là bội số của bước. Do đó , danh sách gcdcác khác biệt ( I, gia số) sẽ là giá trị tuyệt đối của bước.

May mắn gcdlà đã được ký (xem ghi chú ở trên)

Vì vậy, chương trình này:

ṂrṀ

Một phạm vi số nguyên tăng dần từ tối thiểu đến tối đa .

m

Mô-đun, chọn mọi phần tử thứ n.

Ig/$

$Chuỗi kết hợp Monadic ( ) I(tăng, chênh lệch) và g/(giảm gcdtrên các yếu tố của danh sách). Nếu số gia là dương thì gcdsẽ là số dương và danh sách trả về sẽ từ trái sang phải (tăng) và ngược lại.


Yay! Đánh bại câu trả lời 05AB1E bằng 1 byte!
dùng202729

Sử dụng gcdthay vì minlàm cho chúng tôi buộc. Quá tệ Tôi nhận được một gcd có dấu, nếu không tôi sẽ ở 7;)
Emigna

3

MATL , 13 byte

1)0GdYkG0)3$:

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

Giải trình:

Consider the example input [2 14 17]:
           # implicit input, STACK: [[2 14 17]]
1)         # push 1, index, STACK: [2]
0G         # push 0, duplicate input, STACK: [2, 0, [2 14 17]]
d          # take differences, STACK: [2, 0, [12, 3]]
Yk         # get value in [12, 3] nearest to 0, STACK: [2, 3]
G0)        # get last element in input, STACK: [2, 3, 17]
3$:        # 3-input :, computes 2:3:17, the range from 2 to 17 by 3
           # STACK: [[2 5 8 11 14 17]], implicit output.


3

JavaScript (ES6), 92 90

Chỉnh sửa 2 byte đã lưu thx Arnauld

Dễ dàng, vì nó là đủ để kiểm tra sự khác biệt giữa hai đầu tiên và hai cuối cùng. Nhưng vẫn không thể tin được lâu.

s=>(e=(z=s.pop(a=s[0]))-s.pop(d=s[1]-a),[...Array((z-(a-=d=e*e>d*d?d:e))/d)].map(_=>a+=d))

Ít chơi gôn

s=>{
  a =s[0]
  b =s[1]
  z = s.pop()
  y = s.pop()
  d = b-a
  e = z-y
  d = e*e>d*d?d:e  
  n = (z-a)/d+1
  return [...Array(n)].map((_,i) => a + i*d)
}

Kiểm tra

var F=
s=>(e=(z=s.pop(a=s[0]))-s.pop(d=s[1]-a),[...Array((z-(a-=d=e*e>d*d?d:e))/d)].map(_=>a+=d))

var test=`In: 2 5 8 14 17 Out: 2 5 8 11 14 17
In: 2 5 17 Out: 2 5 8 11 14 17
In: 2 14 17 Out: 2 5 8 11 14 17
In: 21 9 6 3 Out: 21 18 15 12 9 6 3
In: 10 9 5 Out: 10 9 8 7 6 5
In: 1 10 91 100 Out: 1 10 19 28 37 46 55 64 73 82 91 100`.split`\n`
.map(r=>r.split`Out`.map(x=>x.match(/\d+/g)))

test.forEach(([i,k])=>{
  var o=F(i.slice(0))
  var ok = o+''==k
  console.log(ok?'OK':'KO',i+' => '+o)
})


a-=d=e*e>d*d?d:enên hoạt động và tiết kiệm 2 byte.
Arnauld

@Arnauld nó hoạt động thực sự cảm ơn
edc65

2

Ngôn ngữ Wolfram (Mathicala) , 50 byte

Range[#&@@#,#[[-1]],#&@@Differences@#~SortBy~Abs]&

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


Có phải một "danh sách các số" bao gồm việc có các số làm đối số riêng lẻ không? Nếu vậy, có vẻ như bạn có thể tiết kiệm được một số byte tốt.
numbermaniac

@numbermaniac Tôi không nghĩ vậy, vì không có nội dung nào lấy được đầu vào cuối cùng ...
JungHwan Min

À ... đúng rồi. Quên về điều đó.
numbermaniac

Bạn có thể sử dụng {##}Last@{##}nhưng thứ tốt nhất tôi có thể có là 51 byte.
numbermaniac


1

Haskell , 73 69 byte

f(h:t)=do(#)<-[(-),(+)];[h,h#minimum(abs<$>zipWith(-)t(h:t))..last t]

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


1
Tôi đã tìm thấy một giải pháp 63 byte nhưng nó khá khác so với của bạn. Tôi có nên làm một bài riêng?
dùng1472751

@ user1472751 Tôi không phải Laikoni, nhưng trang web này nhằm mục đích cạnh tranh, cũng như hợp tác. Vì vậy, tôi sẽ gửi nó.
H.PWiz

@ user1472751 Cách tiếp cận tốt đẹp! Hãy đi trước và gửi nó như là câu trả lời của riêng bạn.
Laikoni

1

J , 49, 47 46 byte

(0-[:<./2|@-/\]){.@[&]\({.<.{:)+[:i.{:(+*)@-{.

Lấy cảm hứng từ giải pháp của Emigna.

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

 (0-[:<./2|@-/\]){.@[&]\({.<.{:)+[:i.{:(+*)@-{. - fork of 3 verbs

                        ({.<.{:)+[:i.{:(+*)@-{. - generates a list in the entire range of values
                                     {:     -{. - last minus first element  
                                       (+*)@    - adds the signum of the difference
                                 [:i.           - makes a list 
                       ({.<.{:)                 - the smallest of first and last elements                                     
                               +                - adds the offset to the list (translates all elements according to the first one)

 (0-[:<./2|@-/\])                               - finds the step
         2|@-/\]                                - the absolute differences between all consecutive elements
    [:<./                                       - the smallest one
  0-                                            - negate (for splitting)

                 {.@[&]\                        - splits the list from the right verb into left verb's result sublists and takes their first elements

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


1

Husk , 9 byte

m←C▼Ẋ≠⁰…⁰

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

Cảm ơn H.PWiz rất nhiều vì đã giảm một nửa số byte, bằng cách chỉ ra rằng việc áp dụng vào danh sách sẽ điều chỉnh nó! ...


@ HP.Wiz X_X Tôi không biết Husk có liệt kê các phạm vi như thế không ... Bạn có chắc chắn không muốn đăng nó dưới dạng câu trả lời riêng của mình không?
Ông Xcoder

@ HP.Wiz Cảm ơn một sự lỏng lẻo !
Ông Xcoder

Ngoài ra, có thể F⌋được thay thế bởi ?
H.PWiz

@ H.PWiz @ _ @ Tại sao điều đó thậm chí hoạt động?
Ông Xcoder

Sự khác biệt nhỏ nhất (tuyệt đối) sẽ là sự khác biệt ban đầu. Lý do duy nhất gcdlà để đối phó với đồng bằng tiêu cực
H.PWiz

1

C # (.NET Core) , 167 + 13 = 180 145 + 13 = 158 byte

a=>{int x=a[1]-a[0],y=a[2]-a[1],d=x*x<y*y?x:y,s=Math.Abs((a[a.Length-1]-a[0])/d),i=0,j=a[0];var r=new int[s+1];for(;i<=s;j+=d)r[i++]=j;return r;}

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

+13 cho using System;

Đáng ngạc nhiên, thử thách này có nhiều sắc thái mà tôi dự đoán ban đầu.

Lời cảm ơn

-22 byte được lưu do một số đơn giản hóa gọn gàng từ @DLosc.

Khói

a=>{
    int x = a[1]-a[0],        // difference between first and second numbers
        y = a[2]-a[1],        // difference between second to last and last numbers
        d = x*x < y*y? x : y, // smallest absolute value difference
        s = Math.Abs((a[a.Length-1] - a[0]) / d), // number of steps in the reconstructed sequence (not the number of elements)
        i = 0,                // step position
        j = a[0];             // next number in reconstructed sequence

    var r = new int[s+1];

    // reconstruct the sequence
    for(; i <= s; j+=d)
        r[i++]=j;

    return r;
}





0

Japt , 12 byte

ÌõUg Uäa ñ g

Thử nó


Giải trình

Tạo một mảng các số nguyên ( õ) từ phần tử cuối cùng của mảng đầu vào ( Ì) đến đầu tiên ( Ug). Tính bước giữa các phần tử bằng cách lấy tất cả hai cặp phần tử từ đầu vào và giảm chúng theo chênh lệch tuyệt đối ( Uäa) sau đó sắp xếp ( ñ) mảng đó và lấy phần tử đầu tiên ( g).

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.