Thu, 25 May 2017 16:41:21 +0300
Paljon asioita
5 | 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 |