나만의 모험을 선택하십시오


17

자신 만의 모험 선택 서적은 독자가 스토리의 결과에 영향을 미치는 결정을 내려야하는 대화 형 문학의 한 형태입니다. 이야기의 특정 지점에서 독자는 여러 가지 옵션을 선택할 수 있으며 각 옵션은 독자를 책의 다른 페이지로 보냅니다.

예를 들어, 판타지 환경에서 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입니다. 가장 큰 페이지 번호에는 제한이 없습니다. (int 범위에 맞을 것이라고 가정 할 수 있습니다.)
  • 루프가 존재할 수 있습니다. 예를 들어 목록이 5 ~ 10 페이지, 10 ~ 19, 19 ~ 5로 점프했을 수 있습니다.
  • 막 다른 곳이있을 수 있습니다. 즉, 대상 페이지로 이동할 위치가 없을 수 있습니다.
  • 반대로, 도달 할 수없는 페이지가있을 수 있습니다. 즉, 원점 페이지가 점프의 대상이 아닐 수 있습니다.
  • 1에서 100 사이의 모든 페이지 번호가 사용되는 것은 아닙니다.
  • 출력은 1로 시작하고 100으로 끝나는 공백으로 구분 된 유효한 페이지 번호 경로로 구성되어야합니다.

이것은 코드 골프이므로 가장 짧은 솔루션이 승리합니다!

편집 : 테스트를 위해 다른 샘플을 추가했습니다.


1
100 페이지에서 점프가 없다고 가정 할 수 있습니까?
— 피터 테일러

그렇습니다.
— migimaru

나는 lisp 또는 합금과 같은 것이 매우 적은 문자로 이것을 달성 할 수 있다고 생각합니다. 나중에 퇴근 할 때 시도 할 것입니다.
— JoséNunoFerreira

답변:


7

골프 스크립트, 58 57 문자

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

경고 : 이것은 매우 비효율적입니다. 인접 행렬을 반복적으로 제곱 한 다음 경로를 찾아서 작동합니다. E그래프에 가장자리가 있으면 최대 2E 의 모든 길이의 경로를 찾을 수 있습니다 (더 짧은 경로는 많은 시간을 찾을 수 있습니다). 합리적인 시간에 첫 번째 테스트 사례에 대한 결과를 제공해야하지만 두 번째 테스트 사례를 시도하려는 경우 몇 개의 메모리 여유 공간이 있는지 확인하고 오래 걸으십시오.

합리적으로 효율적인 솔루션을 원한다면 67 문자로 제공합니다.

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

Golfscript에서 행렬 곱셈을 할 수 있다는 것을 몰랐습니다!
— migimaru

@migimaru는 Turing-powerful 언어이지만 배열 처리에 많은 단점이 있습니다.
— 피터 테일러

사실입니다. 난 그냥 인접 행렬이 작은 공간에 맞는 볼 기대하지 않았을 것 같아요;)
— migimaru

@Peter 죄송합니다,이 문제를 해결하려고했는데 cat input | ruby1.9 golfscript.rb peter.gsMacBook이 정말 뜨거워졌습니다. 어떻게 실행해야합니까?
— Gareth

3
@ 가레스. 30 분 후에 죽였을 때 최대 2GB의 메모리였습니다. 경고를 좀 더 명확하게 설명하겠습니다.
— 피터 테일러

14

파이썬 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

자바 스크립트 : 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 : 감사합니다! 관련 측면 참고 :이 문제는 var키워드가 없는 JavaScript 변수 가 전역 범위를 갖는다는 것을 알 때까지 디버깅하는
— 버거였습니다

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]

언 골프 드 :

$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

펄, 88 자

기본적으로 Clueless 항목의 Perlized 버전; 사전 경기와 사후 경기는 재미 있습니다 :)

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

1

파이썬- 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")}

언 골프 드 :

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. 를 통해 입력이 이루어 STDIN집니다.
ideone.com에서 실행하려면, 변화 object C extends App하는 object Main extends Application스칼라 2.8로 실행합니다.


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

언 골프 :

$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
사용자 기원 φ 는 문자 수를 수정하기위한 편집을 제안했습니다. 지역 대회에 대한 사람들의 기대에 부응하기 위해 골프 용 버전 앞에 공백이없는 골프 버전을 넣을 가치가 있습니다.
— 피터 테일러

-1

모든 항목을 2d 배열에 넣고 여러 루프로 모든 항목을 검색합니다. 마지막 항목에 도달 할 수 있으면 관련 항목을 다른 결과 배열로 순서대로 수집하고 결과에서 더 작은 배열을 선택합니다 .

편집 => 자바 : 또한 재귀 함수, 아래의 전체 코드를 사용했습니다.

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.