เลือกการผจญภัยของคุณเอง


17

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

ตัวอย่างเช่นในการตั้งค่าจินตนาการเราอาจต้องตัดสินใจในหน้า 14 ว่าจะเสี่ยงเข้าไปในถ้ำลึกลับโดย "กระโดด" ถึงหน้า 22 หรือสำรวจป่าใกล้เคียงโดยการกระโดดไปที่หน้า 8 "กระโดด" เหล่านี้สามารถแสดงได้ เป็นคู่ของหมายเลขหน้าดังนี้:

14 22
14 8

ในกรณีส่วนใหญ่มีเรื่องราวตอนจบมากมาย แต่มีเพียงไม่กี่คนที่ดี เป้าหมายคือการนำทางเรื่องราวไปสู่จุดจบที่ดี

งาน:

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

นี่คือกอล์ฟรหัส

ตัวอย่างอินพุต (โดยที่ 1 คือจุดเริ่มต้นและ 100 คือเป้าหมาย):

1 10
10 5
10 13
5 12
5 19
13 15
12 20
15 100

ตัวอย่างผลลัพธ์:

1 10 13 15 100

ตัวอย่างอินพุต:

15 2
1 4
2 12
1 9
3 1
1 15
9 3
12 64
4 10
2 6
80 100
5 10
6 24
12 80
6 150
120 9
150 120

ตัวอย่างผลลัพธ์:

1 15 2 12 80 100

หมายเหตุ:

  • รายการของการกระโดดจะถูกป้อนโดยผู้ใช้ทั้งจากไฟล์หรือ stdin คุณสามารถเลือกได้ว่าสะดวกที่สุด
  • อินพุตจะมีการกระโดด 1 ครั้งต่อบรรทัดโดยที่ต้นทางและปลายทางคั่นด้วยช่องว่างเดียว
  • บรรทัดในอินพุตไม่รับประกันว่าจะอยู่ในลำดับที่เฉพาะเจาะจง
  • เส้นทางที่ประสบความสำเร็จจะเริ่มต้นที่หน้า 1 และสิ้นสุดที่หน้า 100
  • คุณอาจคิดว่ามีอย่างน้อย 1 เส้นทางไปยังเป้าหมาย คุณไม่จำเป็นต้องค้นหาเส้นทางทั้งหมดหรือไม่จำเป็นต้องหาเส้นทางที่สั้นที่สุด เพียงแค่หาอย่างน้อยหนึ่ง
  • หมายเลขหน้าที่เล็กที่สุดจะเป็น 1 ไม่ จำกัด จำนวนหน้ามากที่สุด (คุณสามารถสันนิษฐานได้ว่ามันจะพอดีกับช่วงของ int)
  • อาจมีลูป ตัวอย่างเช่นรายการอาจมีการข้ามจากหน้า 5 ถึง 10, 10 ถึง 19 และ 19 ถึง 5
  • อาจมีจุดจบ นั่นคือหน้าปลายทางอาจไม่มีที่ใดก็ได้ที่จะข้ามไป
  • ในทางกลับกันอาจมีหน้าเว็บที่ไม่สามารถเข้าถึงได้ นั่นคือหน้าต้นกำเนิดอาจไม่ได้เป็นปลายทางของการกระโดดใด ๆ
  • ไม่รับประกันว่าจะมีการใช้หมายเลขหน้าทั้งหมดระหว่าง 1 ถึง 100
  • ผลลัพธ์ของคุณควรประกอบด้วยเส้นทางที่ถูกต้องของหมายเลขหน้าเริ่มต้นด้วย 1 และสิ้นสุดที่ 100 คั่นด้วยช่องว่าง

จำไว้ว่านี่คือรหัสกอล์ฟดังนั้นทางออกที่สั้นที่สุดชนะ!

แก้ไข:เพิ่มตัวอย่างอื่นสำหรับการทดสอบ


1
เราสามารถสันนิษฐานได้ว่าไม่มีการข้ามจากหน้า 100?
ปีเตอร์เทย์เลอร์

ใช่คุณอาจคิดว่า
migimaru

ฉันมีความรู้สึกว่าบางสิ่งบางอย่างเช่นเสียงกระเพื่อมหรือโลหะผสมสามารถทำได้ในไม่กี่ตัวอักษรฉันจะพยายามในภายหลังเมื่อฉันออกไปทำงาน
JoséNunoFerreira

คำตอบ:


7

Golfscript, 58 57 ตัวอักษร

~]2/.,{:A{){=}+{0=}\+A\,\`{\+}+/}/]A+}*{)100=\0=1=*}?' '*

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

หากคุณต้องการโซลูชันที่มีประสิทธิภาพพอสมควรฉันขอเสนอที่ 67 ตัวอักษร:

~]2/:A,[1]]({A{{{?)}+1$\,,}%~!*},{({\-1==}+2$?\[+]+}/}*{100?)}?' '*

ฉันไม่ทราบว่าคุณสามารถทำการคูณเมทริกซ์ใน Golfscript!
migimaru

@migimaru เป็นภาษาที่มีพลังของทัวริง แต่มีข้อบกพร่องมากมายที่การจัดการอาเรย์อาจมี
Peter Taylor

นั่นเป็นเรื่องจริง ฉันเดาว่าฉันไม่ได้คาดหวังว่าจะเห็นเมทริกซ์คำ
วิเศษณ์

@ ปีเตอร์ขออภัยฉันลองใช้สิ่งนี้cat input | ruby1.9 golfscript.rb peter.gsและสิ่งที่เกิดขึ้นคือ MacBook ของฉันร้อนมาก ฉันจะรันมันได้อย่างไร
Gareth

3
@ กาเร็ ธ ใช่แล้ว เมื่อฉันฆ่ามันหลังจากครึ่งชั่วโมงมันขึ้นอยู่กับหน่วยความจำ 2GB ฉันจะทำให้คำเตือนชัดเจนยิ่งขึ้น
Peter Taylor

14

Python, 232 213 157 143 135 132 ตัวอักษร (เส้นทางที่สั้นที่สุด)

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

import sys
l=[k.split()for k in sys.stdin]
s={"100":"100"}
while"1"not in s:
 for i,j in l:
    if j in s:s[i]=i+" "+s[j]
print s["1"]

3

Javascript: 189 ตัวอักษร

นี่เป็นโซลูชันแบบเรียกซ้ำที่ค้นหาเส้นทางที่สั้นที่สุดผ่านการผจญภัย

รหัสแข็งแรงเล่นกอล์ฟ:

a=prompt().split('\\n');b=0;while(!(d=c(b++,1)));function c(e,f,i,g){if(e>0)for(i=0;h=a[i++];){g=h.split(' ');if(g[0]==f){if(g[1]==100)return h;if(j=c(e-1,g[1]))return g[0]+' '+j}}}alert(d)

ในการทดสอบ ( คำเตือน: การวนซ้ำไม่สิ้นสุดสำหรับอินพุตที่ไม่ดี! ):

  1. คัดลอกหนึ่งในสตริงอินพุตต่อไปนี้ (หรือใช้รูปแบบที่คล้ายกันเพื่อเลือกการผจญภัยของคุณเอง:

    • 1 10\n10 5\n10 13\n5 12\n5 19\n13 15\n12 20\n15 100
    • 15 2\n1 4\n2 12\n1 9\n3 1\n1 15\n9 3\n12 64\n4 10\n2 6\n80 100\n5 10\n6 24\n12 80\n6 150\n120 9\n150 120
  2. วางลงในพรอมต์ของซอทดสอบ

รูปแบบและรหัสความคิดเห็น:

//Get Input from user
inputLines = prompt().split('\\n');

//Starting at 0, check for solutions with more moves
moves = 0;
while (!(solution = getSolution(moves++, 1)));

/**
 * Recursive function that returns the moves string or nothing if no
 * solution is available.
 *
 * @param numMoves - number of moves to check
 * @param startPage - the starting page to check
 * @param i - A counter.  Only included to make this a local variable.
 * @param line - The line being tested.  Only included to make this a local variable.
 */
function getSolution(numMoves, startPage, i, line) {
    //Only check for solutions if there are more than one moves left
    if (numMoves > 0) {
        //Iterate through all the lines
        for (i=0; text = inputLines[i++];) {
            line = text.split(' ');
            //If the line's start page matches the current start page
            if (line[0] == startPage) {
                //If the goal page is the to page return the step
                if (line[1] == 100) {
                    return text;
                }
                //If there is a solution in less moves from the to page, return that
                if (partialSolution = getSolution(numMoves - 1, line[1])) {
                    return line[0] + ' ' + partialSolution;
                }
            }
        }
    }
}

//Output the solution
alert(solution);

ในการทดสอบ ( คำเตือน: การวนซ้ำไม่สิ้นสุดสำหรับอินพุตที่ไม่ดี! ):

  1. คัดลอกหนึ่งในสตริงอินพุตต่อไปนี้ (หรือใช้รูปแบบที่คล้ายกันเพื่อเลือกการผจญภัยของคุณเอง:

    • 1 10\n10 5\n10 13\n5 12\n5 19\n13 15\n12 20\n15 100
    • 15 2\n1 4\n2 12\n1 9\n3 1\n1 15\n9 3\n12 64\n4 10\n2 6\n80 100\n5 10\n6 24\n12 80\n6 150\n120 9\n150 120
  2. วางลงในพรอมต์ของซอทดสอบ


ใช้การสอบถามซ้ำได้ที่นี่ ฉันยังชอบเคล็ดลับของการให้การขัดแย้งฟังก์ชั่นพิเศษเพียงเพื่อ จำกัด ตัวแปรขอบเขต :)
migimaru

@migimaru: ขอบคุณ! สังเกตด้านที่เกี่ยวข้อง: ปัญหานี้เป็นคนเสพเวจมรรคแก้ปัญหาจนผมได้เรียนรู้ว่าตัวแปร JavaScript โดยไม่ต้องvarคำหลักที่มีขอบเขตทั่วโลก :)
Briguy37

3

ทับทิม 1.9, 98

j=$<.map &:split
f=->*p,c{c=='100'?abort(p*' '):j.map{|a,b|a==c&&!p.index(b)&&f[*p,b,b]}}
f[?1,?1]

Ungolfed:

$lines = $<.map &:split
def f (*path)
    if path[-1] == '100' # story is over
        abort path.join ' ' # print out the path and exit
    else
        # for each jump from the current page
        $lines.each do |from, to|
            if from == path[-1] && !path.include?(to) # avoid loops
                # jump to the second page in the line
                f *path, to
            end
        end
    end
end

ใช้ประโยชน์ได้ดีมากที่นั่น
migimaru

3

Perl, 88 ตัวอักษร

โดยทั่วไปเป็นรุ่นที่เข้าถึงได้ยากของรายการ Clueless '; การแข่งขันก่อนและหลังการแข่งขันสนุก :)

@t=<>;%s=(100,100);until($s{1}){for(@t){chomp;/ /;$s{$`}="$` $s{$'}"if$s{$'}}}print$s{1}

1

Python - 239 237 236

import sys
global d
d={}
for i in sys.stdin:
 a,b=[int(c) for c in i.split(' ')]
 try: d[b]+=[a]
 except: d[b]=[a]
def f(x,h):
 j=h+[x]
 if x==1:
  print ''.join([str(a)+" " for a in j[::-1]])
  exit()
 for i in d[x]:
  f(i,j)
f(100,[])

น่าเสียดายที่โซลูชันแบบเรียกซ้ำหางนี้มีความเสี่ยงที่จะวนซ้ำใน "เรื่องราว" ...

การใช้งาน : cat ./test0 | ./sol.py เอาต์พุตสำหรับกรณีทดสอบ 1:

1 10 13 15 100

เอาต์พุตสำหรับกรณีทดสอบ 2:

1 15 2 12 80 100

0

สกาล่า 2.9, 260 256 254 252 248 247 241 239 234 227 225 212ตัวละคร 205

object C extends App{var i=io.Source.stdin.getLines.toList.map(_.split(" "))
def m(c:String):String=(for(b<-i)yield if(b(1)==c)if(b(0)!="1")m(b(0))+" "+b(0)).filter(()!=).mkString
print(1+m("100")+" 100")}

Ungolfed:

object Choose extends App
{
    var input=io.Source.stdin.getLines.toList.map(_.split(" "))
    def findroute(current:String):String=
    (
        for(branch<-input)
        yield 
        if(branch(1)==current)
            if(branch(0)!="1")findroute(branch(0))+" "+branch(0)
    ).filter(()!=).mkString
    print(1+findroute("100")+" 100")
}

การใช้งาน:

รวบรวมและทำงานด้วยscalac filename การป้อนข้อมูลจะได้รับการผ่านscala C เพื่อให้ทำงานบน ideone.com เปลี่ยนแปลงเพื่อที่จะเรียกว่ามันเป็น Scala 2.8STDIN
object C extends Appobject Main extends Application


0

PHP, 166 146 138 ตัวอักษร

$a[]=100;while(1<$c=$a[0])for($i=1;$i<$argc;$i++){list($p,$q)=explode(' ',$argv[$i]);if($q==$c)array_unshift($a,$p);}echo implode(' ',$a);

Ungolfed:

$a[]=100;
while(1<$c=$a[0])
    for($i=1;$i<$argc;$i++){
        list($p,$q)=explode(' ',$argv[$i]);
        if($q==$c)array_unshift($a,$p);
    }
echo implode(' ',$a);

การใช้งาน:

php golf.php "1 10" "10 5" "10 13" "5 12" "5 19" "13 15" "12 20" "15 100"

สิ่งนี้ไม่ได้สร้างผลลัพธ์ใด ๆ สำหรับฉันเมื่อฉันเรียกใช้จากบรรทัดคำสั่งใน windows หรือบน ideone.com
Gareth

มันทำงานบนคอมพิวเตอร์ของฉัน (windows) ฉันได้เพิ่มตัวอย่างการใช้งาน ฉันไม่สามารถได้รับมันทำงานบน ideone.com แม้ว่า
Alfwed

อ่า ... ที่อธิบายมันฉันพยายามส่งอินพุตSTDINมากกว่าเป็นข้อโต้แย้ง
Gareth

1
แหล่งกำเนิดของผู้ใช้φเสนอการแก้ไขเพื่อแก้ไขจำนวนตัวละคร มันอาจจะคุ้มค่าที่จะนำเวอร์ชั่นของกอล์ฟมาใช้โดยไม่ต้องเว้นวรรคก่อนรุ่นที่ไม่ได้อัปโหลดเพื่อตอบสนองความคาดหวังของผู้คนในการประชุมท้องถิ่น
Peter Taylor

-1

ฉันจะใส่ทั้งหมดลงในอาร์เรย์ 2d และค้นหารายการทั้งหมดที่มีหลายวงหากพวกเขาสามารถเข้าถึงรายการสุดท้ายแล้วฉันจะรวบรวมรายการที่เกี่ยวข้องเพื่อเรียงลำดับผลลัพธ์อื่นและจากผลลัพธ์ฉันจะเลือกอาร์เรย์ที่หนึ่งมีขนาดเล็กกว่า .

แก้ไข => JAVA: ฉันยังใช้ฟังก์ชันเรียกซ้ำรหัสเต็มด้านล่าง;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Jumper {
    static int x = 0;
    public static ArrayList<ArrayList<String>> c = new ArrayList<ArrayList<String>>();  
    public static void main(String[] args) throws IOException {
       //Read from line and parse into array
        BufferedReader in = new BufferedReader(new FileReader("list.txt"));
        ArrayList<String> s = new ArrayList<String>();
        String line = null; 
        while ((line = in.readLine()) != null){s.add(line);}
        c.add(new ArrayList<String>());
            //When you get all items forward to method
        checkPages(0, s,Integer.parseInt(s.get(0).split(" ")[0]),Integer.parseInt(s.get(s.size()-1).split(" ")[1]));
    }   

    public static void checkPages (int level,ArrayList<String> list,int from, int dest){
        if(level <= list.size()){           
            for(int i=level;i<list.size();i++){
                int a = Integer.parseInt(list.get(i).split(" ")[0]);
                int b = Integer.parseInt(list.get(i).split(" ")[1]);
                if(a == from){
                    c.get(x).add(list.get(i));
                    if(b==dest){
                        c.add(new ArrayList<String>());
                        x++;
                    }else{
                        checkPages(i, list, b,dest);
                        c.get(x).remove(list.get(i));
                    }
                }

            }

        }
    }

}

นี่คือรหัสกอล์ฟดังนั้นคุณต้องเตรียมการ
Gareth

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