Кратчайший маршрут через одностороннюю систему

9

В моем родном городе Рил есть система одностороннего движения, которая, кажется, была разработана для того, чтобы люди как можно дольше не попадали в пункт назначения. Ваша задача, если вы решите попробовать это, - создать программу, обеспечивающую кратчайший маршрут через такую ​​систему трафика.

вход

Ввод будет включен STDIN, и будет список начальной и конечной точек, за которым следует пустая строка, за которой следует список запросов, как показано ниже:

A B
B A
B C
C D
D C

A D
C A
B A

Каждая дорога может быть пройдена только в указанном (ых) направлении (ях), поэтому в приведенном выше примере дорога A - B - это улица с двусторонним движением, тогда как B - C - это улица с односторонним движением от B до C. Перемещение от C до B запрещено.

Начальная и конечная точки будут представлены одной заглавной буквой.

Вывод

Выходными данными должен быть кратчайший маршрут (измеряемый количеством посещенных точек) от заданной начальной точки к заданной конечной точке для каждого полученного запроса. Если такого маршрута не существует, выведите пустую строку. Если существует более одного кратчайшего маршрута, выведите первый при сортировке всех кратчайших маршрутов лексикографически.

Для приведенного выше примера результат будет:

A B C D

B A

Тестовые сценарии

Как и прежде, я предоставляю тесты для этой задачи на основе сценариев, написанных Джои и Вентеро : -

а также тесты и ожидаемый вывод для тех, кто не может использовать вышеуказанные сценарии

Применение: ./test [your program and its arguments]

Награды

Все ответы, которые, очевидно, имели какую-то попытку сыграть в гольф, которые соответствуют спецификации и проходят все тесты, получат мое одобрение. Самый короткий рабочий ответ до 26.01.2012 будет принят.

Gareth
источник
output the first when sorting all shortest routes lexicographically- Итак, если A B Dи A C Dоба являются действительными решениями, A B Dвместо вывода ?
Мистер Лама
@GigaWatt Да, все верно.
Гарет
Это очень близко к дубликату codegolf.stackexchange.com/questions/3474/…
Питер Тейлор
1
@PeterTaylor Почему вы не подняли этот вопрос, пока он находился в песочнице для вопросов? Что ты предлагаешь? Я мог бы удалить это, пока нет ответов на это, я полагаю?
Гарет
@Gareth, потому что на этот раз была активность в нескольких потоках в meta одновременно, и я не заметил, что в песочнице для вопросов появился новый ответ. Удаление - одна возможность; или вы могли бы расширить его, чтобы взвесить края - у нас еще не было направленного вопроса Дейкстры.
Питер Тейлор

Ответы:

3

Haskell, 223 207 символов

main=interact$unlines.f.break null.map words.lines
s%[f,t]=[[f]]#t where[]#_="";x#t|y@(_:_)<-[z|z<-x,last z==t]=unwords$minimum y|1<3=s&x#t
s&z=[x++[b]|x<-z,[a,b]<-s,last x==a,notElem b x];f(s,_:q)=map(s%)q
Хаммар
источник
2

Python (2.x), 382 369 358 338 323 318 символов

Все советы и комментарии приветствуются!

import os;u=str.split;l=u(os.read(0,1e9),'\n')
p,g,c=l.index(''),{},map;o=g.setdefault
def f(g,s,e,q=[]):q=q+[s];y=([],[q])[s==e];[c(y.append,f(g,n,e,q))for n in set(o(s,[]))-set(q)];return y
for k,v in c(u,l[:p]):o(k,[]);g[k]+=v
for w,e in c(u,l[p+1:]):h=sorted(f(g,w,e));print''if not h else' '.join(min(h,key=len))

Должен пройти тесты в этой форме. Подача ввода через стандартный ввод, например python shortestroute.py < test.txt.

ChristopheD
источник
Кажется, что провал запроса 2 теста 4. Возвращает A B I J Mвместо A B G J M.
Гарет
@ Гарет: действительно была небольшая ошибка, связанная с лексографическими решениями подобной длины, должна быть исправлена ​​сейчас ...
ChristopheD
1

C: 450 , 437 , 404 , 390 символов

#include<stdio.h>
#include <string.h>
r[99][99],p[99],q[99],m[99],i,j,x,y,s;
char t[9],e[9999];
F(k)
{
    m[k]^s?r[p[k]=q[i]][k]?m[q[j++]=k]=s:0:0;
    if(++k<99)F(k);
}
f()
{
    F(0);
    if(++i^j)f();
}
P(o)
{
    if(p[o])P(p[o]);
    *t=m[o]^s?0:o;
    strcat(e,t);
}
w()
{
    gets(t);
    r[*t][t[2]]=*t?w():0;
}
W()
{
    gets(t);
    x=*t,x?y=t[j=2],s=x+y*99,m[q[t[2]=i=p[x]=0]=x]=s,f(),P(y),strcat(e,"\n"),W():0; 
}
main()
{
    w();
    W();
    puts(e);
}
Ali1S232
источник
puts("\n")печатает две строки. puts()автоматически добавляет терминатор конца строки к строкам, которые он печатает. Чтобы избежать такого поведения, используйте fputs(str, stdout)или просто printf(str).
JB
Слегка изменяет правила - следует сразу принять все входные данные и затем вывести все ответы на запросы за один раз. Я получу +1, потому что он отлично работает (и обнаружил ошибки в тестах), но я не смогу принять его в более длинной программе, которая полностью соответствует требованиям ввода / вывода.
Гарет
@ Гарет: исправлено. однако вывод ответа не должен быть длиннее 9999 символов!
Ali1S232