デッドコード除去


20

デッドコードは何もせずに座っており、決して実行されないことを私たちに見つめています...しかし、今日は復canすることができます。

仕様

入力は複数行の文字列になります。

各行は、割り当てまたは式のいずれかです。

割り当て

割り当ては、<name> = number名前が文字、アンダースコア、数字のシーケンスであるが、数字で始まる形式ではありません。

変数は何度でも割り当てることができます。

表現

式は次の形式です <var_name OR number> <operation> <var_name OR number> ...

式は次の任意の組み合わせです。

  • 定義済みの変数
  • 基本的な算術演算子 +-*/
  • 数字(整数)

期待される出力

あなた出力冗長で文字列べき割り当て割り当てのいずれかによって使用されることはありません表現、それを後に除去します。ので、予めご了承ください割り当てが追加の場合も冗長化することができます割り当て同じ変数には、前に実行される表現変数を使用して実行されます。

テストケース

a = 10
a * 3

でる

a = 10
a * 3

foo = 8
2 - 1
a = 18

でる

2 - 1

a = 10
a = 8
b = 4
ab = 72  
b / 6
b + 1

でる

b = 4
b / 6
b + 1

a = 1
a = 2
a + 1

でる

a = 2
a + 1

FooBar1 = 0
Fuz__ = 8
Fuz__ / 1

でる

Fuz__ = 8
Fuz__ / 1

a = 1
a + 1
a = 2
a + 1

でる

a = 1
a + 1
a = 2
a + 1

a = 1
1 / 5 * 8 + 4

でる

1 / 5 * 8 + 4

a = 1
a + 1
a = 1
a + 1

でる

a = 1
a + 1
a = 1
a + 1

a = 7
5 / a

でる

a = 7
5 / a

1
この特に難しいケースを追加する必要がありますa = 1; a + 1; a = 1; a + 1;か?以前に同じ値()に設定されていたa = 1ためaに、2番目を破棄できる場合1
flodel

3
@flodelいいえ、値を見る必要はありません
Caridorc

@flodelテストケースが組み込まれました
-Caridorc

式の最初の要素としてではなく、式で変数が使用されるテストケースを追加する必要があります。特に重要なのは、式の最後のメンバーとしてです。
isaacg

@isaacgデッドコードなし、varはどこにでもあり、テストケースが追加されました
-Caridorc

回答:


9

PHP-197バイト

この関数は、各行を逆順で1つずつ分析し、使用される変数の配列を維持することにより機能します。

  • =行に等しい文字がある場合、それは割り当てです。
    • 変数が使用され、割り当てが有用であり、行が出力されますが、変数はそれ以上使用されていないと見なされます。
    • それ以外の場合は、何もしません。
  • それ以外の場合、行は式です。各スペースの後に行を分割し、使用される変数のリストに各シンボルを追加します。数字(12、...)と演算子は(+-、...)あまりにも追加されますが、彼らは、有効な変数名ではないので、それは問題ではありません。その後、行はもちろん印刷されます。
function($c){$u=[];foreach(array_reverse(split('
',$c))as$l){if($p=strpos($l,'=')){if(!isset($u[$x=substr($l,0,$p-1)]))continue;
unset($u[$x]);}else$u+=array_flip(split(' ',$l));$f="
$l$f";}echo$f;}

以下は、バージョン化されていないバージョンです。

function removeDeadCode($code)
{
    $usedVariables = [];
    $finalCode = '';

    foreach (array_reverse(explode("\n", $code)) as $line)
    {
        if ($equalPosition = strpos($line, '='))
        {
            $variable = substr($line, 0, $equalPosition - 1);
            if (isset($usedVariables[$variable]))
            {
                $finalCode = "\n" . $line . $finalCode;
                unset($usedVariables[$variable]);
            }
        }
        else
        {
            $usedVariables += array_flip(explode(' ', $line));
            $finalCode = "\n" . $line . $finalCode;
        }
    }

    echo $finalCode;
}

7

網膜、45バイト

m`^(\w+) =.*\n(?=((?!\b\1\b)[^!])*(^\1 =|\Z))
<empty>

カウントのために、各行は個別のファイル(<empty>空のファイル)\nに入り、実際の改行(0x0A)に置き換える必要があります。

これは、文字列が常に改行で終わることを前提としています。

この正規表現は.NET固有の機能を使用しないため、regex101でテストできます

考え方は非常に単純です。変数の別の使用を渡すことなく、同じ変数または文字列の末尾への別の割り当てを検索(前方検索)できるすべての割り当てを削除します。


6

Pyth、40バイト

eMf|!}K\=eT&Jf}+dhceTK++dYdPT!}KeJ_.__.z

ちょっと長いようです。明日は1バイトか2バイト節約できるかもしれません。

オンラインで試す:デモンストレーションまたはテストスイート

説明:

_.__.z入力行のすべての接尾辞を逆順にします。例えば、入力FooBar1 = 0; Fuz__ = 8; Fuz__ / 1はリストを提供します:

[['Fuz__ / 1', 'Fuz__ = 8', 'FooBar1 = 0'], 
 ['Fuz__ / 1', 'Fuz__ = 8']
 ['Fuz__ / 1']]

次いで、リスト要素のためのIフィルタT、ここで=の最後の要素であるしないT(式)または(割り当て)の最後の要素Tの変数名が含まれ、式です。その後、残りの各要素の最後の要素を別の行に出力します。

eMf|!}K\=eT&Jf}+dhceTK++dYdPT!}KeJ_.__.z
                                      .z  all input lines
                                     _    reverse order
                                   ._     all prefixes
                                  _       reverse order
  f                                       filter for elements T, which satisfy:
      K\=                                   K = '='
    !}K  eT                                 '=' is not in T[-1]
   |                                        or
             f             PT                 filter for elements Y in T[:-1],
                                              which satisfy:
                 hceTK                          extract variable name of T[-1]
                                                with an additional space at the end
               +d                               and at the beginning
              }       ++dYd                     ^ in space+Y+space
            J                                 assign these list to J
           &                                  J not empty and
                             !KeJ             '=' is not in J[-1]
eM                                        take the last element of each and print

8
.__.
すごい

このコードはpyth.herokuapp.com/…で
isaacg

@isaacg修正済み。
ジャクベ

4

CJam、49バイト

LqN/W%{_'=#_){(<:V1$\e=_{\Va-\}&}{;S/+1}?},\;W%N*

オンラインで試す

ここでのアプローチは、入力行を最初から最後まで処理している間、未割り当ての変数のリストが維持されることです。

  • 行が式の場合、式内のすべての変数がリストに追加されます。実際、実装では、コードを保存し、リストに数字と演算子を追加しても害はないため、すべてのトークンがリストに追加されます。

  • 行が割り当ての場合、割り当てられた変数名がリストにあるかどうかをテストします。そうである場合、割り当てが受け入れられ、変数名がリストから削除されます。それ以外の場合、割り当てはスキップされます。

説明 :

L     Start with empty list.
qN/   Get input and split at newlines.
W%    Reverse to process lines back to front.
{     Start of filter block.
  _     Copy line.
  '=#   Find equal sign.
  _     Copy position of equal sign, will use original later to extract
        variable name from assignment.
  )     Increment to produce truthy/falsy value (-1 from find means not found).
  {     Start if-block that processes assignments.
    (<    Slice off everything but variable name.
    :V    Save in variable V for later re-use.
    1$\   Place copy of unassigned variable list and new variable name at
          top of stack.
    e=    Count occurrences. This tells us if variable name was in list.
    _     Copy the condition value because it will also be used as the
          overall filter result.
    {     Start of block that removes variable name from list.
      \V    Bring list to top, and push variable name.
      a-    Remove the variable name from list.
      \     Swap to get variable list to bottom of stack for next iteration,
            and filter result to top.
    }&    End of conditional block to remove variable name.
  }     End of if-block for assignment.
  {     Start of else-block for expression.
    ;     Pop result of find operation.
    S/    Split expression at spaces.
    +     Concatenate the new variables with the existing ones in the list.
    1     Filter result, expressions are always accepted.
  }?    End of if for assignment vs. expression.
},    End of filter.
\;    Get rid of variable list at bottom of stack.
W%    Reverse order of filtered result, since we worked back to front.
N*    Join with newlines.

4

Python 2、270 267バイト

import sys,re
d={}
s=list(enumerate(sys.stdin))
for n,l in s:
 try:v,_=l.split('=');v=v.strip();d[v]=d.get(v,[])+[[0,n]]
 except:
  for v in re.findall('[a-zA-Z_]\w*',l):d[v][-1][0]+=1
print''.join(l for n,l in s if n not in[n for x in d.values()for c,n in x if c==0])

インデントは次のとおりです。1.スペース2.タブ

@Kamehamehaのおかげで3バイト節約できました!


で、印刷後のスペースprint ''.joininではin [n取り除くことができます。
カメハメハ

また、行の後にダブルスペースの代わりにを使用して1バイトを節約することにより、このトリックを使用できます。tabexcept
カメハメハ

2

R 144

Q=R=c()
for(L in rev(scan(,"",,,"\n"))){W=strsplit(L," ")[[1]]
if("="%in%W)if(W[1]%in%R)R=R[R!=W[1]]else next else R=c(R,W)
Q=c(L,Q)}write(Q,"")

どこで

  • L 入力からの行(最後の行から開始)
  • W 行の記号(変数、演算子、数字)
  • R印刷されるシンボルのベクトルです。割り当てが必要な変数が含まれます。
  • Q 出力のラインのベクトルです

あなたは置き換えることができscan(what="",sep="\n")scan(,"",sep="\n")。名前付きsep引数をそれに相当する位置に置き換えることもできますが、コンマがどこに行くのか思い出せません。
アレックスA.

...保存6.とてもいい。アレックス、ありがとう!
flodel

2

JavaScriptの(ES6)164 177

テンプレート文字列を使用すると、すべての改行が重要でカウントされます。

FireFoxでスニペットの実行をテストします(矢印関数を含むES6互換性に必要)

f=s=>(k=>{s=s.split`
`,s.map((t,n)=>(r=t.match(/\w+/g)).map(v=>k[v]=f,~t.search`=`?k[s[k[v=r[0]]]=r[0]=0,v]=n:0))
for(v in k)s[k[v]]=0})([])||s.filter(r=>r).join`
`

ungolfed=s=>
{
  k={} // list line defining variables, by name, until used
  s=s.split`\n`
  s.forEach((t,n)=>
  {
    r=t.match(/\w+/g); // list variables in the line, operators are lost
    if (t.search`=` >= 0) // if it's an assignment
    {
      v=r[0] // new variable
      s[k[v]]=r[0]=0 // kill previous definition if not used
      k[v]=n
    }
    r.forEach(v=>k[v]='') // for each used variable, forget its definition line
  })
  for(v in k)s[k[v]]=0; // kill all remaining unused definitions
  return s.filter(r=>r).join`\n`
}

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


;[['a = 10\na * 3', 'a = 10\na * 3']
 ,['foo = 8\n2 - 1\na = 18','2 - 1'] 
 ,['a = 10\na = 8\nb = 4\nab = 72\nb / 6\nb + 1','b = 4\nb / 6\nb + 1'] 
 ,['a = 1\na = 2\na + 1','a = 2\na + 1'] 
 ,['FooBar1 = 0\nFuz__ = 8\nFuz__ / 1','Fuz__ = 8\nFuz__ / 1'] 
 ,['a = 1\na + 1\na = 2\na + 1','a = 1\na + 1\na = 2\na + 1']
 ,['a = 1\na + a\na = 2', 'a = 1\na + a']
 ,['a = 1\n1 / 5 * 8 + 4', '1 / 5 * 8 + 4']
 ,['a = 1\na + a\na = 2', 'a = 1\na + a']
 ,['a = 1\na + 1\na = 1\na + 1', 'a = 1\na + 1\na = 1\na + 1']
 ,['a = 7\n5 / a', 'a = 7\n5 / a']
]
.forEach(([i,k])=>(r=f(i),
  out('Test '+(r==k?'OK':'Fail')+'\nInput:  '+i.replace(/\n/g,',')
      +'\nResult: '+r.replace(/\n/g,',')
      +'\nCheck:  '+k.replace(/\n/g,',')+'\n')
));
Note: newlines trasformed to commas to save space in output
<pre id=O></pre>


ねえ、それは164バイトではありません!
Cyphase

@Cyphaseライン1:20 + 1改行、ライン2; 92 + 1改行、ライン3:48 + 1改行、ライン4:1。21 + 93 + 49 + 1 =>164。このungolfed部分は説明のみを目的としています。TEST一部は...オムちょうど...推測する
edc65

知っている。ただの冗談です。ごめんなさい :)。
Cyphase

1

JavaScriptのES6、79 75 118バイト

s=>s.split`
`.filter((l,i,a)=>(q=l.split`=`)[1]?!~(a.slice(i+1)+0).search(q[0]+'=')&&~s.search(q[0]+'[^=]'):1).join`
`

これがケースで機能しない場合は教えてください。ゴルフのアイデアは大歓迎です。


説明

s=>          // Function with argument "s"
  s.split`   // Splits each line
  `
  .filter(   // Filters through each line,
    (item,index,array)=>
      (q=l.split`=`)[1]? // If there is something after the equal sign
        !~ // XOR (~) will  essentially make -1, 0. NOT (!) will make 0, 1, vice-versa
         (a.slice(i+1)+0) // Gets following lines
         .search`^${z=q[0]}=` // Checks if following lines have the same variable name and then =
        && // AND...
         ~s.search(z+'[^=]') // Check if there is an expression with the variable
        :1) // If there is no equal sign, return 1 (true)
  .join` // Join everything back, seperated by newlines
  `

Safari Nightlyでテスト済み。Firefoxフレンドリーバージョン:

s=>s.split`
`.filter((l,i,a)=>(q=l.split`=`)[1]?!~(a.slice(i+1)+0).search(`^${z=q[0]}=`)&&~s.search(z+'[^=]'):1).join`
`

babeljsにドロップインして、ES5バージョンを入手できます。


@Blackhole私はそれを修正しました。
ダウンゴート

@ edc65の例によれば、セパレータは改行です。入力もスペースなどを含む厳密な形式です。
Downgoat15年

@ edc65よろしいですか?関数を括弧で囲み、そのように実行してみてください。それは私のために働きます(Safari Nightly)。
ダウンゴート

頑固すぎるかもしれませんが、どんな場合でもうまくいくには単純すぎると感じています。Firefoxで検索呼び出しに角かっこを追加してエラーなしで実行しました(私よりもずっと短い)。そして、「a = 1 \ na + a \ na = 2」を試しました。そして、それは失敗します
...-edc65

あなたの答えに私の提案を追加してくれてありがとう。-1まだバグがあるため
edc65

1

Haskell、187バイト

を使用しdます。

import Data.List
f=filter
(!)=map
b((v,e,w):t)=e||or((\(_,p,_)->p)!take 1(f(\(x,_,y)->v==x||v`elem`y)t))
d=unlines.(\l->snd!f fst(zip(b!tails(((\(v:o:w)->(v,o/="=",w)).words)!l))l)).lines
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.