Yastıklı ipler arasında maksimum Hamming mesafesi


18

Eşit uzunlukta iki tel arasındaki Hamming mesafesi , karşılık gelen karakterlerin farklı olduğu konumların sayısıdır. Dizeler eşit uzunlukta değilse, Hamming mesafesi tanımlanmamıştır.

Meydan okuma

Aşağıda açıklanan kurallara göre gerektiği gibi doldurulmuş bir dizeler listesinden tüm dize çiftleri arasındaki en büyük Hamming mesafesini bulan bir program veya işlev yazın.

Karakterler içeriden olacaktır a-zA-Z0-9.

Dizelerin uzunluğu eşit olmayabilir, bu nedenle her karşılaştırma için daha kısa dizenin aşağıdaki gibi doldurulması gerekir:

  • dizeyi baştan itibaren gerekli uzunlukta eşleştirmek için gerektiği kadar sarın
  • Her bir tek kaydırma (1, 3, 5, vb.) harflerinin durumlarını değiştirin
  • kaydırırken işleri a-zA-Zdeğişmeden bırakmak

Örneğin, 5 karakter dizesini ab9Cd18 karakterle sonuçlanacak şekilde doldurmanız gerektiğini varsayalım . Sonuç olarak:

ab9CdAB9cDab9CdAB9
     ^^^^^     ^^^

ile ^vaka değişikliklere vurgu için 1. ve 3. tamamladı altına ekledi.

Giriş çıkış

Giriş / çıkış formatı esnektir. Girişin en az iki dizesi olduğunu ve tüm dizelerin en az bir karakteri olacağını varsayabilirsiniz.

Çıktı bir tamsayıdır.

kurallar

Bu . Standart kurallar geçerlidir.

Test senaryoları

[ "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

Referans uygulaması

Kodunuzla deneyebileceğiniz diğer örnekleri karşılaştırmak için burada deneyebileceğiniz (tamamen ungolfed) R koduyla örnekleri test ettim .


1
her garip zaman sarma harflerin vakalarını değiştirmek - Ah oğlum, bu gereksinim benim çözüm için bir acı olacak ... Ben meydan okumayı seviyorum, ama +1
Bay Xcoder

Önerilen test durumu: ["AacaAc", "Aab"] => 2. Jelly cevabım için amaçlanan bir golf bu durumda başarısız olacaktı, ama diğerlerini geçecekti.
Bay Xcoder

@ngm Mükemmel bir meydan okuma! +1
Don Bin

Yanıtlar:


7

Jöle , 20 bayt

Bundan gerçekten memnun değil. Belki de ~ 15 bayt bile golf edilebilir olmalıdır.

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

Çevrimiçi deneyin!

veya Bir test takımına göz atın!

açıklama

LÞŒcµṁ / sḢL $ ŒsÐeFn) §Ṁ Tam program veya monadik bağlantı. N = giriş. | Örnek: ["abc12D5", "abC34d3", "ABC14dabc23DAbC89d"]
L N N'yi boyuna göre sıralayı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 ']] (Jelly'de, dizeler karakter listesidir)
  Œc Sırasız çiftler: [x, y] tüm x için y, N'de | [[['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',
                        Burada, farklı bir deyişle, farklı pozisyonlarda demek istiyorum. |
    µ) Monadik bağlantılı harita. |
     ṁ / x gibi y kalıp. Yani, x'i y uzunluğuna ulaşıncaya kadar döndürün. | [['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 uzunluğundaki parçalara bölün. | [[['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 Çift dizinli parçalar (1 dizinli) ile değiştirin. | [[['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 Düzleştirin. | [['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 y ile vektörize eşitsizlik. | [[[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]]]
                  Haritayı bitirdikten sonra, her bir bool (0 veya 1) dizisini toplayın. | [[5], [17], [14]]
                   Ṁ Maksimum. | 17

Jelly'e tamamen aşina değilim, ama sonunda atlayabilir ve yine de aynı maksimum değeri elde edebilirsiniz .
Chas Brown

@ChasBrown Ugh, hayır, buna ihtiyacım var. Aksi takdirde, en kısa olanı en uzun olanın uzunluğuna doldurmak yerine, en uzun olanı ṁ/en kısa olanın uzunluğuna kırpmak yerine , istediğimiz şey bu değildir ... Sanırım test senaryoları çok iyi seçilmiş (ve bu oldukça talihsiz bir tesadüf) ...
Bay Xcoder

@ChasBrown Örnek olarak deneyin ["AacaAc", "Aab"].
Bay Xcoder

Ah evet, anlıyorum ... Beni biraz daha öğrenmem gerekiyor Jelly ... :)
Chas Brown

5

Python 2 , 86 bayt

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)

Çevrimiçi deneyin!

Verilen iki dizeleri, s,t, zip((s+s.swapcase())*len(t),t))uzunluğunun dizilerini bir liste olacak len(t)çünküzip en kısa iterable için kesikler. Eğer len(s)<len(t), o zaman bu " sistenen " takas ile "pads" ve biz sumfarklı karakterler hesaplar .

Eğer len(t)<=len(s), o zaman sonuç sum, sumdeğerlendiriyor olmamızdan daha az veya ona eşit olacaktır t,s; dolayısıyla bu maxdurumda ortaya çıkan sonuç üzerinde bir etkisi yoktur .


1 bayt kaydetmek y!=yerine kullanabilirsiniz!=y
Bay Xcoder

@Bay. Xcoder: Teşekkürler, ama çözümümü büyük ölçüde yeniden işledim ...
Chas Brown


3

Jöle , 19 bayt

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

Çevrimiçi deneyin!

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

Yakut , 89 82 bayt

Chas Brown'un cevabına benzer bir çoğaltma yöntemi kullanarak, her bir çiftin Hamming mesafesini hesaplamadan önce giriş listesinin çapraz ürününü kendine karşı oluşturur . Ruby, dizeleri bir araya getiremez veya ek ek yük olmadan boolean ekleyemez, bu nedenle bunun yerine dize çiftini manuel olarak yinelemek gerekir.

GB'den -7 bayt.

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

Çevrimiçi deneyin!



2

Java 10 ,748 740 667 666 616 bayt

Bu en yoğun ve okunamayan olmalı, ama şimdiye kadar bulduğum en uzun golf.

h(String[])Açık bir diziyle çağrı yöntemi (var argümanı yok): ör.

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

döner 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();}

Sen edebilirsiniz Çevrimiçi Deneyin !

Ungolfed ve yorum yaptı:

// 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();
}

Ben biliyorum daha iyi bir çözüm özellikle dize eşleştirme kısmı için, elde edilebilir.

EDIT : int dizisinin boyutunu hammingDistance()verilen dize sayısının karesine değiştirerek 8 bayt tıraş edin . Ayrıca birArrayIndexOutOfBounds test durumlarından birine atılan sorunu .

DÜZENLEME 2 : Kevin Cruijssen'in yorumları sayesinde 33 bayt kaydedildi : sınıf bildirimi kaldırıldı, isimler 1 karaktere kısaltıldı, operatörler değişti, vb.

DÜZENLEME 3 : 1 bayt kaydedin ve var-arg yöntemini diziye değiştirerek Şeytan onaylı skora ulaşın.

DÜZENLEME 4 : Kevin Cruijssen sayesinde 50 bayt daha kaydet : varAnahtar kelimeyi, kaldırılan StringBuilderörneği vb. Kullanmak için Java sürümünü 8'den 10'a güncelleyin .


1
Çok zamanım yok, ama golf için bazı temel şeyler: Sınıfı bırakın, sadece yöntemler yeterlidir. Tüm yöntem ve tek bayt değişken isimleri .. Yani yerine değiştirin hammingDistancekullanımını dveya başka kullanılmayan değişken. Çoğunuz &&olabilir &ve ||olabilir |. c^' 'olabilir c^32. boolean w = false;olabilir boolean w=0>1;. i=0döngü başlatma çıkarılabilir ve değiştirilebilir ,i,jiçin ,i=0,j. ++jKaldırılan olabilir ve ++ilave edilebilir .charAt(j++). .toString()olabilir +"". for(j=i+1;j<l;++j)olabilirfor(j=0;++j<l;) . Vb.
Kevin Cruijssen


Teşekkürler! Bu güzel bir bayt kaldırma. Bağlantılar için de teşekkürler, bir göz atıyorum ve en kısa sürede düzenleyeceğim!
joH1

1
Şeytan onaylı skora yükseldi. xD Bazı küçük şeyler: StringBuilderolabilir StringBuffer(Java 10'a geçerseniz olabilir var b=new StringBuffer(l);. booleanve charsonra da olabilir var. Yerel olarak Java 10'unuz yoksa, TIO'da kullanılabilir ). Ayrıca for(;i<n;++i){for(char c:s.toCharArray())b.append(e(w,c));w=!w;}olabilir for(;i++<n;w=!w)for(char c:s.toCharArray())b.append(e(w,c));. Ve ben çok emin kaldırabilir değilim StringBuffertamamen ve sadece kullanımı Stringve +=yerine append.
Kevin Cruijssen

Dostum, birkaç aylık temiz kod ve iyi kodlama uygulamaları bana golf bile nasıl unuttu! Cevabımı güncelleyeceğim ve TIO'yu ekleyeceğim.
joH1

1

05AB1E , 33 29 bayt

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

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Büyük olasılıkla bayt sayısında yarıya indirilebilir, ancak çalışır ..

Açıklama:

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

Java 11, 387 bayt

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

Çevrimiçi deneyin. (NOT: Java 11 henüz TIO'da olmadığından , aynı bayt sayımındaki String.repeat(int)gibi taklit edilmiştir repeat(String,int).)

Açıklama:

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 bayt

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]))))

Çevrimiçi deneyin!

@ngm: Kodunuzu golf yapmak için elimden geleni yaptım (elbette ağır özelleştirmelerimle), ancak bildiğiniz gibi R, dizeleri manipüle etmede çok golfy değil: P


Bahse girerim bu 150 baytın altında olabilir, ama henüz ne kadar emin değilim.
Giuseppe

@Giuseppe: Ben de şüpheliyim ... ama kısa dizeleri manipülasyon kodları yazma konusunda gerçekten iyi değilim ve R de bana çok yardımcı olmuyor: D
digEmAll

@DigEmAll kendi mücadelemi çözmeye çalışmayacağım, ancak outertüm kombinasyonları almak ve yerine kod noktalarında modüler aritmetik yapmak için birkaç olasılık olabilir chartr.
ngm

@ngm: mümkün ... Sayılara dokunmadan harflerin durumunu değiştirmek için kısa bir çözüm / formül bulamadığım için aritmetik yaklaşımı
attım
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.