เกมชื่อเมือง


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

Ruby, 58 55 44 ตัวละคร

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

อีกหนึ่งการติดตั้งทับทิม ใช้ regex ที่ไม่คำนึงถึงขนาดตัวพิมพ์ (เหมือนโซลูชันเก่าของVentero ) แต่การทดสอบนั้นแตกต่างกัน

รุ่นก่อนหน้า:

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

ดีมาก! และฉันคิดว่าคุณสามารถลดได้ถึง 55 ถ้าคุณใช้!~แทนการปฏิเสธการแสดงออกทั้งหมด
Cristian Lupascu

นั่นคือ regexp ที่สมาร์ท
กำหนด

@ w0lf แน่นอน! ฉันจะไม่คิดอย่างนั้นได้อย่างไร
Howard

5

Python ( 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ในตอนท้ายโดยทั่วไปตรวจสอบว่าสำหรับทุกค่าใน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 's วิธีการแก้ปัญหา :

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

max_byความคิดที่ดีกับ และเวอร์ชั่นใหม่ของคุณเป็นแรงบันดาลใจให้ฉันสำหรับรุ่นที่ใหม่กว่า (และสั้นกว่า)
Howard

@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/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 การใช้ case-insensitive regex เป็นความคิดที่ยอดเยี่ยม! กรุณาโพสต์สิ่งนี้เป็นคำตอบของคุณเอง; ฉันไม่คู่ควรที่จะใช้มัน :)
Cristian Lupascu

@Ventero การ-32แก้ปัญหาก็มีความคิดสร้างสรรค์เช่นกัน แต่ขึ้นอยู่กับความจริงที่ว่าชื่อขึ้นต้นด้วยตัวอักษรตัวพิมพ์ใหญ่และลงท้ายด้วยตัวพิมพ์เล็กซึ่งอาจไม่ใช่ทุกกรณี
Cristian Lupascu

@ w0lf ถูกต้องฉันคิดว่าฉันอ่านรายละเอียดว่ามันจะเป็นกรณี แต่เห็นได้ชัดว่าฉันเข้าใจผิด ;)
Ventero


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นอกจากนี้คุณไม่จำเป็นต้องมี parens ในg[x|x<-c,x/=b]
Lynn

1
@ ลินน์ดีฉันอย่างใดคิดว่าfromEnumจะต้อง ตลกผมเอาวงเล็บเหล่านั้นออกไปแล้วครั้งหนึ่ง แต่ผมจะต้องมีการคัดลอกจากแท็บที่ไม่ถูกต้อง ...
Angs

2

GolfScript, 78 ตัวอักษร

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

รุ่นแรกใน GolfScript นอกจากนี้ยังใช้วิธีการดุร้าย คุณสามารถดูสคริปต์ที่ทำงานบนการป้อนข้อมูลตัวอย่างออนไลน์


2

Huskขนาด 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

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

รันด้วยชื่อประเทศเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

บันทึก:

  • การสร้างแรงแบบไร้เดียงสาของพีชคณิต
  • สำหรับการตรวจสอบจะถือว่าชื่อประเทศขึ้นต้นด้วยตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
  • สมมติว่ามีคำตอบเดียวเท่านั้น
  • ใน C สมมติว่าอาร์เรย์ ** v ของ main () สามารถเขียนได้

ไม่แน่ใจว่ามันถูกต้อง แต่ถ้าคุณทำ#define L(x)for(int i=x;i<n;i++)และไม่ประกาศiที่จุดเริ่มต้นของmainคุณบันทึก 1 ไบต์
Tsathoggua

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

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.