範囲を修復する


30

いくつかがに置き換えられた正の整数のリストの入力が与えられた場合、置き換えられて0変更された欠損数を含むリストを出力します0

入力リストの特性:

  • リストの長さは常に少なくとも2です。

  • 入力リストをとして定義しa、「元のリスト」(つまり、番号が0s に置き換えられる前のリスト)を定義しますb。いずれの場合もn、またはのa[n]いずれb[n]0です。

  • いずれの場合もn、またはのb[n]いずれb[n-1] + 1b[n-1] - 1です。つまり、の数値bは常に1、以前のインデックスから各インデックスごとに変化します。もちろん、最初の要素はこの規則を免除されています。

  • ゼロのすべての実行a(つまり、連続した要素がに置き換えられます 0xに対して、実行の開始のインデックスとy 終了を表すa[x-1]to a[y+1]は、常に増加のみまたは減少のみのいずれかになります。したがって、ゼロを埋める方法は1つしかありません。

    • これは、配列の最初の要素も最後の要素もゼロにできないことも意味します。

簡単に言えば、ゼロの連続を埋めるには、前の数字から次の数字までの範囲に置き換えるだけです。たとえば、次の入力

1 2 0 0 0 6 7

出力する必要があります

1 2 3 4 5 6 7

これはであるため、バイト単位の最短コードが優先されます。

テストケース:

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

代わりに0、プログラムは次のような別の値を取ることができますnullか?
ダウンゴート

@Downgoatいいえ、欠落している数値はとして指定する必要があります0
ドアノブ

回答:


15

JavaScript(ES6)、72 66 64 54 53バイト

@Neilのおかげで12バイト節約されました!

@IsmaelMiguelのおかげで1バイト節約

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

JavaScriptにかなり適しています。


オンラインで試してみてください(すべてのブラウザが動作します)

説明

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
それa.find((q,r)=>r>i&&q)>b?++b:--bは同じだと思うb+=a.find((q,r)=>r>i&&q)>b||-1
イスマエルミゲル

@IsmaelMiguelそれは賢い、ありがとう!
ダウンゴート

どういたしまして。私はそれがあなたのために働いてうれしいです。
イスマエルミゲル

&&を&だけに置き換えることができると思います(説明に&が1つ、答えに2つあることに気づいただけです)
チャーリーウィン


7

Haskell、68 61 58バイト

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

使用例: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]

仕組み:入力からゼロを削除して、を呼び出しますg。ましょう残りのリストaの最初とb2番目の要素。リストをab-1からa下に連結しb+1(そのうちの1つは空になります)、aドロップされた再帰呼び出しを連結します。

編集:@Zgarbは3バイトを節約しました。ありがとう!


6

Mathematica、59バイト

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

テストケース

%[{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バイト

+1を含む -p

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

stdinのリストが必要です。例:echo 1 0 3 0 1 | perl -p file.pl


ここにコピーペーストが表示されます。;-)
ケニー

3

ゼリー、12 11バイト

ḢWW;ḟ0Ṫr¥\F

オンラインでお試しください!

代替バージョン、8バイト(非競合)

残念なことに、Jelly's popは、この課題より前の最新バージョンでは反復可能にキャストしませんでした。これは修正されており、現在のバージョンでは以下が機能します。

ḟ0Ṫr¥\FḊ

オンラインでお試しください!

使い方

Ḣ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.

代替バージョンでḢWW;は、不要になります。ただし、最初の要素はポップする前に反復可能にキャストされるため、実際には変更されません。最後は、最初の要素の重複を削除します。


3

網膜、39 34 31バイト

@Martinのおかげで3バイト節約されました。

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

入力を受け取り、出力を単項で与えます。

コードは、すべての空の場所(0)を反復的に埋めprevious_number - 1 + 2 * if_next_nonzero_number_biggerます。 previous_number - 1であり$1if_next_nonzero_number_biggerです$3

10進数のI / Oでは、すべてのテストケースでオンラインインタープリターで確認できるように、コードの長さは51バイトです。


1先読みの最初のバイトを省略することにより、別のバイトを保存できます。
マーティンエンダー

@MartinBüttner右、編集。
-randomra

2

GNU Sed(execbashを使用した拡張機能付き)、61

スコアには-rsedのオプションの+1が含まれます。

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • 0sの実行を見つけて置換する..
  • エンドポイント番号を中括弧で囲ん{1..4}で、ローカルエンドポイントのようにbash brace拡張を作成します。ここでのbashブレース拡張利点は、生成されたシーケンスが、開始または終了のどちらが大きいかに関係なく、常に正しい方向に実行されることです。
  • コマンドのeオプションを使用sしてbashを呼び出し、このブレースの展開を評価します
  • さらに0sが見つかった場合は、最初に戻ります。

イデオン。


2

Python 2、195 111バイト(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

入力:[list]intである必要があります
出力:[list]intsである


ごめんなさい!一定。ヘッドアップをありがとう。
バジェリ

心配ない。いい解決策。:) これを使用して112バイトまで減らすことができます。これは同じアプローチで、もう少しゴルフをします。Python ゴルフをするためのヒント集もここにあります
アレックスA.

1

Perl、85 82バイト

+1を含む -p

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

stdinのリストが必要です。例:echo 1 0 3 0 1 | perl -p file.pl

これはネストされた正規表現を使用します。やや読みやすい:

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バイト

(中間変数を削除)

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

1

Pyth、17バイト

u+G+treGHHfTtQ[hQ

仕組み:

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)

つまり、すべてのゼロが入力から削除され、すべての要素の間に排他的な範囲が挿入されます。この範囲は、1つだけ離れた要素の長さがゼロです。



1

Vim:231キーコマンド

文字の前に^がある場合は、その文字を入力するときにコントロールを保持する必要があることに注意してください。

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 

あなたもこれを実行できるようにステップ!

  1. 行をVimにコピーします
  2. タイプ :s/\^V/<Ctrl-V><Ctrl-V>/gしてEnterキーを押します(2つのsは青の^ Vになります)
  3. タイプ :s/\^R/<Ctrl-V><Ctrl-R>/gしてEnterキーを押します(青い^ Rsが表示されます)。
  4. タイプ :s/\^X/<Ctrl-V><Ctrl-X>/gしてEnterキーを押します(青い^ Xが表示されます)。
  5. タイプ :s/\^O/<Ctrl-V><Ctrl-O>/gしてEnterを押します
  6. タイプ :s/\^A/<Ctrl-V><Ctrl-A>/gしてEnterを押します
  7. タイプ :s/\^\[/<Ctrl-V><Ctrl-[>/gしてEnterを押します([]をエスケープする必要があるため、このコマンドは少し異なります)
  8. タイプ 0"yy$ます。コマンドは現在、yレジスタに格納されています
  9. 行に入力を設定し、次のコマンドで実行します @y

誰かがコマンドを共有するより良い方法を知っているなら、私に知らせてください。私はこれが長いことを知っていますが、私が思いつくことができる最高です。

入出力

入力文字列は、ファイル内の任意の行で単独でなければなりません。1 0 0 4 3 0 0 0 7

出力は単に入力文字列を上書きします1 2 3 4 3 4 5 6 7

説明

アルゴリズム

  1. ゼロ以外の数字から開始し、最後の数字ではないことを確認してください
  2. 次のゼロ以外の数を見つける
  3. それらの違いを取る。答えが否定である場合、範囲を修復するためにデクリメントする必要があり、そうでない場合、範囲を修復するためにインクリメントする必要があります。
  4. 最初の文字に戻り、前の数字を増減して各ゼロを置き換えます。
  5. 最後のキャラクターに到達するまで繰り返します

使用されるマクロ

@e-終了を確認します。最後の番号にはeが追加されます。カーソルの下の番号の末尾にeがある場合、eを削除して実行を停止します。それ以外の場合は、@ bで補間サイクルを開始します。

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

@b-補間サイクルを開始します。減算演算(@s)のためにカーソルの下の数値を保存してから、次の非ゼロの項(@f)を見つけます

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

@s-@dで使用する減算コマンドを格納します。補間ステップの開始時の番号は単純に(val)^Xあり(val)ます。これは、@ bコマンドによって設定されます。

@f-次の非ゼロ項を見つけます。現在の値を名前のないレジスタに書き込み@f @d、次の行に書き込み、@ zを実行します。これは、数値がゼロの場合はこのコマンドを繰り返し、そうでない場合は@dを実行します。

wmbyiwo@f @d^[@z

@z-名前のないレジスタが0の場合、条件付き実行。このコマンドは、形式の新しい行に2つのコマンドが必要ですcommand1 command2。名前のないレジスタが0の場合command1は実行され、そうでない場合command2は実行されます。どちらのコマンドにもスペースを含めることはできません。

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

@t-一時コマンドレジスタ。さまざまなコマンドを短時間実行してから実行します。主にifステートメントで使用されます。

@d-補間方向を決定します。(@sを使用して)カーソルの下の数値からシーケンスの最初の数値を減算します。結果が負の場合、^ Xが@aに保存されるように、補間は減少する必要があります。そうでなければ、^ Aが@aに保存されるようにインクリメントする必要があります。これが保存されたら、この補間サイクルの最初に戻り、@ iを実行して実際に補間します

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

@a- ^Aまたは^X補間ステップ中に増分または減分するためにをします。これは、@ dコマンドによって設定されます。

@i-補間。現在の場所の番号を@xにコピーし、次の番号に移動します。その数値がゼロの場合は、@ xに置き換え、@ aを実行して適切に上下に変更してから、このコマンドを繰り返します。数値がゼロでない場合、この補間サイクルの終わりに達しました。この番号を先頭として新しいものを開始する必要があるため、@ eを実行して終了を確認し、再度実行します。

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

@x-一時ストレージレジスタ。補間コマンドで使用(@i)

キーストロークを分解する

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バイト

再帰的な解決策

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)

非ゴルフ

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)

golfedソリューションでは、私がいるという事実を利用して条件を交換h*True=hし、h*False=[]

結果

>>> 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バイト

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

のポイント間を線形補間する無名関数afind(a)非ゼロ要素のインデックスの配列であり、aそしてa(a>0)正の値です。友人の提案で>はなくのおかげで1バイト節約されました~=

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.