都市名ゲーム


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はい、できます
-defhlt

2番目のルール-「[...]は何にも一致してはならない」-最初の文字と最後の文字の間に不一致があってもよいという要件または単なるステートメントですか?(例:["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まで下げることができると思います。
クリスチャンルパスク

それは賢い正規表現です
-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

この関数で何が起こっているのかを頭で包もうとしています。正確にどのようなものがありjxy?それらはどのように定義されていますか?これらの質問が不十分な場合は申し訳ありませんが、私はPythonを初めて使います。
ロブ

@MikeDtrick:コマンドでj生成される都市の順列が含まれますpermutationsif最後のbig は、のすべての値についてj、の1つの値の最後のj文字がの次の値の最初の文字と同じであることを基本的に検証しますj。正直なところ、私はそれが何をするのか、神秘的な方法zipzip機能するのか分からない。
beary605

さて、説明ありがとうございます!+1
ロブ

5

Ruby 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ありがとう!あなたの新しいソリューションは本当に素晴らしいです、それを打ち負かすのは難しいでしょう。;)
Ventero

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/MDK5cgets().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大文字と小文字を区別しない正規表現の使用は素晴らしいアイデアです!これを自分の回答として投稿してください。私はそれを使うに値しません。:)
クリスチャンルパスク

@Ventero -32ソリューションも非常に巧妙ですが、名前が大文字で始まり、小文字で終わるという事実に依存しています。
クリスチャンルパスク

@ w0lfそのとおりです、仕様書でそうだと思いましたが、明らかに間違いです。;)
Ventero

3

Python、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、bogo-sortスタイル!
beary605

3

Haskell94 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に感謝します。

オンラインでお試しください!


Data.Charインポートを取り除くことができますlast b==[r!!0!!0..]!!32。また、あなたは中括弧を必要としませんg[x|x<-c,x/=b]
Lynn

1
@Lynnいいね、どうやら絶対に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代わりに最初の1のランダムなソリューションを選択するが、同じようにうまく動作します。)
リン・

@Lynnありがとうございます!zip部分は非常に巧妙だったのでÐf、他の多くのプログラムでそれをすばやく使用してスペースを節約できると思います!
ハリー

1

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

コマンドライン引数として国名で実行する

注意:

  • 順列のブルートフォース生成
  • チェックのために、国名は大文字で始まり、小文字で終わると仮定します。
  • 答えが1つしかないと仮定する
  • Cでは、main()の** v配列が書き込み可能であると想定しています

正確に有効かどうかはわかり#define L(x)for(int i=x;i<n;i++)ませんがi、最初に宣言していない場合はmain1バイトを節約してください。
ツァソググア

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

そしてここにLinq 5セントのC#があります

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バイト

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()) : "";
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.