하나님의 90 억 이름


74

90 억의 하나님의 이름은 Arthur C. Clarke의 짧은 이야기입니다. 그것은 티베트 승려 그룹에 관한 것으로, 알파벳 순서로 쓰여진 하나님의 가능한 모든 이름을 적어 두는 데 전념하고 있습니다. 본질적으로, 그들은 몇 가지 규칙에 의해 제한되는 알파벳의 가능한 모든 순열을 쓰는 데 전념합니다. 이야기에서 수도원은 일부 엔지니어를 고용하여 모든 작업을 수행하는 프로그램을 작성합니다. 당신의 목표는 그 프로그램을 작성하는 것입니다.

규칙 :

  • 수도사의 알파벳은 13 문자를 사용합니다 (내 추정에 따르면). ABCDEFGHIJKLM13 자 이상의 다른 문자를 사용할 수 있습니다 .

  • 가능한 이름의 최소 길이는 1 자입니다. 최대 길이는 9 자입니다.

  • 어떤 캐릭터도 연속으로 3 번 이상 반복 할 수 없습니다. AAABA유효한 이름이지만 AAAAB그렇지 않습니다.

  • 에서 순서대로 (파일로) 모든 가능한 이름을 인쇄해야합니다 귀하의 프로그램 AMMMLMMMLM없는 알파벳의 모든 문자로 구분 (줄 바꿈, 세미콜론, 무엇이든).

  • 이것은 코드 골프이며 모든 언어를 사용할 수 있습니다. 2014 년 6 월 1 일까지 가장 짧은 솔루션이 승리합니다.

편집 : 이름은로 시작하여 A로 끝나고 MMMLMMMLM수십억 개의 모든 이름을 순차적으로 진행해야합니다. 그러나 특정 순서는 당신에게 달려 있습니다. 그런 다음, 첫째 등 모두 두 글자로 된 이름을 모두 한 글자로 된 이름을 인쇄 할 수 있습니다 또는 당신이로 시작하는 모든 이름을 인쇄 할 수 있습니다 A, 모든으로 시작하는 사람 B, 또는 다른 패턴. 그러나 사람은 파일을 읽을 수 있고 시간이 있다고 가정 할 때 원하는 모든 논리적 순서에 따라 파일을 모두 확인할 수 있어야합니다.


29
우주를 끝내려고하십니까?
Boluc Papuccuoglu 2016 년

8
관심있는 사람을위한 이야기 링크 .
ThatOneGuy 2016 년


1
이것은 현재 문제의 이름 수가 실제로 11,459,252,883인지 확인합니다 ( edc65의 C 프로그램 에서 볼 수 있음 ). MathSE에서 Ross Millikan의 솔루션을 구현 하면 가변 알파벳 크기 k에 대해 길이가 <= 9 인 이름 수에 대해 다음 다항식을 생성합니다 f(k) = k^9 + k^8 + k^7 - 5*k^6 + k^5 + k^4 + 4*k^3 - 2*k^2 + k. 세이지 구현 : goo.gl/0srwhq
res

3
@ edc65 그래서 105.8GB모든 말과 행동 ! 별이 나오지 않아서 다행이다.
recursion.ninja

답변:


34

루비, 46

?A.upto(?M*9){|s|s[/(.)\1{3}|[N-Z]/]||puts(s)}

내 원래의 유사한 솔루션은 길고 잘못되었습니다 (base13 숫자를 출력합니다. 이는 0으로 시작하기 때문에 숫자가 전부는 아닙니다).하지만 어쨌든 투표를했기 때문에 여기에 남겨 두겠습니다.

1.upto(13**9){|i|(s=i.to_s 13)[/(.)\1{3}/]||puts(s)}

14
글쎄, 나는 약 1 시간 동안 코드를 실행했고 이것을보고 끝내기 전에 최대 20 억 개의 이름과 21GB 텍스트 파일을 얻었습니다. 나는 파일이 얼마나 클지 과소 평가했다.
CSturgess

2
@CSturgess 글쎄, 루비는 이런 종류의 언어 중에서 가장 빠른 언어는 아닙니다 ...
BenjiWiebe

8
@ BenjiWiebe 그러나 승려가 손으로 쓰는 것보다 여전히 빠릅니다!
Turophile 2016 년

1
더 많은 투표권이 있기 때문에 이것을 수락합니다.
CSturgess

4
엄청나게 많은 양의 메모리 (내 계산이 정확하면 ~ 30 TB)가 필요하기 때문에 이것을 별도의 답변으로 게시하지는 않지만 이론적으로 이를 사용하여 43 자로 줄일 수 있습니다.k=*?A..?M*9;puts k-k.grep(/(.)\1{3}|[N-Z]/)
Ventero

24

C 140177235

좋은 오래된 절차 스타일, 공상.
8 분 동안 11,459,252,883 개의 이름을 씁니다 (쓰기 없음).
다음으로 런타임 및 이름 파일로 편집하십시오. 하늘을보십시오 ...
런타임 57 분, 파일 크기 126,051,781,713 (행당 9 자 + crlf). 직접 확인하기 위해 승려의 이메일 주소를 알려주십시오.

편집 골프를 조금 더하고, 반복되는 문자 확인을 재 작업했습니다.
여전히 가장 짧지는 않지만 적어도 이것은 종료되고 필요한 출력을 생성합니다.
런타임 51 분, 파일 크기 113,637,155,697 (이때 선행 공백 없음)

참고 사항 : 분명히 출력 파일은 매우 압축 가능하지만 36 시간 동안 작업 한 후 7zip을 70 %로 죽여야했습니다. 기묘한.

char n[]="@@@@@@@@@@";p=9,q,r;main(){while(p)if(++n[p]>77)n[p--]=65;else for(r=q=p=9;r&7;)(r+=r+(n[q]!=n[q-1])),n[--q]<65&&puts(n+q+1,r=0);}

언 골프

char n[]="@@@@@@@@@@";
p=9,q,r;
main()
{
    while (p)
    {
        if (++n[p] > 77)
        {
            n[p--] = 65; // when max reached, set to min and move pointer to left
        }
        else 
        {
            for (r=q=p=9; r & 7 ;) // r must start as any odd number
            {
                r += r+(n[q]!=n[q-1])); // a bitmap: 1 means a difference, 000 means 4 letters equal
                n[--q] < 65 && puts(n+q+1,r=0);
            }
        }
    }
}

아니 #include?
Simon Kuang

@SimonKuang에서 일부 컴파일러는 기본 컴파일러 (stdio)를 자동으로 넣습니다.
Paul Draper

1
@Simon C 표준입니다. 기본적으로 전역 객체는 int이며 전역 함수는 int를 반환합니다. Visual Studio에서 '입력'에 대한 경고 C4013이 정의되지 않았지만 어쨌든 유효합니다.
edc65

4
트윗에 들어갑니다!
CincauHangus 2018 년

19

골프 스크립트, 58 47 자

"A"13
9?,{13base{65+}%n+}%{`{\4*/,}+78,1/%1-!},

Peter Taylor 덕분에 나는 seppuku에서 Ruby 솔루션을 꺾지 않았습니다. 최대 10 개까지 직접 코드를 실행 하고, 여기가 네 -에 - 어 - 행 번호를 건너 뜁니다 증거입니다 .


1
간편한 저장 : n+대신 사용하십시오 ''+n. 나는 그것을 제어 문자와 알파벳을 사용하는 규칙 내 생각, 그래서 당신은 또한 대체 할 수 65+13+및 명명하여 다른 문자를 저장합니다 13:^. 그리고 그럴 수 있다고 생각 13,{ stuff [...]합니다 13,1/{ stuff 4*.
피터 테일러

1
저의 초기 생각은 절약이 필터를 통해 이루어지고 약간의 작업만으로도 가능하다는 생각이었습니다. 에서 8 13,로 대체 {65+}%n+}%{ backtick {\4*/,}+78,1/%1-!},하여 생명을 구할 수 있습니다.
피터 테일러

캐릭터가 실제로 볼 수있는 것이면 효과가 있습니다. 실제로 개행을 문자로 포함시킬 수도 있습니다. 문자 순서가있는 한.
CSturgess

@ 피터 테일러 : 당신은 신사와 학자입니다!
Claudiu

그 후가 아니 AAAM어야 합니까? AAABABAAAB
justhalf

18

Bash + Linux 명령 줄 유틸리티, 43 바이트

jot -w%x $[16**9]|egrep -v "[0ef]|(.)\1{3}"

이것은 내 대답은 아래에 유사한 기술을 사용하지만, 단지베이스 (16)에 계산하고 모든 "이름"를 포함 떼어 내고 0, e또는 f뿐만 아니라 이들 3 개 이상 같은 연속 자리를.

다음과 같이 스님의 알파벳으로 변환하십시오.

jot -w%x $[16**9]|egrep -v "[0ef]|(.)\1{3}" | tr 1-9a-d A-M

Bash + coreutils (dc 및 egrep), 46 바이트

수정-수정 된 버전

dc<<<Edo9^[p1-d0\<m]dsmx|egrep -v "0|(.)\1{3}"

실행하는 데 시간이 걸리지 만 올바른 것으로 생각합니다.

dc14 ^ 9에서 1까지 아래로 내려 가고 밑수 14에서 출력됩니다. 또한 "0"숫자로 이름을 필터링하여 이름에 올바른 문자 세트를 얻습니다.

질문은 모든 알파벳을 사용할 수 있다고 지정하므로 [1-9] [AD]를 사용하고 있습니다. 그러나 테스트를 위해 tr을 사용하여 [AM]으로 변환 할 수 있습니다.

dc<<<Edo9^[p1-d0\<m]dsmx|egrep -v "0|(.)\1{3}" | tr 1-9A-D A-M

이것은 시퀀스를 산출합니다 :

MMMLMMMLM MMMLMMMLL MMMLMMMLK ... AC AB AA M L K ... C B A

dc명령이 작동하려면 꼬리 재귀가 필요합니다. 이것은 dc 버전 1.3.95 (Ubuntu 12.04)에서는 작동하지만 1.3 (OSX Mavericks)에서는 작동하지 않습니다.


10

APL (59)

↑Z/⍨{~∨/,↑⍷∘⍵¨4/¨⎕A[⍳13]}¨Z←⊃,/{↓⍉⎕A[1+(⍵/13)⊤¯1⌽⍳13*⍵]}¨⍳9

자체 알파벳으로 작성 :) 조금 길다. 로 실행하는 데 시간이 오래 걸리므로 9원하는 경우 테스트하기 위해 더 낮은 숫자로 시도하십시오.

설명:

  • {... }¨⍳9: 1에서 9까지의 각 숫자에 대해
    • ⍳13*⍵: 1에서 모든 숫자를 얻습니다. 13^⍵
    • ¯1⌽(그래서 우리는이 일에 의해 왼쪽으로 목록을 회전 13^⍵, 1, 2, ..., 13^⍵-1로 변신하는 0, 1, 2 ...모듈 13^⍵).
    • (⍵/13)⊤: 숫자 13을 사용하여 밑 13의 각 숫자를 인코딩하십시오.
    • ⎕A[1+... ]: 하나를 추가하고 (배열은 1 인덱싱 됨) ⎕A(알파벳)을 찾습니다
    • ↓⍉: 행렬을 열을 따라 벡터로 구성합니다.
  • Z←⊃,/: 벡터의 각 내부 벡터를 결합하여 가능한 이름 목록을 제공합니다 (그러나 아직 규칙을 충족하지는 않음).
  • {... : 각 이름에 대해 4 개의 반복 문자 규칙을 충족하는지 테스트하십시오.
    • 4/¨⎕A[⍳13]: 각 문자에 대해 해당 문자의 문자열 4 개를 생성하십시오.
    • ⍷∘⍵¨: 각 문자열에 대해 존재하는지 테스트하십시오.
    • ∨/,↑: 논리적 또는 이 모든 테스트를 수행합니다.
    • ~: 1규칙을 준수하고 규칙을 준수 0한다는 의미입니다.
  • Z/⍨: Z루엘을 충족시키는 모든 요소 중에서 선택
  • : 각각을 별도의 줄에 표시

9
나는 실망했다. 명성을 감안할 때 APL은 키보드를 입력 할 수없는 한 가지 솔루션을 제공한다고 생각합니다.
Mark

7
@Mark, 나는 APL이 그것을 가지고 있다고 확신하지만, 그 성격이 무엇인지 아무도 모른다 :)
Paul Draper

1
이것을 돌에 써야하고, 미래의 사람들이 이것을 발견하면, 그것이 단지 원시적 언어라고 생각할 수도 있습니다.
CincauHangus 2018 년

9

펄, 70 68 66 50 자

$"=",";map/(.)\1{3}/||say,glob$i.="{@a}"for@a=A..M

용법:

$ perl -E 'code' > output_file

좋은 점은 인쇄물이 버퍼링되어 있기 때문에 먼저 1 자 솔루션을 모두 인쇄 한 다음 2 자 단어 등을 인쇄합니다.


이 솔루션의 가장 좋은 점은 1의 왼쪽에있는 가슴입니다.
Dan Hanly

8

펄-35 바이트

#!perl -l
/(.)\1{3}|[N-Z]/||print for A..1x9

shebang을 1 바이트로 계산합니다.

이것은 히스 토크 라트의 대답을 느슨하게 번역 한 입니다.

A..1x9조금 이상합니다. 이것은 속기입니다 'A'..'111111111'. 누산기는 실제로 터미널 값 (대문자 만 포함)에 도달하지 않지만 9 자 보다 길면 여전히 종료됩니다 . 예를 들어 1x4대신 사용하여 테스트 할 수 있습니다 .


존경! 왜 내가 그렇게 생각하지 않았습니까? ;)
Zaid

루비는 그것을 반복하기 위해 전체 범위를 만들 필요는 없습니다. 내 의견의 코드에 엄청난 양의 메모리가 필요한 유일한 이유는 범위를 배열로 변환하여 사용할 수 있기 때문 Array#-입니다.
Ventero

@Ventero Ahh 예, grep그렇게 할 것입니다. 전 루비에 유창하지 않습니다.
primo

6

피그 (와이어가 너무 길어 골프 용 언어)

속삭임 : 101 ...

Pe(*ItCh(((J(x)for x in ItPr("ABCDEFGHIJKLM",repeat=j)if not An((i*3 in x)for i in x))for j in R(14))))

비록 이것이 파이썬에서 실제로 어떻게하는지에 가깝지만 :

from itertools import *
for i in range(14):
    for j in ("".join(k) for k in product("ABCDEFGHIJKLM",repeat=i) if not any((i*3 in k) for i in k)):
        print j

물론 긴 줄 합병증 빼기;)


3

Pyth , 34 자

Kf<T"n"GJKFbJI>lb9Bb~Jm+bdfXVb*Y3K

설명:

Kf<T"n"G        K = list of letters in the alphabet before n.
JK              J = copy of K
FbJ             For b in J:
I>lb9B          If length of b > 9: break
b               print(b)
~J              J+=
~Jm+bd          J+=map(lambda d:b+d,
       XVb*Y3   index of Y*3 in reversed(b)
      fXVb*Y3K  filter for non-zero for Y in K on function index of Y*3 in reversed(b)
~Jm+bdfXVb*Y3K  J+=map(lambda d:b+d, filter(lambda Y:index of Y*3 in reversed(b), K))

2

파이썬 2-212 바이트

from itertools import chain,product as p
a='ABCDEFGHIJKLM'
q={c*4 for c in a}
c=0
for n in chain(*(p(*([a]*l)) for l in range(1,10))):
 n=''.join(n)
 if not any(u in n for u in q):print n
 c+=1
 if c==10**9:break

0

Japt , 21 바이트

Ep9 osE kè/0|(.)\1{3}

온라인으로 사용해보십시오! (링크는 최대 계산 만합니다 14**4.)

작동 원리

Ep9 osE kè/0|(.)\1{3}/

Ep9  14**9
osE  Range from 0 to n (exclusive), mapped through base-14 conversion
kè   Remove elements that match at least once...
/0|(.)\1{3}/  the regex that matches a zero or four times same char.

Array객체가 최대 2**53-1길이를 가질 수 있는 표준 ECMAScript 2017 구현을 JS 레이어 (및 배열을 저장하기에 충분한 메모리)로 가정합니다 .

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