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


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.