가장 우스운 조합 자물쇠 찾기


18

숫자 대신 문자가있는 조합 자물쇠가 있습니다. 다음과 같이 보입니다 : http://pictures.picpedia.com/2012/09/Word_Combination_Padlock.jpg 5 개의 릴이 있으며 각 릴에는 10 개의 다른 문자가 있습니다.

대부분의 사람들은 임의의 문자열 대신 조합하여 단어를 사용하는 것을 좋아합니다. (물론 안전하지만 기억하기는 더 쉽습니다.) 따라서 자물쇠를 만들 때는 가능한 한 많은 5 글자 영어 단어를 만드는 데 사용할 수있는 문자 조합을 갖도록 작성하는 것이 좋습니다.

당신의 임무는 당신이 그것을 받아들이도록 선택한다면, 가능한 많은 단어를 만들 수 있도록 릴에 문자를 할당하는 것입니다. 예를 들어, 솔루션은

ABCDEFGHIJ DEFGHIJKLM ZYXWVUTSR ABCDEFGHIJ ABCDEFGHIJ

(당신이 너무 상상력이 없다면, 그것은)입니다.

일관성을 유지하려면 http://www.cs.duke.edu/~ola/ap/linuxwords 의 단어 목록을 사용 하십시오.

적절한 이름을 포함하여 해당 목록에있는 5 글자 단어는 괜찮습니다. Sino- 및 L' vov 및 목록에서 z가 아닌 문자를 포함하는 다른 단어는 무시하십시오.

우승 프로그램은 가장 큰 단어 집합을 생성하는 프로그램입니다. 여러 프로그램이 동일한 결과를 발견하면 가장 먼저 게시되는 것이 우선합니다. 프로그램은 5 분 안에 실행되어야합니다.

편집 : 활동이 중단되고 더 나은 해결책이 나오지 않았기 때문에 Peter Taylor를 승자로 선언합니다! 독창적 인 솔루션에 대해 모두 감사합니다.


문화마다 그토록 많이 다른 것을 고려할 때 적절한 이름을 어떻게 셀 수 있습니까?
elssar

@elssar, 올바르게 이해하면 올바른 문화 이름과 상관없이 목록의 모든 단어가 정상입니다.
우고 렌

아 맞다, 거기에 ,
elssar

따라서 코드 질문이 아닙니다. 그러나 논리?
Brigand

2
이것은 코드 도전 으로 태그됩니다 : 도전은 무엇입니까? 당신이 요구 한 것은 도메인 크기가 약 110.3 비트 인 함수를 최대화하는 값입니다. 따라서 문제를 무차별 적으로 시행하는 것은 불가능하지만 정확한 답을 얻는 것이 가능해야하며, 심지어 올바른 것으로 입증 될 수도 있습니다. 이를 염두에두고 답을 구하기위한 전제 조건은 무엇이며, 승자를 선택하기 위해 어떤 기준을 사용 하시겠습니까?
피터 테일러

답변:


6

간단한 탐욕스러운 언덕 등반으로 1275 단어

코드는 C #입니다. 생산 된 솔루션은

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

테스트하기가 쉽기 때문에 해당 출력 형식을 사용하고 있습니다.

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

이 정확한 솔루션으로 답변을 편집하려고했지만 당신이 나를 이겼습니다.
cardboard_box

1000 개의 무작위 시작 조합에서 동일한 언덕 등반 검색을 실행하고 발견 된 1000 개의 로컬 옵티마 중에서 가장 좋은 것을 선택하면 항상 동일한 솔루션을 생성하는 것처럼 보이므로 글로벌 최적 일 가능성이 높습니다.
피터 테일러

그것은 가능성에 대한 당신의 정의에 달려 있습니다 ;-) 그러나 그것은 1275를 최대로 산출하는 다른 접근법들에 의해 더 "확인됩니다". (그리고 Quantum-Tic-Tac-Toe는 어디로 갔습니까?)
Howard

@Howard, 그것은 단일 프로젝트에서 여러 진입 점을 지원하지 않는 .Net의 인공물이었습니다. 이와 같은 것들에 사용하는 하나의 "샌드 박스"프로젝트가 있으며 일반적으로 다른 Main메소드를 호출 하도록 메소드를 변경합니다 _Main.
피터 테일러

나는 유전자 알고리즘을 시도하고 몇 분 안에 같은 결과를 얻었고 다음 시간에는 아무것도 얻지 않았으므로 그것이 최적이라면 놀라지 않을 것입니다.
cardboard_box

4

파이썬 (3), 1273 ≈ 30.5 %

이것은 매우 순진한 접근 방법입니다. 각 위치에서 각 문자의 빈도를 집계 한 다음 나머지 문자가 릴에 맞을 때까지 "최악의"문자를 제거하십시오. 나는 그것이 그렇게 잘하는 것에 놀랐습니다.

가장 흥미로운 것은 C # 1275 솔루션과 거의 동일한 출력을 가지고 있다는 N것입니다 A. 그것은 Aa V와 a를 버리기 전에도 11 번째부터 마지막까지의 제거 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))

생산 :

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

백분율은 무엇을 나타 냅니까?
Joe Z.

제안 된 릴 세트로 만들 수있는 주어진 단어의 퍼센트
Eevee

괜찮아. (아, 방금 당신이 누군지 봤어요)
Joe Z.

하, 작은 세상.
Eevee

3

매스 매 티카 , 1275 개 단어 또 다시 ...

질문이 그것을 요구하지 않는 것처럼이 코드는 골프가 아닙니다.

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

단어 수는 빠르게 (10 초 미만) 대부분의 실행에서 1275로 진화하지만 절대로 넘어 가지 않습니다. 이론적 인 지역 최대치를 벗어나기 위해 한 번에 여러 문자로 교란을 시도했지만 결코 도움이되지 않았습니다. 1275가 주어진 단어 목록의 제한이라고 생각합니다. 다음은 완전한 실행입니다.

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}

다른 "우승"선택은 다음과 같습니다.

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

Peter가 언급했듯이 이들은 실제로 다른 순서로 동일한 솔루션입니다. 정렬 :

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

@belisarius 감사합니다! ENABLE2k 보다 흥미 롭습니다 .
Mr.Wizard

나는 이것을 위해 Combinatorica의 NetworkFlow를 고려하고 있었지만 그것을 사용하는 유용한 방법을 찾지 못했습니다
Dr. belisarius

@ belisarius 나는 당신이 길을 찾을 수 있기를 바랍니다. 나는 그것을보고 싶다.
Mr.Wizard

@belisarius 내 코드 shortlist는 오래 걸리지 만 이것이 골프는 아니지만 더 짧은 것을 좋아합니다. 도울 수 있니?
Mr.Wizard

1
귀하의 "승리 한"선택은 다이얼 내에서 모두 동일한 모듈로 순열이라고 생각합니다.
피터 테일러

2

파이썬, 1210 단어 (~ 29 %)

이번에 단어를 올바르게 계산했다고 가정하면 FakeRainBrigand의 솔루션보다 약간 낫습니다. 유일한 차이점은 각 릴을 순서대로 추가 한 다음 릴과 일치하지 않는 모든 단어를 목록에서 제거하여 다음 릴에 대해 약간 더 나은 분포를 얻는 것입니다. 이 때문에 정확히 동일한 첫 번째 릴을 제공합니다.

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)

프로그램 출력

SBCAPFDTMG
AOREILUHTP
ARIOLENUTS
ENTLRCSAID
SEYDTKHRNL
1210

좋고, 1210은 내 체커에서 작동합니다.
Brigand

1

iPython ( 273 210 바이트 1,115 단어)

1115/4176 * ~ 27 %

나는 이것을 iPython에서 계산했지만 내 역사 (디버깅을 제거하려고 다듬어)는 다음과 같이 보였다.

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]

우리가 짧게 가고 있다면; 나는 이것을 다듬을 수 있었다.

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]

단축 :

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]

내 결과는 다음과 같습니다 ['sbcapfdtmg', 'aoeirulhnt', 'aironeluts', 'etnlriaosc', 'seyrdtnlah'].

* 4176의 수학은 하이픈이나 아포스트로피가 생략 된 단어로 인해 약간 짧을 수 있습니다.


1
이 솔루션은 좋은 휴리스틱이며 좋은 솔루션을 반환 할 가능성이 있지만 최적의 솔루션을 반환한다고 보장하지는 않습니다. 그 이유는 릴 사이의 구속 조건을 캡처하지 않기 때문입니다. 각 릴은 실제로 종속적 일 때 독립 변수로 취급합니다. 예를 들어, 가장 일반적인 첫 글자를 공유하는 단어가 두 번째 글자 분포에 큰 차이가있을 수 있습니다. 이 경우 솔루션에서 실제로 단어를 허용하지 않는 릴 조합이 생성 될 수 있습니다.
ESultanik

1

? (할일) 단어

단어는라는 파일에 저장해야합니다 words

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

내 i7에서 약 170ms 동안 실행됩니다. 단어 목록을 분석하여 각 위치에서 가장 일반적인 문자를 찾습니다 (명심하지 않은 후보자를 모두 필터링). 게으른 순진한 솔루션이지만 최소한의 코드로 합리적인 결과를 얻을 수 있습니다.

결과 :

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

5 글자 단어는 몇 개나 찾았습니까?
DavidC

나는 파이썬에서 같은 일을하고 16353을 얻었다.
cardboard_box

이것이 FakeRainBrigand와 같은 탐욕스러운 알고리즘입니까?
피터 테일러

1
@cardboard_box, 결과는 확실히 잘못되었습니다. 사전에는 5 글자 단어가 많지 않습니다.
피터 테일러

1
그렇습니다, 그것은 1115입니다. 나는 정확한 단어의 수 대신 어떤 단어의 정확한 글자 수를 세었습니다. 커피가 더 필요하다고 생각합니다.
cardboard_box

0

편집 : 이제 규칙이 수정되었으므로이 방법은 실격입니다. 새 규칙에 맞게 수정하려고 할 때까지 누구나 관심을 가질 수 있도록 여기에 남겨 두겠습니다.

파이썬 : 277 자

나는이 문제의 일반화 된 버전이 NP-Hard라고 확신하며 질문은 가장 빠른 해결책을 찾을 필요가 없으므로 다음과 같은 방법을 사용하십시오.

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)

단어 목록 파일의 이름을 "w"로 바꾸어 문자 몇 개를 저장했습니다.

출력은 주어진 구성에서 가능한 다음 단어 자체의 수입니다.

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'))
...

프로그램이 종료되기 전 마지막 라인이 최적의 솔루션임을 보장합니다.


나는 실제로 올해를 마무리 할 수 ​​있도록 C 또는 ASM 버전의 코드를보고 싶습니다 :-) 또는 적어도 1116에 도달 할 때까지 실행하십시오. itertools없이 작성할 수 있으므로 jython에서 실행할 수 있습니다 ? (빠른 일반 파이썬보다하지만 쉽게 사이 썬보다.)
산적

자이 썬에 대해서는 신경 쓰지 마십시오. 나는 알파를 잡아야했다. 여전히 메모리가 너무 크지 만 충돌이 불가피합니다.
Brigand

이것이 어셈블리로 구현 되더라도 현재 하드웨어에서 완료하는 데 평생보다 더 오래 걸릴 것이라고 확신합니다 :
-P

문제는 내가 반복하고 있다는 것입니다 (26 choose 10) ^ 5 ≈ 4.23 * 10 ^ 33 가능성. 비록 우리가 나노 초당 하나의 가능성을 테스트 할 수 있다고해도, 현재 우주 시대의 10 ^ 7 배는 끝날 것입니다.
ESultanik

1
주어진 단어 목록의 어떤 단어에서도 5 번째 위치에 나타나지 않는 2 개의 문자가 있으므로 약 4 배로 가능성의 수를 줄일 수 있습니다. 질문.
피터 테일러
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.