Гра назви міст


16

Якщо вам подобається, напишіть програму, яка сортує міста за правилами гри назви міста.

  • Кожна назва міста повинна починатися з останньої літери попередньої назви міста. НапрLviv -> v -> Viden -> n -> Neapolis -> s -> Sidney -> y -> Yokogama -> a -> Amsterdam -> m -> Madrid -> d -> Denwer

  • У відсортованому списку перша літера першого міста та остання літера останнього не повинні відповідати нічого , не повинні бути однаковими.

  • Можна припустити, що в назвах міст є лише літери.
  • Вихід програми повинен мати таку саму величину, як і вхід

Приклад:

% ./script Neapolis Yokogama Sidney Amsterdam Madrid Lviv Viden Denwer
["Lviv", "Viden", "Neapolis", "Sidney", "Yokogama", "Amsterdam", "Madrid", "Denwer"]

2
Чи можемо ми припустити, що завжди знайдеться правильне рішення?
Гарет

@Gareth так, можна
дефш

друге правило - "[...] нічого не повинно відповідати" - це вимога чи просто твердження, яке говорить про те, що нормально відповідати між першим та останнім листом? (наприклад: такий список ["Viden" ... "Lviv"]недійсний?)
Крістіан Лупаску

@ w0lf від "не слід" Я мав на увазі, що це не повинно, це не є обов'язковим. Тож ваш приклад справедливий.
дефш

Підказка: Якщо ви хочете приємного рішення, ви можете звести це до обчислення ейлерових шляхів, де кожна буква є вершиною, а кожне слово - ребром. (Наприклад, Берлін - це край BN ) Це можна вирішити в O (n), де n - кількість ребер.
FUZxxl

Відповіді:


11

Рубі, 58 55 44 символи

p$*.permutation.find{|i|i*?,!~/(.),(?!\1)/i}

Ще одна реалізація рубіну. Використання також чутливо до регістру регулярний вираз (як Ventero «s старий розчин ) , але тест робиться по- різному.

Попередня версія:

p$*.permutation.find{|i|(i*?,).gsub(/(.),\1/i,"")!~/,/}

Дуже хороша! І я думаю, що ви можете зменшити це до 55, якщо використовуватимете !~замість того, щоб знехтувати цілий вираз.
Крістіан Лупаску

Це розумне regexp
defhlt

@ w0lf Звичайно! Як я не міг про це думати?
Говард

5

Пітон ( 162 141 124)

Сила для перемоги.

from itertools import*
print[j for j in permutations(raw_input().split())if all(x[-1]==y[0].lower()for x,y in zip(j,j[1:]))]

1
Я думаю, ви можете зняти &(j[0][0]!=j[-1][-1])стан; дивіться коментарі до запитання вище.
Крістіан Лупаску

1
124 from itertools import*;print[j for j in permutations(raw_input().split())if all(x[-1]==y[0].lower()for x,y in zip(j,j[1:]))]
Ev_genus

Я намагаюся обернути голову навколо того, що відбувається в цій функції. Що саме j, x, y? Як вони визначаються? Вибачте, якщо ці питання кульгають, я новачок у Python і хотів би попрацювати з ним ще трохи.
Роб

@MikeDtrick: jмістить перестановку міст, яка генерується за допомогою permutationsкоманди. Велика ifв кінці в основному підтверджує, що для всіх значень у j, остання літера одного значення в jє такою ж, як перша літера наступного значення в j. Чесно кажучи, я не знаю, що zipробить, zipпрацює таємничими способами.
beary605

Гаразд, дякую за пояснення! +1
Роб

5

Рубін 1,9, 63 54 символи

Нове рішення засноване на Говарда «S рішення :

p$*.permutation.max_by{|i|(i*?,).scan(/(.),\1/i).size}

Для цього використовується той факт, що завжди знайдеться правильне рішення.

Старе рішення, засноване на w0lf «s рішення :

p$*.permutation.find{|i|i.inject{|a,e|a&&e[0]=~/#{a[-1]}/i&&e}}

Гарна ідея з max_by. І ваша нова версія надихнула мене на ще більшу (і коротшу) версію.
Говард

@Howard Дякую! Ваше нове рішення дійсно приголомшливе, важко буде це перемогти. ;)
Вентеро

4

Рубін 74 72 104 103 71 70

p$*.permutation.find{|i|i.inject{|a,e|a[-1].casecmp(e[0])==0?e:?,}>?,}

Демо: http://ideone.com/MDK5c (у демонстраційній версії, яку я використовував gets().split()замість $*; я не знаю, чи може Ideone імітувати аргументи командного рядка).


схоже на мій варіант, $*.permutation{|p|p p if p.inject(p[0][0]){|m,e|m.casecmp(e[0])==0?e[-1]:?_}>?_}але ваш на 9 символів коротший!
дефш

2
p$*.permutation.find{|i|i.inject{|a,e|a&&e[0]=~/#{a[-1]}/i&&e}}зовсім трохи коротше. Рішення Ruby 1,8 (!), p$*.permutation.find{|i|i.inject{|a,e|a&&a[-1]-32==e[0]&&e}}
Яке

@ Ventero Використання нечутливого до регексу рекреації - це геніальна ідея! Будь ласка, опублікуйте це як власну відповідь; Я не гідний цим користуватися. :)
Крістіан Лупаску

@ Вентеро -32рішення також дуже геніальне, але воно покладається на те, що назви починаються з великої літери і закінчуються з малої літери, що може бути не завжди так.
Крістіан Лупаску

@ w0lf Ти маєш рацію, я думав, що читав у специфікаціях, що так і буде, але явно помиляюся. ;)
Вентеро

3

Пітона, 113

Дуже схожа на відповідь @ beary605, і навіть більш жорстока.

from random import*
l=raw_input().split()
while any(x[-1]!=y[0].lower()for x,y in zip(l,l[1:])):
 shuffle(l)
print l

1
Woohoo, стиль бого-сортування!
beary605

3

Haskell , 94 74 байт

g[a]=[[a]]
g c=[b:r|b<-c,r<-g[x|x<-c,x/=b],last b==[r!!0!!0..]!!32]
head.g

Рекурсивно знаходить усі рішення. -7 байт, якщо це нормально, щоб вивести всі рішення замість першого. Дякуємо @Lynn за те, що позбувся набридливого імпорту, голивши 18 байт за рахунок!

Спробуйте в Інтернеті!


Ви можете позбутися Data.Charімпорту за допомогою last b==[r!!0!!0..]!!32. Крім того, вам не потрібні парони вg[x|x<-c,x/=b]
Лінн

1
@Lynn приємно, я якось думав, fromEnumщо це обов'язково. Смішно, я забрав ці круглі дужки вже один раз, але, мабуть, скопіював з неправильної вкладки…
Ангели

2

GolfScript, 78 символів

" ":s/.{1${1$=!},{:h.,{1$-1={1$0=^31&!{[1$1$]s*[\](\h\-c}*;}+/}{;.p}if}:c~;}/;

Перша версія в GolfScript. Це також робить грубу силу підходу. Ви можете бачити сценарій, що працює на прикладі введення в Інтернеті .


2

Лушпиння , 10 байт

←fΛ~=o_←→P

Спробуйте в Інтернеті!

Пояснення

←fΛ~=(_←)→P  -- example input: ["Xbc","Abc","Cba"]
          P  -- all permutations: [["Xbc","Abc","Cba"],…,[Xbc","Cba","Abc"]]
 f           -- filter by the following (example with ["Xbc","Cba","Abc"])
  Λ          -- | all adjacent pairs ([("Xbc","Cba"),("Cba","Abc")])
   ~=        -- | | are they equal when..
     (_←)    -- | | .. taking the first character lower-cased
         →   -- | | .. taking the last character
             -- | : ['c'=='c','a'=='a'] -> 4
             -- : [["Xbc","Cba","Abc"]]
←            -- take the first element: ["Xbc","Cba","Abc"]

Як варіант, 10 байт

Ми також могли б порахувати кількість сусідніх пар, які задовольняють присудок ( #), сортувати за ( Ö), що приймає останній елемент ( ), на однакову кількість байтів:

→Ö#~=o_←→P

Спробуйте в Інтернеті!


2

Желе , 25 18 байт (вдосконалення ласкаво просимо!)

UżḢŒuE
ḲŒ!çƝẠ$ÐfḢK

Спробуйте в Інтернеті!

UżḢŒuE        dyadic (2-arg) "check two adjacent city names" function:
Uż            pair (żip) the letters of the reversed left argument with the right argument,
  Ḣ           get the Ḣead of that pairing to yield just the last letter of left and the first letter of right,
   Œu         capitalize both letters,
     E       and check that they're equal!
ḲŒ!çƝẠ$ÐfḢK    i/o and check / fold function:
ḲŒ!            split the input on spaces and get all permutations of it,
   çƝẠ$        run the above function on every adjacent pair (çƝ), and return true if Ȧll pairs are true
       Ðf      filter the permutations to only get the correct ones,
         ḢK    take the first of those, and join by spaces!

Дякуємо @Lynn за більшість цих удосконалень!

25-байтне рішення:

Uḣ1Œu=⁹ḣ1
çƝȦ
ḲŒ!©Ç€i1ị®K

Спробуйте в Інтернеті!

Uḣ1Œu=⁹ḣ1      dyadic (2-arg) "check two adjacent city names" function:
Uḣ1Œu          reverse the left arg, get the ḣead, and capitalize it (AKA capitalize the last letter),
     =⁹ḣ1      and check if it's equal to the head (first letter) of the right argument.
çƝȦ            run the above function on every adjacent pair (çƝ), and return true if Ȧll pairs are true
ḲŒ!©Ç€i1ị®K     main i/o function:
ḲŒ!©           split the input on spaces and get all its permutations, ©opy that to the register
    Ç€         run the above link on €ach permutation,
      i1       find the index of the first "successful" permutation,
        ị®K    and ®ecall the permutation list to get the actual ordering at that ịndex, separating output by spaces

2
Деякі вдосконалення: спробуйте в Інтернеті! Я написав невеликий журнал змін у полі "Введення". (О, після того, як Ðfя використовую Xвибір випадкового рішення замість першого, але працює так само добре.)
Лінн

@Lynn Дуже дякую! Роздільна частина була дуже розумною, і я думаю, що я можу скористатись цим Ðfшвидко у багатьох інших програмах, щоб заощадити місце!
Гаррі

1

Математика 236 символів

Визначте список міст:

d = {"Neapolis", "Yokogama", "Sidney", "Amsterdam", "Madrid", "Lviv", "Viden", "Denver"}

Знайдіть шлях, який включає всі міста:

c = Characters; f = Flatten;
w = Outer[List, d, d]~f~1;
p = Graph[Cases[w, {x_, y_} /;x != y \[And] (ToUpperCase@c[x][[-1]]== c[y][[1]]) :> (x->y)]];
v = f[Cases[{#[[1]], #[[2]], GraphDistance[p, #[[1]], #[[2]]]} & /@  w, {_, _, Length[d] - 1}]];
FindShortestPath[p, v[[1]], v[[2]]]

Вихід:

{"Lviv", "Viden", "Neapolis", "Sidney", "Yokogama", "Amsterdam","Madrid", "Denver"}

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


Графік p показаний нижче:

графік


1

C, 225

#define S t=v[c];v[c]=v[i];v[i]=t
#define L(x)for(i=x;i<n;i++)
char*t;f;n=0;main(int c,char**v){int i;if(!n)n=c,c=1;if(c==n-1){f=1;L(2){for(t=v[i-1];t[1];t++);if(v[i][0]+32-*t)f=n;}L(f)puts(v[i]);}else L(c){S;main(c+1,v);S;}}

Запустити з назви країн як аргументів командного рядка

Примітка:

  • генерація грубої сили перестановок
  • для його перевірки передбачається, що назви країн починаються з верхнього регістру і закінчуються з малого регістру.
  • припускає, що існує лише одна відповідь
  • В C припускається, що масив ** v main () записується

Не впевнений, що він дійсно дійсний, але якщо ви це зробите #define L(x)for(int i=x;i<n;i++)та не заявляєте iна початку, mainви збережете 1 байт.
Цатогуа

1

J, 69 65 60 59 54 символи

Дещо поза темпом.

{.l\:+/2=/\|:tolower;"2({.,{:)@>l=.(i.@!@#A.]);:1!:1[1

Приклад:

   {.l\:+/2=/\|:tolower;"2({.,{:)@>l=.(i.@!@#A.]);:1!:1[1
Neapolis Yokogama Sydney Amsterdam Madrid Lviv Viden Denwer
+----+-----+--------+------+--------+---------+------+------+
|Lviv|Viden|Neapolis|Sydney|Yokogama|Amsterdam|Madrid|Denwer|
+----+-----+--------+------+--------+---------+------+------+

1

C #, 398

І ось C # з Linq 5 центів

IEnumerable<string>CityNameGame(string[]input){var cities=new List<string>(input);string lastCity=null;while(cities.Any()){var city=lastCity??cities.First();lastCity=cities.First(name=>string.Equals(city.Substring(city.Length-1),name.Substring(0,1),StringComparison.CurrentCultureIgnoreCase));cities.RemoveAll(name=>name==city||name==lastCity);yield return string.Format("{0}→{1}",city,lastCity);}}

0

К, 96

{m@&{&/(~).'+(,_1_1#'x),,-1_-1#'x}@'$m:{$[x=1;y;,/.z.s[x-1;y]{x,/:{x@&~x in y}[y;x]}\:y]}[#x;x]}

.

k){m@&{&/(~).'+(,_1_1#'x),,-1_-1#'x}@'$m:{$[x=1;y;,/.z.s[x-1;y]{x,/:{x@&~x in y}[y;x]}\:y]}[#x;x]}`Neapolis`Yokogama`Sidney`Amsterdam`Madrid`Lviv`Viden`Denver
Lviv Viden Neapolis Sidney Yokogama Amsterdam Madrid Denver

0

C # (.NET Core) , 297 байт

using System;
using System.Linq;
var S="";int I=0,C=s.Count();for(;I<C;I++)S=Array.Find(s,x=>s[I].Substring(0,1).ToUpper()==x.Substring(x.Length-1).ToUpper())==null?s[I]:S;for(I=0;I<C;I++){Console.Write(S+" ");S=C>I?Array.Find(s,x=>S.Substring(S.Length-1).ToUpper()==x.Substring(0,1).ToUpper()):"";}

Спробуйте в Інтернеті!

using System;
using System.Linq;

var S = "";
int I = 0, C = s.Count();
for (; I < C; I++)
    S = Array.Find(
        s, x =>
        s[I].Substring(0, 1).ToUpper() == x.Substring(x.Length - 1).ToUpper()
    ) == null ?
    s[I] :
    S;
for (I = 0; I < C; I++) {
    Console.Write(S + " ");
    S = C > I ? Array.Find(s, x => S.Substring(S.Length - 1).ToUpper() == x.Substring(0, 1).ToUpper()) : "";
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.