월요일 미니 골프 # 3 : 아나그램 거리


24

Monday Mini-Golf : 매주 월요일에 게시 되는 일련의 짧은 과제입니다.
(죄송합니다. 조금 늦었습니다.)

나는 대부분의 사람들이 두 문자열 사이의 거리를 계산하는 알고리즘 인 Levenshtein distance에 대해 들어 보았습니다 . 이 과제는 anagram distance 라고하는 내 자신의 발명 *의 유사한 알고리즘을 구현하는 것 입니다. 주요 차이점은 문자의 순서는 중요하지 않다는 것입니다. 대신 한 문자열 또는 다른 문자열에 고유 한 문자 만 측정됩니다.

도전

도전의 목표는 두 개의 문자열을 받아 그들 사이의 거리를 반환하는 프로그램이나 함수를 작성하는 것입니다. 이를 수행하는 주요 방법은 다음 논리를 사용하는 것입니다.

  1. 두 문자열을 모두 소문자로 변환하고 선택적으로 각 문자를 알파벳순으로 정렬하십시오.
  2. 문자열에 하나 이상의 동일한 문자가 포함되어 있지만 각 문자열에서이 문자의 첫 번째 인스턴스를 제거하십시오.
  3. 나머지 문자열의 길이를 추가하고 결과를 반환 / 출력하십시오.

입력이 다음과 같은 경우 :

Hello, world!
Code golf!

그런 다음 소문자로 정렬하면 다음과 같이됩니다.

 !,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는 최종 바이트 수에 먼저 도달 한 제출에갑니다. 우승자는 다음주 10 월 12 일 월요일에 선발됩니다. 행운을 빌어 요!

편집 : 놀라운 12 바이트에 Pyth (다시)를 사용하여 우승자 인 @isaacg에게 축하드립니다 !

*이 알고리즘을 다른 곳에서 사용하거나 다른 이름을 지정한 경우 알려주십시오. 20 분 동안 검색 할 수 없었습니다.


나중에“이 정확한 알고리즘을 사용할 필요는 없습니다…
Édouard

@ Édouard True; 지적 해 주셔서 감사합니다. 나는 그것이 더 낫다고 믿는다.
ETHproductions

벌써 화요일입니다. ;)
Martin Ender 2013 년

@ MartinBüttner Wi-Fi없이 이동 중에 도전을 작성하는 것은 다소 어렵습니다. ;) 걱정하지 마십시오. 조금 새로운 것이 준비 될 것입니다.
ETHproductions

답변:


14

Pyth, 12 바이트

ls.-M.prR0.z

테스트 스위트

해당 연산은 Pyth의 bagwise 빼기 연산자 .-와 동일하며 양방향으로 적용됩니다. 당신은 그것을 백 워드 xor라고 부를 수 있다고 생각합니다.

해결책은 다음과 같습니다.

.z: 2 개의 문자열 목록으로 입력을받습니다.

rR0: 둘 다 소문자로 변환합니다.

.p: 모든 순열, 즉 정상 및 역순을 형성합니다.

.-M: .-각 주문에 대해 조작을 맵핑하십시오 .

s: 결과를 연결합니다.

l: 길이를 인쇄합니다.


그리고 나는 모든 대답이 너무 길다고 생각했다 .... 잘했다!
ETHproductions

8

자바 스크립트 (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

나는 어레이 기반 ES6 답변을 한 시간 동안 일했고 122까지만 얻을 수있었습니다. 내가 잘못된 방향을 찾고있는 것 같습니다! +1
ETHproductions

BTW, 당신은 대체 할 수 .join("")+b.join``+b어떤 효과.
ETHproductions

1
와우, 테스트 스위트를 어디서 구했습니까? 훌륭합니다! 3 ~ 4 번 더 +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){}}+~/$/

더 좋은 방법이 있어야합니다.

편집 : 너무 게으른 길을 조사한 iamnotmaynard 덕분에 57 문자.

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

sub문자열을 취할 수 있습니다. c.downcase대신 사용할 수 /#{Regexp.escape c}/i없습니까?
복원 Monica Monica iamnotmaynard

나는 두 문자열을와 downcase해야 할 것 (동등, 또는 upcase.)
histocrat

아 물론 이죠 (그렇지만 그렇게하면 여전히 몇 바이트를 절약 할 수있을 것 같습니다.)
Monica reinstate Monica iamnotmaynard

4

파이썬, 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)}))

파이썬 <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를 사용하면 세트를 정의하는 더 짧은 방법이 있으므로 이전 버전보다 바이트를 저장할 수 있습니다.


3

레티 나, 40 20 바이트

Martin Bü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]<}

두 문자열을 구분하는 탭 문자로 입력을받습니다.

이것은 멍청했다. 실제로 알고리즘을 구현하는 것은 어려운 일이 아니었고 비교적 쉬운 일이었습니다. 그러나 나는 pb에서 수행하기 어려운 두 가지 일을 수행해야했습니다 : 대소 문자 구분 및 itoa. 나는 단지 211 바이트 길이의 소문자로 소문자로 변환하는 프로그램을 가지고 있었고 다른 모든 것은이 과제를 위해 특별히 노력했습니다.

이 프로그램이 YouTube에서 실행되는 것을 볼 수 있습니다! 다음과 같은 경우 명심해야 할 몇 가지 사항이 있습니다.

  • 이 버전의 프로그램은 650 바이트로 약간 수정되었습니다. 유일한 차이점은 255가 -1 대신 플래그 값으로 사용된다는 것입니다 chr(-1). 시계 모드에서 실행할 때 인쇄하려고 하면 인터프리터가 충돌 하기 때문 입니다.
  • 해당 비디오의 입력은 Hello, world!Code golf.입니다. 이것은 챌린지의 예제 입력 중 하나와 약간 다릅니다. 나는 그것이 짧기 때문에 그것을 사용했지만 수정하여 올바른 출력은 9 대신 10이되도록 수정했습니다. 이것은 pb에서 어려운 여러 자릿수이지만 숫자가 올바르게 인쇄되었음을 보여줍니다.
  • 통역사가 끔찍하며 여기에 표시됩니다. 특히 탭 문자는 간격을 벗어나므로 비디오의 많은 부분에 대해 줄이 표시되지 않습니다. 바이트가 10으로 설정 될 때마다 언어가 여전히 한 줄로 간주하더라도 줄 바꿈이 표시됩니다. 화면을 지우는 대신 커서를 시작 부분으로 이동한다는 사실은 비디오에 실제로는 존재하지 않는 문자가 종종 있다는 것을 의미합니다. pbi에는 이것에 대한 보호가 있지만 사실chr(10)제대로 처리되지 않으면 여기에서 크게 쓸모가 없습니다. 말씀 드린 모든 것이보기에는 거의 아름답다고 생각합니다. 그것은 다른 끔찍한 코드를 해석하는 끔찍한 코드, 눈 앞에서 분해되는 부분이지만, 모든 것이 정답을 얻도록 충분히 작동합니다. 쓰레기가 인쇄되는 것처럼 보이지만 소스에 대한 지식을 충분히 면밀히 살펴보면 어떤 일을하고 있는지와 그 이유를 알 수 있습니다. 이 비디오를 볼 때 Cypher와 같은 느낌이 듭니다.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 바이트

배열을 사용하여 첫 번째 문자열에 각 문자의 개수를 저장하고 두 번째 문자열의 개수를 최소화합니다. 다음으로 배열 요소의 절대 값의 합계를 찾습니다. 이것이 거리입니다.

골프 :

#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. +

설명은 (대부분) 해당 답변에서 복사되었습니다. 두 개의 문자열 입력을 가져 와서 소문자로 만들고 문자 배열로 다시 캐스팅합니다. diff기능 (의 별칭 Compare-Object) 두 배열과 반환 둘 사이에 다른 항목을합니다. 를 사용하여 수익률을 배열로 다시 캐스팅 ()한 다음 길이를 확인하여이를 활용합니다.

+ 예를 들어 / 테스트 param([char[]]$a,[char[]]$b)(diff $a $b).length에서 가짜 결과를 얻었습니다 . 배열을 수동으로 분리하면 (예 : ran ) 제대로 작동했지만 캐스팅과 자본 / 소문자가 겹칠 때마다 실패합니다. 문서에서 읽을 수있는 모든 것은 기본적으로 대소 문자를 구분하지 않으므로 ... ... ???all lowercase.ALL UPPERCASE!(diff ('a','l','l'...diff


매우 이상합니다. 대소 문자 구분이 다른 다른 경우에는 필요하지 않습니다.
Jonathan Leech-Pepin

1

배쉬, 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

배쉬 + GNU 유틸리티, 53

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

sed문자열을 소문자로 변환하고에 대한 문자열을 줄로 분할합니다 sort. 우리는 이것을 두 번해야하기 때문에 함수에 넣었습니다. comm3 -3관련 라인을 필터링 wc -l하고 숫자를 생성합니다.

입력은 다음을 통해 이루어집니다 STDIN. 두 명령이 순차적으로 읽히 EOF므로 문자열 사이와 끝에서 두 번 (Ctrl-D) 을 보내야 합니다. 있는 1경우 file을 덮어 씁니다 .


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 #, 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. -연산자로 각 그룹을 줄이면 다음과 같은 효과가 있습니다.

    • 하나의 값만 발견되면 (즉, 문자가 하나의 입력에만 나타남) 해당 값이 반환됩니다.
    • 두 개의 값이 발견되면 (즉, 문자가 두 입력에 모두 나타남) 첫 번째 값에서 두 번째 값을 뺍니다.
  4. 이전 단계의 값의 절대 값을 합산하십시오.


0

스칼라 , 134 81 바이트

그들의 작업에 대한 @ASCII 전용 감사합니다.

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

온라인으로 사용해보십시오!




오, 나는 그것을 놓쳤다, 나는 scalagolf에서 배울 것이있다
V. Courtois

하하, 아마도 배울 것이 더 많습니다. 첫 번째 스칼라 : P
ASCII 전용

그 트릭은 좋았습니다.
V. Courtois
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.