月曜日のミニゴルフ#3:アナグラム距離


24

月曜日のミニゴルフ:毎週月曜日に(願わくば!)投稿された一連の短いチャレンジ。
(これは少し遅れてごめんなさい。)

皆さんの多くは、2つのストリング間の距離を計算するアルゴリズムであるレーベンシュタイン距離を聞いたことがあると思います。さて、この課題は、アナグラム距離と呼ばれる、独自の発明*の同様のアルゴリズムを実装することです。主な違いは、文字の順序は重要ではないということです。代わりに、一方の文字列または他方の文字列に固有の文字のみが測定されます。

チャレンジ

チャレンジの目標は、2つの文字列を受け取り、それらの間のアナグラム距離を返すプログラムまたは関数を作成することです。これを行う主な方法は、次のロジックを使用することです。

  1. 両方の文字列を小文字に変換し、(オプションで)各文字をアルファベット順にソートします。
  2. 文字列には少なくとも1つの等しい文字が含まれていますが、各文字列からこの文字の最初のインスタンスを削除します。
  3. 残りの文字列の長さを追加し、結果を返す/出力します。

入力が次の場合:

Hello, world!
Code golf!

次に、小文字でソートされ、これらは次のようになります:(JSのデフォルトのソートにより、先頭のスペースに注意してください)

 !,dehllloorw
 !cdefgloo

両方の文字列にあるすべての文字を削除すると、次のようになります。

,hllrw
cfg

したがって、元の2つの文字列間のアナグラム距離= 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は、最初に最終バイトカウントに達した送信に進みます。勝者は10月12日の次の月曜日に選ばれます。

編集:驚異的な12バイトの Pyth(再び)を使用して、勝者@isaacgにおめでとうございます!

*このアルゴリズムが他の場所で使用されたり、別の名前が付けられたりした場合は、お知らせください!20分間の検索では見つけることができませんでした。


タスクを「次のロジックを使用して[処理を行う] […]プログラムを記述する」と記述して、後で「この正確なアルゴリズムを使用する必要はありません[…]」と矛盾します。
エドゥアール

@ÉdouardTrue; それを指摘してくれてありがとう。今はもっといいと思う。
-ETHproductions

また火曜日です。;)
マーティンエンダー

@MartinBüttnerWi-Fiなしで外出中にチャレンジを書くのはちょっと難しいです。;)心配しないで、新しいものをもうすぐ準備します。
ETHproductions

回答:


14

Pyth、12バイト

ls.-M.prR0.z

テストスイート

問題の演算は.-、両方向に適用されるPythのbagwise減算演算子に相当します。それをbagwise xorと呼ぶことができると思います。

解決策は次のとおりです。

.z:2つの文字列のリストとして入力を取得します。

rR0:両方を小文字に変換します。

.p:すべての順列を形成します。つまり、通常と逆順です。

.-M.-各注文に操作をマッピングします。

s:結果を連結します。

l:長さを印刷します。


そして、私はすべての答えが長すぎるかもしれないと思った。
ETHproductions

8

JavaScript(ES7)、92バイト

無名関数を定義します。

テストするには、以下のスニペットを実行します。コードを編集し、「テスト」をクリックして、その出力と元の出力を比較できます。(改善を見つけたらコメントを残してください!)入力は"Hello, world!", "Code golf!"入力ボックスのようです。

6バイトを節約してくれた@ETHproductionsに感謝します!


(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

私は1時間アレイベースのES6アンサーに取り組んでいたが、122までしか解決できなかった。間違った方向を見ているようだ!+1
ETHproductions

ところで、あなたは置き換えることができ.join("")+b.join``+bいない効果を持ちます。
ETHproductions

1
うわー、どこでそのテストスイートを入手しましたか?すばらしい!あと
3、4

@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){}}+~/$/

より良い方法が必要です。

編集:iamnotmaynardが私が面倒だったパスを調査してくれた57文字。

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

sub文字列を取ることができます。のc.downcase代わりに使用できません/#{Regexp.escape c}/iか?
モニカiamnotmaynard

私は両方の文字列をダウンケースする必要があります(または、大文字、同等に。)
histocrat

ああ、もちろん。(そうすることで、まだ数バイト節約できるように
思え

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を削除することで回答を改善 はじめてのゴルフ、優しくしてください!

str.lowerを再定義し、印刷が不要であることを認識させてくれたsp3000に感謝します。またスペース。まだ学習中。

python> = 3.5を使用すると、セットを定義する方法が短くなるため、以前のバージョンで1バイトを保存できます。


3

網膜、40 20バイト

MartinBüttnerのおかげで20バイト節約されました。

各行を独自のファイルに配置\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]<}

2つの文字列を区切るタブ文字を使用して入力を受け取ります。

これはすごかった。実際にアルゴリズムを実装することは難しい部分ではなく、比較的簡単に実現しました。しかし、私は、pbで行うのが難しい2つのことをしなければなりませんでした。大文字と小文字を区別しないこととitoaです。たまたま小文字に変換するプログラムがあり(それ自体は211バイトの長さ)、特にこの課題に取り組むために他のすべてが最後に追加されました。

このプログラムはYouTubeで実行できます。あなたがそうするなら、あなたが心に留めておくべきいくつかの事柄があります:

  • このバージョンのプログラムはわずかに変更されており、650バイトになります。唯一の違いは、-1の代わりに255がフラグ値として使用されることchr(-1)です。これは、監視モードで実行しているときに印刷しようとするとインタープリターがクラッシュするためです。
  • そのビデオ入力があるHello, world!Code golf.。これは、チャレンジの入力例の1つとわずかに異なります。短いので使用しましたが、正しい出力が9ではなく10になるように変更しました。これは、pbでは難しい複数の数字であっても数字が正しく印刷されることを示すためです。
  • 通訳はひどいです、そして、それはここに示します。注目すべきは、タブ文字がスペースをスローするため、ビデオの大部分が整列しないことです。バイトが10に設定されるたびに、言語ではまだ1つの「行」と見なされても改行が表示されます。画面をクリアするのではなく、カーソルを最初に移動するだけで、ビデオには実際には存在しない多くのキャラクターが存在することがあり、実際にそこから離れることはありません。PBIにはこれに対するいくつかの保護がありますが、chr(10)適切に処理されないため、ここではほとんど役に立たなくなります。言われていることすべて、私はそれが見ることはほとんど一種の美しいと思う。それは他の恐ろしいコードを解釈する恐ろしいコードの巨大な混乱であり、その断片は目の前で分解しますが、すべてが正しい答えを得るのに十分です。ゴミが印刷されているように見えますが、ソースの知識を十分に注視していれば、それが何をしているのか、いつでも理由を確認できます。このビデオを見ると、サイファーのように感じます。I... I don’t even see the code. All I see is blonde, brunette, red-head.

これ以上苦労することなく、ここにコードはありません。

### 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バイト

配列を使用して、最初の文字列の各文字のカウントを格納し、2番目の文字列のカウントを最小化します。次に、配列の要素の絶対値の合計を見つけます。これは距離です。

ゴルフ:

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

ゴルフをしていない:

#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 Code Golfでの回答とほぼ同じコードですが... ... -eq0その回答から切り取るだけで奇妙な動作が発生するため、明示的.ToLower()param宣言の外に再キャストする必要がありました。+

また、(ほとんど)その回答からコピーされた説明-2つの文字列入力を受け取り、それらを小文字にして、文字配列として再キャストします。diff関数(のエイリアスCompare-Object)は、2つの配列を返すの両者の異なるアイテムをとります。を使用して、戻り値を配列として再キャストし、()その長さをチェックすることで、これを活用します。

+たとえばparam([char[]]$a,[char[]]$b)(diff $a $b).lengthall lowercase./ ALL UPPERCASE!テストで偽の結果を得ていました。配列を手動で分離した場合(たとえば、ran (diff ('a','l','l'...)、それはうまく機能しましたが、キャスティングと大文字/小文字の重複があるたびに失敗しました。私がドキュメントで読むことができるものはすべてdiff、デフォルトでは大文字と小文字を区別しないため、... shrug ???


非常に奇妙な。他のケースでは必要ありません(大文字と小文字の区別が異なる場合でも)。
ジョナサンリーチペピン

1

Bash、68 67バイト

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

これはうまくいくと思う。2行目の末尾のスペースに注意してください。

テストケース

$ ./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'

EOFで終了する独自の行に入力文字列を含むSTDINから入力を取得します。

スイッチ:

-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

sedは小文字に変換し、文字列をの行に分割しますsort。これを2回行う必要があるため、関数に入れました。 comm3 -3関連する行を除外しwc -l、数値を生成します。

入力は経由STDINです; 2つのコマンドは順番に読み取られるためEOF、文字列間と最後に2回(Ctrl-D)送信する必要があります。fileを上書きします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. 2つの文字列の一意の文字を一緒に検索します。つまり、文字列に現れるすべての文字を決定します。
  3. 各文字列のヒストグラムを計算します。つまり、各文字列について、手順2で取得した各文字が何回出現するかを見つけます。
  4. ヒストグラムを減算し、差の絶対値を取得します。これは、ある文字列が他の文字列より多く出現する回数を表します。
  5. 結果は、それらの絶対差の合計です。

これは長すぎるように思えます-最適だと確信していますか?
リトシアスト

@ThomasKwaいいえ、すべてではない:-)で
ルイス・Mendo


0

F#、134126バイト

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. -演算子を使用して各グループを縮小すると、次の効果があります。

    • 値が1つだけ見つかった場合(つまり、文字が1つの入力のみに現れた場合)、その値が返されます。
    • 2つの値が見つかった場合(つまり、両方の入力に文字が現れた場合)、最初の値から2番目の値を引きます。
  4. 前のステップの値の絶対値を合計します。


0

Scala134 81バイト

@ASCIIのみの作業に感謝します。

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

オンラインでお試しください!




EW、私はscalagolfに学ぶべきもの持って、それを逃した
V.クルトワ

ハハ、私はおそらくもっと学ぶべきことがあります。最初はScalaです:P
ASCIIのみ

これらのトリックは素晴らしいものでした。
V.クルトワ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.