En Kötü Şifreli Kilidi Bul


18

Rakamlar yerine harfler içeren bir kombinasyon asma kilit var. Şöyle görünüyor: http://pictures.picpedia.com/2012/09/Word_Combination_Padlock.jpg Her biri üzerinde 10 farklı harf bulunan 5 makara var.

Çoğu insan rastgele bir harf dizisi yerine kombinasyonları için bir kelime kullanmayı sever. (Elbette daha az güvenli, ancak hatırlaması daha kolay.) Bu yüzden kilidi üretirken, mümkün olduğunca 5 harfli İngilizce kelimeler oluşturmak için kullanılabilecek harflerin bir kombinasyonuna sahip olmak iyi bir şey olacaktır.

Göreviniz, kabul etmeyi seçerseniz, makaralara mümkün olduğunca çok sayıda kelimenin yaratılmasına izin verecek bir harf ataması bulmaktır. Örneğin, çözümünüz

ABCDEFGHIJ DEFGHIJKLM ZYXWVUTSR ABCDEFGHIJ ABCDEFGHIJ

(Kendini çok yaratıcı hissetmiyorsan, bu).

Tutarlılık için lütfen http://www.cs.duke.edu/~ola/ap/linuxwords adresindeki kelime listesini kullanın.

Bu listedeki 5 harfli sözcükler, uygun adlar da dahil olmak üzere, sorun değildir. Sino- ve L'vov'u ve listedeki az olmayan bir karakter içeren diğer kelimeleri yoksayın.

Kazanan program en geniş kelime grubunu üreten programdır. Birden fazla programın aynı sonucu bulması durumunda, ilk gönderilen program kazanır. Program 5 dakikadan kısa bir sürede çalıştırılmalıdır.

Düzenleme: aktivite öldüğünden ve daha iyi bir çözüm çıkmadığından, Peter Taylor'ı kazanan ilan ediyorum! Yaratıcı çözümleriniz için herkese teşekkürler.


Kültürler arasında çok fazla çeşitlilik gösterdiklerini düşünerek doğru isimleri nasıl sayabiliriz?
elssar

@elssar, Doğru anlarsam, uygun bir ad (herhangi bir kültürde) olup olmadığına bakılmaksızın listedeki herhangi bir kelime TAMAM.
ugoren

Ah, orada , bunu görmedim
elssar

Yani, bir kod sorusu değil; ama mantık?
Brigand

2
Bu kod-meydan okuma olarak etiketlenir : meydan okuma nedir? İstediğiniz tek şey, alan boyutu yaklaşık 110,3 bit olan bir işlevi en üst düzeye çıkaran değerdir. Bu nedenle, sorunu kaba kuvvetle zorlamak mümkün değildir, ancak kesin cevabı almak ve hatta belki de doğru olduğunu kanıtlamak mümkün olmalıdır. Tüm bunları akılda tutarak, bir cevabın dikkate alınması için önkoşullar nelerdir ve bir kazanan seçmek için hangi kriterleri kullanacaksınız?
Peter Taylor

Yanıtlar:


6

Basit açgözlü tepe tırmanma tarafından 1275 kelime

Kod C #. Üretilen çözüm

Score 1275 from ^[bcdfgmpstw][aehiloprtu][aeilnorstu][acdeklnrst][adehklrsty]$

Bu çıktı biçimini kullanıyorum çünkü test etmek gerçekten kolay:

grep -iE "^[bcdfgmpstw][aehiloprtu][aeilnorstu][acdeklnrst][adehklrsty]$" linuxwords.txt | wc

namespace Sandbox {
    class Launcher {
        public static void Main(string[] args)
        {
            string[] lines = _Read5s();
            int[][] asMasks = lines.Select(line => line.ToCharArray().Select(ch => 1 << (ch - 'a')).ToArray()).ToArray();
            Console.WriteLine(string.Format("{0} words found", lines.Length));

            // Don't even bother starting with a good mapping.
            int[] combos = _AllCombinations().ToArray();
            int[] best = new int[]{0x3ff, 0x3ff, 0x3ff, 0x3ff, 0x3ff};
            int bestSc = 0;
            while (true)
            {
                Console.WriteLine(string.Format("Score {0} from {1}", bestSc, _DialsToString(best)));

                int[] prevBest = best;
                int prevBestSc = bestSc;

                // Greedy hill-climbing approach
                for (int off = 0; off < 5; off++)
                {
                    int[] dials = (int[])prevBest.Clone();

                    dials[off] = (1 << 26) - 1;
                    int[][] filtered = asMasks.Where(mask => _Permitted(dials, mask)).ToArray();
                    int sc;
                    dials[off] = _TopTen(filtered, off, out sc);
                    if (sc > bestSc)
                    {
                        best = (int[])dials.Clone();
                        bestSc = sc;
                    }
                }

                if (bestSc == prevBestSc) break;
            }

            Console.WriteLine("Done");
            Console.ReadKey();
        }

        private static int _TopTen(int[][] masks, int off, out int sc)
        {
            IDictionary<int, int> scores = new Dictionary<int, int>();
            for (int k = 0; k < 26; k++) scores[1 << k] = 0;

            foreach (int[] mask in masks) scores[mask[off]]++;

            int rv = 0;
            sc = 0;
            foreach (KeyValuePair<int, int> kvp in scores.OrderByDescending(kvp => kvp.Value).Take(10))
            {
                rv |= kvp.Key;
                sc += kvp.Value;
            }
            return rv;
        }

        private static string _DialsToString(int[] dials)
        {
            StringBuilder sb = new StringBuilder("^");
            foreach (int dial in dials)
            {
                sb.Append('[');
                for (int i = 0; i < 26; i++)
                {
                    if ((dial & (1 << i)) != 0) sb.Append((char)('a' + i));
                }
                sb.Append(']');
            }
            sb.Append('$');
            return sb.ToString();
        }

        private static IEnumerable<int> _AllCombinations()
        {
            // \binom{26}{10}
            int set = (1 << 10) - 1;
            int limit = (1 << 26);
            while (set < limit)
            {
                yield return set;

                // Gosper's hack:
                int c = set & -set;
                int r = set + c;
                set = (((r ^ set) >> 2) / c) | r;
            }
        }

        private static bool _Permitted(int[] dials, int[] mask)
        {
            for (int i = 0; i < dials.Length; i++)
            {
                if ((dials[i] & mask[i]) == 0) return false;
            }
            return true;
        }

        private static string[] _Read5s()
        {
            System.Text.RegularExpressions.Regex word5 = new System.Text.RegularExpressions.Regex("^[a-z][a-z][a-z][a-z][a-z]$", System.Text.RegularExpressions.RegexOptions.Compiled);
            return File.ReadAllLines(@"d:\tmp\linuxwords.txt").Select(line => line.ToLowerInvariant()).Where(line => word5.IsMatch(line)).ToArray();
        }
    }
}

Cevabımı tam olarak bu çözümle düzenlemek üzereydim, ama sen beni yendin.
cardboard_box

1000 rastgele başlangıç ​​kombinasyonundan aynı tepe tırmanma aramasını çalıştırdığımda ve bulunan 1000 yerel optima'nın en iyisini seçtiğimde, her zaman aynı çözümü üretiyor gibi görünüyor, bu yüzden küresel optimum gibi görünüyor.
Peter Taylor

Bu olası ;-) tanımınıza bağlıdır. Ancak, 1275'i maksimum veren diğer yaklaşımlar tarafından “doğrulanır”. (Peki Kuantum-Tic-Tac-Toe nereye gitti?)
Howard

@Howard, bu sadece .Net'in tek bir projede birden fazla giriş noktasını desteklemeyen bir eserdi. Bunun gibi şeyler için kullandığım bir "sanal alan" projem var ve genellikle Mainfarklı _Mainyöntemleri çağırmak için yöntemi değiştiriyorum .
Peter Taylor

Genetik bir algoritma denedim ve birkaç dakika içinde aynı sonucu aldım ve ertesi saatte hiçbir şey olmadı, bu yüzden optimum olsaydı şaşırmazdım.
carton_box

4

Python (3), 1273 ≈% 30,5

Bu gerçekten naif bir yaklaşımdır: her bir pozisyonda her harfin sıklığını takip edin, ardından kalan harfler makaralara oturana kadar "en kötü" harfi ortadan kaldırın. Çok iyi olduğu anlaşılıyor.

En ilginç olanı, C # 1275 çözümü ile hemen hemen aynı çıktıya sahip olmam dışında, Nbunun yerine son makaramda bir var A. Bu Ada a Vve a atmadan önce 11. son elememdi G.

from collections import Counter

def main(fn, num_reels, letters_per_reel):
    # Read ye words
    words = []
    with open(fn) as f:
        for line in f:
            word = line.strip().upper()
            if len(word) == num_reels and word.isalpha():
                words.append(word)

    word_pool_size = len(words)

    # Populate a structure of freq[reel_number][letter] -> count
    freq = [Counter() for _ in range(num_reels)]
    for word in words:
        for r, letter in enumerate(word):
            freq[r][letter] += 1

    while True:
        worst_reelidx = None
        worst_letter = None
        worst_count = len(words)
        for r, reel in enumerate(freq):
            # Skip reels that already have too-few letters left
            if len(reel) <= letters_per_reel:
                continue

            for letter, count in reel.items():
                if count < worst_count:
                    worst_reelidx = r
                    worst_letter = letter
                    worst_count = count

        if worst_letter is None:
            # All the reels are done
            break

        # Discard any words containing this worst letter, and update counters
        # accordingly
        filtered_words = []
        for word in words:
            if word[worst_reelidx] == worst_letter:
                for r, letter in enumerate(word):
                    freq[r][letter] -= 1
                    if freq[r][letter] == 0:
                        del freq[r][letter]
            else:
                filtered_words.append(word)
        words = filtered_words

    for reel in freq:
        print(''.join(sorted(reel)))

    print("{} words found (~{:.1f}%)".format(
        len(words), len(words) / word_pool_size * 100))

üretir:

BCDFGMPSTW
AEHILOPRTU
AEILNORSTU
ACDEKLNRST
DEHKLNRSTY
1273 words found (~30.5%)

Yüzde neyi temsil eder?
Joe Z.

önerilen makara seti ile yapılabilecek kelimelerin yüzdesi
Eevee

Tamam. (Vay, kim olduğunu gördüm.)
Joe Z.

ha, küçük dünya.
Eevee

3

Mathematica , tekrar tekrar 1275 kelime ...

Sorunun bunun için çağrıldığı görülmediğinden bu kod Golf değil.

wordlist = Flatten @ Import @ "http://www.cs.duke.edu/~ola/ap/linuxwords";
shortlist = Select[ToLowerCase@wordlist, StringMatchQ[#, Repeated[LetterCharacter, {5}]] &];
string = "" <> Riffle[shortlist, ","];

set = "a" ~CharacterRange~ "z";
gb = RandomChoice[set, {5, 10}];

best = 0;
While[True,
  pos = Sequence @@ RandomInteger /@ {{1, 5}, {1, 10}};
  old = gb[[pos]];
  gb[[pos]] = RandomChoice @ set;
  If[best < #,
    best = #; Print[#, "   ", StringJoin /@ gb],
    gb[[pos]] = old
  ] & @ StringCount[string, StringExpression @@ Alternatives @@@ gb]
]

Kelime sayımı hızlı bir şekilde (10 saniyeden az) çoğu koşuda 1275'e dönüşür, ancak asla bunun ötesine geçmez. Teorik bir yerel maksimumdan kurtulmak için harfleri bir kerede birden fazla bozmaya çalıştım, ama hiç yardımcı olmadı. 1275'in verilen kelime listesi için sınır olduğundan şüpheleniyorum. İşte tam bir çalışma:

36   {tphcehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafwdyhone}

37   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafwdyhone}

40   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsibxpctio,iafldyhone}

42   {tpicehmqkt,agvkqxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

45   {tpicehmrkt,agvkqxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

48   {tpicehmrkt,agvkwxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

79   {tpicehmskt,agvkwxtnpy,nkehuaakri,nsfbxpctio,iafldyhone}

86   {tpicehmskt,agvkwxtnpy,nkehuaakri,esfbxpctio,iafldyhone}

96   {tpicehmskt,agvkwxtnpy,nkehuaokri,esfbxpctio,iafldyhone}

97   {tpicehmskt,agvkwxtnpy,nkehuaokri,esfbxpctio,ipfldyhone}

98   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfbxpctio,ipfldyhone}

99   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfbzpctio,ipfldyhone}

101   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzpctio,ipfldyhone}

102   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzpctno,ipfldyhone}

105   {tpicehmskv,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

107   {tpicehmskn,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

109   {tpgcehmskn,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

115   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhone}

130   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldyhons}

138   {tpgcehmsan,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

143   {tpgcehmsab,agvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

163   {tpgcehmsab,auvkwxtnpy,nkehuaokri,esfhzmctno,ipfldytons}

169   {tpgcehmsab,auvkwctnpy,nkehuaokri,esfhzmctno,ipfldytons}

176   {tpgcehmsab,auvkwctnpy,nkehuaokri,esfhzmctno,ihfldytons}

189   {tpgcehmsab,auvkwchnpy,nkehuaokri,esfhzmctno,ihfldytons}

216   {tpgcehmsab,auvkwchnpy,nkehtaokri,esfhzmctno,ihfldytons}

220   {tpgcehmsab,auvkwthnpy,nkehtaokri,esfhzmctno,ihfldytons}

223   {tpgcehmsab,auvkwthnpy,nkehtaokri,esfhbmctno,ihfldytons}

234   {tpgcehmsab,auvkwthnpy,nkegtaokri,esfhbmctno,ihfldytons}

283   {tpgcehmsab,auvkwthnpy,nkegtaokri,esfhbrctno,ihfldytons}

285   {tpdcehmsab,auvkwthnpy,nkegtaokri,esfhbrctno,ihfldytons}

313   {tpdcehmsab,auvkwthnly,nkegtaokri,esfhbrctno,ihfldytons}

371   {tpdcehmsab,auvkethnly,nkegtaokri,esfhbrctno,ihfldytons}

446   {tpdcehmsab,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

451   {tpdcehmslb,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

465   {tpdcwhmslb,auvoethnly,nkegtaokri,esfhbrctno,ihfldytons}

545   {tpdcwhmslb,auioethnly,nkegtaokri,esfhbrctno,ihfldytons}

565   {tpdcwhmslb,auioethnly,nkegtaocri,esfhbrctno,ihfldytons}

571   {tpdcwhmslb,auioethnly,nkegtaocri,esfhwrctno,ihfldytons}

654   {tpdcwhmslb,auioethnly,nkegtaocri,esfhwrctno,ihfedytons}

671   {tpdcwhmslb,auioethnly,nkegtaocri,esfhirctno,ihfedytons}

731   {tpdcwhmslb,auioethnly,nkegtaocri,esfhirctno,ihredytons}

746   {tpdcwhmslb,arioethnly,nkegtaocri,esfhirctno,ihredytons}

755   {tpdcwhmslb,arioethnuy,nkegtaocri,esfhirctno,ihredytons}

772   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhirctno,ihredytons}

786   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhirctno,lhredytons}

796   {tpdcwhmslb,arioethnuy,nkegtaocri,ekfhgrctno,lhredytons}

804   {tpdcwhmslb,arioethwuy,nkegtaocri,ekfhgrctno,lhredytons}

817   {tpdcwhmslb,arioethwuy,nklgtaocri,ekfhgrctno,lhredytons}

834   {tpdcwhmslb,arioethwuy,nklgtaocri,ekfhdrctno,lhredytons}

844   {tpdcwhmslb,arioethwup,nklgtaocri,ekfhdrctno,lhredytons}

887   {tpdcwhmslb,arioethwup,nklgtaocri,ekshdrctno,lhredytons}

901   {tpdcwhmslb,arioethwup,nklgtaouri,ekshdrctno,lhredytons}

966   {tpdcwhmslb,arioethwup,nklgtaouri,elshdrctno,lhredytons}

986   {tpdcwhmsfb,arioethwup,nklgtaouri,elshdrctno,lhredytons}

1015   {tpdcwhmsfb,arioethwup,nklgtaouri,elsidrctno,lhredytons}

1039   {tpdcwhmsfb,arioethwup,nklgtaouri,elsidrctno,khredytons}

1051   {tpdcwhmsfb,arioethwup,nklgtaouri,elskdrctno,khredytons}

1055   {tpdcwhmsfb,arioethwup,nklgtaouri,elskdrctno,khredytlns}

1115   {tpdcwhmsfb,arioethwup,nelgtaouri,elskdrctno,khredytlns}

1131   {tpdcwhmsfb,arioethwup,nelwtaouri,elskdrctno,khredytlns}

1149   {tpdcwhmsfb,arioethwup,nelwtaouri,elskdrctna,khredytlns}

1212   {tpdcwhmsfb,arioelhwup,nelwtaouri,elskdrctna,khredytlns}

1249   {tpdcwhmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1251   {tpgcwhmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1255   {tpgcwdmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlns}

1258   {tpgcwdmsfb,arioelhwup,nelstaouri,elskdrctna,khredytlas}

1262   {tpgcwdmsfb,arioelhwut,nelstaouri,elskdrctna,khredytlas}

1275   {tpgcwdmsfb,arioelhput,nelstaouri,elskdrctna,khredytlas}

İşte bazı "kazanan" seçimler:

{"cbpmsftgwd", "hriuoepatl", "euosrtanli", "clknsaredt", "yhlkdstare"}
{"wptdsgcbmf", "ohlutraeip", "erotauinls", "lknectdasr", "sytrhklaed"}
{"cftsbwgmpd", "ropilhtaue", "niauseltor", "clstnkdrea", "esdrakthly"}
{"smgbwtdcfp", "ihulpreota", "ianrsouetl", "ekndasctlr", "kehardytls"}

Peter'ın dediği gibi bunlar aslında farklı düzenlerde aynı çözümdür. sıralama:

{"bcdfgmpstw", "aehiloprtu", "aeilnorstu", "acdeklnrst", "adehklrsty"}

@belisarius Teşekkürler! ENABLE2k ile daha ilginç .
Mr.Wizard

Bunun için Combinatorica'nın NetworkFlow'unu düşünüyordum, ancak bunu kullanmanın yararlı bir yolunu bulamadım
Dr.Belisarius

@belisarius Umarım bir yol bulursun; Bunu görmek istiyorum.
Sihirbaz

@belisarius Bu arada benim kod shortlistuzun hissediyorum ve bu Golf olmasa da daha kısa bir şey istiyorum. Yardım edebilir misin?
Mr.Wizard

1
"Kazanan" seçimlerinizin kadranlarda aynı modulo permütasyonu olduğunu düşünüyorum.
Peter Taylor

2

Python, 1210 kelime (~% 29)

Bu sefer kelimeleri doğru saydığımı varsayarsak, bu FakeRainBrigand'ın çözümünden biraz daha iyidir. Tek fark, her makarayı sırayla ekleyip listeden makarayla eşleşmeyen tüm kelimeleri kaldırmam, böylece sonraki makaralar için biraz daha iyi bir dağılım elde ederim. Bu nedenle, aynı ilk makarayı verir.

word_list = [line.upper()[:-1] for line in open('linuxwords.txt','r').readlines() if len(line) == 6]
cur_list = word_list
s = ['']*5
for i in range(5):
    count = [0]*26
    for j in range(26):
        c = chr(j+ord('A'))
        count[j] = len([x for x in cur_list if x[i] == c])
    s[i] = [chr(x+ord('A')) for x in sorted(range(26),lambda a,b: count[b] - count[a])[:10]]
    cur_list = filter(lambda x:x[i] in s[i],cur_list)
for e in s:
    print ''.join(e)
print len(cur_list)

Program çıktıları

SBCAPFDTMG
AOREILUHTP
ARIOLENUTS
ENTLRCSAID
SEYDTKHRNL
1210

Güzel ve 1210 benim denetleyicisi çalışır.
Brigand

1

iPython ( 273 210 Bayt, 1115 kelime)

1115/4176 * ~% 27

Bunları iPython'da hesapladım, ancak geçmişim (hata ayıklamayı kaldırmak için kesilmiş) böyle görünüyordu.

with open("linuxwords") as fin: d = fin.readlines()
x = [w.lower().strip() for w in d if len(w) == 6]
# Saving for later use:
# with open("5letter", "w") as fout: fout.write("\n".join(x))
from string import lowercase as low
low=lowercase + "'"
c = [{a:0 for a in low} for q in range(5)]
for w in x:
    for i, ch in enumerate(w):
        c[i][ch] += 1

[''.join(sorted(q, key=q.get, reverse=True)[:10]) for q in c]

Kısaca gidersek; Bunu buna göre ayarlayabilirim.

x = [w.lower().strip() for w in open("l") if len(w)==6]
c=[{a:0 for a in"abcdefghijklmnopqrstuvwxyz'-"}for q in range(5)]
for w in[w.lower().strip()for w in open("l") if len(w)==6]:
 for i in range(5):c[i][w[i]]+=1
[''.join(sorted(q,key=q.get,reverse=True)[:10])for q in c]

Kısaltılmış:

c=[{a:0 for a in"abcdefghijklmnopqrstuvwxyz'-"}for q in range(5)]
for w in[w.lower() for w in open("l")if len(w)==6]:
 for i in range(5):c[i][w[i]]+=1
[''.join(sorted(q,key=q.get,reverse=True)[:10])for q in c]

Benim sonuçları şöyleydi: ['sbcapfdtmg', 'aoeirulhnt', 'aironeluts', 'etnlriaosc', 'seyrdtnlah'].

* 4176'daki matematiğim, kısa çizgi veya kesme işareti bulunan kelimeler atlandığı için biraz kısa olabilir


1
Bu çözüm iyi bir buluşsal yöntem olsa da ve muhtemelen iyi bir çözüm getirecektir, ancak en uygun çözümü döndürmenin garanti edildiğine inanmıyorum. Bunun nedeni, makaralar arasındaki kısıtlamaları yakalamamanızdır: Aslında her bir makaraya bağımlı olduklarında bağımsız bir değişken olarak davranıyorsunuz. Örneğin, en yaygın ilk harfi paylaşan kelimelerin ikinci harflerinin dağılımında büyük bir varyans olması söz konusu olabilir. Bu durumda, çözümünüz aslında hiçbir kelimeye izin vermeyen makara kombinasyonları üretebilir.
ESultanik

1

S

? (yapılacaklar) kelimeler

Kelimeler şu adlı bir dosyada saklanmalıdır: words

(!:')10#/:(desc')(#:'')(=:')(+:)w@(&:)(5=(#:')w)&(&/')(w:(_:)(0:)`:words)in\:.Q.a

Benim i7 üzerinde yaklaşık 170 ms çalışır. Her pozisyonda en yaygın harfi arayan kelime listesini analiz eder (açıkça aday olmayanları filtreleyerek). Tembel naif bir çözümdür ancak minimum kodla oldukça iyi bir sonuç verir.

Sonuçlar:

"sbcapfdtmg"
"aoeirulhnt"
"aironeluts"
"etnlriaosc"
"seyrdtnlah"

Kaç tane 5 harfli kelime buldun?
DavidC

Python aynı şeyi yaptı ve 16353. var
cardboard_box

FakeRainBrigand ile aynı açgözlü algoritma mı?
Peter Taylor

1
@cardboard_box, sonucunuz kesinlikle yanlış. Sözlükte çok fazla 5 harfli kelime yok.
Peter Taylor

1
Evet, 1115. Doğru kelimelerin sayısı yerine herhangi bir kelimedeki doğru harflerin sayısını saydım. Sanırım başka bir kahveye ihtiyacım var.
karton_kutu

0

Düzenleme: Artık kurallar değiştirildiğine göre, bu yaklaşım diskalifiye edilir. Sonunda yeni kurallar için değişiklik yapmaya başlayana kadar herkesin ilgilenmesi durumunda burada bırakacağım.

Python: 277 Karakter

Bu sorunun genelleştirilmiş sürümünün NP-Hard olduğundan eminim ve soru en hızlı çözümü bulmayı gerektirmedi , bu yüzden bunu yapmanın kaba kuvvet yöntemi:

import itertools,string
w=[w.lower()[:-1] for w in open('w') if len(w)==6]
v=-1
for l in itertools.product(itertools.combinations(string.ascii_lowercase,10),repeat=5):
 c=sum(map(lambda d:sum(map(lambda i:i[0] in i[1],zip(d,l)))==5,w))
 if c>v:
  v=c
  print str(c)+" "+str(l)

Birkaç karakter kaydetmek için kelime listesi dosyasını sadece "w" olarak yeniden adlandırdığımı unutmayın.

Çıktı, belirli bir yapılandırmadan sonra yapılandırmanın kendisinden mümkün olan sözcük sayısıdır:

34 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
38 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'))
42 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'l'))
45 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'n'))
50 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'r'))
57 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 's'))
60 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'k', 's'))
64 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'l', 's'))
67 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'n', 's'))
72 (('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'), ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'r', 's'))
...

Program sona ermeden önceki son çıktı satırı en uygun çözümdür.


Kodunuzun bir C veya ASM sürümünü görmek isterim, böylece bu yıl gerçekten bitirebilirim :-) Veya en azından 1116'ya kadar çalıştırın. İtertools olmadan yazabilir misiniz, bu yüzden jython üzerinde çalıştırabilirim ? (normal python'dan daha hızlı, ancak cython'dan daha kolay.)
Brigand

Jython olayı hakkında boşver. Alfa almam gerekiyordu. Hala çöktü (çok fazla bellek) ama bu kaçınılmaz görünüyor.
Brigand

Bu montajda uygulansa bile mevcut donanımda tamamlamamın
ömrümden

Sorun şu ki (26 seçim 10) ^ 5 ≈ 4.23 * 10 ^ 33 olasılıkları tekrar ediyorum. Her bir nanosaniye için bir olasılığı test etsek bile, evrenin şu anki yaşının bitmesi yaklaşık 10 ^ 7 kat daha fazla zaman alacaktır.
ESultanik

1
Verilen kelime listesindeki herhangi bir kelimede 5. sırada görünmeyen iki karakter vardır, bu nedenle olasılık sayısını yaklaşık 4 kat azaltabilirsiniz. soru.
Peter Taylor
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.