Kendi Maceranızı Seçin


17

Kendi Maceralarını Seç kitaplar, okuyucunun hikayenin sonucunu etkileyen kararlar alması gereken etkileşimli bir edebiyat türüdür. Hikayenin belirli noktalarında okuyucunun seçilebilecek birden fazla seçeneği vardır ve her biri okuyucuyu kitaptaki farklı bir sayfaya gönderir.

Örneğin, bir fantezi ortamında, sayfa 14'te "atlayarak" gizemli bir mağaraya girip girmeyeceğine veya sayfa 8'e atlayarak yakındaki ormanı araştırmaya karar vermek gerekebilir. Bu "sıçramalar" ifade edilebilir sayfa numaraları çifti olarak, şöyle:

14 22
14 8

Çoğu durumda, hikayenin birçok sonu vardır, ancak sadece birkaç iyi olanı vardır. Amaç, iyi bir sona ulaşmak için hikayede gezinmektir.

Görev:

Belirli bir kitap için "sıçramalar" listesi verildiğinde, göreviniz belirli bir sona yol açacak bir rota belirlemektir. Bu oldukça kolay olduğundan, asıl zorluk bunu mümkün olduğunca az karakterle yapmaktır.

Bu kod golf .

Örnek giriş (burada 1 başlangıç ​​ve 100 hedeftir):

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

Örnek çıktı:

1 10 13 15 100

Örnek giriş:

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

Örnek çıktı:

1 15 2 12 80 100

Notlar:

  • Atlamaların listesi kullanıcı tarafından bir dosyadan veya stdin'den girilir. Hangisinin en uygun olduğunu seçebilirsiniz.
  • Girdi, başlangıç ​​noktası ve hedef tek bir boşlukla ayrılmış olarak satır başına 1 atlama içerir.
  • Girişteki satırların belirli bir sırada olacağı garanti edilmez.
  • Başarılı bir yol 1. sayfada başlar ve 100. sayfada sona erer.
  • Hedefe giden en az 1 yol olduğunu varsayabilirsiniz. Tüm yolları bulmanıza veya en kısa olanı bulmanıza gerek yoktur. Sadece en az birini bul.
  • En küçük sayfa numarası 1 olacaktır. En büyük sayfa numarasının sınırı yoktur. (Bir int aralığına uyacağını varsayabilirsiniz.)
  • Döngüler olabilir. Örneğin, listede sayfa 5 ila 10, 10 ila 19 ve 19 ila 5 arasında atlamalar olabilir.
  • Çıkmazlar olabilir. Diğer bir deyişle, bir hedef sayfanın atlamak için hiçbir yeri olmayabilir.
  • Tersine, erişilemeyen sayfalar olabilir. Yani, başlangıç ​​sayfası herhangi bir atlamanın hedefi olmayabilir.
  • 1 ile 100 arasındaki tüm sayfa numaralarının kullanılması garanti edilmez.
  • Çıktınız, 1 ile başlayan ve 100 ile biten, boşluklarla ayrılmış geçerli bir sayfa numarası yolundan oluşmalıdır.

Unutmayın, bu kod golf, bu yüzden en kısa çözüm kazanır!

EDIT: Test için başka bir örnek eklendi.


1
100. sayfada atlama olmadığını varsayabilir miyiz?
Peter Taylor

Evet, bunu varsayabilirsiniz.
migimaru

Lisp veya alaşım gibi bir şeyin çok az karakterde bunu başarabileceği hissine sahibim, işten çıktığımda daha sonra deneyeceğim.
JoséNunoFerreira

Yanıtlar:


7

Golfscript, 58 57 karakter

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

Uyarı : Bu süper verimsizdir. Bitişiklik matrisini tekrar tekrar kareye alıp bir rota arayarak çalışır; Egrafikte kenarlar varsa , 2 E'ye kadar her uzunluk yolunu bulacaktır (ve daha kısa olanları birçok kez bulacaktır). İlk test vakası için makul bir süre içinde bir sonuç vermelidir, ancak ikincisini denemek istiyorsanız, birkaç gig belleğiniz olduğundan emin olun ve uzun bir yürüyüşe çıkın.

Oldukça verimli bir çözüm istiyorsanız 67 karakter teklif ediyorum:

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

Golfscript'te matris çarpımı yapabileceğinizin farkında değildim!
migimaru

@migimaru, bu Turing-güçlü bir dildir, ancak dizi işlemenin sahip olabileceği birçok eksiklik.
Peter Taylor

Bu doğru. Sanırım ben sadece bitişik matrislerin böyle küçük bir alana sığdığını görmeyi beklemiyordum;)
migimaru

@Peter Üzgünüm, bunu çalıştırmayı denedim cat input | ruby1.9 golfscript.rb peter.gsve olan her şey MacBook'umun gerçekten ısınmasıydı. Nasıl çalıştırmalıyım?
Gareth

3
@Gareth, evet. Yarım saat sonra öldürdüğümde, 2GB'a kadar bellek vardı. Uyarıyı biraz daha açık hale getireceğim.
Peter Taylor

14

Piton, 232 213 157 143 135 132 karakter (kısa yol)

Bu uygulama, açıklanan tüm uç durumları (döngüler, çıkmaz sokaklar, yetim sayfaları vb.) İşleyebilir ve sona en kısa yolu bulacağını garanti eder. Djikstra'nın en kısa yol algoritmasına dayanmaktadır.

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

Bu, maceradaki en kısa yolu bulan özyinelemeli bir çözümdür.

Kod-golfed:

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)

Test etmek için ( UYARI: hatalı giriş için sonsuz döngü! ):

  1. Aşağıdaki giriş dizelerinden birini kopyalayın (veya kendi maceranızı seçmek için benzer bir format kullanın):

    • 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. Bunu test kemanının komut istemine yapıştırın .

Biçimlendirilmiş ve Yorumlanmış kod:

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

Test etmek için ( UYARI: hatalı giriş için sonsuz döngü! ):

  1. Aşağıdaki giriş dizelerinden birini kopyalayın (veya kendi maceranızı seçmek için benzer bir format kullanın):

    • 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. Bunu test kemanının komut istemine yapıştırın .


Burada özyineleme güzel kullanımı. Ben de sadece değişkenlerin kapsamını sınırlamak için fonksiyona ekstra argümanlar verme hilesini seviyorum :)
migimaru

@migimaru: Teşekkürler! İlgili bir not: Bu sorun, JavaScript değişkenlerininvar Anahtar kelime genel kapsamı :)
Briguy37

3

Yakut 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

Orada uyarısı çok güzel kullanımı.
migimaru

3

Perl, 88 karakter

temelde Clueless 'girişinin perlize edilmiş bir versiyonu; maç öncesi ve maç sonrası eğlencelidir :)

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

ne yazık ki, bu kuyruk özyinelemeli çözüm "hikaye" deki döngülere karşı savunmasız ...

Kullanım : kedi ./test0 | ./sol.py Test durumu 1 için çıktı:

1 10 13 15 100

Test örneği 2 için çıktı:

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

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

Kullanımı:

İle derleyin scalac filenameve ile çalıştırın scala C. Giriş üzerinden alınır STDIN.
İdeone.com çalıştırmak için, değişim object C extends Appiçin object Main extends ApplicationScala 2.8 olarak çalıştırmak için.


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

Kurtulmamış:

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

Kullanımı:

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

Windows veya ideone.com'daki komut satırından çalıştırdığımda bu benim için herhangi bir çıktı üretmiyor mu?
Gareth

Bilgisayarımda çalışır (windows). Bir kullanım örneği ekledim. Yine de
ideone.com'da

Ah ... bu açıklıyor, ben STDINargüman olarak değil, girdi göndermeye çalışıyordum .
Gareth

1
Kullanıcı oluşumu character karakter sayısını düzeltmek için bir düzenleme önerdi. İnsanların yerel konvansiyondan beklentilerini karşılamak için, golf edilmemiş versiyondan önce boşluk olmadan golf edilmiş bir versiyon koymak faydalı olabilir.
Peter Taylor

-1

Hepsini bir 2d dizisine koyar ve tüm öğelere birden fazla döngüle bakarsanız, son öğeye ulaşabilirlerse, başka bir sonuç dizisine sırayla ilgili öğeleri toplar ve sonuçlardan daha küçük bir dizi seçerdim .

EDIT => JAVA: Ben de özyinelemeli işlev, tam kod aşağıda kullandım;

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

            }

        }
    }

}

Bu kod golf, bu yüzden bir uygulama sağlamanız gerekir.
Gareth

Merhaba Gareth, şimdi gitmeliyim, eve geldiğimde en kısa zamanda ekleyeceğim.
burak
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.