空の空白を埋めて空のスペースを埋める


10

placeAt非負の整数の配列と非負の整数のインデックスを取る関数(など)を記述します。与えられたインデックスに1を配置し、他のエントリを1スポットシフトしてそのスポットを空にする必要があります。0は空のスポットを表します。

  • 目的のインデックスのエントリが0の場合は、1を入力します。
  • それ以外の場合は、インデックスの左側で最も近い0を探します。エントリをその左に1スポット左にシフトしてスペースを確保し、インデックスを1で埋めます。
  • 左側に0がない場合は、同じことを右に行ってください。
  • どちらも可能でない場合(つまり、0がない場合)は、配列を変更せずに返します。

アイテムは0インデックスです。関数名は任意の名前にすることができます。

例:

(文字は正の整数値を表します。)

[a, b, 0, c, d, 0] placeAt 2    // output [a, b, 1, c, d, 0]    place 2 is 0, just fill
[a, b, 0, c, d, 0] placeAt 3    // output [a, b, c, 1, d, 0]    place 3 is filled, shift items left
[a, b, 0, c, d, 0] placeAt 0    // output [1, a, b, c, d, 0]    place 0 is filled, can't shift left, shift items right
[a, b, 0, c, d, 0] placeAt 1    // output [a, 1, b, c, d, 0]    place 1 is filled, can't shift left, shift items right
[0, a, b, 0, c, d, 0] placeAt 2 // output [a, b, 1, 0, c, d, 0] place 2 is filled, shift items left
[0, a, b, 0, c, d, 0] placeAt 4 // output [0, a, b, c, 1, d, 0] place 4 is filled, shift items left (notice you keep shifting up until a 0)
[0, 2, 0, 2] placeAt 3          // output [0, 2, 2, 1]          place 3 is filled, shift items left

これはコードゴルフの挑戦です。9日の終わりに最短のエントリーが勝ちます。


4
両方が可能であるときに、左または右にシフトするかどうかをどのようにして知っていますか また、ない場合はどうなり0ますか?
— xnor 2015

のために[0, 2, 0, 2] placeAt 3、出力することは合法[2, 0, 2, 1]ですか?コードは実際に呼び出される関数である必要がありますplaceAtか?一部の言語には正確に関数がないことに注意してください。「例外をスローする」も一部の言語には適用されない場合があります。エラーを示す出力を許可することをお勧めします。
— xnor 2015

配列は負の値を持つことができますか?
— Kade

このチャレンジのルールでOPの意図を理解していると99%確信しているので、投稿を再編成し(現在はキューにあります)、質問に答えようとします。eguneys、必要に応じて私の答えを修正できます。
— ETHproductions 2015

@xnor左シフトは常に右シフトよりも優先されます。0がない場合は、元の配列を返します。また、これ[2, 0, 2, 1]は正当な出力ではありません。可能な限り少ない要素をシフトする必要があるため、関数には任意の名前を付けることができます。
— ETHproductions 2015

回答:


4

JavaScript(ES6)、85

EcmaScript 6に準拠した任意のブラウザーでスニペットを実行してテストします(特にChromeはMSIEではありません。Firefoxでテストした場合、Safari 9は実行できます)。

(私は他の答えをまったく見ずにこれを見つけました、今、それはリンクのものと非常に似ていることがわかります。それでもかなり短いです。おそらく、これに対する多くの賛成を得ることはありません)

F=(a,p,q=~a.lastIndexOf(0,p)||~a.indexOf(0))=>(q&&(a.splice(~q,1),a.splice(p,0,1)),a)

// Ungolfed
U=(a,p)=>{
  q = a.lastIndexOf(0, p)
  if (q < 0) q = a.indexOf(0)
  if (q >= 0) {
    a.splice(q, 1)
    a.splice(p, 0, 1)
  }
  return a
}  

// TEST
out=x=>O.innerHTML+=x+'\n';

[ [['a', 'b', 0, 'c', 'd', 0], 2, ['a', 'b', 1, 'c', 'd', 0]] // place 2 is 0, just fill
, [['a', 'b', 0, 'c', 'd', 0], 3, ['a', 'b', 'c', 1, 'd', 0]] // place 3 is filled, shift items left
, [['a', 'b', 0, 'c', 'd', 0], 0, [1, 'a', 'b', 'c', 'd', 0]] // place 0 is filled, can't shift left, shift items right
, [['a', 'b', 0, 'c', 'd', 0], 1, ['a', 1, 'b', 'c', 'd', 0]] // place 1 is filled, can't shift left, shift items right
, [[0, 'a', 'b', 0, 'c', 'd', 0], 2, ['a', 'b', 1, 0, 'c', 'd', 0]] // place 2 is filled, shift items left
, [[0, 'a', 'b', 0, 'c', 'd', 0], 4, [0, 'a', 'b', 'c', 1, 'd', 0]] // place 4 is filled, shift items left (notice you keep shifting up until a 0)
, [['a', 'b', 'c', 'd'], 2, ['a', 'b', 'c', 'd']] // impossible
, [[0, 2, 0, 2], 3, [0, 2, 2, 1]]] // place 3 is filled, shift items left
.forEach(t=>{
  i=t[0]+''
  r=F(t[0],t[1])+''
  k=t[2]+''
  out('Test ' + (r==k?'OK':'Fail') +'\nInput: '+i+' '+t[1]+'\nResult:'+r+'\nCheck: '+k+'\n')
})
<pre id=O></pre>


+1は、コンマ演算子について、そして私を倒すために学んだところです
— rink.attendant.6 '17

@ rink.attendant.6しかし、&&を使用した結合spliceは、私のコンマよりも優れています
— edc65

3

ジュリア、122バイト

物事を始めるためのスペックの単純な実装。

f(x,i)=(i+=1;x[i]==0?(x[i]=1):i>2&&x[i-1]==0?(x[i-1]=x[i];x[i]=1):i<length(x)-1&&x[i+1]==0?(x[i+1]=x[i];x[i]=1):error();x)

非ゴルフ:

function placeAt(x::Array, i::Int)
    # Make i 1-indexed
    i += 1

    # Shift and modify the array as necessary
    if x[i] == 0
        x[i] = 1
    elseif i > 2 && x[i-1] == 0
        x[i-1], x[i] = x[i], 1
    elseif i < length(x)-1 && x[i+1] == 0
        x[i+1], x[i] = x[i], 1
    else
        error()
    end

    # Return the modified array
    x
end

1

JavaScript(ES6)、98バイト

CoffeeScriptの回答とほとんど同じアプローチですが、returnステートメントを保存するために極端に短絡しています。

f=(a,x)=>(~($=a.lastIndexOf(0,x))||~(_=a.indexOf(0,x)))&&a.splice(~$?$:_,1)&&a.splice(x,0,1)&&a||a

説明

説明を簡単にするために、コードを少し並べ替えました。

// Declare function f with two arguments: array and position
f = (a, x) => {
    // Take the part of the array from beginning to x and find the last 0
    $ = a.lastIndexOf(0, x)

    // Find the first 0 after position x
    _ = a.indexOf(0, x);

    // indexOf returns -1 if they aren't found
    // ~1 == 0 so I am checking if either $ or _ is truthy (zeros were found)
    if (~$ || ~_)
       // If zeros were found in the left, use that.
       // Otherwise use the found zero in the right.
       // Delete it from the array
       // Array.prototype.splice will return an array which evaluates to truthy
       // and continues execution with the &&
       // Insert value 1 at position x, deleting 0 elements
       // The last value is returned
       return a.splice(~$ ? $ : _, 1) && a.splice(x, 0, 1) && a
    else
       // No zeros were found so just return the original
       // In the golfed code the if would have evaluated to false to cut into the || part
       return a
}

JS短絡評価に関する情報をいくつか示します。

デモ

現時点では、ES6を使用しているため、このデモはFirefoxとEdgeでのみ機能します。

f=(a,x)=>(~($=a.lastIndexOf(0,x))||~(_=a.indexOf(0,x)))&&a.splice(~$?$:_,1)&&a.splice(x,0,1)&&a||a

// Snippet stuff
console.log = x => O.innerHTML += x + '\n';

console.log(f(['a', 'b', 0, 'c', 'd', 0], 2))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 3))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 0))
console.log(f([0, 'a', 'b', 0, 'c', 'd', 0], 2))
console.log(f([0, 'a', 'b', 0, 'c', 'd', 0], 4))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 2))
console.log(f(['a', 'b', 0, 'c', 'd', 0], 1))
<pre id=O></pre>


これはどのように機能しますか、説明してください。
— eguneys

@eguneys説明が追加されました
— rink.attendant.6 2015

それは動作しませんf(['a', 'b', 0, 'c', 'd', 0], 2)
— eguneys

@eguneys修正されました。CoffeeScriptが短縮形スライスを使用すると、自動的に1つ追加されることを忘れていました[a..b]。
— rink.attendant.6 2015

動作しないf(['a', 'b', 0, 'c', 'd', 0], 1)
— eguneys

1

Ruby、208バイト

def f(a,i)
  x=a.take(i).rindex(0);y=a[i+1..-1].index(0)
  if a[i]==0
    a[i]=1
  elsif !x.nil?
    a.delete_at(x);a.insert(i,1)
  elsif !y.nil?
    a.delete_at(y+i+1);a.insert(i,1)
  end
  a
end

PPCGへようこそ!Rubyの簡単なゴルフのヒント:インデントは必要ないため、すべてのスペースを取り除くことができます。その場合、単一の改行は同じバイト数であるため、セミコロンも必要ありません。ステートメントの最後のメソッド呼び出しには括弧は必要ないため、たとえば.rindex 0毎回1バイトを節約できます。メソッドの代わりにprocを使用して、いくつかのバイトを節約することもできます。これは、名前を付ける必要さえありません->a,i{...}。if / elsif / elsifは、おそらくネストされた3項演算子で短縮でき...?...:...?...:...ます。
— マーティンエンダー2015

親切なアドバイスをありがとうございました。調べて、何ができるか見てみます。
— 2015

1

Haskell、119バイト

e=elem 0
r=reverse
f=(g.).splitAt
g(a,y@(x:b))|e(x:a)=r(h(x:r a)1)++b|e y=a++h y 1|1<2=a++y 
h(0:r)n=n:r
h(a:r)n=n:h r a

使用例:

*Main> mapM_ (print.uncurry f) [ 
                (2,[2,3,0,4,5,0]),
                (3,[2,3,0,4,5,0]),
                (0,[2,3,0,4,5,0]),
                (1,[2,3,0,4,5,0]),
                (2,[0,2,3,0,4,5,0]),
                (4,[0,2,3,0,4,5,0]),
                (3,[0,2,0,2]),
                (2,[2,3,4,5])  ]
[2,3,1,4,5,0]
[2,3,4,1,5,0]
[1,2,3,4,5,0]
[2,1,3,4,5,0]
[2,3,1,0,4,5,0]
[0,2,3,4,1,5,0]
[0,2,2,1]
[2,3,4,5]

仕組み:指定された位置にある入力リストを左側の部分aに、要素自体の位置にx、右側の部分に分割しbます。0in がある場合は、の逆のa++x最初までスペースを作ります。にがある場合は、そこにスペースを作ります。まったくない場合は、すべての部分を変更せずに組み合わせて、元のリストを再度取得します。0a++x0x++b0


0

CoffeeScript、96バイト

f=(a,_)->a.splice((if~($=a.lastIndexOf 0,_)then $ else a.indexOf 0),1);a.splice(_,0,1)if 0in a;a

0

Python 2、102バイト

def f(a,i):
 x=(a[i-1::-1]+a[i:]+[0]).index(0)
 if x<len(a):del a[(x,i-x-1)[x<i]];a[i:i]=[1]
 return a

削除するゼロのインデックスを計算します。挿入インデックスまで逆にしたリストをインデックスの後ろの部分と通常の順序で連結し、最初のゼロのインデックスを見つけます。ValueErrorゼロが見つからない場合の例外を回避するために、最後にゼロが追加されます。次に、削除、挿入、および戻ります。


0

R、87バイト

f=function(a,i)if(0%in%a)append(a[-abs(min((b=which(a==0))*(1-(b<=i+1)*2)))],1,i)else a

説明

function(a,i)
if(0%in%a)                      # as long as a 0 exists
    append(                     # append 1 after i
        a[
          -abs(                 # remove absolute of min index
            min(                # minimum of adjusted index
              (b=which(a==0))*  # index of all 0's
              (1-(b<=i+1)*2)    # multiple -1 if <= i
              )
            )
        ]
        ,1
        ,i
    )
else                            # otherwise return untouched
    a

テスト

> f(c(2, 3, 0, 4, 5, 0) , 2)   
[1] 2 3 1 4 5 0
> f(c(2, 3, 0, 4, 5, 0) , 3)   
[1] 2 3 4 1 5 0
> f(c(2, 3, 0, 4, 5, 0) , 0)   
[1] 1 2 3 4 5 0
> f(c(2, 3, 0, 4, 5, 0) , 1)   
[1] 2 1 3 4 5 0
> f(c(0, 2, 3, 0, 4, 5, 0) , 2)
[1] 2 3 1 0 4 5 0
> f(c(0, 2, 3, 0, 4, 5, 0) , 4)
[1] 0 2 3 4 1 5 0
> f(c(0, 2, 0, 2) , 3)         
[1] 0 2 2 1
> 

0

C#、265バイト

ゴルフ(265文字)

static void placeAt(String[]Q,int P){int I;if(Q[P]=="0"){Q[P]="1";}else{I=Array.IndexOf(Q,"0");if(I>=0){if(I<P){for(int i=I;i<=P;i++){Q[i]=(i==P)?"1":Q[i+1];}}else if(I>P){for(int i=I;i>=P;i--){Q[i]=(i==P)?"1":Q[i-1];}}}}foreach(String s in Q)Console.Write(s+" ");}

空白とインデント付き

static void placeAt(String[] Q, int P)
    {
        int I;

        if(Q[P] == "0")
        {
            Q[P] = "1";
        }
        else
        {
            I = Array.IndexOf(Q, "0");
            if (I >= 0)
            {
                if (I < P)
                {
                    for (int i = I; i <= P; i++)
                    {
                        Q[i] = (i == P) ? "1" : Q[i + 1];
                    }
                }
                else if (I > P)
                {
                    for (int i = I; i >= P; i--)
                    {
                        Q[i] = (i == P) ? "1" : Q[i - 1];
                    }
                }
            }
        }

        foreach (String s in Q)
            Console.Write(s + " ");
    }

プログラム全体

using System;

class FillZero
{
    static void placeAt(String[] Q, int P)
    {
        int I;

        if(Q[P] == "0")
        {
            Q[P] = "1";
        }
        else
        {
            I = Array.IndexOf(Q, "0");
            if (I >= 0)
            {
                if (I < P)
                {
                    for (int i = I; i <= P; i++)
                    {
                        Q[i] = (i == P) ? "1" : Q[i + 1];
                    }
                }
                else if (I > P)
                {
                    for (int i = I; i >= P; i--)
                    {
                        Q[i] = (i == P) ? "1" : Q[i - 1];
                    }
                }
            }
        }

        foreach (String s in Q)
            Console.Write(s + " ");
    }

    static void Main()
    {
        String[] X = {"a", "b", "0", "c", "d", "0"};
        placeAt(X , 1);

    }

}

テストケース ここに画像の説明を入力してください


1
これは機能しません([0, 'a', 'b', 0, 'c', 'd'], 2)
— eguneys

1
たとえばString[] Q, int Pに、不要な空白をすべて削除することで、一部の文字を節約できますString[]Q,int P。
— ProgramFOX 2015

こんにちは@eguneys、指摘してくれてありがとう。ロジックを変更したため、すべてのテストケースで機能します。テストケースの画像も更新しました。配置は正しく行われますが、シフト結果は異なります。
— Merin Nakarmi、2015

@ProgramFOX様、貴重なコメントありがとうございます。約10文字を保存しました。
— Merin Nakarmi、2015

0

C、154バイト

p(a,l,i,c)int*a;{for(c=i;c+1;c--){if(!a[c]){for(;c<i;c++)a[c]=a[c+1];return a[i]=1;}}for(c=i;c<l;c++){if(!a[c]){for(;c>i;c--)a[c]=a[c-1];return a[i]=1;}}}

与えられたテストケースを渡し、配列へのポインタで、lは、アレイ(私はこれは簡単には壊れません願っています)の長さであり、私は挿入のための指標であり、cが内部的に使用されます。ループの左と右の検索を組み合わせることで改善される可能性があります。

例

int main(int argc, char * argv[]) {
    int a[] = {0, 2, 0, 2};
    p(a, 4, 3);
}

未ゴルフ

単純明快で、K&Rスタイルの宣言を超えるトリックはありません。

p(a,l,i,c) int *a; {
    /* Search left from i (also handles a[i] == 0) */
    for (c=i;c+1;c--) {
            if (!a[c]) {
                    /* Shift items left until i */ 
                    for (;c<i;c++) a[c]=a[c+1];
                    return a[i]=1;
            }
    }
    /* Search right from i */
    for (c=i;c<l;c++) {
            if(!a[c]) {
                    /* Shift items right until i */
                    for(;c>i;c--) a[c]=a[c-1]; 
                    return a[i]=1;
            }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.