Sửa chữa các phạm vi


30

Đưa ra một đầu vào của một danh sách các số nguyên dương với một số thay thế 0, xuất ra danh sách với các số bị thiếu đã được thay đổi để 0thay thế.

Đặc điểm của danh sách đầu vào:

  • Danh sách sẽ luôn có độ dài ít nhất là 2.

  • Hãy để chúng tôi xác định danh sách đầu vào là avà "danh sách ban đầu" (nghĩa là danh sách trước khi số được thay thế bằng 0s) là b. Đối với bất kỳ n, a[n]là một trong hai b[n]hoặc 0.

  • Đối với bất kỳ n, b[n]là một trong hai b[n-1] + 1hoặc b[n-1] - 1. Đó là, các số trong bsẽ luôn thay đổi theo 1từng chỉ số so với trước đó. Tất nhiên, yếu tố đầu tiên được miễn trừ khỏi quy tắc này.

  • Đối với mỗi chạy của zero trong a(có nghĩa là, các yếu tố liên tiếp thay thế bằng 0), với xđại diện các chỉ số bắt đầu chạy và y đại diện cuối cùng, a[x-1]để a[y+1]sẽ luôn luôn được hoặc chỉ tăng hoặc pha duy nhất giảm. Do đó, sẽ chỉ có một cách có thể để điền vào các số không.

    • Điều này cũng có nghĩa là cả phần tử đầu tiên và phần tử cuối cùng của mảng đều không thể là số không.

Nói một cách đơn giản hơn, để điền vào một số 0, chỉ cần thay thế nó bằng một phạm vi từ số trước đến số theo sau nó. Ví dụ: đầu vào của

1 2 0 0 0 6 7

phải xuất

1 2 3 4 5 6 7

Vì đây là , mã ngắn nhất tính bằng byte sẽ thắng.

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

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23

Thay vì 0chương trình của chúng tôi có thể lấy một giá trị khác như null?
Hạ cấp

@Downgoat Không, số thiếu phải được đưa ra là 0.
Doorknob

Câu trả lời:


15

JavaScript (ES6), 72 66 64 54 53 byte

Đã lưu 12 byte nhờ @Neil!

Đã lưu 1 byte nhờ @IsmaelMiguel

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

Khá tốt cho JavaScript.


Dùng thử trực tuyến (tất cả các trình duyệt hoạt động)

Giải trình

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`

1
Tôi nghĩ điều đó a.find((q,r)=>r>i&&q)>b?++b:--bcũng giống nhưb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@IsmaelMiguel thật thông minh, cảm ơn!
Hạ cấp

Không có gì. Tôi rất vui vì nó làm việc cho bạn.
Ismael Miguel

Tôi nghĩ bạn có thể thay thế && bằng chỉ & (Chỉ cần lưu ý rằng bạn có một & trong phần giải thích và hai trong câu trả lời)
Charlie Wynn


7

Haskell, 68 61 58 byte

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

Ví dụ sử dụng: g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]-> [7,6,5,4,3,4,5,6,7,6,5].

Cách thức hoạt động: loại bỏ số không khỏi đầu vào, sau đó gọi g. Hãy alà phần tử đầu tiên và bsau đó thứ hai của danh sách còn lại. Nối các danh sách từ alên xuống b-1và từ axuống dưới b+1(một trong số chúng sẽ trống) và một cuộc gọi đệ quy abị bỏ.

Chỉnh sửa: @Zgarb lưu 3 byte. Cảm ơn!


6

Toán học, 59 byte

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

Trường hợp thử nghiệm

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)

4

Perl, 47 45 44 39 37 byte

Bao gồm +1 cho -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

Mong đợi danh sách trên stdin. Ví dụ: tiếng vang 1 0 3 0 1 | perl -p file.pl


Tôi thấy một số bản sao dán ở đây .. ;-) Hoàn thành btw.
Kenney

3

Thạch, 12 11 byte

ḢWW;ḟ0Ṫr¥\F

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

Phiên bản thay thế, 8 byte (không cạnh tranh)

Thật không may, Jelly's popđã không chuyển sang lặp lại, trong phiên bản mới nhất trước thử thách này. Điều này đã được sửa, và các công việc sau đây trong phiên bản hiện tại.

ḟ0Ṫr¥\FḊ

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

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

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

Trong phiên bản thay thế, ḢWW;trở nên không cần thiết. Tuy nhiên, do phần tử đầu tiên được chuyển thành lặp lại trước khi bật, nên nó không thực sự được sửa đổi. Cuối cùng loại bỏ bản sao của phần tử đầu tiên.


3

Võng mạc, 39 34 31 byte

3 byte được lưu nhờ @Martin.

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

Đưa đầu vào và cho đầu ra trong unary.

Mã lặp đi lặp lại lấp đầy mọi chỗ trống (0) với previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1$1if_next_nonzero_number_bigger$3.

Với I / O thập phân, mã dài 51 byte như bạn có thể thấy trong trình thông dịch trực tuyến với tất cả các trường hợp thử nghiệm .


Bạn có thể lưu một byte khác bằng cách bỏ qua cái đầu tiên 1trong giao diện.
Martin Ender

@ MartinBüttner Phải, chỉnh sửa.
Randomra

2

GNU Sed (có execphần mở rộng sử dụng bash), 61

Điểm bao gồm +1 cho -rtùy chọn để sed.

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • Tìm chạy của 0s và thay thế chúng..
  • Đặt dấu ngoặc xung quanh các số điểm cuối để tạo ra một mở rộng dấu ngoặc nhọn như {1..4}cho các điểm cuối cục bộ. Cái hay của việc mở rộng bash brace ở đây là chuỗi được tạo sẽ luôn chạy đúng hướng, bất kể bắt đầu hay kết thúc lớn hơn.
  • Sử dụng etùy chọn cho slệnh để gọi ra bash để đánh giá việc mở rộng dấu ngoặc này
  • Nếu có thêm 0s được tìm thấy, nhảy trở lại bắt đầu.

Ideone.


2

Python 2, 195 111 byte (cảm ơn Alex !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

Đầu vào: phải là một [list]trong số int
Đầu ra: [list]của ints


Xin lỗi vì điều đó! Đã sửa. Cảm ơn cho những người đứng đầu lên.
vageli

Đừng lo lắng. Giải pháp tốt đẹp. :) Bạn có thể giảm xuống còn 112 byte bằng cách này , đây là cách tiếp cận tương tự của bạn, chỉ cần đánh gôn thêm một chút. Chúng tôi cũng có một bộ sưu tập các mẹo chơi golf trong Python ở đây .
Alex A.

1

Perl, 85 82 byte

bao gồm +1 cho -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

Mong đợi danh sách trên stdin. Ví dụ : echo 1 0 3 0 1 | perl -p file.pl.

Điều này sử dụng một regrec lồng nhau. Một chút có thể đọc được:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.

1

Python 2, 92 88 byte

(Loại bỏ biến trung gian)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]

1

Bình thường, 17 byte

u+G+treGHHfTtQ[hQ

Cách thức hoạt động:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

Nói cách khác: tất cả các số 0 được xóa khỏi đầu vào, sau đó một phạm vi độc quyền được chèn vào giữa mọi phần tử. Phạm vi này là độ dài bằng không trên các phần tử chỉ cách nhau một.



1

Vim: 231 lệnh chính

Lưu ý rằng bất kỳ ^ trước một ký tự có nghĩa là bạn nên giữ quyền kiểm soát trong khi nhập ký tự đó

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

Các bước để bạn có thể chạy này quá!

  1. Sao chép dòng vào Vim
  2. Nhập :s/\^V/<Ctrl-V><Ctrl-V>/gvà nhấn enter (hai s sẽ cung cấp cho bạn màu xanh ^ V)
  3. Nhập :s/\^R/<Ctrl-V><Ctrl-R>/gvà nhấn enter (bạn sẽ thấy màu xanh ^ R ngay bây giờ)
  4. Nhập :s/\^X/<Ctrl-V><Ctrl-X>/gvà nhấn enter (bạn sẽ thấy màu xanh ^ Xs ngay bây giờ)
  5. Nhập :s/\^O/<Ctrl-V><Ctrl-O>/gvà nhấn enter
  6. Nhập :s/\^A/<Ctrl-V><Ctrl-A>/gvà nhấn enter
  7. Nhập :s/\^\[/<Ctrl-V><Ctrl-[>/gvà nhấn enter (lệnh này hơi khác một chút vì tôi cần thoát [)
  8. Loại 0"yy$. Lệnh hiện được lưu trong thanh ghi y
  9. Thiết lập đầu vào trên một dòng và chạy với @y

Nếu ai đó biết một cách tốt hơn để chia sẻ lệnh, xin vui lòng cho tôi biết. Tôi biết điều này là dài, nhưng đó là điều tốt nhất tôi có thể nghĩ ra.

Đầu ra đầu vào

Chuỗi đầu vào phải ở một mình trên bất kỳ dòng nào trong tệp. 1 0 0 4 3 0 0 0 7 7

Đầu ra sẽ đơn giản ghi đè chuỗi đầu vào 1 2 3 4 3 4 5 6 7

Giải trình

Thuật toán

  1. Bắt đầu ở một số khác không, đảm bảo đó không phải là số cuối cùng
  2. Tìm số khác không tiếp theo
  3. Lấy sự khác biệt của họ. Nếu câu trả lời là âm, bạn nên giảm để sửa phạm vi, nếu không, tăng để sửa phạm vi.
  4. Quay trở lại ký tự đầu tiên và thay thế mỗi số 0 bằng cách tăng / giảm số trước đó.
  5. Lặp lại cho đến khi bạn đến nhân vật cuối cùng

Macro được sử dụng

@e - Kiểm tra kết thúc. Số cuối cùng sẽ có một e gắn vào nó. Nếu số bên dưới con trỏ có e ở cuối, hãy xóa e và dừng thực thi. Nếu không, hãy bắt đầu một chu trình nội suy với @b.

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b - Bắt đầu chu trình nội suy. Lưu số dưới con trỏ cho thao tác trừ (@s) và sau đó tìm thuật ngữ khác không tiếp theo (@f)

mayiwo^R"^V^X ^["sy0dd`a@f

@s - Lưu lệnh trừ để sử dụng trong @d. Nó chỉ đơn giản là (val)^Xnơi (val)số bắt đầu của bước nội suy. Điều này được đặt bởi lệnh @b.

@f - Tìm thuật ngữ khác không tiếp theo. Viết giá trị hiện tại vào thanh ghi không tên, sau đó viết @f @dvào dòng tiếp theo, rồi chạy @z. Điều này sẽ lặp lại lệnh này nếu số đó bằng 0 và thực thi @d nếu không.

wmbyiwo@f @d^[@z

@z - Thực thi có điều kiện nếu thanh ghi không tên là 0. Lệnh này mong đợi hai lệnh trên một dòng mới ở định dạng command1 command2. Nếu thanh ghi không tên là 0, command1được thực thi, nếu không thì command2được thực thi. Lưu ý rằng không có lệnh nào có thể có bất kỳ khoảng trắng nào trong đó.

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t - Đăng ký lệnh tạm thời. Lưu trữ các lệnh khác nhau trong một thời gian ngắn trước khi thực hiện chúng. Được sử dụng chủ yếu trong câu lệnh if.

@d - Xác định hướng nội suy. Trừ số đầu tiên trong chuỗi từ số dưới con trỏ (sử dụng @s). Nếu kết quả là âm, phép nội suy phải giảm để ^ X được lưu vào @a. Nếu không, chúng ta nên tăng để ^ A được lưu vào @a. Khi điều này được lưu, hãy quay trở lại điểm bắt đầu của chu trình nội suy này và chạy @i để thực sự nội suy

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - Lưu trữ ^Ahoặc ^Xtăng hoặc giảm trong bước nội suy. Điều này được đặt bởi lệnh @d.

@i - Nội suy. Sao chép số tại vị trí hiện tại vào @x và chuyển sang số tiếp theo. Nếu số đó bằng 0, hãy thay thế nó bằng @x và chạy @a để sửa đổi nó lên hoặc xuống một cách chính xác, sau đó lặp lại lệnh này. Nếu số không bằng 0, chúng ta đã đạt đến cuối chu kỳ nội suy này. Một số mới nên được bắt đầu với số này là số bắt đầu, vì vậy hãy chạy @e để kiểm tra kết thúc và chạy lại.

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x - Đăng ký lưu trữ tạm thời. Được sử dụng trong lệnh nội suy (@i)

Phá vỡ các tổ hợp phím

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run

0

Python 3.5, 159 byte

một giải pháp đệ quy

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

Ung dung

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

Trong giải pháp chơi gôn, tôi thay thế các điều kiện bằng cách sử dụng thực tế rằng h*True=hh*False=[]

Kết quả

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]


0

MATLAB, 39 38 37 byte

@(a)interp1(find(a),a(a>0),find(a/0))

Hàm ẩn danh nội suy tuyến tính giữa các điểm trong a. find(a)là một mảng các chỉ số của các phần tử khác không trong aa(a>0)là các giá trị dương. Đã lưu 1 byte nhờ vào đề xuất của một người bạn >chứ không phải ~=.

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.