Ölü kod ortadan kaldırılması


20

Ölü kod orada hiçbir şey yapmadan oturur, asla idam edilmeyeceğini bilerek bize bakar ... ama bugün intikam alabiliriz.

Şartname

Giriş çok satırlı bir dize olacaktır.

Her satır bir ödev veya bir ifade olabilir .

atama

Ödev, <name> = numberadın bir harf, alt çizgi ve sayı dizisi olduğu, ancak bir rakamla başlamadığı biçimdedir .

Değişkenlere istediğiniz sayıda atanabilir.

ifade

Bir ifade şu şekildedir <var_name OR number> <operation> <var_name OR number> ...

Bir ifade aşağıdakilerin herhangi bir kombinasyonu olabilir:

  • Tanımlanmış değişkenler
  • Temel aritmetik işleçler +-*/
  • Sayılar (tamsayılar)

Beklenen çıktı

Dizeyi yedekli atamalarla , onu izleyen ifadelerin hiçbiri tarafından asla kullanılmayan atamalarla çıkarmalısınız . Bir ifadeden önce aynı değişkene ek bir atama yapılırsa atamaların da gereksiz hale getirilebileceğini lütfen unutmayın kullanan yürütülmeden .

Test senaryoları

içinde

a = 10
a * 3

dışarı

a = 10
a * 3

içinde

foo = 8
2 - 1
a = 18

dışarı

2 - 1

içinde

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

dışarı

b = 4
b / 6
b + 1

içinde

a = 1
a = 2
a + 1

dışarı

a = 2
a + 1

içinde

FooBar1 = 0
Fuz__ = 8
Fuz__ / 1

dışarı

Fuz__ = 8
Fuz__ / 1

içinde

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

dışarı

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

içinde

a = 1
1 / 5 * 8 + 4

dışarı

1 / 5 * 8 + 4

içinde

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

dışarı

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

içinde

a = 7
5 / a

dışarı

a = 7
5 / a

1
Bu özellikle zor durumda eklemek olmalı: a = 1; a + 1; a = 1; a + 1;? İkincisi a = 1, adaha önce aynı değere ayarlandığı için atılabilir ( 1).
flodel

3
@flodel Hayır, değerlere bakmaya gerek yok
Caridorc

@flodel testcase Incorporated
Caridorc

Bir değişkenin bir ifadede kullanıldığı, ancak ifadenin ilk öğesi olarak kullanılmadığı bir test durumu eklemelisiniz. Özellikle önemli olan ifadenin son üyesi.
isaacg

@isaacg ölü kod yok, var herhangi bir yerde olabilir, testcase eklendi
Caridorc

Yanıtlar:


9

PHP - 197 bayt

İşlev, her satırı ters sırada ve birbiri ardına analiz ederek ve kullanılan değişkenlerin bir dizisini koruyarak çalışır.

  • =Satırda eşit bir karakter varsa , bu bir ödevdir.
    • Değişken kullanılır, atama yararlıdır ve satır yazdırılır, ancak değişken artık kullanılmıyor olarak kabul edilmez.
    • Aksi takdirde, hiçbir şey yapmayın.
  • Aksi takdirde, çizgi bir ifadedir. Her boşluktan sonra çizgiyi ayırırız ve her sembolü kullanılan değişkenler listesine ekleriz. Sayılar ( 1,, 2…) ve işleçler ( +,, -…) de eklenecektir, ancak geçerli değişken adları olmadığından bu bir sorun değildir. Çizgi daha sonra elbette yazdırılır.
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;}

İşte ungolfed sürümü:

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

Retina , 45 bayt

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

Sayım amacıyla, her satır ayrı bir dosyaya ( <empty>boş bir dosyadır) gider ve \ngerçek bir satır beslemesi (0x0A) ile değiştirilmelidir.

Bu, dizenin her zaman bir satır feed'i ile biteceğini varsayar.

Bu normal ifade .NET'e özgü herhangi bir özellik kullanmadığından, normal ifadex101'de test edebilirsiniz .

Fikir oldukça basittir: Değişkenin başka bir kullanımını geçmeden aynı değişkene veya dizenin sonuna başka bir ödev bulabileceğimiz (ileriye doğru arama yapabileceğimiz) tüm ödevleri kaldırın.


6

Pyth, 40 bayt

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

Biraz uzun görünüyor. Belki yarın bir veya iki bayt tasarruf edebilirim.

Çevrimiçi deneyin: Gösteri veya Test Paketi

Açıklama:

_.__.zgiriş satırlarının tüm postfixlerini ters sırayla verir. Örneğin girdi FooBar1 = 0; Fuz__ = 8; Fuz__ / 1listeyi verir:

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

Daha sonra liste elemanları için bir filtre T, ki burada =son elemanının içinde değildir T(ifade) ya da (atama) son öğe Tdeğişken adı içeren, bir ifadesidir. Daha sonra, kalan öğelerin her birinin son öğesini ayrı bir satıra yazdırın.

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
Aww çok şirin ....__.
orlp


@isaacg Düzeltildi.
Jakube

4

CJam, 49 bayt

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

Çevrimiçi deneyin

Buradaki yaklaşım, giriş satırlarını öne doğru işlerken atanmamış değişkenlerin bir listesinin tutulmasıdır:

  • Çizgi bir ifadeyse, ifadedeki tüm değişkenler listeye eklenir. Aslında, uygulamada tüm kodlar listeye eklenir, çünkü kodu kaydeder ve listede sayı ve işleç bulundurmak herhangi bir zarar vermez.

  • Satır bir ödevse, atanan değişken adının listede olup olmadığını test eder. Öyleyse, atama kabul edilir ve değişken adı listeden kaldırılır. Aksi takdirde, atama atlanır.

Açıklama:

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 bayt

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])

Girinti: 1. Boşluk 2. Sekme

@Kamehameha sayesinde 3 bayt kaydedildi!


İçinde baskı sonrası boşluk print ''.joinve iniçinde in [nkaldırılabilir.
Kamehameha

Ayrıca, bu hile tab, daha sonra çift boşluk yerineexcept satırdan bir bayt .
Kamehameha

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,"")

nerede

  • L girişten bir satırdır (son satırdan başlayarak)
  • W bir satırdaki semboller (değişkenler, operatörler, sayılar)
  • Ryazdırılacak sembollerin bir vektörüdür. Ataması gereken değişkenleri içerir.
  • Q çıktıdaki satırların vektörüdür

Sen yerini alabilir scan(what="",sep="\n")ile scan(,"",sep="\n"). Ayrıca, adlandırılmış separgümanı konumsal eşdeğeriyle de değiştirebilirsiniz, ancak virgüllerin bunun için nereye gideceğini hatırlayamıyorum.
Alex

... tasarruf 6. Çok güzel. Teşekkürler Alex!
flodel

2

JavaScript (ES6) 164 177

Şablon dizelerini kullanarak, tüm yeni satırlar anlamlıdır ve sayılır.

İçinde pasajı çalışan test FireFox (ok fonksiyonları da dahil olmak üzere ES6 uyumluluk için gereklidir)

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>


Hey, bu 164 bayt değil!
Cyphase

@Cyphase line 1:20 + 1 satırsonu, satır 2; 92 + 1 satırsonu, satır 3:48 + 1 satırsonu, satır 4: 1. 21 + 93 + 49 + 1 => 164. ungolfedParça sadece açıklama amaçlıdır. TESTBölüm ... uhm sadece tahmin ... olan
edc65

Biliyorum. Sadece şaka yapıyordum. Üzgünüm :).
Cyphase

1

JavaScript ES6, 79 75 118 bayt

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`
`

Bunun bir dava için işe yarayıp yaramadığını söyle. Golf için herhangi bir fikir bekliyoruz.


açıklama

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'de test edildi. Firefox dostu sürüm:

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`
`

İçeri içine atabileceğiniz babeljs bir ES5 sürümü almak için.


@Blackhole Bunu düzelttim.
Downgoat

@ edc65 örneklere göre ayırıcı yeni satır. Girdi ayrıca boşluklar vb.
İle

@ edc65 Emin misin? İşlevi parantez içine almayı deneyin ve bu şekilde çalıştırın. Benim için çalışıyor (Safari Nightly).
Downgoat

Belki çok inatçıyım ama yine de her durumda iyi çalışmanın çok basit olduğunu hissediyorum. Arama çağrısında parantez ekleyerek Firefox'ta hatasız çalışmasını sağladım (hala benimkinden çok daha kısa). Ve denedim "a = 1 \ na + a \ na = 2". Ve başarısız ...
edc65

Cevabımı önerime eklediğin için teşekkürler. -1 çünkü hala dinlenmişti
edc65

1

Haskell, 187 bayt

Kullanın 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.