การกำจัดรหัสที่ตายแล้ว


20

รหัสตายอยู่ที่นั่นไม่ทำอะไรเลยจ้องมองที่เรารู้ว่ามันจะไม่ถูกประหารชีวิต ... แต่วันนี้เราสามารถแก้แค้นได้

สเปค

อินพุตจะเป็นสตริงหลายบรรทัด

แต่ละบรรทัดอย่างใดอย่างหนึ่งอาจจะเป็นที่ได้รับมอบหมายหรือการแสดงออก

การมอบหมาย

การมอบหมายเป็นรูปแบบ<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ก่อนหน้านี้ถูกตั้งค่าเป็นค่าเดียวกัน ( 1)
flodel

3
@flodel ไม่ไม่จำเป็นต้องดูค่า
Caridorc

@flodel testcase จัดตั้งขึ้น
Caridorc

คุณควรเพิ่มกรณีทดสอบที่ใช้ตัวแปรในนิพจน์ แต่ไม่เป็นองค์ประกอบแรกของนิพจน์ สิ่งสำคัญอย่างยิ่งคือการเป็นสมาชิกคนสุดท้ายของการแสดงออก
isaacg

@isaacg ไม่มีรหัสตาย var อาจเป็นที่ใดก็ได้เพิ่ม testcase
Caridorc

คำตอบ:


9

PHP - 197 ไบต์

ฟังก์ชั่นการทำงานโดยการวิเคราะห์แต่ละบรรทัดในลำดับย้อนกลับและหนึ่งหลังจากที่อื่นและการบำรุงรักษาอาร์เรย์ของตัวแปรที่ใช้

  • หากมีอักขระที่เท่ากัน=ในบรรทัดแสดงว่าเป็นการกำหนด
    • มันเป็นตัวแปรที่ใช้การกำหนดมีประโยชน์และมีการพิมพ์บรรทัด แต่ตัวแปรจะไม่ถูกนำมาใช้อีกต่อไป
    • มิฉะนั้นไม่ทำอะไรเลย
  • มิฉะนั้นบรรทัดคือนิพจน์ เราแบ่งบรรทัดหลังแต่ละช่องว่างและเพิ่มแต่ละสัญลักษณ์ลงในรายการตัวแปรที่ใช้ จะเพิ่มตัวเลข ( 1,, 2…) และโอเปอเรเตอร์ ( +,, -…) ด้วยเช่นกัน แต่เนื่องจากชื่อตัวแปรไม่ถูกต้องจึงไม่มีปัญหา แน่นอนว่าบรรทัดนั้นถูกพิมพ์ออกมา
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)

นี่ถือว่าสมมติว่าสตริงจะจบลงด้วยการป้อนบรรทัดเสมอ

ในฐานะที่เป็น regex นี้ไม่ได้ใช้คุณสมบัติ .NET เฉพาะใด ๆคุณสามารถทดสอบบน regex101

แนวคิดนี้ค่อนข้างง่าย: ลบการกำหนดทั้งหมดที่เราสามารถค้นหา (ค้นหาไปข้างหน้า) การกำหนดอื่นให้กับตัวแปรเดียวกันหรือสิ้นสุดของสตริงโดยไม่ผ่านการใช้งานของตัวแปรอื่น


6

Pyth, 40 ไบต์

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

ดูเหมือนว่าจะนาน บางทีฉันสามารถบันทึกหนึ่งหรือสองไบต์ในวันพรุ่งนี้

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

_.__.zให้ postfix ทั้งหมดของบรรทัดอินพุตในลำดับที่กลับกัน เช่นอินพุตFooBar1 = 0; Fuz__ = 8; Fuz__ / 1ให้รายการ:

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

จากนั้นฉันกรององค์ประกอบรายการ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
มันน่ารักจัง ....__.
58

รหัสนี้ล้มเหลวในpyth.herokuapp.com/…
isaacg

@isaacg แก้ไขแล้ว
Jakube

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 bytes

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. Space 2. แท็บ

บันทึกแล้ว 3 ไบต์ขอบคุณ @Kamehameha!


พื้นที่หลังจากการพิมพ์ในprint ''.joinและinในin [nสามารถถอดออกได้
Kamehameha

นอกจากนี้คุณสามารถใช้เคล็ดลับนี้โดยใช้tabแทนการเว้นวรรคสองครั้งหลังexceptบรรทัดและบันทึกหนึ่งไบต์
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,"")

ที่ไหน

  • L เป็นเส้นจากอินพุต (เริ่มจากบรรทัดสุดท้าย)
  • W คือสัญลักษณ์ (ตัวแปรตัวดำเนินการตัวเลข) ในบรรทัด
  • Rเป็นเวกเตอร์ของสัญลักษณ์ที่จะพิมพ์ มันมีตัวแปรที่จำเป็นต้องได้รับมอบหมาย
  • Q เป็นเวกเตอร์ของเส้นในผลลัพธ์

คุณสามารถแทนที่ด้วยscan(what="",sep="\n") scan(,"",sep="\n")คุณอาจสามารถแทนที่sepอาร์กิวเมนต์ที่ตั้งชื่อด้วยตำแหน่งเทียบเท่า แต่ฉันจำไม่ได้ว่าจะใช้เครื่องหมายจุลภาคที่ไหน
Alex 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`
`

คุณสามารถแวะไปที่babeljเพื่อรับ ES5 เวอร์ชั่น


@ Blackhack ฉันได้รับการแก้ไขแล้ว
Downgoat

@ edc65 ตามตัวอย่างตัวคั่นเป็นบรรทัดใหม่ว่า อินพุตยังอยู่ในรูปแบบที่เข้มงวดพร้อมช่องว่างเป็นต้น
Downgoat

@ edc65 คุณแน่ใจหรือไม่ ลองห่อฟังก์ชันในวงเล็บแล้วเรียกใช้แบบนั้น มันใช้งานได้สำหรับฉัน (Safari Nightly)
Downgoat

บางทีฉันอาจจะดื้อเกินไป แต่ฉันก็ยังรู้สึกว่ามันง่ายเกินไปที่จะทำงานได้ดีในทุกกรณี ฉันทำให้มันทำงานโดยไม่มีข้อผิดพลาดใน Firefox เพิ่มวงเล็บในการค้นหา (ยังคงสั้นกว่าของฉัน) และลอง "a = 1 \ na + a \ na = 2" และมันก็ล้มเหลว ...
edc65

ขอบคุณที่เพิ่มคำแนะนำของฉันในคำตอบของคุณ -1 เพราะมันยัง
บั๊กอยู่

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.