แจกแจงแผนการสัมผัส


26

A "สัมผัสโครงการ" คือสตริงของตัวอักษรaที่จะzดังกล่าวว่าเกิดขึ้นครั้งแรกของตัวละครที่อยู่ในลำดับจากน้อยไปมาก (ไม่มีช่องว่าง) aเริ่มต้นจาก ตัวอย่างเช่น (ที่มีการปรากฏครั้งแรก):

abccdbebdcfa
^^^ ^ ^   ^

จำนวนของรูปแบบการสัมผัสของความยาวNจะได้รับจากหมายเลขที่เบลล์ B(N)( OEIS A000110 )

ความท้าทาย

งานของคุณคือการใช้การแจงนับของรูปแบบสัมผัสเหล่านี้เช่นการทำแผนที่ bijective จากจำนวนเต็มไปยังรูปแบบสัมผัส คุณได้รับเป็นจำนวนเต็มบวกเช่นเดียวกับจำนวนเต็มไม่เป็นลบN <= 26 หรือคุณสามารถใช้ช่วง0 <= i < B(N) 1 <= i <= B(N)คุณควรเอาท์พุทแบบแผนสัมผัสของความยาวNเช่นที่ทุกคนiให้สตริงที่แตกต่างกัน

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

คุณสามารถใช้ตัวอักษรพิมพ์เล็กหรือพิมพ์ใหญ่

รหัสของคุณจะต้องสามารถจัดการกับการป้อนข้อมูลที่ถูกต้องในระยะเวลาที่เหมาะสม (เช่นไม่เกินสองสามชั่วโมงสำหรับN = 26กรณีที่เลวร้ายที่สุดi) สิ่งนี้ควรอนุญาตโซลูชันที่ปรับมาตราส่วนแบบทวีคูณด้วยN(สำหรับฐานขนาดเล็ก) แม้ในภาษาที่ช้า แต่ห้ามใช้โซลูชันที่ขยายขนาดเชิงเส้นด้วยi(เช่นB(N)) โดยเฉพาะอย่างยิ่งนั่นหมายความว่าคุณไม่สามารถวนซ้ำตามรูปแบบความยาวสัมผัสที่ถูกต้องทั้งหมดNจนกว่าคุณจะละทิ้งiรูปแบบ

ใช้กฎมาตรฐานของ

ตัวอย่าง

การกำหนดที่แน่นอนของiแผนการถึง (เช่นคำสั่งของแผนการสำหรับที่กำหนดN) ขึ้นอยู่กับคุณ แต่ถ้าคุณเลือกการเรียงลำดับพจนานุกรมการแก้ปัญหาของคุณควรสอดคล้องกับตารางต่อไปนี้ ( -แสดงว่ามีการป้อนข้อมูลไม่ถูกต้อง):

N\i 1    2    3    4    5    6    7    8    9    10   11   12   13   14   15
1   a    -    -    -    -    -    -    -    -    -    -    -    -    -    -
2   aa   ab   -    -    -    -    -    -    -    -    -    -    -    -    -
3   aaa  aab  aba  abb  abc  -    -    -    -    -    -    -    -    -    -
4   aaaa aaab aaba aabb aabc abaa abab abac abba abbb abbc abca abcb abcc abcd

นี่คือสคริปต์ CJam สั้น ๆที่สร้างแผนการคล้องจองที่ถูกต้องทั้งหมดสำหรับความยาวที่กำหนด (แต่อย่าลองมากกว่า 10 หรือคุณจะรอสักครู่)

ความท้าทายที่เกี่ยวข้อง


5
ฉันอาจจะใส่ความโปรดปรานในการแก้ปัญหาแบบพหุนาม (เวลาN) (ใน) หากไม่ได้กลายเป็นเรื่องไม่ยุติธรรมเลยและฉันก็โง่เกินกว่าที่จะหาได้
Martin Ender

แม้ว่าค่าหัวจะขึ้นอยู่กับการแก้ปัญหาเวลาแบบพหุนาม แต่ฉันก็ยังอยากเห็นการแก้ปัญหาแบบเอกซ์โปเนนเชียลไทม์ที่เป็นไปตามขีด จำกัด เวลา (ขณะนี้การใช้การอ้างอิงทางคณิตศาสตร์ของฉันยังคงเป็นผู้ชนะความท้าทาย)
Martin Ender

B (26) เป็นหมายเลขระฆังที่เล็กที่สุดที่ไม่พอดีกับจำนวนเต็ม 64 บิต Meanie :-(
Anders Kaseorg

คำตอบ:


3

CJam, 68 66 ไบต์

r~:W)1a*{__(;\);_,,.*.+}W(*r~{X@\=_2$\/:CX<!{X:C):X;}&C*-C'a+o}W*;

ลองออนไลน์

นี่เป็นโปรแกรม CJam แรกของฉัน มันเริ่มต้นชีวิตในฐานะพอร์ตของโซลูชัน Perl ของฉันและเริ่มแรกนั้นมีความยาวมากกว่า 130 ไบต์ ยินดีรับข้อเสนอแนะเพิ่มเติมสำหรับการเล่นกอล์ฟ

เช่นเดียวกับโปรแกรม Perl ของฉันมันมีอยู่สองส่วน

Part 1:
r~:W                                         | Read the first input (n) and store it in W
    )1a*                                     | Create an array of n+1 1s
        {              }W(*                  | Repeat n-1 times:
         __                                  | Duplicate array twice
           (;\);                             | Remove first element of 1st array. Swap
                                             | arrays. Remove last element of 2nd array
                _,,                          | Duplicate array. Count items. Create range
                   .*.+                      | Multiply arrays. Add 1st array to result

Part 2:
r~                                           | Read the second input (i)
   {                                  }W*    | Repeat n times:
    X@                                       | Push y (initially 1). Bring item 2 (last array) to top
     \=                                      | Swap top two items. Pop array[y] (v)
       _2$                                   | Duplicate v. Copy item 2 (i) to top
          \/:CX                              | Swap i & v. i/v. Store in C (c). Push y
               <!{       }&                  | If !(i/v < c):
                  X:C):X;                    | c = y. ++y (store in X)
                           C*-C'a+o          | i -= c * v. Push y. Push "a". Add c. Print
                                         ;   | Discard top item (integer 0)

การแก้ปัญหาอาร์เรย์ที่สร้างขึ้นโดยส่วนที่ 1 เพิ่ม]_`o~ระหว่างส่วนที่ 1 และ 2 ถ้า n เป็นอาร์เรย์จะมีลักษณะเช่นนี้5 [[1 1 1 1 1 1] [1 2 3 4 5] [2 5 10 17] [5 15 37] [15 52]]0 ดัชนีของแต่ละอาร์เรย์ไม่ได้ใช้พวกเขาเพียงทำให้ง่ายขึ้นโดยไม่ต้องคำนวณออฟเซ็ต อาร์เรย์มีการคำนวณดังนี้:

[2 5 10 17] [2 5 10 17] [2 5 10 17]        | Duplicate twice
[2 5 10 17] [2 5 10 17] [5 10 17]          | Discard first item of array
[2 5 10 17] [5 10 17] [2 5 10 17]          | Swap last two arrays
[2 5 10 17] [5 10 17] [2 5 10]             | Discard last item of array
[2 5 10 17] [5 10 17] [2 5 10] [2 5 10]    | Duplicate array
[2 5 10 17] [5 10 17] [2 5 10] 3           | Count items in array
[2 5 10 17] [5 10 17] [2 5 10] [0 1 2]     | Integer to range 0 - n-1
[2 5 10 17] [5 10 17] [0 5 20]             | Multiply arrays [2*0 5*1 10*2]
[2 5 10 17] [5 15 37]                      | Add arrays [5+0 10+5 17+20]

มันเก็บสำเนาของอาเรย์เก่าในขณะที่การคำนวณอันถัดไป อาร์เรย์จะถูกอ่านและละทิ้งในลำดับที่ย้อนกลับโดยส่วนที่ 2


13

Python 2, 153

u=[1]*999;i=60;exec"u[i]=i%30*u[i-30]+u[i-29];i+=1;"*900
def x(l,n,a=0):m=u[30*l+a];c=n>=a*m;return'.'*l and chr(65+min(n/m,a))+x(l-1,[n%m,n-m*a][c],a+c)

มันใช้ลำดับตัวอักษรและการจัดทำดัชนีตาม 0

อนุญาตlแสดงความยาวของคำต่อท้ายของตัวอักษรและaแสดงจำนวนตัวอักษรที่แตกต่างที่ใช้ในส่วนก่อนหน้า จากนั้นฟังก์ชั่นp(l,a)ที่คำนวณจำนวนวิธีการเลือกตัวอักษรที่เหลืออาจเป็น 40 ไบต์:

p=lambda l,a:l<1or a*p(l-1,a)+p(l-1,a+1)

อย่างไรก็ตามสิ่งนี้ช้าเกินไปสำหรับความท้าทายดังนั้นค่าที่จำเป็นจะถูกคำนวณล่วงหน้าและเก็บไว้ในuอาร์เรย์ ในแต่ละขั้นตอนของการคำนวณถ้าตัวอักษรตัวต่อไปเป็นตัวที่aใช้แล้วn = k * p (l - 1, a) + n 'โดยที่kคือตัวอักษร 0 ดัชนีของตัวอักษรและn'คือ ค่าของnการเรียกใช้ฟังก์ชันถัดไปซึ่งมีข้อมูลเกี่ยวกับตัวอักษรที่เหลืออยู่ ถ้าตัวอักษรใหม่ถูกนำมาใช้แล้วn = a * p (L - 1 ก) + n'


1
ใช้เวลานานแค่ไหนสำหรับการป้อนข้อมูลกรณีที่เลวร้ายที่สุด
Michael Klein

1
@MichaelKlein ระยะเวลาเล็กน้อย
feersum

ตรงนี้เป็นสิ่งที่ฉันวางแผนไว้ (ยกเว้นฉันจะทำกับ JS) งานที่ดี! +1
ETHproductions

11

Haskell (GHC 7.10), 150 ไบต์

s=(1,\_->[]):s
k!((y,b):l@((x,a):_))|let h i|i<x=k:a i|(p,q)<-divMod(i-x)y=p:b q=(x+k*y,h):(k+1)!l
n#i=(['a'..]!!).fromEnum<$>snd(iterate(0!)s!!n!!0)i

ผู้ประกอบการn # iคำนวณiTH (ศูนย์จัดทำดัชนี) nสัมผัสโครงการของความยาว มันทำงานในการดำเนินงาน O (n²) (ใหญ่เต็ม), การใช้ประโยชน์จากรายการอนันต์ขี้เกียจของ Haskell สำหรับการบันทึกอัตโนมัติ ตัวอย่างการวิ่ง:

*Main> 26 # 0
"abcdefghijklmnopqrstuvwxyz"
*Main> 26 # 1
"abcdefghijklmnopqrstuvwxya"
*Main> 26 # 2
"abcdefghijklmnopqrstuvwxyb"
*Main> 26 # 49631246523618756271
"aaaaaaaaaaaaaaaaaaaaaaaabb"
*Main> 26 # 49631246523618756272
"aaaaaaaaaaaaaaaaaaaaaaaaab"
*Main> 26 # 49631246523618756273
"aaaaaaaaaaaaaaaaaaaaaaaaaa"
*Main> [1 # i | i <- [0..0]]
["a"]
*Main> [2 # i | i <- [0..1]]
["ab","aa"]
*Main> [3 # i | i <- [0..4]]
["abc","aba","abb","aab","aaa"]
*Main> [4 # i | i <- [0..14]]
["abcd","abca","abcb","abcc","abac","abaa","abab","abbc","abba","abbb","aabc","aaba","aabb","aaab","aaaa"]

(ถ้าสูงสุด N คือ 25 แทน 26 .fromEnumอาจลบได้เพราะ B (25) พอดีกับ 64- บิตInt)


1
ดูดี. คุณจะช่วยเพิ่มเวอร์ชั่น golfed ให้น้อยลงเพื่อให้การเล่นง่ายขึ้นหรือไม่
Michael Klein

4

Perl 257 + 1 (แฟล็ก -p) = 258

Perl 182 + 10 (แฟล็ก -pMbignum) = 192

($n,$i)=split;@m=[@a=(1)x($n+1)];while($a[2]){push@m,[@a=map{$a[$_]*$_+$a[$_+1]}0..$#a-1]}$_='';$y=1;while($w=pop@m){$c=int($i/($v=$$w[$y]));$c=$y++if($c>=$y);$i-=$c*$v;$_.=chr$c+65}

ขอบคุณdev-nulสำหรับการบันทึกจำนวนมาก! ตอนนี้ฉันเขียนมันใหม่ตามสิ่งที่ฉันเรียนรู้จากการทำเวอร์ชั่น CJam

คำนวณความคล้องจองตามลำดับตัวอักษรจากน้อยไปมาก 0 ดัชนี

สองส่วน: ส่วนที่ 1 คือ128 90 ไบต์และคำนวณเมทริกซ์สำหรับส่วนที่ 2 ส่วนที่ 2 คือ129 92 ไบต์และคำนวณคณิตศาสตร์ง่ายๆเพื่อคำนวณตัวอักษรแต่ละตัว ถ้าฉันสามารถกำจัดเมทริกซ์และแทนที่ด้วยตัวเลขง่าย ๆ สองตัวฉันสามารถคำนวณเส้นทางเดียวผ่านเมทริกซ์สำหรับแต่ละตัวเลขและบันทึกจำนวนมากได้! เห็นได้ชัดว่าความคิดนั้นใช้งานไม่ได้!

น่าเสียดายที่มันไม่ได้iส่งเสียงเพลงที่เหมาะสมสำหรับค่าที่สูงกว่า 9007199254740992 แต่มันทำงานได้อย่างสวยงามสำหรับค่าต่ำ! ฉันเพิ่มห้องสมุด Bignum ที่ราคา 11 ไบต์ perl -pMbignum bell-rhyme.plมันเรียกใช้จากบรรทัดคำสั่งด้วย -pMbignum = 10 ไบต์ นอกจากนี้ยังรวดเร็วมากสำหรับค่าอินพุตใด ๆ


2

Oracle SQL 11.2, 412 284 283 ไบต์

WITH a AS(SELECT CHR(96+LEVEL)d,LEVEL b FROM DUAL CONNECT BY LEVEL<=:i),v(s,c,n)AS(SELECT d,1,1 FROM a WHERE b=1 UNION ALL SELECT s||d,b,LENGTH(REGEXP_REPLACE(s||d,'([a-z])\1+','\1'))FROM v,a WHERE(b<=n OR b=c+1)AND LENGTH(s)<:n)SELECT s FROM v WHERE:n=LENGTH(s)AND:i<=:n ORDER BY 1;

น่าเสียดายที่มีความยาวไม่เกิน 8 เท่านั้นค่าใด ๆ ที่มากกว่าจะส่งผลให้: ORA-01489: ผลลัพธ์ของการต่อสตริงยาวเกินไป

ยกเลิกแข็งแรงเล่นกอล์ฟ

WITH a AS(SELECT CHR(96+LEVEL)d,LEVEL b FROM DUAL CONNECT BY LEVEL<=:i),
v(s,c,n) AS
(
  SELECT d,1,1 FROM a WHERE b=1
  UNION ALL
  SELECT s||d,b,LENGTH(REGEXP_REPLACE(s||d,'([a-z])\1+','\1')) 
  FROM v,a 
  WHERE (b<=n OR b=c+1) AND LENGTH(s)<:n
)
SELECT s FROM v WHERE LENGTH(s)=:n AND :i<=:n ORDER BY 1;

มุมมองจะสร้างตัวอักษร: i ในคอลัมน์ a และค่าในมุมมอง b

มุมมองแบบเรียกซ้ำ v ใช้สตริงที่สร้างขึ้นเป็นพารามิเตอร์ v มูลค่าของตัวอักษรตัวสุดท้ายที่ใช้ใน c และค่าตัวอักษรที่ยิ่งใหญ่ที่สุดที่ใช้ใน n พารามิเตอร์ n เท่ากับความยาวของสตริงโดยไม่มีตัวอักษรที่ซ้ำกันนั่นคือสิ่งที่ regex ใช้

ตัวอักษรนั้นถูกต้องหากค่าของมันคือ <= มูลค่าของตัวอักษรที่ยิ่งใหญ่ที่สุดที่ใช้ไปแล้วหรือเป็นตัวอักษรถัดไปที่จะใช้

อย่างใดแบบสอบถามต้องการ LENGTH (s) ส่วน <: n เพื่อให้ทำงานฉันจะต้องหายไปบางสิ่งบางอย่างในการทำงานของแบบสอบถาม

SELECT หลักจะดูแลการกรองอินพุตที่ไม่ถูกต้องและสตริงที่สั้นกว่าที่สร้างขึ้นก่อนที่จะถึงความยาวเป้าหมาย

รุ่น 412 ไบต์

WITH a AS(SELECT * FROM(SELECT d,b,ROW_NUMBER()OVER(PARTITION BY b ORDER BY d)l FROM(SELECT CHR(64+DECODE(MOD(LEVEL,:i),0,:i,MOD(LEVEL,:i)))d,CEIL(LEVEL/:i)b FROM DUAL CONNECT BY LEVEL<=:i*:n))WHERE l<=b),v(s,c,p)AS(SELECT d,1,l FROM a WHERE b=1 UNION ALL SELECT s||d,c+1,l FROM v,a WHERE c+1=b AND(l<=LENGTH(REGEXP_REPLACE(s,'([A-Z])\1+','\1'))OR l=p+1))SELECT s FROM v WHERE LENGTH(s)=:n AND :i<=:n ORDER BY 1;

อย่าลองเคียวรี 412 ไบต์ที่มี 26 ซึ่งทำให้ฐานข้อมูลอยู่ในโหมด จำกัด อย่างน้อยในเวอร์ชัน xe ของฉันที่ทำงานในคอนเทนเนอร์นักเทียบท่าบน macbook ฉันสามารถลอง exadata ในที่ทำงาน แต่น่าเศร้าที่ฉันยังต้องทำงานเพื่อหาเลี้ยงชีพ


0

Mathematica, 136 ไบต์

(For[j=2^#-1;t=#2,c=1;m=0;x=t;r=If[#>0,++m,c*=m;d=x~Mod~m+1;x=⌊x/m⌋;d]&/@j~IntegerDigits~2;;c<=t,t-=c;--j];FromCharacterCode[r+64])&

เพื่อความสมบูรณ์นี่คือการดำเนินการอ้างอิงของฉัน ตรงข้ามกับคำตอบที่มีอยู่สิ่งนี้ไม่ได้ทำงานในเวลาพหุนาม (เป็นเลขชี้กำลังNด้วยฐาน 2) แต่มีข้อ จำกัด ด้านเวลา (กรณีที่เลวร้ายที่สุดจะยังคงทำงานได้ในครึ่งชั่วโมง)

ความคิดคือสิ่งนี้:

  • สำหรับแต่ละรูปแบบสัมผัสเราสามารถระบุตำแหน่งที่ตัวละครสูงสุดเพิ่มขึ้นจนถึง:

    ABCDEFGHDIJDEKBBIJEIKHDFII
    ^^^^^^^^ ^^  ^
    

    เราสามารถรักษาเครื่องหมายเหล่านั้นเป็นเลขฐานสองซึ่งทำให้ง่ายต่อการวนซ้ำในโครงสร้างดังกล่าวทั้งหมด เราจำเป็นต้องวนซ้ำจาก 2 n-1ถึง 2 n (หรือวิธีอื่น ๆ ) ซึ่งเป็นที่มาของความซับซ้อนของเวลาแบบเอกซ์โปเนนเชียล

  • สำหรับแต่ละโครงสร้างดังกล่าวเป็นเรื่องง่ายที่จะพิจารณาว่ามีสตริงดังกล่าวจำนวนเท่าใด: มีเพียงช่องว่างระหว่างเครื่องหมายที่สามารถเลือกได้อย่างอิสระและค่าสูงสุดที่ด้านหน้าของช่องว่างจะบอกเราว่าอักขระแต่ละตัวมีความแตกต่างกันเท่าใดในแต่ละตำแหน่ง นี่คือผลิตภัณฑ์ที่เรียบง่าย ถ้าจำนวนนี้มีขนาดเล็กกว่าเราลบมันออกมาจากi iมิฉะนั้นเราจะพบโครงสร้างของรูปแบบสัมผัสที่ร้องขอ
  • ในการระบุรูปแบบในโครงสร้างที่กำหนดเราเพียงแสดงi(หรือส่วนที่เหลือของมัน) เป็นหมายเลขฐานผสมที่น้ำหนักของตัวเลขจะถูกกำหนดโดยจำนวนของตัวละครที่ได้รับอนุญาตในตำแหน่งที่เหลือ

ฉันสงสัยว่าสิ่งนี้จะช่วยแก้ปัญหาที่สั้นกว่าในภาษาอื่น ๆ ที่ส่งมาหรือไม่เพราะมันไม่จำเป็นต้องมี memoisation หรือ precomputation

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