Monday Mini-Golf # 3: Jarak anagram


24

Monday Mini-Golf: Serangkaian tantangan pendek , diposting (mudah-mudahan!) Setiap hari Senin.
(Maaf ini agak terlambat.)

Saya yakin sebagian besar dari Anda pernah mendengar tentang jarak Levenshtein , sebuah algoritma untuk menghitung jarak antara dua string. Nah, tantangan ini adalah tentang mengimplementasikan algoritma serupa dari penemuan saya *, yang disebut jarak anagram . Perbedaan utama adalah bahwa urutan karakter tidak masalah; alih-alih, hanya karakter yang unik untuk satu string atau yang lain yang diukur.

Tantangan

Tujuan dari tantangan ini adalah untuk menulis program atau fungsi yang mengambil dua string dan mengembalikan jarak anagram di antara mereka. Cara utama untuk melakukan ini adalah dengan menggunakan logika berikut:

  1. Konversikan kedua string menjadi huruf kecil dan (secara opsional) mengurutkan masing-masing karakter secara alfabet.
  2. Sementara string mengandung setidaknya satu karakter yang sama, hapus instance pertama dari karakter ini dari setiap string.
  3. Tambahkan panjang string yang tersisa dan kembalikan / hasilkan hasilnya.

Contoh

Jika inputnya adalah:

Hello, world!
Code golf!

Kemudian, huruf kecil dan disortir, ini menjadi: (berdasarkan jenis JS default; perhatikan spasi terkemuka)

 !,dehllloorw
 !cdefgloo

Menghapus semua karakter yang ada di kedua string, kita berakhir dengan:

,hllrw
cfg

Dengan demikian, jarak anagram antara dua string asli = 6 + 3 = 9.

Detail

  • String dapat diambil dalam format apa pun yang masuk akal.
  • String hanya akan terdiri dari ASCII yang dapat dicetak.
  • String itu sendiri tidak akan mengandung spasi apa pun selain ruang biasa. (Tidak ada tab, baris baru, dll.)
  • Anda tidak perlu menggunakan algoritme yang tepat ini, asalkan hasilnya sama.

Kasus uji

Input 1:

Hello, world!
Code golf!

Output 1:

9

Input 2:

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

Output 2:

0

Input 3:

All unique characters here!
Bdfgjkmopvwxyz?

Output 3:

42

Input 4:

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

Keluaran 4:

30

Input 5:

all lowercase.
ALL UPPERCASE!

Output 5:

8

Mencetak gol

Ini adalah , jadi kode terpendek yang valid dalam byte menang. Tiebreaker pergi ke pengiriman yang mencapai jumlah byte terakhirnya terlebih dahulu. Pemenang akan dipilih Senin depan, 12 Oktober. Semoga beruntung!

Sunting: Selamat kepada pemenang, @isaacg, menggunakan Pyth (lagi) untuk 12 byte yang luar biasa !

* Jika algoritma ini telah digunakan di tempat lain dan / atau diberi nama lain, beri tahu saya! Saya tidak dapat menemukannya dengan pencarian 20 menit.


Menggambarkan tugas sebagai "tulis sebuah program [...] yang [melakukan hal-hal] menggunakan logika berikut" untuk kemudian menambahkan "Anda tidak perlu menggunakan algoritma yang tepat ini [...]" adalah sedikit kontradiktif.
Édouard

@ Édouard Benar; terima kasih telah menunjukkan itu. Saya percaya itu lebih baik sekarang.
ETHproduksi

Ini sudah Selasa lagi. ;)
Martin Ender

@ MartinBüttner Agak sulit untuk menulis tantangan saat Anda berada di jalan tanpa wi-fi. ;) Jangan khawatir, saya akan menyiapkan yang baru sebentar lagi.
ETHproduksi

Jawaban:


14

Pyth, 12 byte

ls.-M.prR0.z

Suite uji

Operasi yang dimaksud setara dengan operator pengurangan searah Pyth .-, yang diterapkan di kedua arah. Anda bisa menyebutnya bagor xor, saya kira.

Solusinya adalah:

.z: dapatkan input sebagai daftar 2 string.

rR0: konversi keduanya menjadi huruf kecil.

.p: Bentuk semua permutasi, yaitu normal dan terbalik.

.-M: Petakan .-operasi pada setiap pemesanan.

s: Menggabungkan hasilnya.

l: Cetak panjangnya.


Dan saya pikir semua jawaban mungkin terlalu panjang .... Bagus sekali!
ETHproduksi

8

JavaScript (ES7), 92 byte

Menentukan fungsi anonim.

Untuk menguji, jalankan snippet di bawah ini. Anda dapat mengedit kode dan mengklik 'Tes' untuk membandingkan hasilnya dengan yang asli. (Berikan komentar jika Anda menemukan peningkatan!) Inputnya seperti"Hello, world!", "Code golf!" di kotak input.

Terima kasih kepada @ETHproductions untuk menghemat 6 byte!


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

Lebih lanjut tentang test suite


Bagaimana itu bekerja

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

Saya telah mengerjakan jawaban ES6 berbasis array selama satu jam, dan hanya mampu menurunkannya menjadi 122. Sepertinya saya mencari ke arah yang salah! +1
ETHproduk

BTW, Anda bisa mengganti .join("")+bdengan .join``+btanpa efek.
ETHproduksi

1
Wow, dari mana Anda mendapatkan test suite itu? Itu brilian! Seandainya saya bisa memberi +1 tiga atau empat kali lagi ....
ETHproduksi

@ ETHproductions Terima kasih! : DI membuat test suite sendiri, sebenarnya. Lihat pos meta saya!
jrich

Saya memberi +1 di sana, saya harap itu tidak bisa +5 di sini. ;)
ETHproduksi

6

CJam, 23 19 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

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

Ruby, 62

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

Harus ada cara yang lebih baik.

Sunting: 57 karakter berkat iamnotmaynard yang menyelidiki jalan yang terlalu malas untuk saya.

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

subdapat mengambil string. Tidak bisakah Anda menggunakan c.downcasebukan /#{Regexp.escape c}/i?
Pasang kembali Monica iamnotmaynard

Saya harus menurunkan kedua string (atau huruf besar, setara.)
histokrat

Ah, tentu saja. (Meskipun tampak bagi saya bahwa hal itu masih akan menyelamatkan Anda beberapa byte.)
Pasang kembali Monica iamnotmaynard

4

Python, 90 87 81 80 79 byte

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

Python <versi 3.5, 80 byte

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

Penjelasan

Untuk setiap karakter dalam a atau b, hitung jumlah kemunculan di setiap string, dan tambahkan perbedaan (positif).

Sunting: Baca kembali aturan, fungsi anonim yang direalisasikan dapat diterima, peningkatan jawaban dengan menyingkirkan raw_input. Golf pertama, harap lembut!

Terima kasih kepada sp3000 untuk peningkatan mendefinisikan ulang str.lower dan membuat saya menyadari bahwa cetak tidak perlu. Juga spasi. Masih belajar.

Menggunakan python> = 3.5, ada cara yang lebih pendek untuk mendefinisikan set, sehingga byte dapat disimpan lebih dari versi sebelumnya.


3

Retina, 40 20 byte

20 byte disimpan berkat Martin Büttner.

Tempatkan setiap baris dalam file sendiri dan ganti \ndengan baris baru literal.

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

2

pb , 648 byte

^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]<}

Mengambil input dengan karakter tab yang memisahkan kedua string.

Yang ini doozy. Sebenarnya menerapkan algoritma itu bukan bagian yang sulit, yang datang dengan relatif mudah. Tetapi saya harus melakukan dua hal yang sulit dilakukan di pb: Kasus tidak sensitif dan itoa. Saya kebetulan memiliki program untuk mengkonversi ke huruf kecil hanya berbaring (sepanjang 211 byte) dan segala sesuatu yang lain ditempel di ujung untuk melakukan pekerjaan untuk tantangan ini secara khusus.

Anda dapat menonton program ini berjalan di YouTube! Ada beberapa hal yang harus diingat jika Anda melakukannya:

  • Versi program ini sedikit dimodifikasi, dengan berat 650 byte. Satu-satunya perbedaan adalah bahwa 255 digunakan sebagai nilai flag alih-alih -1, karena mencoba mencetak membuat chr(-1)crash interpreter ketika berjalan dalam mode tontonan.
  • Input dalam video itu adalah Hello, world!dan Code golf.. Ini sedikit berbeda dari salah satu contoh input dalam tantangan; Saya menggunakannya karena pendek tetapi dimodifikasi sehingga output yang benar adalah 10 bukan 9. Ini hanya untuk menunjukkan bahwa angka dicetak dengan benar bahkan jika itu beberapa digit, yang sulit di pb.
  • Penerjemahnya buruk, dan itu terlihat di sini. Khususnya, karakter tab membuang spasi sehingga hal-hal tidak berbaris untuk sebagian besar video, setiap kali byte diatur ke 10 itu menunjukkan jeda baris meskipun bahasa masih menganggapnya sebagai satu "baris", dan fakta bahwa itu hanya menggerakkan kursor ke awal alih-alih membersihkan layar berarti bahwa kadang-kadang ada sejumlah karakter dalam video yang bahkan tidak benar-benar ada, mereka tidak pernah pergi dari ketika mereka ada di sana. Ada beberapa perlindungan terhadap hal ini di pbi tetapi kenyataannyachr(10)tidak ditangani dengan benar membuat mereka sebagian besar tidak berguna di sini. Semua yang dikatakan, saya pikir itu hampir jenis yang indah untuk ditonton. Ini adalah kekacauan besar dari kode mengerikan yang menafsirkan kode mengerikan lainnya, potongan-potongan itu mogok di depan mata Anda, namun semuanya bekerja cukup hanya untuk mendapatkan jawaban yang benar. Sepertinya sampah sedang dicetak tetapi jika Anda cukup memperhatikan dengan sumbernya, Anda dapat mengetahui apa yang dilakukannya dan mengapa pada titik mana pun. Saya merasa seperti Cypher ketika menonton video ini:I... I don’t even see the code. All I see is blonde, brunette, red-head.

Tanpa basa-basi lagi, inilah kodenya 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 byte

Menggunakan array untuk menyimpan hitungan masing-masing karakter dalam string pertama, meminimalkan hitungan dalam string kedua. Selanjutnya ia menemukan jumlah nilai absolut dari elemen-elemen array: ini adalah jarak.

Golf:

#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;}

Tidak Disatukan:

#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 byte

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

Hampir kode yang persis sama dengan jawaban saya di Anagram Code Golf ... tapi ... Saya mendapatkan perilaku aneh jika saya hanya memotong -eq0dari jawaban itu, jadi saya akhirnya perlu secara eksplisit .ToLower()dan menyusun kembali di luar paramdeklarasi. +

Penjelasan juga (sebagian besar) disalin dari jawaban itu - Mengambil dua input string, membuatnya lebih kecil, dan melemparkannya kembali sebagai char-array. The difffunction (alias untuk Compare-Object) mengambil dua array dan kembali item yang berbeda antara keduanya. Kami memanfaatkannya dengan kembali casting sebagai array dengan (), dan kemudian memeriksa panjangnya.

+ Misalnya, saya mendapatkan hasil palsu dengan param([char[]]$a,[char[]]$b)(diff $a $b).lengthdiall lowercase. / ALL UPPERCASE!tes. Jika saya secara manual memisahkan array (mis. Ran (diff ('a','l','l'...), itu berfungsi dengan baik, tetapi akan gagal setiap kali ada modal / huruf kecil tumpang tindih dengan casting. Semua yang saya dapat baca pada dokumentasi menyatakan diffsecara case-insensitive secara default, jadi ... shrug ???


Sangat aneh. Ini tidak diperlukan untuk semua kasus lain (bahkan dengan sensitivitas case berbeda).
Jonathan Leech-Pepin

1

Bash, 68 67 byte

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

Saya pikir ini berhasil. Perhatikan ruang trailing di baris kedua.

Uji kasus

$ ./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 byte + 3 sakelar (a, F, n) = 55 49 byte

# 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'

Mengambil input dari STDIN dengan string input di jalur mereka sendiri, diakhiri oleh EOF.

Switch:

-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

Kode:

# %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

Utilitas Bash + GNU, 53

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

sedberubah menjadi huruf kecil dan membagi string menjadi garis untuk sort. Karena kita perlu melakukan ini dua kali saya memasukkannya ke dalam fungsi. comm3 -3menyaring garis yang relevan danwc -l menghasilkan nomor.

Masukan melalui STDIN; karena dua perintah membaca berurutan, Anda harus mengirim EOF(Ctrl-D) dua kali, di antara string dan di akhir. Timpa file 1, jika ada.


1

Matlab, 91 byte

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

Cobalah online .

Ini berfungsi sebagai berikut:

  1. Mengubah string menjadi huruf kecil.
  2. Menemukan karakter unik dari dua string bersama. Artinya, tentukan semua karakter yang pernah muncul di string.
  3. Hitung histogramnya dari setiap string. Artinya, untuk setiap string ditemukan berapa kali masing-masing karakter yang diperoleh pada langkah 2 muncul.
  4. Kurangi histogram dan ambil nilai absolut dari perbedaannya. Ini menunjukkan berapa kali karakter muncul dalam satu string lebih banyak daripada yang lain.
  5. Hasilnya adalah jumlah dari perbedaan mutlak itu.

Ini sepertinya terlalu lama - apakah Anda yakin itu optimal?
lirtosiast

@ ThomasKwa Tidak, tidak sama sekali :-)
Luis Mendo


0

F #, 134 126 byte

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)

Penjelasan :

  1. Hitung berapa kali setiap karakter (huruf kecil) muncul di a dan bsecara terpisah.
  2. Kelompokkan hitungan dengan karakter umum mereka
  3. Kurangi setiap grup dengan - operator, yang memiliki efek sebagai berikut:

    • Jika hanya satu nilai yang ditemukan (yaitu karakter muncul hanya dalam satu input), nilai itu dikembalikan.
    • Jika dua nilai ditemukan (yaitu karakter muncul di kedua input) kurangi nilai kedua dari yang pertama.
  4. Jumlahkan nilai absolut dari nilai-nilai dari langkah sebelumnya.


0

Scala , 134 81 byte

Terima kasih @ ASCII-hanya untuk pekerjaan mereka.

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

Cobalah online!




ya, saya merindukan itu, saya memiliki hal-hal untuk dipelajari di scalagolf
V. Courtois

Haha, saya mungkin punya lebih banyak hal untuk dipelajari. Yang pertama adalah Scala: P
ASCII-only

tipuan itu bagus.
V. Courtois
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.