Tên thành phố trò chơi


16

Nếu bạn thích, hãy viết một chương trình sắp xếp các thành phố theo quy tắc của trò chơi tên thành phố.

  • Mỗi tên của thành phố nên bắt đầu từ chữ cái cuối cùng trong tên thành phố trước đó. Ví dụLviv -> v -> Viden -> n -> Neapolis -> s -> Sidney -> y -> Yokogama -> a -> Amsterdam -> m -> Madrid -> d -> Denwer

  • Trong danh sách được sắp xếp, chữ cái đầu tiên của thành phố đầu tiên và chữ cái cuối cùng của chữ cuối cùng không nên khớp với bất cứ thứ gì không phải là cùng một chữ cái.

  • Bạn có thể giả sử tên thành phố chỉ có chữ cái.
  • Đầu ra chương trình nên có cùng chữ viết hoa với đầu vào

Thí dụ:

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

2
Chúng ta có thể cho rằng sẽ luôn có một giải pháp hợp lệ không?
Gareth

@Gareth có, bạn có thể
defhlt

quy tắc thứ hai - "[...] không nên khớp bất cứ điều gì" - đó có phải là một yêu cầu hay chỉ là một tuyên bố nói rằng không có sự không khớp giữa chữ cái đầu tiên và chữ cái cuối cùng? (ví dụ: một danh sách như ["Viden" ... "Lviv"]không hợp lệ?)
Cristian Lupascu

@ w0lf bởi "không nên" Ý tôi là nó không phải, nó không bắt buộc. Vì vậy, ví dụ của bạn là hợp lệ.
defhlt

Gợi ý: Nếu bạn muốn một giải pháp tốt đẹp , bạn có thể giảm điều này thành phép tính các đường dẫn eulerian, trong đó mỗi chữ cái là một đỉnh và mỗi từ là một cạnh. (Ví dụ, Berlin là cạnh BN ) Điều này có thể giải được trong O (n), trong đó n là số cạnh.
FUZxxl

Câu trả lời:


11

Ruby, 58 55 44 ký tự

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

Một thực hiện ruby ​​khác. Sử dụng cũng trường hợp regex không nhạy cảm (như giải pháp cũ của Ventero ) nhưng thử nghiệm được thực hiện khác nhau.

Phiên bản trước:

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

Rất đẹp! Và tôi nghĩ bạn có thể giảm xuống 55 nếu bạn sử dụng !~thay vì phủ định toàn bộ biểu thức.
Cristian Lupascu

Đó là
regrec

@ w0lf Tất nhiên rồi! Làm thế nào tôi có thể không nghĩ về điều đó?
Howard

5

Con trăn ( 162 141 124)

Lực lượng vũ phu cho chiến thắng.

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
Tôi nghĩ bạn có thể loại bỏ &(j[0][0]!=j[-1][-1])điều kiện; xem các ý kiến ​​câu hỏi ở trên.
Cristian Lupascu

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

Tôi đang cố gắng che giấu những gì đang diễn ra trong chức năng này. Chính xác những gì đang j, x, y? Chúng được định nghĩa như thế nào? Tôi xin lỗi nếu những câu hỏi này là khập khiễng, tôi mới biết về Python và muốn làm việc với nó thêm nữa.
Cướp

@MikeDtrick: jchứa một hoán vị của các thành phố, được tạo bằng permutationslệnh. Chữ ifcuối cùng về cơ bản xác nhận rằng đối với tất cả các giá trị trong j, chữ cái cuối cùng của một giá trị jgiống như chữ cái đầu tiên của giá trị tiếp theo j. Thành thật mà nói, tôi cũng không biết những gì zipnó làm, ziphoạt động theo những cách bí ẩn.
beary605

Được rồi, cảm ơn bạn đã giải thích! +1
Cướp

5

Ruby 1.9, 63 54 ký tự

Giải pháp mới dựa trên giải pháp của Howard :

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

Điều này sử dụng thực tế là sẽ luôn có một giải pháp hợp lệ.

Giải pháp cũ, dựa trên giải pháp của w0lf :

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

Ý tưởng tốt đẹp với max_by. Và phiên bản mới của bạn đã truyền cảm hứng cho bản thân tôi cho một phiên bản mới hơn (và ngắn hơn).
Howard

@ Xin cảm ơn! Giải pháp mới của bạn thực sự tuyệt vời, sẽ rất khó để đánh bại điều đó. ;)
Ventero

4

Ruby 74 72 104 103 71 70

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

Bản trình diễn: http://ideone.com/MDK5c (trong bản demo tôi đã sử dụng gets().split()thay vì $*; Tôi không biết liệu Ideone có thể mô phỏng các đối số dòng lệnh không).


trông giống với biến thể của tôi $*.permutation{|p|p p if p.inject(p[0][0]){|m,e|m.casecmp(e[0])==0?e[-1]:?_}>?_}nhưng của bạn ngắn hơn 9 ký tự!
defhlt

2
p$*.permutation.find{|i|i.inject{|a,e|a&&e[0]=~/#{a[-1]}/i&&e}}là khá ngắn hơn một chút. Một giải pháp Ruby 1.8 (!) Thậm chí còn ngắn hơn:p$*.permutation.find{|i|i.inject{|a,e|a&&a[-1]-32==e[0]&&e}}
Ventero

@Ventero Sử dụng regex không phân biệt chữ hoa chữ thường là một ý tưởng tuyệt vời! Xin vui lòng gửi đây là câu trả lời của riêng bạn; Tôi không xứng đáng để sử dụng nó. :)
Cristian Lupascu

@Ventero -32giải pháp cũng rất khéo léo, nhưng nó dựa vào thực tế là tên bắt đầu bằng chữ in hoa và kết thúc bằng chữ thường, có thể không phải luôn luôn như vậy.
Cristian Lupascu

@ w0lf Bạn nói đúng, tôi nghĩ rằng tôi đã đọc trong thông số kỹ thuật rằng đó là trường hợp, nhưng rõ ràng là tôi đã nhầm. ;)
Ventero

3

Con trăn, 113

Rất giống với câu trả lời của @ beary605, và thậm chí còn tàn bạo hơn.

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, phong cách bogo-sort!
beary605

3

Haskell , 94 74 byte

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

Đệ quy tìm tất cả các giải pháp. -7 byte nếu xuất ra tất cả các giải pháp thay vì đầu tiên. Cảm ơn @Lynn vì đã thoát khỏi việc nhập khẩu phiền phức, loại bỏ 18 byte khỏi điểm số!

Hãy thử trực tuyến!


Bạn có thể thoát khỏi việc Data.Charnhập khẩu với last b==[r!!0!!0..]!!32. Ngoài ra, bạn không cần parens trongg[x|x<-c,x/=b]
Lynn

1
@Lynn tốt đẹp, tôi bằng cách nào đó nghĩ rằng fromEnumsẽ là phải. Thật buồn cười, tôi đã lấy những dấu ngoặc đơn đó đi một lần rồi, nhưng tôi phải sao chép từ tab sai
Angs

2

GolfScript, 78 ký tự

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

Một phiên bản đầu tiên trong GolfScript. Nó cũng làm một cách tiếp cận vũ phu. Bạn có thể thấy tập lệnh chạy trên ví dụ đầu vào trực tuyến .


2

Husk , 10 byte

←fΛ~=o_←→P

Hãy thử trực tuyến!

Giải trình

←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"]

Ngoài ra, 10 byte

Chúng ta cũng có thể đếm số lượng các cặp liền kề thỏa mãn vị ngữ ( #), sắp xếp trên ( Ö) và lấy phần tử cuối cùng ( ) cho cùng một số byte:

→Ö#~=o_←→P

Hãy thử trực tuyến!


2

Jelly , 25 18 byte (Chào mừng cải tiến!)

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

Hãy thử trực tuyến!

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!

Cảm ơn @Lynn vì hầu hết những cải tiến này!

Giải pháp 25 byte:

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

Hãy thử trực tuyến!

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
Một số cải tiến: Hãy thử trực tuyến! Tôi đã viết một chút thay đổi trong trường "Đầu vào". (Ồ, sau khi Ðftôi sử dụng Xđể chọn một giải pháp ngẫu nhiên thay vì giải pháp đầu tiên, nhưng cũng hoạt động tốt.)
Lynn

@Lynn Cảm ơn bạn rất nhiều! Phần zip rất thông minh và tôi nghĩ rằng tôi có thể sử dụng Ðfnhanh chóng trong rất nhiều chương trình khác của mình để tiết kiệm không gian!
Harry

1

Toán học 236 ký tự

Xác định danh sách các thành phố:

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

Tìm đường dẫn bao gồm tất cả các thành phố:

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]]]

Đầu ra:

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

Cách tiếp cận trên giả định rằng các thành phố có thể được sắp xếp dưới dạng biểu đồ đường dẫn.


Biểu đồ p được hiển thị dưới đây:

đồ thị


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

Chạy với tên quốc gia làm đối số dòng lệnh

Ghi chú:

  • thế hệ vũ phu của hoán vị
  • để kiểm tra, giả sử rằng tên quốc gia bắt đầu bằng chữ in hoa và kết thúc bằng chữ thường.
  • giả sử chỉ có một câu trả lời
  • Trong C, giả sử rằng mảng ** v của hàm main () có thể ghi được

Không chắc chắn nó chính xác, nhưng nếu bạn làm #define L(x)for(int i=x;i<n;i++)và không khai báo ikhi bắt đầu, mainbạn sẽ tiết kiệm được 1 byte.
Tsathoggua

1

J, 69 65 60 59 54 ký tự

Hơi lạc nhịp.

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

Thí dụ:

   {.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

Và đây là C # với Linq 5 xu

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

K, 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 byte

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()):"";}

Hãy thử trực tuyến!

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()) : "";
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.