Monday Mini-Golf # 3: ระยะทางแอนนาแกรม


24

Monday Mini-Golf:ชุดของความท้าทายสั้น ๆโพสต์ (หวังว่า!) ทุกวันจันทร์
(ขอโทษทีช้าไปหน่อย)

ฉันแน่ใจว่าคนส่วนใหญ่ของคุณเคยได้ยินระยะทางของLevenshteinซึ่งเป็นอัลกอริทึมสำหรับการคำนวณระยะห่างระหว่างสองสาย ดีความท้าทายนี้เป็นเรื่องเกี่ยวกับการใช้อัลกอริทึมของการประดิษฐ์ * ของตัวเองที่คล้ายกันเรียกว่าระยะทางแอนนาแกรม ความแตกต่างที่สำคัญคือลำดับของตัวละครนั้นไม่สำคัญ จะวัดเฉพาะอักขระที่ไม่ซ้ำกับสตริงหนึ่งหรืออักขระอื่นเท่านั้น

ท้าทาย

เป้าหมายของการท้าทายคือการเขียนโปรแกรมหรือฟังก์ชั่นที่ใช้สองสายและส่งคืนระยะห่างระหว่างแอนนาแกรม วิธีหลักในการทำเช่นนี้คือการใช้ตรรกะต่อไปนี้:

  1. แปลงทั้งสองสตริงเป็นตัวพิมพ์เล็กและ (เป็นทางเลือก) จัดเรียงอักขระตามลำดับตัวอักษร
  2. ในขณะที่สตริงมีอักขระที่เท่าเทียมกันอย่างน้อยหนึ่งตัวให้ลบอินสแตนซ์แรกของอักขระนี้ออกจากแต่ละสตริง
  3. เพิ่มความยาวของสตริงที่เหลือและส่งคืน / ผลลัพธ์

ตัวอย่าง

หากอินพุตเป็น:

Hello, world!
Code golf!

จากนั้นลดขนาดและเรียงลำดับสิ่งเหล่านี้จะกลายเป็น: (ตามการเรียงลำดับเริ่มต้นของ JS ให้สังเกตช่องว่างนำหน้า)

 !,dehllloorw
 !cdefgloo

การลบตัวละครทั้งหมดที่อยู่ในสตริงทั้งสองนั้นเราก็จบลงด้วย:

,hllrw
cfg

ดังนั้นระยะห่างระหว่างแอนนาแกรมระหว่างสองสายดั้งเดิม = 6 + 3 = 9

รายละเอียด

  • สตริงอาจถูกนำมาใช้ในรูปแบบที่เหมาะสม
  • สตริงจะประกอบด้วย ASCII ที่พิมพ์ได้เท่านั้น
  • สตริงเองจะไม่มีช่องว่างใด ๆ นอกเหนือจากช่องว่างปกติ (ไม่มีแท็บบรรทัดใหม่ ฯลฯ )
  • คุณไม่จำเป็นต้องใช้อัลกอริทึมที่แน่นอนนี้ตราบใดที่ผลลัพธ์เหมือนกัน

การทดสอบกรณี

อินพุต 1:

Hello, world!
Code golf!

เอาท์พุท 1:

9

อินพุต 2:

12345 This is some text.
.txet emos si sihT 54321

เอาท์พุท 2:

0

อินพุต 3:

All unique characters here!
Bdfgjkmopvwxyz?

เอาท์พุท 3:

42

อินพุต 4:

This is not exactly like Levenshtein distance,
but you'll notice it is quite similar.

เอาท์พุท 4:

30

อินพุต 5:

all lowercase.
ALL UPPERCASE!

ผลลัพธ์ 5:

8

เกณฑ์การให้คะแนน

นี่คือดังนั้นรหัสที่ถูกต้องสั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker ไปที่การส่งที่ถึงจำนวนไบต์สุดท้ายก่อน ผู้ชนะจะได้รับเลือกในวันจันทร์ที่ 12 ตุลาคมโชคดี!

แก้ไข:ขอแสดงความยินดีกับผู้ชนะ @isaacg โดยใช้ Pyth (อีกครั้ง) เป็นเวลา12 ไบต์!

* หากอัลกอริทึมนี้ถูกใช้ในที่อื่นและ / หรือตั้งชื่ออื่นโปรดแจ้งให้เราทราบ! ฉันไม่สามารถค้นหาได้ด้วยการค้นหา 20 นาที


การอธิบายภารกิจในฐานะ“ เขียนโปรแกรม […] ที่ [ทำสิ่ง] โดยใช้ตรรกะต่อไปนี้” เพื่อเพิ่มในภายหลัง“ คุณไม่จำเป็นต้องใช้อัลกอริทึมที่แน่นอน […]” นี้เป็นสิ่งที่ขัดแย้งกัน
Édouard

@ Édouard True; ขอบคุณสำหรับการชี้ให้เห็นว่า ฉันเชื่อว่ามันจะดีขึ้นแล้ว
ETHproductions

มันเป็นแล้วอังคารอีกครั้ง ;)
Martin Ender

@ MartinBüttnerมันยากที่จะเขียนความท้าทายในขณะที่คุณอยู่บนท้องถนนโดยไม่ต้องใช้ Wi-Fi ;) ไม่ต้องกังวลฉันจะมีใหม่พร้อมเล็กน้อย
ETHproductions

คำตอบ:


14

Pyth, 12 ไบต์

ls.-M.prR0.z

ชุดทดสอบ

การดำเนินการที่เป็นปัญหานั้นเทียบเท่ากับตัวดำเนินการลบแบบสองส่วนของ Pyth .-ซึ่งใช้ทั้งสองทิศทาง คุณสามารถเรียกมันว่า bagwise xor ได้ฉันว่า

ทางออกคือ:

.z: รับอินพุตเป็นรายการของ 2 สาย

rR0: แปลงทั้งสองเป็นตัวพิมพ์เล็ก

.p: ฟอร์มการเรียงสับเปลี่ยนทั้งหมดเช่นปกติและย้อนกลับ

.-M: แมป.-การดำเนินการผ่านการสั่งซื้อแต่ละครั้ง

s: เชื่อมผลลัพธ์เข้าด้วยกัน

l: พิมพ์ความยาว


และฉันคิดว่าคำตอบทั้งหมดอาจยาวเกินไป .... ทำได้ดีมาก!
ETHproductions

8

JavaScript (ES7), 92 ไบต์

กำหนดฟังก์ชั่นที่ไม่ระบุชื่อ

ในการทดสอบให้เรียกใช้ตัวอย่างข้อมูลด้านล่าง คุณสามารถแก้ไขรหัสและคลิก 'ทดสอบ' เพื่อเปรียบเทียบผลลัพธ์กับต้นฉบับ (แสดงความคิดเห็นหากคุณพบว่าการปรับปรุง!) การป้อนข้อมูลเป็นเหมือน"Hello, world!", "Code golf!"ในกล่องใส่

ขอบคุณ @ETHproductions สำหรับการบันทึก 6 ไบต์!


(a,b)=>[for(v of a[t="toLowerCase"]())if((b=b[t]())==(b=b.replace(v,"")))v][l="length"]+b[l]
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

เพิ่มเติมเกี่ยวกับชุดทดสอบ


มันทำงานอย่างไร

//Define function w/ paramters a, b
(a,b)=>
     //lowercase a
     //for each character v in a:
     [for(v of a[t="toLowerCase"]())
          //lowercase b
          //remove the first instance of v in b
          //if b before removal equals b after removal (if nothing was removed):
          if((b=b[t]())==(b=b.replace(v,"")))
               //keep v in the array of a's values to keep
               v]
     //get the length of the computed array
     [l="length"]
     //add b's length
     +b[l]
     //implicitly return the sum

ฉันทำงานกับคำตอบ ES6 แบบอาเรย์เป็นเวลาหนึ่งชั่วโมงและทำได้แค่ลงไปที่ 122 ดูเหมือนว่าฉันกำลังมองไปในทิศทางที่ผิด! +1
ETHproductions

BTW คุณสามารถแทนที่.join("")+bด้วย.join``+bไม่มีผลกระทบ
ETHproductions

1
ว้าวคุณได้รับชุดทดสอบนั้นอยู่ที่ไหน มันยอดเยี่ยม! ฉันหวังว่าฉันจะสามารถ +1 อีกสามหรือสี่ครั้ง ....
ETHproductions

@ETHproductions ขอขอบคุณ! : DI ทำชุดทดสอบด้วยตัวเองจริง ๆ แล้ว ลองดูโพสต์เมตาของฉัน!
jrich

ฉัน +1 ที่นี่หวังว่ามันจะไม่สามารถ +5 ได้ที่นี่ ;)
ETHproductions

6

CJam, 23 19 ไบต์

2{'¡,lelfe=}*.-:z:+

ลองใช้ออนไลน์ในล่าม CJam

มันทำงานอย่างไร

2{         }*        Do the following twice:
  '¡,                  Push the string of the first 161 Unicode charcters.
     lel               Read a line from STDIN and convert it to lowercase.
        fe=            Count the number of occurrences of each of the 160
                       characters in the lowercased line.
             .-      Vectorized subtraction; push the differences of the
                     occurrences of all 161 characters.
               :z    Apply absolute value to each difference.
                 :+  Push the sum of all results.

4

ทับทิม, 62

#!ruby -naF|
gets
p$F.count{|c|!$_.sub!(/#{Regexp.escape c}/i){}}+~/$/

จะต้องมีวิธีที่ดีกว่า

แก้ไข: 57 ตัวอักษรขอบคุณ iamnotmaynard ตรวจสอบเส้นทางที่ฉันขี้เกียจเกินไป

#!ruby -naF|
gets.upcase!
p$F.count{|c|!$_.sub!(c.upcase){}}+~/$/

subสามารถใช้สาย คุณไม่สามารถใช้c.downcaseแทนได้/#{Regexp.escape c}/iหรือ
Reinstate Monica iamnotmaynard

ฉันต้อง downcase ทั้งสตริง (หรือ upcase เท่า.)
histocrat

อ่าแน่นอน (แม้ว่าฉันจะรู้สึกว่าการทำเช่นนั้นจะช่วยให้คุณประหยัดได้ไม่กี่ไบต์)
Reinstate Monica iamnotmaynard

4

Python, 90 87 81 80 79 ไบต์

lambda a,b,s=str.lower:sum(abs(s(a).count(c)-s(b).count(c)))for c in{*s(a+b)}))

Python <3.5 รุ่น 80 ไบต์

lambda a,b,s=str.lower:sum(abs(s(a).count(c)-s(b).count(c))for c in set(s(a+b)))

คำอธิบาย

สำหรับอักขระแต่ละตัวใน a หรือ b ให้นับจำนวนที่ปรากฏในแต่ละสตริงและเพิ่มความแตกต่าง (บวก)

แก้ไข: อ่านกฎใหม่ฟังก์ชั่นนิรนามที่ยอมรับได้เป็นที่ยอมรับคำตอบที่ดีขึ้นโดยกำจัด raw_input กอล์ฟแรกโปรดอ่อนโยน!

ขอบคุณ sp3000 สำหรับการปรับปรุง redefining str.lower และทำให้ฉันรู้ว่าการพิมพ์นั้นไม่จำเป็น นอกจากนี้ยังมีช่องว่าง ยังคงเรียนรู้

การใช้ python> = 3.5 มีวิธีการกำหนดเซตที่สั้นกว่าดังนั้นไบต์สามารถบันทึกได้ในเวอร์ชันก่อนหน้า


3

จอประสาทตา 40 40ไบต์

บันทึกไปแล้ว 20 ไบต์ขอบคุณ Martin Büttner

วางแต่ละบรรทัดในไฟล์ของตนเองและแทนที่\nด้วยบรรทัดใหม่ตามตัวอักษร

+i`(.)(.*\n.*)\1
$2
.

2

pb , 648 ไบต์

^w[B!0]{t[B]vb[T]^>}vb[-1]w[X!0]{<t[64]w[T!0]{w[B!0]{b[B-1]v}^[Y]t[T-1]}}w[B!-1]{w[B=0]{b[27]}t[26]w[T!0]{w[B!0]{b[B-1]v}^[Y]t[T-1]}>}b[0]w[X!0]{<w[B!0]{b[1]v}^[Y]w[B=0]{b[32]}w[B=1]{b[0]}}^w[B!0]{t[B]vb[B+T]^>}vb[1]<w[B!9]{t[B]b[0]vv<[X]w[B!0]{>}b[T]^^<[X]w[B!0]{>}<}b[0]<w[X!-1]{t[B]vb[1]^w[B!1]{>}vvw[X!-1]{w[B=T]{b[0]<[X]^w[B!1]{>}^b[0]vt[2]}<}^[Y]vw[B!1]{>}b[0]^<}t[0]w[B!1]{w[B!0]{t[T+1]b[0]}>}b[0]vvw[X!-1]{w[B!0]{t[T+1]b[0]}<}>b[11]^b[T]w[B!0]{vw[B!11]{>}t[B]b[0]>b[T]<[X]^t[B]b[0]vw[B!11]{>}<w[T!0]{t[T-1]b[B+1]w[B=11]{b[0]^<[X]b[B+1]vw[B!11]{>}<}}^<[X]}vw[B!11]{b[B+48]>}b[0]<w[B!0]{w[B!0]{>}<t[B]^^<[X]w[B!0]{>}b[T]<[X]vvw[B!0]{>}<b[0]<}

รับอินพุตด้วยอักขระแท็บแยกทั้งสองสตริง

อันนี้มันดูเหลวไหล การใช้งานอัลกอริทึมที่จริงแล้วไม่ใช่ส่วนที่ยากซึ่งค่อนข้างง่าย แต่ฉันต้องทำสองสิ่งที่ทำได้ยากใน pb: การไม่รู้สึกตัวพิมพ์เล็กและใหญ่ ฉันเคยมีโปรแกรมสำหรับแปลงเป็นตัวพิมพ์เล็กเพียงนอนอยู่รอบ ๆ (ตัวยาว 211 ไบต์) และทุกอย่างก็ถูกตรึงไว้ที่ปลายเพื่อทำงานสำหรับความท้าทายนี้โดยเฉพาะ

คุณสามารถรับชมโปรแกรมนี้ทำงานบน YouTube! มีสองสามสิ่งที่คุณควรจำไว้ถ้าคุณทำ:

  • โปรแกรมรุ่นนี้ได้รับการแก้ไขเล็กน้อยโดยมีน้ำหนัก 650 ไบต์ ข้อแตกต่างเพียงอย่างเดียวคือใช้ 255 เป็นค่าสถานะแทน -1 เนื่องจากพยายามพิมพ์chr(-1)ตัวแปลล้มเหลวเมื่อทำงานในโหมดดู
  • อินพุตในวิดีโอนั้นคือHello, world!และCode golf.และสิ่งนี้แตกต่างจากตัวอย่างอินพุตเล็กน้อยในการท้าทายเล็กน้อย ฉันใช้มันเพราะมันสั้น แต่ถูกดัดแปลงดังนั้นผลลัพธ์ที่ถูกต้องจะเป็น 10 แทนที่จะเป็น 9 นี่เป็นเพียงการแสดงให้เห็นว่าจำนวนที่พิมพ์ถูกต้องแม้ว่ามันจะเป็นตัวเลขหลายหลักซึ่งยากสำหรับ pb
  • ล่ามนั้นแย่มากและมันแสดงให้เห็นที่นี่ โดยเฉพาะอย่างยิ่งอักขระแท็บจะเว้นระยะห่างเพื่อให้สิ่งต่าง ๆ ไม่ถูกจัดเรียงสำหรับส่วนใหญ่ของวิดีโอเมื่อใดก็ตามที่ไบต์ถูกตั้งค่าเป็น 10 มันจะแสดงการแบ่งบรรทัดแม้ว่าภาษาจะยังถือว่าเป็นหนึ่ง "บรรทัด" และ ความจริงที่ว่ามันเพิ่งย้ายเคอร์เซอร์ไปที่จุดเริ่มต้นแทนที่จะล้างหน้าจอหมายความว่ามีบางครั้งจำนวนตัวอักษรในวิดีโอที่ไม่ได้มีจริง ๆ พวกเขาก็ไม่เคยหายไปจากเมื่อพวกเขาอยู่ที่นั่น มีการป้องกันบางอย่างในเรื่องนี้ใน pbi แต่ความจริงที่ว่าchr(10)ไม่ได้รับการจัดการอย่างเหมาะสมทำให้พวกเขาส่วนใหญ่ไร้ประโยชน์ที่นี่ จากทั้งหมดที่กล่าวมาฉันคิดว่ามันเกือบจะดูสวยงาม มันเป็นความยุ่งเหยิงขนาดใหญ่ของรหัสที่น่ากลัวแปลรหัสที่น่ากลัวอื่น ๆ ชิ้นส่วนของมันทำลายลงต่อหน้าต่อตาของคุณและยังทุกอย่างทำงานได้ดีพอที่จะได้คำตอบที่ถูกต้อง ดูเหมือนว่าขยะกำลังถูกพิมพ์ แต่ถ้าคุณดูอย่างใกล้ชิดพอที่มีความรู้เกี่ยวกับแหล่งที่มาคุณสามารถทำสิ่งที่มันกำลังทำอยู่และทำไม ณ จุดใด ฉันรู้สึกเหมือน Cypher เมื่อฉันดูวิดีโอนี้:I... I don’t even see the code. All I see is blonde, brunette, red-head.

โดยไม่ต้องกังวลใจต่อไปนี้เป็นรหัส ungolfed

### UNTIL FURTHER NOTICE, ALL CODE YOU SEE HERE   ###
### IS JUST A SIMPLE LOWERCASE PROGRAM. ALL INPUT ###
### IS PRINTED UNALTERED UNLESS ITS ASCII CODE IS ###
### IN [65, 90], IN WHICH CASE IT IS PRINTED WITH ###
### 32 ADDED TO IT.                               ###

^w[B!0]{t[B]vb[T]^>}    # Copy entire input to Y=0
                        # (If the program ended here, it would be cat!)
vb[-1]                  # Leave a flag at the end of the copy (important later)

# Next, this program will set each of those bytes to 0 or 32, then add the input again.
# A byte needs to be set to 32 iff it's in [65, 90].
# pb can't test > or <, only == and !=.
# A workaround:

# Set each byte to max((byte - 64), 0)



w[X!0]{<        # For each byte:
    t[64]         # Set T to 64 as a loop variable
    w[T!0]{       # While T != 0:
        w[B!0]{     # While the current byte not 0:
            b[B-1]v   # Subtract one from the current cell, then go down one
                      # (guaranteed to be 0 and kill the loop)
        }
        ^[Y]        # Brush is at Y=0 or Y=1 and needs to be at Y=0.
                    # ^[Y] always brings brush to Y=0
        t[T-1]      # T--
    }
}

# Bytes that are currently 0 need to be 0.
# Bytes that are currently in [27, inf) need to be 0.
# Bytes in [1, 26] need to be 32.

# Set bytes that are equal to 0 to 27
# The only groups that have to be worried about are >26 and =<26.

# Then set each byte to max((byte - 26), 0)

w[B!-1]{         # Until we hit the flag:
    w[B=0]{b[27]}   # Set any 0 bytes to 27
    t[26]           # T as loop variable again
    w[T!0]{         # While T != 0:
        w[B!0]{       # While the current byte not 0:
            b[B-1]v     # Subtract one from the current cell, then go down one
                        # (guaranteed to be 0 and kill the loop)
        }
        ^[Y]          # Brush is at Y=0 or Y=1 and needs to be at Y=0.
                      # ^[Y] always brings brush to Y=0
        t[T-1]        # T--
    }
>}
b[0]              # Clear the flag

# Set bytes that are equal to 0 to 32
# All others to 0

w[X!0]{<          # For each byte:
    w[B!0]{       # While the current byte not 0:
        b[1]v       # Set it to 1, then go down one
                    # (guaranteed to be 0 and kill the loop)
    }
    ^[Y]          # Back to Y=0 no matter what
    w[B=0]{b[32]} # Set 0 bytes to 32
    w[B=1]{b[0]}  # Set 1 bytes to 0
}

# Any byte that had a capital letter is now 32. All others are 0.
# Add the original values to the current values to finish.

^w[B!0]{          # For each byte OF ORIGINAL INPUT:
    t[B]vb[B+T]^>   # Add it to the space below
}

### ABOVE IS THE ENTIRE LOWERCASE PROGRAM. THE    ###
### REST OF THE CODE IMPLEMENTS THE ALGORITHM.    ###

vb[1]            # Leave a flag after the end, guaranteed to be further right
                 # than anything else

<w[B!9]{         # Starting from the end, until hitting a tab:
    t[B]b[0]        # Store the last byte and erase it
    vv<[X]          # Go down two columns and all the way to the left
    w[B!0]{>}       # Go right until reaching an empty space
    b[T]            # Print the stored byte
    ^^<[X]w[B!0]{>} # Go back to the end of the first line
    <
}

b[0]              # Erase the tab
<w[X!-1]{         # For each byte in the first line:
    t[B]            # Store that byte
    vb[1]           # Mark that byte to be found later
    ^w[B!1]{>}      # Find the flag at the end
    vvw[X!-1]{      # For everything in the other line:
        w[B=T]{       # If the current byte is the same as the saved byte:
            b[0]        # Set it to 0
            <[X]^       # Go to the beginning of line 2
            w[B!1]{>}   # Find the marker for where the program is working in line 1
            ^b[0]v      # Set that byte that the program is working on to 0
            t[2]        # Stay on line 2 and start looking for a 2 (will never appear)
                        # (If this block was entered, it basically breaks the outer loop.)
        }
        <
    }
    ^[Y]v           # Ensure that the brush is on Y=1
    w[B!1]{>}       # Find the marker for where the program is working in line 1
    b[0]^<          # Erase the marker and start working on the next byte
}

t[0]              # Set T to 0. It's going to be used for counting the remaining bytes.

w[B!1]{           # Until hitting the flag at the very right:
    w[B!0]{         # If the current byte is not 0:
        t[T+1]        # Add 1 to T
        b[0]          # Set the current byte to 0
    }
    >
}
b[0]              # Clear the flag

vvw[X!-1]{        # Same as above, but for Y=2
    w[B!0]{
        t[T+1]
        b[0]
    }
    <
}

# T now contains the number that needs to be printed!!
# Now, to print out a number in decimal...

>b[11]            # A flag that shows the end of the number
                  # (so 0 digits aren't confused for other empty spaces on the canvas)
^b[T]             # The number to be converted to digits
w[B!0]{           # While the number to be converted is not 0:
    vw[B!11]{>}     # Go to the flag
    t[B]b[0]>b[T]   # Move it right
    <[X]^t[B]b[0]   # Store the number to be converted to digits to T and clear its space on the canvas
    vw[B!11]{>}<    # Go to the left of the flag
    w[T!0]{         # While T is not 0:
        t[T-1]        # T--
        b[B+1]        # B++
        w[B=11]{      # If B is 10:
            b[0]        # Set it back to 0
            ^<[X]b[B+1]   # Add 1 to a counter to be converted after
            vw[B!11]{>}<  # Go back to continue converting T
        }
    }
^<[X]}

vw[B!11]{         # Add 48 to all digits to get correct ASCII value
    b[B+48]>
}

b[0]              # Clear the flag value, 0s now appear as 48 instead of 0 so it is unnecessary

<w[B!0]{          # While there are digits on Y=2:
    w[B!0]{>}<      # Go to the last one
    t[B]            # Save it to T
    ^^<[X]          # Go to (0, 0)
    w[B!0]{>}       # Go right until finding an empty space
    b[T]            # Print the digit in T
    <[X]vvw[B!0]{>} # Go to the end of Y=2
    <b[0]           # Erase it
    <               # Repeat until finished. :)
}

2

C ++ 199 ไบต์

ใช้อาร์เรย์เพื่อเก็บจำนวนของอักขระแต่ละตัวในสตริงแรกซึ่งจะนับจำนวนในสตริงที่สอง ถัดไปจะหาผลรวมของค่าสัมบูรณ์ขององค์ประกอบของอาร์เรย์: นี่คือระยะทาง

แข็งแรงเล่นกอล์ฟ:

#define L(c) c<91&c>64?c+32:c
int d(char*a,char*b){int l[128];int i=128,s=0;for(;i-->0;)l[i]=0;for(;a[++i];)l[L(a[i])]++;for(i=-1;b[++i];)l[L(b[i])]--;for(i=0;++i<128;)s+=i[l]>0?i[l]:-i[l];return s;}

Ungolfed:

#define L(c) (c<='Z' && c>='A' ? c+'a'-'A':c)
//convert to lower case
int dist(char a[],char b[]){
  int l[128];
  int i = 128, s = 0;

  for(;i-->0;)
    l[i]=0;

  for(;a[++i]!='\0';)
    l[L(a[i])]++;

  for(i=-1;b[++i]!='\0';)
    l[L(b[i])]--;

  for(i=0;++i<128;)
    s+=i[l]>0?i[l]:-i[l];

  return s;
}

1

PowerShell, 79 ไบต์

param($a,$b)$a=[char[]]$a.ToLower();$b=[char[]]$b.ToLower();(diff $a $b).Length

เกือบรหัสเดียวกันกับคำตอบของฉันในAnagram รหัสกอล์ฟ ... แต่ ... ฉันได้รับพฤติกรรมบางลางถ้าฉันเพียงแค่บุคคลที่ไม่สำคัญออก-eq0จากคำตอบที่ดังนั้นฉันแผลขึ้นจำเป็นต้องชัดเจน.ToLower()และหลอมด้านนอกของparamประกาศ +

คำอธิบาย (ส่วนใหญ่) คัดลอกมาจากคำตอบนั้น - รับอินพุตสตริงสองตัวทำให้เป็นตัวพิมพ์เล็กและโยนมันใหม่เป็น char-arrays diffฟังก์ชั่น (นามแฝงสำหรับCompare-Object) ใช้เวลาสองอาร์เรย์และผลตอบแทนที่รายการที่มีความแตกต่างระหว่างคนทั้งสอง เราใช้ประโยชน์จากการส่งคืนอาเรย์ด้วย()แล้วทำการตรวจสอบความยาว

+ตัวอย่างเช่นฉันได้ผลลัพธ์ปลอมด้วยparam([char[]]$a,[char[]]$b)(diff $a $b).lengthในall lowercase./ ALL UPPERCASE!test ถ้าฉันแยกอาร์เรย์ด้วยตัวเองออก (เช่นวิ่ง(diff ('a','l','l'...) มันทำงานได้ดี แต่จะล้มเหลวทุกครั้งที่มีการทับซ้อนของตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก ทุกอย่างที่ฉันสามารถอ่านได้ในเอกสารระบุว่าdiffเป็นแบบไม่ตรงตามตัวพิมพ์ใหญ่ - เล็กดังนั้น ... ยัก ???


แปลกมาก. ไม่จำเป็นสำหรับกรณีอื่นใด ๆ (แม้จะมีตัวพิมพ์เล็กและใหญ่)
Jonathan Leech-Pepin

1

Bash, 68 67 ไบต์

f()(fold -w1<<<"$1"|sort)
diff -i <(f "$1") <(f "$2")|grep -c ^.\ 

ฉันคิดว่ามันใช้งานได้ หมายเหตุช่องว่างต่อท้ายบนบรรทัดที่สอง

กรณีทดสอบ

$ ./anagram "Hello, world!" "Code golf!"
9
$ ./anagram "12345 This is some text." ".txet emos si sihT 54321"
0
$ ./anagram "All unique characters here!" "Bdfgjkmopvwxyz?"
42
$ ./anagram "This is not exactly like Levenshtein distance," "but you'll notice it is quite similar."
30
$ ./anagram "all lowercase." "ALL UPPERCASE!"
8

1

Perl, 52 46 ไบต์ + 3 สวิตช์ (a, F, n) = 55 49 ไบต์

# 49 bytes (prefix 'x' to all characters so that values() could be removed)
perl -naF -E 'END{$c+=abs for%a;say$c}$a{x.lc}+=2*$.-3 for@F'

# 55 bytes
perl -naF -E 'END{$c+=abs for values%a;say$c}$a{+lc}+=2*$.-3 for@F'

รับอินพุตจาก STDIN ด้วยสตริงอินพุตในบรรทัดของตัวเองซึ่งถูกยกเลิกโดย EOF

สวิทช์:

-aF splits each input line into characters and stores this into @F
-n  loop over all input lines
-E  Execute the script from the next arg

รหัส:

# %a is the hash counting the occurances of the lowercase characters
# $. has the line number. Thus, 2*$.-3 is -1 for line 1 and +1 for line 2
$a{+lc}+=2*$.-3 for @F

# In the end (assuming 2 lines have been read), sum up the absolute values
# from the hash %a. Note that if a character occured more times in string 1
# its value be negative, if more in string 2 then positive, otherwise 0.
END {
    $c+=abs for values %a;
    say $c
}

1

Bash + GNU utils, 53

S(){ sed 's/./\L&\n/g'|sort;};S>1;S|comm -3 1 -|wc -l

sedsortแปลงเป็นตัวพิมพ์เล็กและแยกสตริงในสายสำหรับ เนื่องจากเราต้องทำสองครั้งฉันจึงใส่ฟังก์ชั่น comm3 -3กรองบรรทัดที่เกี่ยวข้องและwc -lสร้างหมายเลข

อินพุตคือผ่านSTDIN; เนื่องจากสองคำสั่งอ่านตามลำดับคุณต้องส่งEOF(Ctrl-D) สองครั้งระหว่างสตริงและท้าย เขียนทับไฟล์1ถ้ามี


1

Matlab, 91 ไบต์

function r=f(s,t)
s=lower(s);t=lower(t);u=unique([s t]);r=sum(abs(histc(s,u)-histc(t,u)));

ลองมันออนไลน์

งานนี้เป็นดังนี้:

  1. แปลงสตริงเป็นตัวพิมพ์เล็ก
  2. ค้นหาอักขระพิเศษของสองสายเข้าด้วยกัน กล่าวคือกำหนดอักขระทั้งหมดที่เคยปรากฏในสตริง
  3. คำนวณฮิสโตแกรมของแต่ละสตริง นั่นคือสำหรับแต่ละสตริงค้นหาจำนวนครั้งของอักขระแต่ละตัวที่ได้รับในขั้นตอนที่ 2 ปรากฏขึ้น
  4. ลบฮิสโทแกรมและรับค่าสัมบูรณ์ของความแตกต่าง นี่แสดงถึงจำนวนครั้งที่อักขระปรากฏในหนึ่งสตริงมากกว่าในอีกสตริงหนึ่ง
  5. ผลที่ได้คือผลรวมของความแตกต่างแน่นอนเหล่านั้น

ดูเหมือนว่าจะนานเกินไป - คุณแน่ใจหรือว่ามันเหมาะสมที่สุด
lirtosiast

@ThomasKwa ไม่ไม่เลย :-)
Luis Mendo


0

F #, 134 126 ไบต์

let g=Seq.countBy Char.ToLower>>List.ofSeq
let f a b=g a@g b|>Seq.groupBy fst|>Seq.sumBy(snd>>Seq.map snd>>Seq.reduce(-)>>abs)

คำอธิบาย :

  1. นับจำนวนครั้งที่อักขระแต่ละตัว (ตัวลด) ปรากฏขึ้นaและbแยกออกจากกัน
  2. จัดกลุ่มการนับเข้าด้วยกันด้วยอักขระทั่วไป
  3. ลดแต่ละกลุ่มด้วย-โอเปอเรเตอร์ซึ่งมีผลต่อไปนี้:

    • หากพบเพียงหนึ่งค่า (เช่นอักขระที่ปรากฏในอินพุตเดียวเท่านั้น) ค่านั้นจะถูกส่งคืน
    • หากพบค่าสองค่า (เช่นอักขระที่ปรากฏในอินพุตทั้งสอง) ลบค่าที่สองจากค่าแรก
  4. รวมค่าสัมบูรณ์ของค่าจากขั้นตอนก่อนหน้า


0

สกาลา , 134 81 ไบต์

ขอบคุณ @ ASCII เท่านั้นสำหรับการทำงานของพวกเขา

(s,t)=>{var k::l::_=List(s,t)map(_.toLowerCase.toBuffer)
((k--l)++(l--k)).length}

ลองออนไลน์!




ew ฉันพลาดนั่นฉันมีสิ่งที่ต้องเรียนรู้ใน scalagolf
V. Courtois

ฮ่าฮ่าฉันอาจมีสิ่งที่ต้องเรียนรู้เพิ่มเติม คนแรกคือสกาล่า: P
ASCII- เท่านั้น

เทคนิคเหล่านั้นดีแม้ว่า
V. Courtois
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.