패딩 된 문자열 목록 사이의 최대 해밍 거리


18

길이가 같은 두 줄 사이의 해밍 거리는 해당 문자가 다른 위치 수입니다. 스트링의 길이가 같지 않으면 해밍 거리가 정의되지 않습니다.

도전

아래 설명 된 규칙에 따라 필요에 따라 채워진 문자열 목록에서 모든 문자열 쌍에서 가장 큰 해밍 거리를 찾는 프로그램 또는 함수를 작성하십시오.

문자는 안에 a-zA-Z0-9있습니다.

문자열의 길이가 같지 않을 수 있으므로 각 비교에서 더 짧은 문자열은 다음과 같이 채워 져야합니다.

  • 필요한 길이와 일치하는 횟수만큼 문자열을 처음부터 줄 바꿈
  • 홀수 시간 줄 바꿈 마다 문자의 경우를 변경하십시오 (1, 3, 5 등)
  • a-zA-Z포장 할 때 물건을 그대로 두십시오

예를 들어, 5 개의 문자열 ab9Cd을 18 자로 끝내야한다고 가정 해 봅시다 . 당신은 결국 :

ab9CdAB9cDab9CdAB9
     ^^^^^     ^^^

^케이스 변경 사항을 강조 표시하기 위해 1, 3 랩 아래 에 추가되었습니다.

입출력

입 / 출력 형식은 유연합니다. 입력에 두 개 이상의 문자열이 있고 모든 문자열에 하나 이상의 문자가 있다고 가정 할 수 있습니다.

출력은 정수입니다.

규칙

이것은 입니다. 표준 규칙이 적용됩니다.

테스트 사례

[ "a", "b" ] => 1
[ "a", "b", "c" ] => 1
[ "a", "a", "c" ] => 1
[ "abc", "abcd" ] => 1
[ "abc12D5", "abC34d3", "ABC14dabc23DAbC89d"] => 17  
[ "a", "Aaa", "AaaA", "aAaAa", "aaaaaaaaaaaaaa", "AAaAA", "aAa" ] => 8
["AacaAc", "Aab"] => 2

참조 구현

코드로 시도 할 수 있는 다른 예제를 비교하기 위해 여기 에서 시도 할 수있는 (완전하게 ungolfed) R 코드로 예제를 테스트했습니다.


1
매번 홀수 시간마다 문자의 대소 문자를 바꿉니다 – 아,이 요구 사항은 제 솔루션에 고통이 될 것입니다 ... 도전은 좋아합니다, +1
Mr. Xcoder

권장 테스트 사례 : ["AacaAc", "Aab"] => 2. 제 젤리 답변에 목적이있는 골프는 그 경우에 실패했을 것이지만 다른 모든 것을 통과했을 것입니다.
Mr. Xcoder

@ngm 탁월한 도전! +1
Don Thousand

답변:


7

젤리 , 20 바이트

정말 행복하지 않습니다. ~ 15 바이트까지 골퍼 할 수 있어야합니다.

LÞŒcµṁ/sḢL$ŒsÐeFn)§Ṁ

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

또는 테스트 스위트를 확인하십시오!

설명

LÞŒcµṁ / sḢL $ ŒsÐeFn) §Ṁ 전체 프로그램 또는 모나 딕 링크. N = 입력 | 예 : [ "abc12D5", "abC34d3", "ABC14dabc23DAbC89d"]
LÞ 길이별로 N을 정렬합니다. | [[ 'a', 'b', 'c', '1', '2', 'D', '5'], [ 'a', 'b', 'C', '3', '4 ','d ','3 '], ['A ','B ','C ','1 ','4 ','d ','a ','b ','c ','2 ','3 ','D ','A ','b ','C ','8 ','9 ','d ']] (젤리에서 문자열은 문자 목록입니다)
  Œc 정렬되지 않은 쌍 : N의 모든 고유 x, y에 대해 [x, y]. | [[[ 'a', 'b', 'c', '1', '2', 'D', '5'], [ 'a', 'b', 'C', '3', ' 4 ','d ','3 ']], [['a ','b ','c ','1 ','2 ','D ','5 '], ['A ',' B ','C ','1 ','4 ','d ','a ','b ','c ','2 ','3 ','D ','A ','b ' , 'C', '8', '9', 'd']], [[ 'a', 'b', 'C', '3', '4', 'd', '3'], [ 'A', 'B', 'C', '1', '4', 'd', 'a', 'b', 'c', '2', '3', 'D',
                        여기서는 분명히 다른 위치를 의미합니다. |
    µ) 모나 딕 링크가있는 맵 |
     like / 금형 x 같은 y. 즉, x가 길이 y에 도달 할 때까지 x를 순환합니다. | [[ 'a', 'b', 'c', '1', '2', 'D', '5'], [ 'a', 'b', 'c', '1', '2 ','D ','5 ','a ','b ','c ','1 ','2 ','D ','5 ','a ','b ','c ', '1'], [ 'a', 'b', 'C', '3', '4', 'd', '3', 'a', 'b', 'C', '3', '4', 'd', '3', 'a', 'b', 'C', '3']]
       sḢL $ x 길이의 덩어리로 나눕니다. | [[[ 'a', 'b', 'c', '1', '2', 'D', '5']], [[ 'a', 'b', 'c', '1' , '2', 'D', '5'], [ 'a', 'b', 'c', '1', '2', 'D', '5'], [ 'a', ' b ','c ','1 ']], [['a ','b ','C ','3 ','4 ','d ','3 '], ['a ',' b ','C ','3 ','4 ','d ','3 '], ['a ','b ','C ','3 ']]]
           evensÐe 짝수 색인 청크 (1 색인)의 경우를 바꿉니다. | [[[ 'a', 'b', 'c', '1', '2', 'D', '5']], [[ 'a', 'b', 'c', '1' , '2', 'D', '5'], [ 'A', 'B', 'C', '1', '2', 'd', '5'], [ 'a', ' b ','c ','1 ']], [['a ','b ','C ','3 ','4 ','d ','3 '], ['A ',' B ','c ','3 ','4 ','D ','3 '], ['a ','b ','C ','3 ']]]
               F 평평하게합니다. | [[ 'a', 'b', 'c', '1', '2', 'D', '5'], [ 'a', 'b', 'c', '1', '2 ','D ','5 ','A ','B ','C ','1 ','2 ','d ','5 ','a ','b ','c ', '1'], [ 'a', 'b', 'C', '3', '4', 'd', '3', 'A', 'B', 'c', '3', '4', 'D', '3', 'a', 'b', 'C', '3']]
                n으로 벡터화 된 불평등. | [[[0, 0, 1, 1, 1, 1, 1]]], [[1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1, 1, 1]], [[1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1]]]]
                  § 맵을 ​​종료 한 후 각 부울 (0 또는 1) 배열을 합산하십시오. | [[5], [17], [14]]
                   Ṁ 최대. | 17

나는 젤리에 대해 완전히 익숙하지 않지만, 당신이 생략 하고도 여전히 같은 최대 값을 얻을 수 있다고 생각합니다 .
Chas Brown

@ChasBrown 윽은, 아니, 내가 해야 하는 필요합니다. 그렇지 않으면, 가장 긴 것의 길이에 가장 짧은 것을 채우는 대신에, ṁ/우리가 원하는 것이 아닌 경우에 따라서는 가장 긴 것의 가장 긴 것의 길이를 가장 길게 다듬을 것입니다 ... 테스트 케이스가 너무 잘 선택된 것 같습니다 (그리고 이것은 유감
스러운

@ChasBrown 예를 들어을 사용해보십시오 ["AacaAc", "Aab"].
Mr. Xcoder

아 네,
알겠습니다

5

파이썬 2 , 86 바이트

lambda a:max(sum(x!=y for x,y in zip((s+s.swapcase())*len(t),t))for s in a for t in a)

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

을 감안할 때 두 개의 문자열은 s,t, zip((s+s.swapcase())*len(t),t))길이의 튜플의 목록이 될 것입니다 len(t)이후 zip가장 짧은 반복자로 자릅니다. 인 경우 원하는 대 / 소문자를 바꾼 상태에서 len(s)<len(t)"패드 아웃" s하고 sum다른 문자를 계산합니다 .

만약 그렇다면 len(t)<=len(s), 결과 sumsum우리가 평가 하고있는 것보다 작거나 같습니다 t,s; 따라서 결과 max에 영향을 미치지 않습니다 .


y!=!=y
Xcoder

@씨. Xcoder : Thx,하지만 결국 내 솔루션을 극적으로 재 작업했습니다 ...
Chas Brown


3

젤리 , 19 바이트

WṁŒsÐeF=ċ0
LÞŒcç/€Ṁ

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

LÞŒcç/€Ṁ
LÞ         Sort by length
  Œc       unordered pairs
      €    to each of the pairs
    ç/     find the hamming distance with molding and swapping case (helper link)
       Ṁ   maximum

WṁŒsÐeF=ċ0
W            wrap the shorter string
 ṁ           repeat this string once for each character in the second string
    Ðe       for every other repeated string
  Œs         swap case
      F      flatten
       =     characterwise equality check between the two strings. If the first
             string is longer, the leftover characters are appended to the result.
             e.g. 'abABab' and 'xbA' give [0,1,1,'B','a','b']
        ċ0   count the number of 0s, giving the Hamming distance.

2

루비 , 89 82 바이트

Chas Brown의 answer 와 유사한 복제 방법을 사용하여 각 쌍의 해밍 거리를 계산하기 전에 입력 목록의 교차 곱을 생성합니다 . 루비는 문자열을 함께 압축하거나 추가 오버 헤드없이 부울을 추가 할 수 없으므로 대신 문자열 쌍을 수동으로 반복해야합니다.

GB에서 -7 바이트

->a{a.product(a).map{|s,t|(0...w=t.size).count{|i|(s+s.swapcase)[i%w]!=t[i]}}.max}

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



2

자바 10 ,748 740 667 666 616 바이트

이것은 가장 조밀하고 읽을 수 없지만, 내가 생각해 낸 가장 긴 골프 여야합니다.

h(String[])명시 적 배열을 사용하여 메소드 호출 (var 인수 없음) : 예,

h(new String[] {"a", "b", "c"});

을 반환합니다 1.

char e(boolean w,char c){return(char)(w&(64<c&c<91|96<c&c<123)?c^32:c);}String p(String s,int l){var p="";int m=s.length(),n=l/m,r=l%m,i=0,j=0;var w=1<0;for(;i<n;++i,w=!w)for(char c:s.toCharArray())p+=e(w,c);for(;j<r;)p+=e(w,s.charAt(j++));return p;}int d(String s,String t){int l=s.length(),n=0,i=0;for(;i<l;)if(s.charAt(i)!=t.charAt(i++))++n;return n;}int h(String s,String t){int l=s.length(),m=t.length();return l>m?d(s,p(t,l)):l<m?d(p(s,m),t):d(s,t);}int h(String[]s){int l=s.length,i=0,j;int[]n=new int[l*l];for(;i<l;++i)for(j=i;++j<l;)n[i*l+j]=h(s[i],s[j]);return java.util.Arrays.stream(n).max().getAsInt();}

온라인으로 해볼 수 있습니다 !

Ungolfed 및 댓글 :

// Encode the character (swap case)
char e(boolean w, char c) {
    return (char) (w & (64 < c & c < 91 | 96 < c & c < 123) ? c ^ 32 : c);
}

// Pad the string to desired length
String p(String s, int l) {
    var p = "";
    int m = s.length(), n = l / m, r = l % m, i = 0, j = 0;
    var w = 1 < 0;
    for (; i < n; ++i, w = !w)
        for (char c : s.toCharArray())
            p += e(w, c);
    for (; j < r;)
        p += e(w, s.charAt(j++));
    return p;
}

// Calculate the actual hamming distance between two same-length strings
int d(String s, String t) {
    int l = s.length(), n = 0, i = 0;
    for (; i < l;)
        if (s.charAt(i) != t.charAt(i++))
            ++n;
    return n;
}
// Pad the strings as needed and return their hamming distance
int h(String s, String t) {
    int l = s.length(), m = t.length();
    return l > m ? d(s, p(t, l)) : l < m ? d(p(s, m), t) : d(s, t);
}

    // Dispatch the strings and gather their hamming distances, return the max
int h(String[] s) {
    int l = s.length, i = 0, j;
    int[] n = new int[l * l];
    for (; i < l; ++i)
        for (j = i; ++j < l;)
            n[i * l + j] = h(s[i], s[j]);
    return java.util.Arrays.stream(n).max().getAsInt();
}

특히 문자열 페어링 부분에 대해 더 나은 솔루션을 얻을 수 있다는 것을 알고 있습니다.

편집 : int 배열의 크기를 hammingDistance()주어진 문자열 수의 제곱 으로 변경하여 8 바이트 를 줄입니다. 또한 ArrayIndexOutOfBounds테스트 사례 중 하나 에서 발생 된 문제를 해결합니다 .

편집 2 : Kevin Cruijssen의 의견 덕분에 33 바이트를 절약했습니다 . 클래스 선언이 제거되고 이름이 1 자로 단축되고 연산자가 변경되었습니다.

편집 3 : 1 바이트를 저장하고 var-arg를 사용하여 메소드를 배열로 변경하여 Satan 승인 점수에 도달하십시오.

편집 4 : Kevin Cruijssen 덕분에 다시 50 바이트를 절약 하십시오. var키워드, 제거 된 StringBuilder인스턴스 등 을 사용하도록 Java 버전을 8에서 10으로 업데이트하십시오 .


1
나는 시간이 많지 않지만 골프를해야 할 몇 가지 기본 사항 : 클래스를 삭제하면 메서드만으로 충분합니다. 모든 메소드 및 변수 이름을 단일 바이트로 변경하십시오. 따라서 hammingDistance사용 d되지 않거나 사용되지 않는 다른 변수 대신 . 당신의 대부분은 &&될 수 있습니다 &||수 있습니다 |. c^' '일 수 있습니다 c^32. boolean w = false;일 수 있습니다 boolean w=0>1;. i=0루프 초기화에서 제거 될 수 있으며, 변경 ,i,j,i=0,j. ++j를 제거하고에 ++추가 할 수 있습니다 .charAt(j++). .toString()일 수 있습니다 +"". for(j=i+1;j<l;++j)일 수 있습니다 for(j=0;++j<l;). 기타
Kevin Cruijssen


감사! 좋은 바이트 리프팅입니다. 링크도 감사합니다, 나는 그것을 살펴보고 최대한 빨리 편집 할 것입니다!
joH1

1
사탄이 승인 한 점수로 찬성. 좀 더 작은 것을 XD : StringBuilder할 수있다 StringBuffer(자바 (10)로 전환하는 경우가있을 수 var b=new StringBuffer(l);. boolean그리고 char다음도 할 수 있습니다 var로컬 자바 (10)가없는 경우. 이 TIO 볼 수 있습니다 ). 또한 일 for(;i<n;++i){for(char c:s.toCharArray())b.append(e(w,c));w=!w;}수 있습니다 for(;i++<n;w=!w)for(char c:s.toCharArray())b.append(e(w,c));. 그리고 나는 당신이 StringBuffer완전히 제거 String하고 +=대신 대신 사용할 수 있다고 확신합니다 append.
Kevin Cruijssen

몇 달 간의 깨끗한 코드와 좋은 코딩 습관으로 골프를 치는 법을 잊게되었습니다! 답변을 업데이트하고 TIO를 포함시킵니다.
joH1

1

05AB1E , 33 29 바이트

Ćü)€é©εćDš«s`g∍}®€¤‚ø€ζ€€Ë_Oà

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

바이트 수로 반으로 줄어들 수 있지만 작동합니다 ..

설명:

Ć           # Enclose the input-list (adding the first item to the end of the list)
            #  i.e. ['ABC1','abcD','abCd32e'] → ['ABC1','abcD','abCd32e','ABC1']
 ü)         # Pair-vectorize each of them
            #  i.e. ['ABC1','abcD','abCd32e','ABC1']
            #   → [['ABC1','abcD'],['abcD','abCd32e'],['abCd32e','ABC1']]
   ێ       # Sort each pair by length
            #  i.e. [['ABC1','abcD'],['abcD','abCd32e'],['abCd32e','ABC1']]
            #   → [['ABC1','abcD'],['abcD','abCd32e'],['ABC1','abCd32e']]
     ©      # Store this list in the register to re-use later on
ε        }  # Map each inner list in this list to:
 ć          # Head extracted
            #  i.e. ['abcD','abCd32e'] → 'abcD' and ['abCd32e']
  Dš        # Duplicate it, and swap the capitalization of the copy
            #  i.e. 'abcD' → 'ABCd'
    «       # Then merge it together
            #  i.e. 'abcD' and 'ABCd' → 'abcDABCd'
     s`     # Swap so the tail-list is at the top of the stack, and get it's single item
            #  i.e. ['abCd32e'] → 'abCd32e'
       g    # Get the length of that
            #  i.e. 'abCd32e' → 7
           # Extend/shorten the string to that length
            #  i.e. 'abcDABCd' and 7 → 'abcDABC'
®           # Get the saved list from the register again
 €¤         # Get the tail from each
            #  i.e. [['ABC1','abcD'],['abcD','abCd32e'],['abCd32e','ABC1']]
            #   → ['abcD','abCd32e','abCd32e']
           # Pair it with the other list
            #  i.e. ['ABC1','abcDABC','ABC1abc'] and ['abcD','abCd32e','abCd32e']
            #   → [['ABC1','abcDABC','ABC1abc'],['abcD','abCd32e','abCd32e']]
    ø       # Zip it, swapping rows / columns
            #  i.e. [['ABC1','abcDABC','ABC1abc'],['abcD','abCd32e','abCd32e']]
            #   → [['ABC1','abcD'],['abcDABC','abCd32e'],['ABC1abc','abCd32e']]
     €ζ     # And then zip each pair again
            #  i.e. [['ABC1','abcD'],['abcDABC','abCd32e'],['ABC1abc','abCd32e']]
            #   → [['Aa','Bb','Cc','1D'],['aa','bb','cC','Dd','A3','B2','Ce'],['Aa','Bb','CC','1d','a3','b2','ce']]
           # Then for each inner list
           #  And for each inner string
  Ë         #   Check if all characters are the same
            #    i.e. 'aa' → 1
            #    i.e. 'cC' → 0
   _        # And inverse the booleans
            #  i.e. [['Aa','Bb','Cc','1D'],['aa','bb','cC','Dd','A3','B2','Ce'],['Aa','Bb','CC','1d','a3','b2','ce']]
            #   → [[1,1,1,1],[0,0,1,1,1,1,1],[1,1,0,1,1,1,1]]
O           # Then sum each inner list
            #  i.e. [[1,1,1,1],[0,0,1,1,1,1,1],[1,1,0,1,1,1,1]] → [4,5,6]
 à          # And take the max as result
            #  i.e. [4,5,6] → 6

1

자바 11, 387 바이트

a->{int l=a.length,i=l,t,j=0,C[]=new int[l];var p=new String[l][2];for(;i-->0;p[i][0]=a[t>0?i:j],p[i][1]=a[t>0?j:i])t=a[i].length()<a[j=-~i%l].length()?1:0;i=0;for(var P:p){var s="";for(var x:P[0].getBytes())s+=(char)(x>64&x<91|x>96&x<123?x^32:x);for(P[0]=repeat(P[0]+s,t=P[1].length()).substring(0,t);t-->0;)if(P[0].charAt(t)!=P[1].charAt(t))C[i]++;i++;}for(int c:C)j=c>j?c:j;return j;}

온라인으로 사용해보십시오. (참고 : Java 11은 아직 TIO가 아니므 String.repeat(int)repeat(String,int)동일한 바이트 수로 에뮬레이션되었습니다 .)

설명:

a->{                      // Method with String-array parameter and integer return-type
  int l=a.length,         //  Length of the input-array
      i=l,                //  Index-integer, starting at the length
      t,j=0,              //  Temp-integers
      C[]=new int[l];     //  Count-array the same size as the input
  var p=new String[l][2]; //  String-pairs array the same size as the input
  for(;i-->0              //  Loop `i` in the range [`l`, 0)
      ;                   //    After every iteration:
       p[i][0]=           //     Set the first String of the pair at index `i` to:
               a[t>0?i:j],//      The smallest of the `i`'th or `j`'th Strings of the input-array
       p[i][1]=           //     And set the second String of the pair at index `i` to:
               a[t>0?j:i])//      The largest of the `i`'th or `j`'th Strings of the input-array
    t=a[i].length()<      //    If the length of the `i`'th item is smaller than
      a[j=-~i%l].length()?//    the length of the `i+1`'th item
                          //    (and set `j` to this `i+1` with wrap-around to 0 for the last item
       1                  //     Set `t` to 1 as flag
      :                   //    Else:
       0;                 //     Set `t` to 0 as flag
                          //  We've now created the String pairs, where each pair is sorted by length
  i=0;                    //  Reset `i` to 0
  for(var P:p){           //  Loop over the pairs
    var s="";             //   Temp-String starting empty
    for(var x:P[0].getBytes())
                          //   Loop over the characters of the first String of the pair
      s+=                 //    Append the temp-String with:
         (char)(x>64&x<91|x>96&x<123?
                         //      If the current character is a letter:
           x^32          //       Swap it's case before appending it to `s`
         :               //      Else (not a letter):
          x);            //       Append it to `s` as is
    for(P[0]=            //    Now replace the first String with:
        repeat(P[0]+s,   //     The first String appended with the case-swapped first String
               t=P[1].length())
                         //     Repeated `t` amount of times,
                         //     where `t` is the length of the second String of the pair
        .substring(0,t); //     And then shorten it to length `t`
        t-->0;)          //    Inner loop over the character of the now same-length Pairs
      if(P[0].charAt(t)!=P[1].charAt(t))
                         //     If the characters at the same indices in the pair are not equal
        C[i]++;          //      Increase the counter for this pair by 1
    i++;}                //    After every iteration of the outer loop,
                         //    increase `i` by 1 for the next iteration
  for(int c:C)           //  Now loop over the calculated counts
    j=c>j?c:j;           //   And set `j` to the maximum
  return j;}             //  And finally return this maximum `j` as result

1

R , 173 바이트

function(x,U=utf8ToInt,N=nchar)max(combn(x,2,function(z,v=z[order(N(z))])sum(U(substr(Reduce(paste0,rep(c(v[1],chartr('A-Za-z','a-zA-Z',v[1])),n<-N(v[2]))),1,n))!=U(v[2]))))

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

@ngm : 코드를 골프화하기 위해 최선을 다했지만 ( 물론 무거운 커스터마이즈로) R은 문자열 조작에서 골프가 아닙니다. : P


나는 이것이 150 바이트 이하일 수 있다고 확신하지만 아직 얼마나 잘 모르겠습니다.
주세페

@Giuseppe : 나는 너무 그 의심 ...하지만 나는 짧은 문자열 조작 코드를 서면으로 정말 좋은 아니에요 R은 매우 중 하나를 나에게 도움이되지 않습니다 : D
digEmAll

@digEmAll 나는 내 자신의 도전을 해결하려고하지는 않지만 outer모든 조합을 얻는 대신 코드 포인트에서 모듈 산술을 수행하는 것을 포함 할 가능성은 거의 없습니다 chartr.
ngm

@ngm : 가능 ... 나는 숫자를 건드리지 않고 문자의 대소 문자를 바꿀 수있는 짧은 해결책 / 수식을 찾을 수 없기 때문에 산술 접근법을 버렸습니다 ...
digEmAll
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.