Drunkard's Journey Home


23

Drunkard's Journey Home

ในการท้าทายนี้คุณต้องเขียนโปรแกรมที่เลียนแบบคนเมาที่เดินโซเซกลับบ้านจากบาร์

การป้อนข้อมูล:

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

สมมติว่าคนเมาเหล้าเริ่มที่บาร์เสมอ (แถวแรกในเมทริกซ์ adjacency)

หากคนขี้เมาเข้าสู่จุดจบสามารถสันนิษฐานได้ว่าเขาเดินทางกลับบ้านหรือถูกจับกุมเพราะความมึนเมาของสาธารณะและโปรแกรมควรกลับไปตามเส้นทางของเขา

สามารถสันนิษฐานได้ว่ากราฟจะมีจุดจบอย่างน้อยหนึ่งจุดเสมอ

นอกจากนี้ยังสามารถสันนิษฐานได้ว่าคนเมาเหล้าจะสามารถออกจากบาร์ได้เสมอ (แถวแรกจะไม่ใช่ศูนย์ทั้งหมด) และถ้าคนขี้เมาติดอยู่ในสถานที่ตั้งแถวนั้นจะเป็นศูนย์โดยศูนย์ทั้งหมด

เอาท์พุท:

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

ตัวอย่าง:

Input
[1,0,1,1]
[0,0,0,0]
[1,0,0,0]
[1,1,1,1]

Possible Outputs
[0,2,0,3,2,0,0,3,1]
[0,3,0,3,1]


Input
[0,1,1,1,0,1]
[1,0,1,0,1,1]
[0,0,0,0,0,0]
[0,0,0,0,0,1]
[1,0,0,0,0,0]
[0,0,0,0,0,0]

Possible outputs
[0,1,5]
[0,5]
[0,1,4,0,2]
[0,3,5]
[0,3,0,1,4,0,5]

Deterministic path:

Input
[0,0,1,0]
[0,0,0,1]
[0,1,0,0]
[0,0,0,0]

Output
[0,2,1,3]

12
สิ่งนี้ทำให้ความทรงจำของนักเรียนกลับมา ... ฉันหมายถึงใช่ฉันกำลังพูดถึงกราฟกำกับอยู่แน่นอน! o :-)
Arnauld

เราสามารถนำเข้าเป็นชุดของสตริงเช่น[ '1011', '0000', '1000', '1111' ]?
Arnauld

เป็นไปได้ไหมที่บาร์จะเป็นจุดจบ กล่าวอีกนัยหนึ่งแถวแรกจะเป็นศูนย์ทั้งหมดหรือไม่ นอกจากนี้จะมีแถวที่นำไปสู่ตัวเองเท่านั้นและเราจะต้องตรวจสอบว่าเป็นเงื่อนไขสิ้นสุดหรือไม่ กล่าวอีกนัยหนึ่งจะมีแถวที่iมีศูนย์ทั้งหมดยกเว้นที่คอลัมน์iหรือไม่
kamoroso94

5
ฉันแค่รอให้ใครสักคนเขียนคำตอบใน Taxi
Belgabad

คุณจะได้รับเส้นทางสุดท้ายในตัวอย่างที่ 2 ได้อย่างไร จากความเข้าใจของฉัน0เชื่อมโยงไปยัง1,2,3,5แต่ผลลัพธ์สุดท้ายได้จาก0ไป4
phflack

คำตอบ:


7

Mathematica ขนาด 72 ไบต์

{1}//.{r___,x_}:>{r,x,n=1;Check[RandomChoice[#[[x]]->(n++&/@#)],##&[]]}&

นี่คือฟังก์ชั่นใช้เมทริกซ์เป็นอาร์กิวเมนต์และส่งกลับรายการและใช้การจัดทำดัชนีแบบ 1

แนวคิดพื้นฐานคือการเริ่มต้นด้วย

{1}//.

ซึ่งใช้กฎที่ตามมาซ้ำ ๆ กับรายการซ้ำ ๆ{1}จนกระทั่งหยุดการเปลี่ยนแปลง กฎตรงกับรูปแบบ

{r___,x_}:>

ซึ่งหมายความว่า "รายการที่มีศูนย์หรือมากกว่าองค์ประกอบที่เรียกว่าrตามองค์ประกอบที่เรียกว่าx." สิ่งนี้ให้xเป็นองค์ประกอบสุดท้ายในรายการปัจจุบันและเราแทนที่รายการด้วย

{r,x,<stuff>}

ซึ่งเป็นรายการต้นฉบับที่มี<stuff>ต่อท้าย สิ่งที่เป็นปัญหาคือ

RandomChoice[#[[x]]->(n++&/@#)]

ซึ่งใช้เวลา#[[x]]( xองค์ประกอบที่สามของอินพุตเมทริกซ์) เป็นรายการน้ำหนักและแม็พกับn++&/@#มันซึ่งสั้นสำหรับRange@Length@#(เช่น{1,2,3,...}ด้วยความยาวที่เหมาะสม) นี่จะทำให้เกิดข้อผิดพลาดหากน้ำหนักเป็นศูนย์ทั้งหมดซึ่งเป็นสาเหตุที่ห่อหุ้มด้วย

Check[...,##&[]]

ซึ่งจะส่งคืน##&[]หากมีการสร้างข้อความแสดงข้อผิดพลาด นี่เป็นเพียงวิธีแฟนซีของการเขียนSequence[]ซึ่งทำหน้าที่เป็นองค์ประกอบ "ไม่มีอะไร" ( {1,2,Sequence[],3}ประเมินผล{1,2,3}) และทำให้รายการไม่เปลี่ยนแปลงทำให้การ//.หยุดแทนที่




3

MATL , 15 ไบต์

1`GyY)ft?th1ZrT

เอาท์พุทเป็นแบบ 1

ลองออนไลน์! แรกอินพุท การป้อนข้อมูลที่สองอินพุตที่สามการป้อนข้อมูลที่สาม

คำอธิบาย

1          % Push 1: initial value of current row index
`          % Do...while
  G        %   Push input matrix
  y        %   Duplicate from below: pushes copy of current row index
  Y)       %   Get that row
  f        %   Find: push (possibly empty) array of indices of non-zero entries
  t        %   Duplicate
  ?        %   If non-empty
    th     %     Attach a copy of itself. This is needed in case the array
           %     contains a single number n, because then the randsample
           %     function would incorrectly treat that as the array [1 2 ... n]
    1Zr    %     Randsample: pick 1 entry at random with uniform probability
    T      %     Push true
           %   End (implicit)
           % End (implicit). Proceed with a new iteration if the top of the
           % stack is truthy. This happens if the current row had some
           % non-zero entry, in which case true was pushed (and is now
           % consumed). If the current row was all zeros, the top of the stack
           % is an empty array that was produced by the find function, which is
           % falsy (and is also consumed now). In that case the loop is exited,
           % and then the stack contains a collection of numbers which
           % collectively describe the path
           % Implicit display


2

Python ขนาด 136 ไบต์

ใช้การจัดทำดัชนีเป็นศูนย์สมมติว่ามีการนำเข้า randrange รับอินพุต m เป็นเมทริกซ์ adjacency

113 ไม่มีการนำเข้า

s=lambda m,c=0,p=[0],x=0:1 in m[c]and(m[c][x]and s(m,x,p+[x],randrange(len(m)))or s(m,c,p,randrange(len(m))))or p

136 พร้อมการนำเข้า

import random as r;s=lambda m,c=0,p=[0],x=0:1 in m[c]and(m[c][x]and s(m,x,p+[x],r.randrange(len(m)))or s(m,c,p,r.randrange(len(m))))or p


3
ฉันขอแนะนำให้ใช้ 136 เป็นจำนวนไบต์หลักของคุณเป็น คำสั่งการนำเข้าที่สอดคล้องกัน
Jonathan Frech

2

Ruby , 70 67 65 ไบต์

f=->m,i=0{m[i].sum<1?[]:m[i][x=rand(m.size)]<1?f[m,i]:[x]+f[m,x]}

ขอบคุณbenj2240สำหรับการบันทึก 2 ไบต์!

ลองออนไลน์!


คุณสามารถบันทึกสองสามไบต์ด้วยm[i].sum<1?:[]
benj2240

@ benj2240 ว้าวฉันไม่เคยรู้ว่าเป็นไปได้ ตอนนี้ฉันรู้แล้วว่า.sumถูกนำมาใช้ใน 2.4 ฉันเคยทำ.reduce(0, :+)...
Cristian Lupascu

2

JavaScript (ES6), 87 ไบต์

f=(a,y=0)=>[y,.../1/.test(r=a[y])?f(a,(g=_=>r[k=Math.random()*r.length|0]?k:g())()):[]]

ลองออนไลน์!


รุ่นสำรอง 81 ไบต์

รับอินพุตเป็นอาร์เรย์ของสตริงไบนารี ขนาดสูงสุดที่รองรับคือ 16x16

f=(a,y=0)=>[y,...+(r=a[y])?f(a,(g=_=>+r[k=Math.random()*r.length|0]?k:g())()):[]]

ลองออนไลน์!


1

Java 10, 135 ไบต์

m->{var R="0 ";for(int r=0,c,t;;R+=(r=c)+" "){t=0;for(int x:m[r])t+=x;if(t<1)return R;for(t=c=m.length;m[r][c*=Math.random()]<1;)c=t;}}

0 การจัดทำดัชนี

คำอธิบาย:

ลองออนไลน์

m->{                   // Method with integer-matrix parameter and String return-type
  var R="0 ";          //  Result-String, starting at "0 "
  for(int r=0,         //  Row-integer, starting at 0
          c,           //  Column-integer
          t;           //  Temp-integer
      ;                //  Loop indefinitely
       R+=             //    After every iteration: Append the result with:
          (r=c)+" "){  //     The current column and a delimiter-space,
                       //     And set the current row to this column at the same time
    t=0;               //   (Re-)set `t` to 0
    for(int x:m[r])    //   Loop over the values of the current row
      t+=x;            //    And add them to `t`
    if(t<1)            //   If the entire row only contained zeroes:
      return R;        //    Return the result
    for(t=c=m.length;  //   Set `t` (and `c`) to the size of the matrix
        m[r][c*=Math.random()]<1;)
                       //   Loop until we've found a 1,
                       //   picking a random column in the range [0,`c`)
      c=t;}}           //    Reset the range of `c` to `t` (the size of the matrix)



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