도시 이름 게임


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

@Gareth 네, 가능합니다
defhlt

두 번째 규칙- "[...]는 아무 것도 일치하지 않아야합니다"-첫 글자와 마지막 글자가 일치하지 않는다고 말하는 것이 요구 사항입니까? (예 : ["Viden" ... "Lviv"]유효하지 않은 목록 입니까?)
Cristian Lupascu

@ w0lf는 "필요하지 않음"으로, 꼭 그럴 필요는 없다는 것을 의미했습니다. 따라서 귀하의 예는 유효합니다.
defhlt

힌트 : 좋은 해결책 을 원한다면 , 각 문자는 꼭짓점이고 각 단어는 가장자리 인 유레 리아 경로 계산으로 줄일 수 있습니다. (예를 들어, 베를린 은 모서리 BN입니다. ) 이것은 O (n)에서 해결할 수 있습니다. 여기서 n은 모서리 수입니다.
FUZxxl

답변:


11

루비, 58 55 44 자

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

또 다른 루비 구현. 대소 문자를 구분하지 않는 정규 표현식 ( Ventero 의 오래된 솔루션 )을 사용하지만 테스트는 다르게 수행됩니다.

이전 버전:

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

아주 좋아요! 그리고 !~전체 표현을 부정하지 않고 사용하면 이것을 55로 줄일 수 있다고 생각합니다 .
Cristian Lupascu

그것은 똑똑한 정규 표현식입니다
defhlt

물론 @ w0lf! 나는 그것을 어떻게 생각할 수 없었습니까?
Howard

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])조건을 제거 할 수 있다고 생각합니다 . 위의 질문 의견을 참조하십시오.
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

이 기능에서 일어나는 일을 머리로 감싸려고합니다. 정확히 무엇 j, x, y? 그것들은 어떻게 정의됩니까? 이 질문이 불분명하다면 죄송합니다 .Python을 처음 사용하고 더 많은 작업을하고 싶습니다.
Rob

@MikeDtrick : 명령으로 j생성 된 도시의 순열을 포함합니다 permutations. if끝에 있는 big 은 기본적으로의 모든 값에 대해 j한 값의 마지막 j문자가의 다음 값의 첫 번째 문자와 동일한 지 확인합니다 j. 솔직히, 나는 중 하나가 모르는 zip않는, zip신비로운 방식으로 작동합니다.
beary605

알겠습니다, 설명 감사합니다! +1
Rob

5

루비 1.9, 63 54 자

새로운 솔루션은 Howard 의 솔루션을 기반으로 합니다 .

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

이것은 항상 유효한 솔루션이 있다는 사실을 사용합니다.

w0lf 의 솔루션을 기반으로 한 오래된 솔루션 :

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

와 좋은 아이디어 max_by. 그리고 새 버전은 더 새롭고 더 짧은 버전에 영감을주었습니다.
Howard

@Howard 감사합니다! 새로운 솔루션은 정말 대단합니다. ;)
Ventero

4

루비 74 72104103 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 자 더 짧습니다!
defhlt

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

@Ventero 대소 문자를 구분하지 않는 정규식을 사용하는 것은 훌륭한 아이디어입니다! 이것을 자신의 답변으로 게시하십시오. 나는 그것을 사용할 가치가 없다. :)
Cristian Lupascu

@ Ventro -32솔루션은 매우 독창적이지만 이름은 대문자로 시작하고 소문자로 끝나는 사실에 의존합니다. 항상 그런 것은 아닙니다.
Cristian Lupascu

@ w0lf 당신 말이 맞아요, 나는 스펙에서 그것이 사실 일 것이라고 생각했지만 분명히 나는 ​​틀렸다. ;)
Ventero

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
보고 우 정렬 스타일!
beary605

3

하스켈 , 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 바이트 성가신 가져 오기를 없애고 점수를 18 바이트 줄인 @Lynn에게 감사드립니다!

온라인으로 사용해보십시오!


Data.Char가져 오기를 제거 할 수 있습니다 last b==[r!!0!!0..]!!32. 또한, 당신은 Parens 필요가 없습니다g[x|x<-c,x/=b]
Lynn

1
@Lynn nice, 나는 어떻게 든 필수 일 fromEnum것이라고 생각했다 . 우스운, 나는 그 괄호를 이미 한 번 가지고 갔다. 그러나 나는 잘못된 탭에서 복사했을 것이다.
Angs

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다른 많은 프로그램에서 빠르게 사용 하여 공간을 절약 할 수 있다고 생각 합니다!
Harry

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는 다음과 같습니다.

graph


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

Run with country names as the command line arguments

노트 :

  • 순열의 무차별 대입
  • 확인을 위해 국가 이름은 대문자로 시작하고 소문자로 끝나는 것으로 가정합니다.
  • 답이 하나만 있다고 가정
  • C에서 main ()의 ** v 배열은 쓰기 가능하다고 가정합니다.

정확히 유효 #define L(x)for(int i=x;i<n;i++)하지는 않지만 i처음에 선언하지 않으면 main1 바이트를 절약하십시오.
Tsathoggua

1

J, 69 65 60 59 54 characters

속도가 다소 떨어졌습니다.

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

And here is C# with Linq 5 cents

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 bytes

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

Try it online!

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()) : "";
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.