Penghapusan kode mati

20

Kode mati duduk di sana tidak melakukan apa-apa, menatap kami tahu itu tidak akan pernah dieksekusi ... tapi hari ini kita bisa membalas dendam.

Spesifikasi

Input akan berupa string multiline.

Setiap baris dapat berupa penugasan atau ungkapan .

Tugas

Tugas adalah bentuk di <name> = numbermana nama adalah urutan huruf, garis bawah dan angka, tetapi tidak dimulai dengan angka.

Variabel dapat ditetapkan berapa kali.

Ekspresi

Ekspresi adalah bentuk <var_name OR number> <operation> <var_name OR number> ...

Ekspresi dapat berupa kombinasi dari:

  • Variabel sudah ditentukan
  • Operator aritmatika dasar +-*/
  • Bilangan (bilangan bulat)

Output yang diharapkan

Anda harus mengeluarkan string dengan penugasan yang berlebihan , penugasan yang tidak pernah digunakan oleh ekspresi yang mengikutinya, dihapus. Harap perhatikan bahwa penugasan juga bisa dibuat berlebihan jika penugasan tambahan untuk variabel yang sama dilakukan sebelum ekspresi menggunakan variabel dieksekusi.

Uji kasus

di

a = 10
a * 3

di luar

a = 10
a * 3

di

foo = 8
2 - 1
a = 18

di luar

2 - 1

di

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

di luar

b = 4
b / 6
b + 1

di

a = 1
a = 2
a + 1

di luar

a = 2
a + 1

di

FooBar1 = 0
Fuz__ = 8
Fuz__ / 1

di luar

Fuz__ = 8
Fuz__ / 1

di

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

di luar

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

di

a = 1
1 / 5 * 8 + 4

di luar

1 / 5 * 8 + 4

di

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

di luar

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

di

a = 7
5 / a

di luar

a = 7
5 / a
Caridorc
sumber
1
Haruskah Anda menambahkan kasus yang sulit ini a = 1; a + 1; a = 1; a + 1;:? Di mana yang kedua a = 1dapat dibuang hanya karena asebelumnya disetel ke nilai yang sama ( 1).
flodel
3
@flodel Tidak, tidak perlu melihat nilai
Caridorc
@flodel testcase dimasukkan
Caridorc
Anda harus menambahkan kasus uji di mana variabel digunakan dalam ekspresi, tetapi bukan sebagai elemen pertama dari ekspresi. Yang paling penting adalah sebagai anggota terakhir dari ekspresi.
isaacg
@isaacg tidak ada kode mati, var mungkin ada di mana saja, testcase ditambahkan
Caridorc

Jawaban:

9

PHP - 197 byte

Fungsi ini bekerja dengan menganalisis setiap baris, dalam urutan terbalik dan satu demi satu, dan mempertahankan array dari variabel yang digunakan.

  • Jika ada karakter yang sama =di baris, itu adalah tugas.
    • Itu variabel yang digunakan, tugas itu berguna, dan garis dicetak, tetapi variabel tidak dianggap digunakan lagi.
    • Kalau tidak, jangan lakukan apa pun.
  • Kalau tidak, garis adalah ekspresi. Kami membagi garis setelah setiap spasi, dan menambahkan setiap simbol ke daftar variabel yang digunakan. Angka ( 1,, 2...) dan operator ( +,, -...) akan ditambahkan juga, tetapi karena mereka bukan nama variabel yang valid, itu bukan masalah. Garis itu tentu saja dicetak.
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;}

Ini adalah versi yang tidak disunat:

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;
}
Lubang hitam
sumber
7

Retina , 45 byte

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

Untuk tujuan penghitungan, setiap baris masuk dalam file terpisah (di mana <empty>file kosong) dan \nharus diganti dengan umpan baris aktual (0x0A).

Ini mengasumsikan bahwa string akan selalu diakhiri dengan umpan baris.

Karena regex ini tidak menggunakan fitur .NET khusus, Anda dapat mengujinya di regex101 .

Idenya cukup sederhana: hapus semua tugas dari mana kita dapat menemukan (mencari maju) tugas lain untuk variabel yang sama atau akhir string tanpa melewati penggunaan variabel lainnya.

Martin Ender
sumber
6

Pyth, 40 byte

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

Sepertinya agak lama. Mungkin saya bisa menyimpan satu atau dua byte besok.

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

_.__.zmemberikan semua postfix dari jalur input dalam urutan terbalik. Misalnya input FooBar1 = 0; Fuz__ = 8; Fuz__ / 1memberi daftar:

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

Lalu saya memfilter untuk elemen daftar T, di mana =tidak ada dalam elemen terakhir T(ekspresi) atau (penugasan) elemen terakhir T, yang berisi nama variabel, adalah ekspresi. Setelah itu cetak elemen terakhir dari masing-masing elemen yang tersisa pada baris terpisah.

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
Jakube
sumber
8
Aww itu sangat lucu ....__.
orlp
Kode ini gagal di pyth.herokuapp.com/...
isaacg
@isaacg Diperbaiki.
Jakube
4

CJam, 49 byte

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

Cobalah online

Pendekatan di sini adalah bahwa daftar variabel yang tidak ditugaskan dipertahankan saat memproses jalur input kembali ke depan:

  • Jika baris adalah ekspresi, semua variabel dalam ekspresi ditambahkan ke daftar. Sebenarnya, dalam implementasi, semua token ditambahkan ke daftar, karena menyimpan kode dan memiliki angka dan operator dalam daftar tidak membahayakan.

  • Jika baris adalah tugas, itu menguji apakah nama variabel yang ditugaskan ada dalam daftar. Jika ya, tugas diterima, dan nama variabel dihapus dari daftar. Kalau tidak, tugas dilewati.

Penjelasan:

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.
Reto Koradi
sumber
4

Python 2, 270 267 byte

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

Lekukan adalah: 1. Spasi 2. Tab

Disimpan 3 byte berkat @Kamehameha!

kirbyfan64sos
sumber
Ruang setelah mencetak masuk print ''.joindan inmasuk in [ndapat dihilangkan.
Kamehameha
Selain itu, Anda dapat menggunakan trik ini dengan menggunakan tabbukan spasi ganda setelah exceptbaris dan menyimpan satu byte.
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,"")

dimana

  • L adalah garis dari input (mulai dari yang terakhir)
  • W adalah simbol (variabel, operator, angka) dalam satu garis
  • Radalah vektor simbol yang akan dicetak. Ini termasuk variabel yang tugasnya diperlukan.
  • Q adalah vektor garis dalam output
flodel
sumber
Anda bisa menggantinya scan(what="",sep="\n")dengan scan(,"",sep="\n"). Anda mungkin juga dapat mengganti separgumen bernama dengan posisi yang setara, tetapi saya tidak dapat mengingat di mana koma akan pergi untuk itu.
Alex A.
... hemat 6. Sangat bagus. Alex terima kasih!
flodel
2

JavaScript (ES6) 164 177

Menggunakan string template, semua baris baru signifikan dan dihitung.

Tes menjalankan snippet di FireFox (diperlukan untuk kompatibilitas ES6 termasuk fungsi panah)

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>

edc65
sumber
Hei, itu bukan 164 byte!
Cyphase
@Cyphase baris 1:20 + 1 baris baru, baris 2; 92 + 1 baris baru, baris 3:48 + 1 baris baru, baris 4: 1. 21 + 93 + 49 + 1 => 164. Bagian ungolfedini hanya untuk penjelasan. The TESTBagian adalah ... uhm hanya menebak ...
edc65
Aku tahu. Aku hanya bercanda. Maaf :)
Cyphase
1

JavaScript ES6, 79 75 118 byte

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

Katakan jika ini tidak berhasil untuk sebuah kasing. Ada ide untuk bermain golf.


Penjelasan

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
  `

Diuji di Safari Nightly. Versi ramah 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`
`

Anda bisa mampir di babeljs untuk mendapatkan versi ES5.

Downgoat
sumber
@ Lubang Lubang Saya sudah memperbaikinya.
Downgoat
@ edc65 menurut contoh pemisah adalah baris baru. Input juga dalam format ketat dengan spasi, dll.
Downgoat
@ edc65 Anda yakin? Cobalah membungkus fungsi dalam tanda kurung dan menjalankannya seperti itu. Ini bekerja untuk saya (Safari Nightly).
Downgoat
Mungkin saya terlalu keras kepala tetapi saya masih merasa terlalu mudah untuk bekerja dengan baik dalam setiap kasus. Saya membuatnya berjalan tanpa kesalahan di Firefox menambahkan tanda kurung di panggilan pencarian (masih jauh lebih pendek dari saya). Dan mencoba "a = 1 \ na + a \ na = 2". Dan gagal ...
edc65
Terima kasih telah menambahkan saran saya ke jawaban Anda. -1 karena masih disadap
edc65
1

Haskell, 187 byte

Gunakan 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
Leif Willerts
sumber