Tanrı'nın 9 Milyar Adı


74

Tanrı'nın 9 Milyar Adı, Arthur C. Clarke'ın kısa bir öyküsüdür. Sırasıyla, Tanrı'nın olası tüm isimlerini kendi alfabesiyle yazmak için ayrılmış olan bir grup Tibet rahipleri hakkında. Temel olarak, birkaç kuralla sınırlandırılmış, alfabelerinin olası her permütasyonunu yazmaya adamıştır. Hikayede, manastır bazı mühendisleri kendileri için tüm işleri yapacak bir program yazmak üzere işe alıyor. Amacınız bu programı yazmak.

Kurallar:

  • Keşiş'in alfabesi (tahminlerime göre) 13 karakter kullanır. Veya ABCDEFGHIJKLMbaşka 13 karakter setini kullanabilirsiniz .

  • Olası bir ismin minimum uzunluğu 1 karakterdir. Maksimum uzunluk 9 karakterdir.

  • Hiçbir karakter art arda 3 defadan fazla tekrar edemez. AAABAgeçerli bir isim, ancak AAAABdeğil.

  • Ne kadar sırayla (bir dosyaya) mümkün olan her isim yazdırmalısınız Programınız Aiçin MMMLMMMLMdeğil alfabe içinde herhangi bir karakter ile ayrılmış, (satırbaşıyla, Sütünlar, neyse).

  • Bu kod golf ve herhangi bir dili kullanabilirsiniz. 1 Haziran 2014 itibariyle en kısa çözüm kazanır.

Düzenleme: İsimler tüm milyarlarca ismin içinde sırayla ilerleyerek başlamalı Ave bitmelidir MMMLMMMLM. Ancak belirli bir dizi size kalmış. Önce 1 harflerin tümünü, sonra 2 harflerin hepsini vb. Yazdırabilirsiniz. Veya A, önce başlayanların , sonra başlayanların tümü Bveya başka bir desen yazdırabilirsiniz . Ancak bir insan, dosyayı okuyabilir ve hepsinin orada olduğunu ve ne zaman olursa olsun, seçtiğiniz her mantık sırasına göre onaylayabilmelidir.


29
Evreni sonlandırmaya mı çalışıyorsunuz efendim?
Boluc Papuccuoglu

8
İlgilenen herkes için hikayeye link verin .
ThatOneGuy


1
Bu, mevcut problemdeki isim sayısının gerçekten 11,459,252,883 ( edc65'in C programında olduğu gibi ) olduğunu doğrular . Ross Millikan'ın MathSE'deki çözümünü uygulamak , değişken alfabe boyutu k için <= 9 olan adların sayısı için aşağıdaki polinom formülünü oluşturur f(k) = k^9 + k^8 + k^7 - 5*k^6 + k^5 + k^4 + 4*k^3 - 2*k^2 + k. Adaçayı uygulaması: goo.gl/0srwhq
res

3
@ edc65 Yani 105.8GBhepsi dedi ve bitti! Yıldızların sönmediğine sevindim ... ya da bunun olması için listeyi yazdırman gerekebilir mi?
recursion.ninja

Yanıtlar:


34

Ruby, 46

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

Özgün, benzer çözümüm daha uzun ve yanlıştı (hepsinin başında sıfırlar olmadığından tamamen temel olmayan sayıları temel alıyor13), ancak yine de oy kullandığı için burada bırakacağım.

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

14
Kodunuzu bir saat kadar çalıştırdım ve bunu görmeden ve bırakmadan önce 2 milyar isim ve 21 GB metin dosyası aldım. Dosyanın ne kadar büyük olacağını hafife aldım.
CSturgess

2
@CSturgess Pekala, Ruby bu tür şeyler için en hızlı dil değil ...
BenjiWiebe

8
@BenjiWiebe Ama yine de keşişler tarafından el yazısıyla yazılmış olmaktan daha hızlı!
Turophile

1
Bunu kabul ediyorum, çünkü daha fazla oy aldı.
CSturgess

4
Bunu çok büyük miktarda bellek gerektirdiğinden, ayrı bir cevap olarak yayınlamamak (eğer benim hesaplamam doğruysa ~ 30 TB), ancak teoride bunu k=*?A..?M*9;puts k-k.grep(/(.)\1{3}|[N-Z]/)
Ventero

24

C 140 177 235

Eski usul usuller iyi, düşkünlük yok.
8 dakika içinde 11,459,252,883 isim yazıyor.
Sonra çalışma zamanı ve ad dosyasının boyutu ile düzenleme yapın. Gökyüzünü izleyin ...
Çalışma süresi 57 dakika, dosya boyutu 126.051,781,713 (satır başına 9 karakter + crlf). Lütfen bana keşişlerin e-posta adresini söyle, böylece onları el ile kontrol etmek için sıkıştırılmış dosyayı gönderebilirim ...

Edit Golfed biraz daha, tekrarlanan mektuplar için kontrol elden geçirdi.
Yine de en kısa değil, fakat en azından bu istenen çıktıyı sonlandırır ve üretir.
Çalışma süresi 51 dak, dosya boyutu 113,637,155,697 (bu sefer başında boşluk yok)

Yan not: açık bir şekilde çıktı dosyası çok sıkıştırılabilir, hala 7zip öldürmek zorunda kaldım, 36 saat çalıştıktan sonra% 70'di. Tuhaf.

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

Ungolfed

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

hayır #includes
Simon Kuang

@SimonKuang, bazı derleyiciler otomatik olarak temel olanları (stdio) koyacaktır.
Paul Draper

1
@Simon bu C standardı. Varsayılan olarak, genel nesneler int ve genel işlevler int döndürür. Visual studio C4013'ün 'koyarlar' konusunda tanımlanmadığı uyarısını verir, ancak yine de geçerlidir.
edc65

4
bir tweet'e uyar!
CincauHangus

19

Golfscript, 58 47 karakter

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

Peter Taylor sayesinde, seppukudan Ruby çözümünü yenmemekten kurtuldum! Kodu kendin 10'a kadar çalıştır ve işte üst üste dört sayıyı atladığının kanıtı .


1
Kolay tasarruf: n+yerine kullanın ''+n. Ben kontrol karakterleri ile bir alfabe kullanmak kuralları dahilinde olduğunu düşünüyorum, bu yüzden de yerini alabilecek 65+olan 13+ve adlandırma başka bir karakter kaydetmek 13:^. Ve bunun 13,{ stuff [...]olabileceğini düşünüyorum 13,1/{ stuff 4*.
Peter Taylor

1
İlk düşüncem, tasarrufun bir filtreden geçeceği ve biraz çalışarak yapılabileceği idi. Ondan 13,sonra {65+}%n+}%{ backtick {\4*/,}+78,1/%1-!},toplam 8 tasarrufla hayatınızı kurtarmak için değiştirebilirsiniz.
Peter Taylor

Karakter fiziksel olarak görebileceğiniz bir şey olduğu sürece çalışacaktır. Gerçekten de yeni satırları karakter olarak dahil edebilirsiniz. Karakterlerin bir sırası olduğu sürece.
CSturgess

@PeterTaylor: Siz bir centilmen ve bilginsiniz!
Claudiu

Sonra AAAMOlması gereken AAABAdeğil BAAAB, doğru mu?
justhalf

18

Bash + Linux komut satırı yardımcı programları, 43 bayt

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

Bu, aşağıda benim cevaba benzer bir teknik kullanır ama sadece baz 16'da sayar ve tüm "isimlerini" içeren çıkarır 0, eya da fonları da 3'ten fazla aynı ardışık rakam ile.

Keşiş'in alfabesine aşağıdaki gibi dönüştürün:

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

Bash + coreutils (dc ve egrep), 46 bayt

Düzenle - düzeltilmiş sürüm

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

Bu çalışması biraz zaman alacak ama bence doğru.

dc14 ^ 9'dan 1'e kadar geri sayım yapar ve taban 14'te çıkış yapar. egrep, 3 ardışık aynı haneden oluşan sayıları filtreler. Ayrıca "0" rakamlı isimleri de filtreleriz, böylece isimlerdeki doğru harfleri alırız.

Soru, herhangi bir alfabenin kullanılabileceğini belirtir, ben de [1-9] [AD] kullanıyorum. Ancak test için bu, tr kullanarak [AM] ye dönüştürülebilir.

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

Bu diziyi verir:

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

Bu dckomutun çalışması için kuyruk özyineleme gerektirdiğini unutmayın . Bu, 1.3.95 (Ubuntu 12.04) sürümünde çalışır ancak 1.3 sürümünde çalışmaz (OSX Mavericks).


10

APL (59)

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

Kendi alfabesiyle yazılmış :) Biraz uzun. Ayrıca, çalıştırmak için uzun bir zaman alır 9, isterseniz test etmek için daha düşük bir numara ile deneyin.

Açıklama:

  • {... }¨⍳9: 1'den 9'a kadar olan her numara için:
    • ⍳13*⍵: 1 ile 1 arasındaki tüm sayıları al 13^⍵
    • ¯1⌽: (Yani biz var 1 bıraktığı için listeyi döndürmek 13^⍵, 1, 2, ..., 13^⍵-1dönüşür ki, 0, 1, 2 ...modülo 13^⍵).
    • (⍵/13)⊤: hane 13 kullanarak her bir sayıyı 13 rakamını kullanarak kodlayın
    • ⎕A[1+... ]: bir tane ekle (diziler 1 dizinli) ve içeri bak ⎕A(alfabe)
    • ↓⍉: matrisi sütunlar boyunca bir vektörler vektörüne çevirin.
  • Z←⊃,/: her bir iç vektör vektörünü bir araya getirerek bize olası isimlerin bir listesini verir (ancak henüz kuralları karşılamıyor).
  • {... : her ad için, 4-tekrarlanan karakter kuralına uyup uymadığını test edin:
    • 4/¨⎕A[⍳13]: her karakter için, o karakterden 4'lü bir dize oluşturun.
    • ⍷∘⍵¨: Her dize için, içinde olup olmadığını sınayın
    • ∨/,↑: mantıklı veya tüm bu testlerden birini yapın,
    • ~: ve onu ters çevirin, yani bu 1kurallara uyması ve 0uymaması anlamına gelir.
  • Z/⍨: Zibadetleri karşılayan tüm unsurlardan birini seçin
  • : her birini ayrı bir satırda göster

9
Hayal kırıklığına uğradım. İtibarına bakıldığında, APL'nin bunun için hiçbir klavyenin yazamadığı tek karakterli bir çözümü olacağını düşünürdünüz.
Mark

7
@Mark, APL'nin buna sahip olduğundan eminim, ama kimse karakterin ne olduğunu bilmiyor :)
Paul Draper

1
kişi bunu bir taşa yazmalı ve gelecekteki insanlar bunu bulduğunda, sadece ilkel bir yazı dili olduğunu düşünebilirler.
CincauHangus

9

Perl, 70 68 66 50 karakter

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

Kullanımı:

$ perl -E 'code' > output_file

İşin güzel yanı, baskıların tamponlanmış olmasıdır, bu nedenle ilk önce tüm 1 karakter çözümlerini, ardından 2 karakter kelimeleri vb. Alırsınız.


Bu çözümle ilgili en iyi şey 1'in solundaki
memedir

8

Perl - 35 bayt

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

Shebang'ı bir bayt olarak sayıyorum.

Bu, histokratın cevabının gevşek bir çevirisidir .

A..1x9biraz tuhaflık; bunun için kısaca 'A'..'111111111'. Akümülatör, terminal değerine asla ulaşmaz (yalnızca büyük harf içerir), ancak 9 karakterden daha uzun olduğunda bir kez sona erecektir . Bu, örneğin 1x4bunun yerine test edilebilir .


Saygı! Şimdi neden bunu düşünmedim? ;)
Zaid

Ruby'nin aynı zamanda yinelemek için tüm aralığı oluşturmak zorunda olmadığını unutmayın. Yorumumdaki kodun bu kadar büyük miktarda bellek gerektirmesinin tek nedeni, aralığı bir Diziye dönüştürmesi (kullanabilmesi için Array#-) olmasıdır.
Ventero

@ Ventero Ahh evet, grepbunu yapacak. Ruby'de tamamen akıcı değilim.
primo

6

Pyg (Waaay çok uzun, golf oynamak için yapılan bir dil için)

fısıltılar : 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))))

Bu aslında Python'da yapacağım şeye yakın olmasına rağmen:

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

Elbette eksi uzun çizgi komplikasyon;)


3

Pyth , 34 karakter

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

Açıklama:

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

Python 2 - 212 bayt

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 bayt

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

Çevrimiçi deneyin! (bağlantı yalnızca en fazla hesaplar 14**4.)

Nasıl çalışır

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.

Bir Arraynesnenin maksimum 2**53-1uzunlukta olabileceği JS katmanı (ve diziyi depolamak için yeterli bellek) olarak standart bir ECMAScript 2017 uygulamasını varsayar .

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.