เส้นทางเดินป่า


9

หลังจากขี่เรือแคนูที่ร้ายกาจของคุณแล้วคุณก็ตกลงไปที่น้ำตกที่ปลายน้ำเชี่ยว เรือแคนูของคุณระเบิด แต่คุณรอดชีวิตจากการระเบิด อย่างไรก็ตามการเดินทางทางแม่น้ำของคุณก็หมดไปจากแผนที่ตอนนี้คุณพบว่าตัวเองหลงทางในป่า โชคดีที่คุณยังมีทักษะการเขียนโปรแกรมดังนั้นคุณตัดสินใจที่จะแกะสลักโปรแกรมไว้ที่ด้านข้างของต้นไม้เพื่อช่วยคุณค้นหาเส้นทางผ่านป่า อย่างไรก็ตามมีพื้นที่ผิวบนต้นไม้ไม่มากดังนั้นคุณต้องทำให้โปรแกรมของคุณสั้นที่สุด

ฟอเรสต์สามารถอธิบายได้ว่าเป็นตัวอักษรnโดยn( n > 5) ของอักขระซึ่งจะประกอบด้วยตัวอักษรตัวพิมพ์เล็กa-zเท่านั้น ป่าตัวอย่าง:

anehcienwlndm
baneiryeivown
bnabncmxlriru
anhahirrnrauc
riwuafuvocvnc
riwnbaueibnxz
hyirorairener
ruwiiwuauawoe
qnnvcizdaiehr
iefyioeorauvi
quoeuroenraib
cuivoaisdfuae
efoiebnxmcsua

คุณอาจสังเกตเห็นว่าในป่านี้มีเส้นทแยงมุมของaตัวละครที่วิ่งผ่านจากมุมบนซ้ายไปยังมุมขวาล่าง นี่คือ "เส้นทาง" ผ่านป่าซึ่งจะพาคุณไปที่ไหนสักแห่งถ้าคุณทำตาม งานของคุณคือการเขียนโปรแกรมที่จะหาเส้นทางเอกพจน์ ตอนนี้ฉันจะอธิบายสิ่งที่สื่อความหมายถึง "เส้นทาง" ในความท้าทายนี้โดยเฉพาะ

"เส้นทาง" ในการท้าทายนี้ถูกกำหนดให้เป็นเส้นที่คล้ายกับเส้นทางซึ่งอาจถูกสร้างขึ้นด้วยอัลกอริทึม Bresenhamแต่ด้วยข้อกำหนดเพิ่มเติมที่:

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

หากต้องการอธิบายข้อกำหนดที่สองให้ชัดเจนยิ่งขึ้นให้พิจารณาบรรทัดต่อไปนี้:

aaa
   aaa
      aaa
         aaa
            aaa

บรรทัดนี้ประกอบด้วย collinear "เซ็กเมนต์" ของตัวละครแต่ละตัวมีความยาวสามตัว มันมีคุณสมบัติเป็นเส้นทาง พิจารณาบรรทัดนี้:

a
 aa
   a
    aa
      a
       aa

บรรทัดนี้ประกอบด้วย collinear "เซ็กเมนต์" ที่ไม่ได้มีความยาวเท่ากันทุกตัวอักษร (บางส่วนมีความยาว 1 อักขระและบางส่วนเป็น 2) ดังนั้นสิ่งนี้จึงไม่ถือว่าเป็นเส้นทาง

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

13  anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua

ผลลัพธ์สำหรับสิ่งนี้จะเป็น:

a

aเนื่องจากเส้นทางถูกสร้างขึ้นโดยใช้ตัวอักษร จะมีเพียงเส้นทางเดียวในป่า นี่คือรหัสกอล์ฟดังนั้นจำนวนอักขระต่ำสุดชนะ หากคุณมีคำถามให้ถามในความคิดเห็น


เกิดอะไรขึ้นถ้ามีหลายเส้นทาง
Eric Tressler

@EricTressler จะมีเพียงเส้นทางเดียวในป่าที่กำหนด ฉันจะแก้ไขสเปคเพื่อสะท้อนว่า
absinthe

สามารถใช้ตัวอักษรเส้นทางที่อื่นที่ไม่ได้เป็นของเส้นทางได้หรือไม่?
Martin Ender

ฟอเรสต์ตัวอย่างประกอบด้วยสิ่งนั้น a แรกในบรรทัดนี้ในป่าตัวอย่างไม่ได้เป็นส่วนหนึ่งของเส้นทาง anhahirrnrauc
Spade

@ MartinBüttnerใช่ แต่พวกเขาจะไม่เป็นสองทางที่ทำจากตัวอักษรเดียวกันทุกจุด
absinthe

คำตอบ:


3

APL (Dyalog 14) (70)

⎕ML←3⋄Z/⍨1=≢¨Z←∪¨(↓⍉F),(↓F),{(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F←⊃{⍵⍴⍨2/⍎⍺}/I⊂⍨' '≠I←⍞

คำอธิบาย:

  • ⎕ML←3: ตั้งMLเป็น3, ความหมายมีความหมายของ APL2
  • I←⍞: อ่านบรรทัดจากแป้นพิมพ์และเก็บไว้ใน I
  • I⊂⍨' '≠I: แยกIช่องว่าง
  • {... }/: ใช้ฟังก์ชั่นนี้กับสองสตริงที่เกิด:
    • 2/⍎⍺: ประเมินค่าอาร์กิวเมนต์ซ้ายและทำซ้ำสองครั้งโดยกำหนดขนาดเมทริกซ์
    • ⍵⍴⍨: จัดรูปแบบอาร์กิวเมนต์ที่ถูกต้องโดยใช้ขนาดนั้น
  • F←⊃: unbox Fมันและเก็บไว้ใน
  • {(⍳≢⍵)⌷¨↓⍵}¨(⊂F),⊂⌽F: รับ diagonals: จากแต่ละแถวในทั้งสองFและ⌽F(มิเรอร์แนวตั้งF), รับค่าที่คอลัมน์ X, ที่ X คือหมายเลขแถว
  • (↓⍉F),(↓F),: รับแถวและคอลัมน์ของ F
  • Z←∪¨: Zพบว่าค่าที่ไม่ซ้ำกันในแต่ละแถวคอลัมน์และเส้นทแยงมุมและเก็บไว้ใน

เนื่องจาก 'forest' เป็นรูปสี่เหลี่ยมผืนผ้าหากมีเส้นทางที่ถูกต้องหมายความว่าหนึ่งในนั้นจะประกอบด้วยอักขระเพียงตัวเดียวเท่านั้นซึ่งเป็นอักขระเส้นทางดังนั้น:

  • Z/⍨1=≢¨Z: รับหัวข้อย่อยเหล่านั้นจากZที่มีองค์ประกอบเดียวเท่านั้น

สิ่งนี้จะแสดงตัวอักษรสำหรับเส้นทางที่ถูกต้องทั้งหมด แต่เนื่องจากควรมีเพียงตัวเดียวที่ไม่สำคัญ


4

Lua - 506 380 - ไบต์

ฉันรู้สึกแย่ที่คุณไม่ได้รับการยอมรับใด ๆ จากความท้าทายที่คุณคิดดังนั้นฉันจึงโยนมันไปด้วยกัน มันสนุกมากที่จะแยกแยะคุณสมบัติที่แตกต่างขั้นต่ำที่พา ธ ต้องมีจากข้อมูลที่คุณให้ ฉันหวังว่าฉันเข้าใจถูกต้อง ... และนำไปใช้อย่างถูกต้อง

a=io.read"*l"n=a:match("%d+")+0 m=a:match"[a-z]+"o=""for i=1,n do for k=1,n^2,n do o=o..m:sub(i+k-1,i+k-1)end end q={m,o}for g=1,n^2 do for u=1,2 do l=q[u]:sub(g,g)for r=1,n do i=1 t=0 e=0 while i do s,e=q[u]:find(l:rep(r),e+1)if s then x=s-(e-s)-i-1 print(s,i,r,n,r)if x==n or x==n-2 or t==0 then t=t+1 i=s end else i=nil end end if t*r==n then print(l)os.exit()end end end end

สามารถทดสอบกับ:

lua divisorPath.lua "input"

หากผู้ท้าชิงปรากฏขึ้นฉันจะลองดูรหัสของฉันเพื่อดูว่ามันคุ้มค่าหรือไม่

Update : golfed เพื่อเป็นเกียรติแก่ผู้ที่จะสูงกว่าเรา ในขณะที่ฉันอยู่ที่นั่นฉันจะต้องแก้ไขรหัสของฉันเพื่อรับรู้เส้นทางไปจากขวาไปซ้าย อุ่ย


3

MATLAB - 270 ตัวอักษร

ต่อไปนี้กำหนดฟังก์ชั่นxที่ยอมรับสตริงฟอเรสต์เป็นอาร์กิวเมนต์และส่งกลับอักขระที่แสดงถึง "พา ธ " ที่ถูกต้องผ่านฟอเรสต์ตามกฎที่กำหนด

function F=x(s),A=sscanf(s,'%d%s');n=A(1);A=reshape(A(2:end),n,n);for c=A(:)',B=A==c;for i=1:n,if~mod(n,i),C=[kron(eye(i),ones(n/i,1)),zeros(n,n-i)];for j=0:n-i,f=@(B)sum(sum(B&circshift(C,[0,j]))==n;D=fliplr(B);if f(B)|f(B')|f(D)|f(D'),F=char(c);end;end;end;end;end;end

รุ่นที่ไม่ย่อเล็กสุดคือ

function F = x(s)
    A = sscanf( s, '%d %s' );
    n = A(1);
    A = reshape( A(2:end), n,n );
    for c = A(:)'
        B = A==c;
        for i = 1:n
            if ~mod( n, i )
                C = [kron( eye(i), ones( n/i,1 ) ), zeros( n,n-i )];
                for j = 0:n-i
                    f = @(B) sum(sum( B & circshift( C, [0 j] ))) == n;
                    D = fliplr(B);
                    if f(B) | f(B') | f(D) | f(D')
                        F = char(c);
                    end
                end
            end
        end
    end
end

หลักฐานขั้นพื้นฐานคือการสร้างมาสก์บูลีนสำหรับเส้นทางที่ใช้ได้ทุกเส้นทางที่เป็นไปได้และส่งคืนอักขระใด ๆ ที่ฟังก์ชันดัชนีในเมทริกซ์ครอบคลุมรูปแบบใด ๆ เพื่อให้บรรลุสิ่งนี้จะมีการสร้างมาสก์รูปแบคสแลชในแนวตั้งหรือบนลงล่างเท่านั้น แต่เมทริกซ์ฟอเรสต์ถูกนำมาเปรียบเทียบในทั้งสี่ทิศทาง

nฟังก์ชั่นการทำงานสำหรับการใด ๆ ตัวอย่างของมันถูกเรียกบน commandline คือ

x('13 anehcienwlndmbaneiryeivownbnabncmxlriruanhahirrnraucriwuafuvocvncriwnbaueibnxzhyirorairenerruwiiwuauawoeqnnvcizdaiehriefyioeorauviquoeuroenraibcuivoaisdfuaeefoiebnxmcsua')

ans =

    a

3

Python - 384 325 275

อัลกอริทึมนี้ตรวจสอบแถวแรกและแถวสุดท้ายของเมทริกซ์เพื่อหาอักขระที่ตรงกันแล้วคำนวณความยาวของแต่ละส่วนของเส้น

012345
------
aaVaaa|0
aaVaaa|1
aaaVaa|2
aaaVaa|3
aaaaVa|4
aaaaVa|5

ในตัวอย่างด้านบน:
V ในแถวแรกอยู่ที่ดัชนี 2, V ในแถวสุดท้ายที่ดัชนี 4
ดังนั้นความยาวของแต่ละส่วนของบรรทัดจะเป็น n / (4-2) +1 = 2 กับ n = 6 .

จากนั้นตรวจสอบว่าบรรทัดนั้นถูกต้องหรือไม่

เพื่อหาเส้นทางจากซ้ายไปขวามันสลับแถวกับคอลัมน์และทำสิ่งเดียวกันอีกครั้ง

แก้ไข:ไม่สามารถไปถึง 270 (คุณ Python และการเยื้องของคุณ !!)

n,m=raw_input().split()
n,r=int(n),range
t=r(n)
a=[m[i:i+n]for i in r(0,n*n,n)]
for v in a,["".join([a[i][j]for i in t])for j in t]:
 for i in t:
  for j in t:
   p=1-2*(j-i<0);d,c=p*(j-i)+1,v[0][i]
   if 6<=sum([v[z][i+(z/(n/d))*p*(n%d==0)]==c for z in t])==n:print c;exit()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.