|
1 #!/usr/bin/env python3 |
|
2 def supista_reitti(reitti, kokonainen = False): |
|
3 if not reitti: |
|
4 return '' |
|
5 kunnat = {'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki'} |
|
6 replacements = { |
|
7 "Ylioppilaskylä-Itä": "Ylioppilaskylä", |
|
8 "Ylioppilaskylä-Länsi": "Ylioppilaskylä", |
|
9 "Caribia": "Ylioppilaskylä", |
|
10 "Jokila": "Lieto", |
|
11 "Piispala": "Lieto", |
|
12 'Saaro': 'Ruissalo', |
|
13 'Silvola': 'Vahto', |
|
14 'Hemmola': 'Vahto', |
|
15 'Paasniittu': 'Ruskon keskusta', |
|
16 'Kahari': 'Ruskon keskusta', |
|
17 } |
|
18 have_already = set() |
|
19 i = 0 |
|
20 while i < len(reitti): |
|
21 if reitti[i] in replacements: |
|
22 reitti[i] = replacements[reitti[i]] |
|
23 if reitti[i] in have_already: |
|
24 del reitti[i] |
|
25 else: |
|
26 have_already.add(reitti[i]) |
|
27 i += 1 |
|
28 prioriteetit = { |
|
29 'Ihala': 150, |
|
30 'Kauppakeskus Mylly': 200, |
|
31 'Kuninkoja': 80, |
|
32 'Moikoinen': 50, |
|
33 'Raision keskusta': 100, |
|
34 'Friskala': 30, |
|
35 'Kukola': 50, |
|
36 'Kaistarniemi': 50, |
|
37 'Papinsaari': 50, |
|
38 'Oriniemi': 50, |
|
39 'Pikisaari': 50, |
|
40 'Häppilä': 50, |
|
41 'Haarla': 50, |
|
42 'Ylioppilaskylä': 50, |
|
43 'Halinen': 70, |
|
44 'Kakskerta': 50, |
|
45 'Pansio': 50, |
|
46 'Räntämäki': 10, |
|
47 'Verkahovi': 20, |
|
48 'Skanssi': 200, |
|
49 'Vaala': 20, |
|
50 'Varissuo': 60, |
|
51 'Kohmo': 80, |
|
52 'Kupittaa': 70, |
|
53 'Kauppatori': 1e15, |
|
54 'Lentoasema': 50, |
|
55 'Runosmäki': 50, |
|
56 'Lieto': 100, |
|
57 'Liedon asemanseutu': 200, |
|
58 'Ilmarinen': 100, |
|
59 'Vahto': 50, |
|
60 'Ruskon keskusta': 200, |
|
61 'Oriketo': 50, |
|
62 'Harittu': 40, |
|
63 'Jäkärlä': 50, |
|
64 'Paattinen': 100, |
|
65 'Kaarinan keskusta': 200, |
|
66 'Naantalin keskusta': 200, |
|
67 'Uittamo': 50, |
|
68 'Piikkiö': 40, |
|
69 'Paimio': 50, |
|
70 'Pargas': 50, |
|
71 'Yli-Maaria': 50, |
|
72 'Saramäki': 50, |
|
73 'Tarvasjoki': 100, |
|
74 'Marttila': 100, |
|
75 'Koski Tl': 100, |
|
76 'Katariina': 50, |
|
77 'Länsikeskus': 50, |
|
78 'Kaanaa': 100, |
|
79 'Satava': 50, |
|
80 } |
|
81 |
|
82 if 'Kauppatori' not in reitti: |
|
83 prioriteetit['Länsikeskus'] = prioriteetit['Skanssi'] = prioriteetit['Kauppatori'] |
|
84 |
|
85 # nimiä joista voidaan joustaa tarvittaessa |
|
86 helpot_supistukset = { |
|
87 'Raision keskusta': 'Raisio', |
|
88 'Ruskon keskusta': 'Rusko', |
|
89 'Naantalin keskusta': 'Naantali', |
|
90 'Kaarinan keskusta': 'Kaarina', |
|
91 'Liedon asemanseutu': 'Lieto as.', |
|
92 'Kauppakeskus Mylly': 'Mylly', |
|
93 } |
|
94 |
|
95 # jos ei nyt millään vaan mahdu muuten... |
|
96 vakavat_supistukset = { |
|
97 'Kauppatori': 'Tori', |
|
98 'Ylioppilaskylä': 'Yo-kylä', |
|
99 } |
|
100 |
|
101 lähtö = reitti[0] |
|
102 määränpää = reitti[-1] |
|
103 reitti_arvot = {} |
|
104 f = lambda i: i**-0.6 |
|
105 jakaja = max(f(i + 1) for i in range(len(reitti))) |
|
106 for i, pysäkki in enumerate(reitti): |
|
107 # muunna indeksi siten että myöhemmät alueet korostuvat |
|
108 i = f(i + 1) / jakaja |
|
109 # ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset |
|
110 i *= prioriteetit.get(pysäkki, 1) |
|
111 reitti_arvot[pysäkki] = i |
|
112 # nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin |
|
113 if lähtö in reitti_arvot: |
|
114 reitti_arvot[lähtö] = 0 |
|
115 # varmista että määränpää tulee kylttiin |
|
116 reitti_arvot[määränpää] = 1e10 |
|
117 # muodosta kyltti-tiedot järjestettynä reittiarvon mukaan |
|
118 painot = sorted([ |
|
119 (pysäkki, reitti_arvot[pysäkki], i) \ |
|
120 for i, pysäkki in enumerate(reitti) \ |
|
121 if reitti_arvot[pysäkki] >= 1 |
|
122 ], key = lambda pysäkki: -pysäkki[1]) |
|
123 # enintään neljä tulee kylttiin |
|
124 painot = painot[:4] |
|
125 # jos neljäs kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan neljäs pois |
|
126 if len(painot) == 4 and painot[3][0] != määränpää and painot[3][1] < (4000 / len(reitti) ** 1.5): |
|
127 del painot[3] |
|
128 # sama kolmannelle |
|
129 if len(painot) == 3 and painot[2][0] != määränpää and painot[2][1] < (500 / len(reitti) ** 1.5): |
|
130 del painot[2] |
|
131 if len(painot) == 2 and painot[1][0] != määränpää and painot[1][1] < (100 / len(reitti) ** 1.5): |
|
132 del painot[1] |
|
133 # lajitellaan painoarvot uudestaan reittijärjestykseen jotta kyltti tulee oikeinpäin |
|
134 painot = sorted(painot, key = lambda paino: paino[2]) |
|
135 # muodostetaan kyltti.. |
|
136 kyltti = [paino[0] for paino in painot] |
|
137 |
|
138 # supista nimet jos mahdollista |
|
139 def viimeistele(kyltti, supistus_taso = 0): |
|
140 if supistus_taso > 0: |
|
141 kyltti = [helpot_supistukset.get(paikka, paikka) for paikka in kyltti] |
|
142 if supistus_taso > 1: |
|
143 kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti] |
|
144 return kyltti |
|
145 tulos = viimeistele(kyltti) |
|
146 if len(' - '.join(kyltti)) > 20: |
|
147 tulos = viimeistele(kyltti, supistus_taso = 1) |
|
148 if len(' - '.join(kyltti)) > 70: |
|
149 tulos = viimeistele(kyltti, supistus_taso = 2) |
|
150 if kokonainen: |
|
151 tulos = [lähtö] + tulos |
|
152 lyhyt_lähtö = replacements.get(lähtö, lähtö) |
|
153 if lyhyt_lähtö != tulos[-1] and helpot_supistukset.get(lyhyt_lähtö, lyhyt_lähtö) in kunnat | {'Kauppatori'} and tulos[-1] in kunnat | {'Kauppatori'}: |
|
154 tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos] |
|
155 return tulos |