Pilih Petualangan Anda Sendiri


17

Buku Pilih Petualangan Anda Sendiri adalah bentuk literatur interaktif di mana pembaca harus membuat keputusan yang mempengaruhi hasil cerita. Pada titik-titik tertentu dalam cerita, pembaca memiliki banyak pilihan yang dapat dipilih, masing-masing mengirimkan pembaca ke halaman berbeda di buku.

Misalnya, dalam pengaturan fantasi, seseorang mungkin harus memutuskan di halaman 14 apakah akan menjelajah ke gua misterius dengan "melompat" ke halaman 22, atau menjelajahi hutan terdekat dengan melompat ke halaman 8. "Lompatan" ini dapat diekspresikan sebagai pasangan nomor halaman, seperti:

14 22
14 8

Dalam kebanyakan kasus, ada banyak akhir cerita tetapi hanya beberapa yang bagus. Tujuannya adalah menavigasi cerita untuk mencapai akhir yang baik.

Tugas:

Diberikan daftar "lompatan" untuk buku yang diberikan, tugas Anda adalah menentukan rute yang akan mengarah ke akhir yang spesifik. Karena ini cukup mudah, tantangan sebenarnya adalah melakukannya dalam karakter sesedikit mungkin.

Ini kode golf .

Input sampel (di mana 1 adalah awal dan 100 adalah tujuannya):

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

Output sampel:

1 10 13 15 100

Input sampel:

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

Output sampel:

1 15 2 12 80 100

Catatan:

  • Daftar lompatan akan dimasukkan oleh pengguna, baik dari file atau stdin. Anda dapat memilih mana yang paling nyaman.
  • Input akan berisi 1 lompatan per baris, dengan asal dan tujuan dipisahkan oleh satu spasi.
  • Garis-garis dalam input tidak dijamin dalam urutan tertentu.
  • Jalur yang berhasil akan dimulai pada halaman 1 dan berakhir pada halaman 100.
  • Anda dapat mengasumsikan setidaknya ada 1 jalur ke tujuan. Anda tidak perlu menemukan semua jalan, Anda juga tidak perlu menemukan yang terpendek. Temukan setidaknya satu saja.
  • Nomor halaman terkecil adalah 1. Tidak ada batasan untuk nomor halaman terbesar. (Anda dapat berasumsi bahwa itu akan sesuai dengan kisaran int.)
  • Loop mungkin ada. Misalnya, daftar mungkin melompat dari halaman 5 ke 10, 10 ke 19, dan 19 ke 5.
  • Mungkin ada jalan buntu. Artinya, halaman tujuan mungkin tidak memiliki tempat untuk melompat.
  • Sebaliknya, mungkin ada halaman yang tidak terjangkau. Artinya, halaman asal mungkin bukan tujuan lompatan apa pun.
  • Tidak semua nomor halaman antara 1 dan 100 dijamin untuk digunakan.
  • Output Anda harus terdiri dari rute yang valid dari nomor halaman, dimulai dengan 1 dan berakhir pada 100, dipisahkan oleh spasi.

Ingat, ini kode golf, jadi solusi terpendek menang!

EDIT: Menambahkan sampel lain untuk pengujian.


1
Bisakah kita berasumsi bahwa tidak ada lompatan dari halaman 100?
Peter Taylor

Ya, Anda mungkin menganggap itu.
migimaru

Saya punya perasaan bahwa sesuatu seperti pelat atau paduan bisa mencapai ini dalam beberapa karakter, saya akan mencobanya nanti ketika saya mulai bekerja.
JoséNunoFerreira

Jawaban:


7

Golfscript, 58 57 karakter

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

Peringatan : ini sangat tidak efisien. Ini bekerja dengan berulang kali mengkuadratkan adjacency matrix dan kemudian mencari rute; jika ada Etepi pada grafik maka akan menemukan setiap jalur dengan panjang hingga 2 E (dan yang lebih pendek akan menemukan banyak kali). Ini akan memberi Anda hasil untuk test case pertama dalam waktu yang wajar, tetapi jika Anda ingin mencoba yang kedua pastikan Anda memiliki beberapa gigs memori gratis dan berjalan jauh.

Jika Anda menginginkan solusi yang cukup efisien maka saya menawarkan 67 karakter:

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

Saya tidak menyadari Anda bisa melakukan perkalian matriks dalam Golfscript!
migimaru

@migimaru, ini adalah bahasa yang kuat di Turing, namun banyak kekurangan yang mungkin dimiliki arraynya.
Peter Taylor

Itu benar. Saya kira saya hanya tidak berharap untuk melihat matriks kedekatan cocok dengan ruang sekecil itu;)
migimaru

@ Peter Maaf, saya mencoba menjalankan ini dengan cat input | ruby1.9 golfscript.rb peter.gsdan semua yang terjadi adalah MacBook saya menjadi sangat panas. Bagaimana saya menjalankannya?
Gareth

3
@ Gareth, ya. Ketika saya membunuhnya setelah setengah jam, itu mencapai 2GB memori. Saya akan membuat peringatan sedikit lebih eksplisit.
Peter Taylor

14

Python, 232 213 157 143 135 132 karakter (jalur terpendek)

Implementasi ini dapat menangani semua kasus tepi yang dijelaskan (loop, jalan buntu, halaman yatim, dll.) Dan menjamin bahwa itu akan menemukan rute terpendek ke akhir. Ini didasarkan pada algoritma jalur terpendek 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 Karakter

Ini adalah solusi rekursif yang menemukan jalur terpendek melalui petualangan.

Kode-Golf:

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)

Untuk menguji ( PERINGATAN: infinite loop untuk input yang buruk! ):

  1. Salin salah satu dari string input berikut (atau gunakan format serupa untuk memilih sendiri, pilih petualangan Anda sendiri):

    • 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. Rekatkan itu ke dalam prompt tes biola .

Kode yang diformat dan Dikomentari:

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

Untuk menguji ( PERINGATAN: infinite loop untuk input yang buruk! ):

  1. Salin salah satu dari string input berikut (atau gunakan format serupa untuk memilih sendiri, pilih petualangan Anda sendiri):

    • 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. Rekatkan itu ke dalam prompt tes biola .


Penggunaan rekursi yang bagus di sini. Saya juga suka trik memberikan fungsi argumen tambahan hanya untuk membatasi ruang lingkup variabel :)
migimaru

@migimaru: Terima kasih! Catatan terkait: Masalah ini adalah bugger untuk debug sampai saya mengetahui bahwa variabel JavaScript tanpa varkata kunci memiliki cakupan global :)
Briguy37

3

Ruby 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]

Tidak Disatukan:

$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

Sangat bagus menggunakan percikan di sana.
migimaru

3

Perl, 88 karakter

pada dasarnya versi entri Clueless 'yang dipercepat; pra-pertandingan dan pasca-pertandingan itu menyenangkan :)

@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,[])

Sayangnya, solusi ekor-rekursif ini rentan terhadap loop dalam "cerita" ...

Penggunaan : cat ./test0 | ./sol.py Output untuk test case 1:

1 10 13 15 100

Output untuk test case 2:

1 15 2 12 80 100

0

Scala 2.9, 260 256 254 252 248 247 241 239 234 227 225 212 205 karakter

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

Tidak Disatukan:

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

Pemakaian:

Kompilasi dengan scalac filenamedan jalankan dengan scala C. Input diambil melalui STDIN.
Untuk berjalan di ideone.com, perubahan object C extends Appuntuk object Main extends Applicationmenjalankannya sebagai Scala 2.8.


0

PHP, 166 146 138 karakter

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

Tidak Disatukan:

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

Penggunaan:

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

Ini tidak menghasilkan output apa pun untuk saya ketika saya menjalankannya dari baris perintah di windows atau di ideone.com?
Gareth

Ini bekerja di komputer saya (windows). Saya menambahkan contoh penggunaan. Saya tidak bisa membuatnya berfungsi di
ideone.com

Ah ... itu menjelaskannya, saya mencoba mengirim masukan melalui STDINbukan sebagai argumen.
Gareth

1
Genesis pengguna φ mengusulkan pengeditan untuk memperbaiki jumlah karakter. Mungkin ada baiknya menempatkan versi golf tanpa spasi putih di depan versi yang tidak disunat, untuk memenuhi harapan masyarakat akan konvensi lokal.
Peter Taylor

-1

Saya akan menempatkan mereka semua ke dalam array 2d dan mencari semua item dengan banyak loop, jika mereka dapat mencapai item terakhir maka saya akan mengumpulkan item terkait agar menjadi array hasil yang lain, dan dari hasil saya akan memilih array mana yang lebih kecil .

EDIT => JAVA: Saya juga menggunakan fungsi rekursif, kode lengkap di bawah ini;

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

            }

        }
    }

}

Ini adalah kode-golf, jadi Anda perlu memberikan implementasi.
Gareth

Hai Gareth, saya harus pergi sekarang saya akan menambahkan secepatnya ketika saya tiba di rumah.
burak
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.