9 พันล้านชื่อของพระเจ้า


74

9 พันล้านชื่อของพระเจ้าเป็นเรื่องสั้นโดย Arthur C. Clarke มันเกี่ยวกับกลุ่มของพระทิเบตที่มีคำสั่งที่อุทิศให้กับการเขียนชื่อที่เป็นไปได้ทั้งหมดของพระเจ้าเขียนในตัวอักษรของตัวเอง โดยพื้นฐานแล้วพวกเขาจะทุ่มเทให้กับการเขียนเรียงลำดับตัวอักษรที่เป็นไปได้ จำกัด โดยกฎบางข้อ ในเรื่องนี้อารามจ้างวิศวกรบางคนให้เขียนโปรแกรมเพื่อทำงานทั้งหมดให้พวกเขา เป้าหมายของคุณคือการเขียนโปรแกรมนั้น

กฎ:

  • ตัวอักษรของพระใช้ 13 ตัวอักษร (ตามการประเมินของฉัน) คุณสามารถใช้ABCDEFGHIJKLMหรือชุดอักขระ 13 ตัวอื่น ๆ

  • ความยาวต่ำสุดของชื่อที่เป็นไปได้คือ 1 ตัวอักษร ความยาวสูงสุดคือ 9 อักขระ

  • ห้ามใช้ตัวอักษรซ้ำเกิน 3 ครั้งติดต่อกัน AAABAเป็นชื่อที่ถูกต้อง แต่AAAABไม่ใช่

  • โปรแกรมของคุณควรพิมพ์ (เป็นไฟล์) ทุกชื่อที่เป็นไปได้ตามลำดับจากAถึงMMMLMMMLMคั่นด้วยอักขระใด ๆ ที่ไม่ได้อยู่ในตัวอักษร

  • นี่คือรหัสกอล์ฟและคุณสามารถใช้ภาษาใดก็ได้ ทางออกที่สั้นที่สุดภายในวันที่ 1 มิถุนายน 2014 ชนะ

แก้ไข: ชื่อควรเริ่มต้นด้วยAและลงท้ายด้วยMMMLMMMLMดำเนินไปเรื่อย ๆ ผ่านหลายพันล้านชื่อตามลำดับ แต่ลำดับเฉพาะนั้นขึ้นอยู่กับคุณ คุณสามารถพิมพ์ชื่อ 1 ตัวอักษรทั้งหมดก่อนจากนั้นจึงพิมพ์ชื่อตัวอักษร 2 ตัวทั้งหมดหรือคุณสามารถพิมพ์ชื่อทั้งหมดที่ขึ้นต้นด้วยAจากนั้นชื่อทั้งหมดที่ขึ้นต้นด้วยBหรือรูปแบบอื่น ๆ แต่มนุษย์ควรจะสามารถอ่านไฟล์และยืนยันว่าพวกเขาอยู่ที่นั่นและในสิ่งที่คุณเลือกตรรกะสมมติว่าพวกเขามีเวลา


29
คุณพยายามจะจบจักรวาลใช่ไหม
Boluc Papuccuoglu

8
เชื่อมโยงไปยังเรื่องราวสำหรับทุกคนที่สนใจ
ThatOneGuy


1
สิ่งนี้ยืนยันว่าจำนวนของชื่อในปัญหาปัจจุบันเป็นจริง 11,459,252,883 (ตามที่พบในโปรแกรม C ของ edc65 ) การใช้วิธีการแก้ปัญหารอสส์ Millikan ที่ MathSEสร้างสูตรพหุนามต่อไปนี้สำหรับจำนวนรายชื่อที่มีความยาว <= 9 สำหรับตัวแปรขนาดตัวอักษร f(k) = k^9 + k^8 + k^7 - 5*k^6 + k^5 + k^4 + 4*k^3 - 2*k^2 + kK: การใช้ Sage: goo.gl/0srwhq
res

3
@ edc65 ดังนั้น105.8GBทั้งหมดพูดและทำ! ฉันดีใจที่ดาวไม่ออกไป ... หรือคุณอาจจะต้องพิมพ์รายการเพื่อให้เกิดขึ้น ... ?
recursion.ninja

คำตอบ:


34

ทับทิม, 46

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

โซลูชันเดิมที่คล้ายกันของฉันยาวกว่าและผิด (ส่งออกหมายเลขฐาน 13 ซึ่งไม่ได้ทั้งหมดเนื่องจากเลขศูนย์นำหน้า) แต่ฉันจะทิ้งไว้ที่นี่เพราะมันได้รับการโหวตแล้ว

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

14
ฉันใช้รหัสของคุณประมาณหนึ่งชั่วโมงและมีชื่อมากถึง 2 พันล้านชื่อและไฟล์ข้อความขนาด 21 GB ก่อนที่จะเห็นสิ่งนี้และเลิกมัน ฉันประเมินค่าไฟล์น้อยเกินไป
CSturgess

2
@Curgeress Well, Ruby ไม่ใช่ภาษาที่เร็วที่สุดสำหรับการเรียงลำดับของสิ่งนี้ออกมี ...
BenjiWiebe

8
@BenjiWiebe แต่ก็ยังเร็วกว่าการเขียนด้วยลายมือของพระ!
Turophile

1
ยอมรับสิ่งนี้เพราะมันมีคะแนนเสียงมากกว่า
CSturgess

4
ไม่โพสต์คำตอบนี้เป็นคำตอบแยกต่างหากเนื่องจากต้องการหน่วยความจำจำนวนมาก (~ 30 TB หากการคำนวณของฉันถูกต้อง) แต่ในทางทฤษฎีคุณสามารถย่อให้เหลือ 43 ตัวอักษรด้วยk=*?A..?M*9;puts k-k.grep(/(.)\1{3}|[N-Z]/)
Ventero

24

C 140 177 235

ดีขั้นตอนแบบเก่าไม่แฟนซี
มันนับ (ไม่เขียน) 11,459,252,883 ชื่อใน 8 นาที
แก้ไขต่อไปด้วยรันไทม์และขนาดของไฟล์ชื่อ ดูท้องฟ้า ...
รันไทม์ 57 นาทีขนาดไฟล์ 126,051,781,713 (9 ตัวอักษร + crlf ต่อแถว) โปรดบอกที่อยู่อีเมลของพระสงฆ์เพื่อให้ฉันสามารถส่งไฟล์ซิปให้พวกเขาเพื่อตรวจสอบด้วยตนเอง ...

แก้ไข Golfed อีกเล็กน้อยทำใหม่การตรวจสอบตัวอักษรซ้ำ
ยังไม่สั้นที่สุด แต่อย่างน้อยหนึ่งนี้จะยกเลิกและสร้างผลลัพธ์ที่ต้องการ
รันไทม์ 51 นาทีขนาดไฟล์ 113,637,155,697 (ไม่มีช่องว่างนำหน้าในขณะนี้)

หมายเหตุด้าน: เห็นได้ชัดว่าไฟล์เอาต์พุตสามารถบีบอัดได้มาก แต่ฉันต้องฆ่า 7zip หลังจากทำงาน 36 ชั่วโมงอยู่ที่ 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);}

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

ไม่มี#includes?
Simon Kuang

@SimonKuang คอมไพเลอร์บางตัวจะใส่ตัวอักษรพื้นฐาน (stdio) เข้าไปโดยอัตโนมัติ
พอลเดรเปอร์

1
@Simon มันเป็นมาตรฐาน C โดยค่าเริ่มต้นวัตถุทั่วโลกเป็น int และฟังก์ชั่นทั่วโลกกลับมา int Visual Studio แสดงผล C4013 คำเตือนเกี่ยวกับ 'Put' ไม่ได้ถูกกำหนด แต่มันก็ใช้ได้
edc65

4
เหมาะกับทวีต!
CincauHangus

19

Golfscript, 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*
Peter Taylor

1
ความคิดเริ่มต้นของฉันคือการประหยัดจะต้องผ่านตัวกรองและสามารถทำงานได้เล็กน้อย จาก13,บนสามารถถูกแทนที่ด้วย{65+}%n+}%{ backtick {\4*/,}+78,1/%1-!},สำหรับการประหยัดทั้งหมด 8 ช่วยชีวิตคุณได้
Peter Taylor

ตราบใดที่ตัวละครเป็นสิ่งที่คุณสามารถมองเห็นได้มันก็จะใช้ได้ จริงๆคุณสามารถรวมบรรทัดใหม่เป็นตัวละคร ตราบใดที่ยังมีฉากต่อไปของตัวละคร
CSturgess

@PeterTaylor: คุณเป็นสุภาพบุรุษและนักวิชาการ!
Claudiu

หลังจากAAAMนั้นควรAAABAและไม่ใช่BAAABใช่ไหม
justhalf

18

Bash + Linux บรรทัดคำสั่ง utils 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}"

อาจใช้เวลาสักครู่ แต่ฉันคิดว่าถูกต้อง

dcนับถอยหลังจาก 14 ^ 9 ถึง 1 และเอาท์พุทในฐาน 14 เช่นพิมพ์ตัวเลขที่มีตัวเลขเดียวกันมากกว่า 3 หลักติดต่อกัน นอกจากนี้เรายังกรองชื่อใด ๆ ด้วยตัวเลข "0" ดังนั้นเราจึงได้รับชุดตัวอักษรที่ถูกต้องในชื่อ

คำถามระบุว่าอาจใช้ตัวอักษรใดก็ได้ดังนั้นฉันจึงใช้ [1-9] [AD] แต่สำหรับการทดสอบสามารถเปลี่ยนเป็น [AM] โดยใช้ tr:

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⌽: หมุนรายการไปทางซ้ายโดยที่ 1 (เพื่อให้เรามี13^⍵, 1, 2, ... , 13^⍵-1ซึ่งกลายเป็น0, 1, 2 ...โมดูโล13^⍵)
    • (⍵/13)⊤: เข้ารหัสแต่ละหมายเลขในฐาน 13 โดยใช้หลัก
    • ⎕A[1+... ]: เพิ่มหนึ่งรายการ (อาร์เรย์มีดัชนี 1 รายการ) และค้นหา⎕A(ตัวอักษร)
    • ↓⍉: เปลี่ยนเมทริกซ์ให้เป็นเวกเตอร์ของเวกเตอร์ตามแนวคอลัมน์
  • Z←⊃,/: เข้าร่วมเวกเตอร์ด้านในของเวกเตอร์แต่ละตัวด้วยกันโดยให้รายชื่อที่เป็นไปได้ (แต่ยังไม่เป็นไปตามกฎ)
  • {... : สำหรับแต่ละชื่อทดสอบว่าเป็นไปตามกฎ 4-repeat-chars:
    • 4/¨⎕A[⍳13]: สำหรับอักขระแต่ละตัวสร้างสตริงที่ 4 ของอักขระนั้น
    • ⍷∘⍵¨: สำหรับแต่ละสายทดสอบว่ามีอยู่ใน
    • ∨/,↑: ใช้ตรรกะหรือการทดสอบทั้งหมดเหล่านี้
    • ~: และกลับด้านนั่น1หมายความว่ามันเป็นไปตามกฎและ0หมายความว่ามันจะไม่
  • Z/⍨: เลือกจากZองค์ประกอบทั้งหมดที่พบซาก
  • : แสดงแต่ละรายการในบรรทัดแยกต่างหาก

9
ฉันผิดหวัง. เมื่อพิจารณาถึงชื่อเสียงคุณจะคิดว่า APL จะมีวิธีแก้ปัญหาหนึ่งตัวสำหรับเรื่องนี้โดยที่คีย์บอร์ดไม่สามารถพิมพ์ได้
Mark

7
@ Mark ผมแน่ใจว่า APL ไม่ได้ว่า แต่ไม่มีใครรู้ว่าสิ่งที่ตัวละครเป็น :)
พอลผัก

1
ควรเขียนสิ่งนี้ลงบนหินและเมื่อมนุษย์ในอนาคตพบสิ่งนี้พวกเขาอาจคิดว่ามันเป็นเพียงภาษาเขียนดั้งเดิม
CincauHangus

9

Perl, 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

Perl - 35 ไบต์

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

นับ Shebang เป็นหนึ่งไบต์

นี่คือการแปลอย่างหลวม ๆ ของคำตอบของฮิสโทแค

A..1x9เป็นเรื่องแปลก 'A'..'111111111'นี้คือชวเลข ตัวสะสมจะไม่ถึงค่าเทอร์มินัลจริง ๆ (มันมีเพียงตัวอักษรตัวพิมพ์ใหญ่เท่านั้น) แต่มันจะยังคงยุติลงเมื่อมันยาวเกิน9ตัวอักษร สิ่งนี้สามารถทดสอบได้เช่นโดยใช้1x4แทน


เคารพ! ตอนนี้ทำไมฉันไม่คิดอย่างนั้นล่ะ ;)
Zaid

โปรดทราบว่า Ruby ไม่จำเป็นต้องสร้างช่วงทั้งหมดเพื่อทำซ้ำ เหตุผลเดียวที่รหัสในความคิดเห็นของฉันต้องการเช่นหน่วยความจำขนาดใหญ่คือมันเปลี่ยนช่วงเป็น Array (เพื่อให้สามารถใช้งานได้Array#-)
Ventero

@Ventero Ahh ใช่grepจะทำเช่นนั้น ฉันไม่ได้พูดภาษา Ruby ทั้งหมด
primo

6

Pyg (Waaay ยาวเกินไปสำหรับภาษาที่ใช้ในการเล่นกอล์ฟ)

เสียงกระซิบ : 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))))

แม้ว่านี่จะใกล้เคียงกับที่ฉันจะทำใน Python:

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

Python 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.

ถือว่าการใช้งาน ECMAScript 2017 มาตรฐานเป็นเลเยอร์ JS (และหน่วยความจำเพียงพอที่จะเก็บอาร์เรย์) ซึ่งArrayวัตถุสามารถมี2**53-1ความยาวสูงสุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.