import java.io.BufferedReader;         // Szövegfájl soronkénti olvasásához
import java.io.IOException;            // Fájlkezelési hibák jelzéséhez; a main ezt továbbadja
import java.nio.charset.StandardCharsets; // Az UTF-8 karakterkódolás megadásához
import java.nio.file.Files;            // Fájl olvasásához szükséges eszközök
import java.nio.file.Paths;            // Fájl elérési útjának megadásához
import java.util.ArrayList;            // Rugalmas méretű listák használatához
import java.util.Scanner;              // Input műveletekhez
import java.util.Locale;               // Tizedesvessző helyett tizedespontot szerenék, ezért kell

// C++ megoldással analóg megoldás!
public class sebesseg {
    public static void main(String args[]) throws IOException {
        ArrayList<adat> ADATOK = new ArrayList<>();

        try (BufferedReader FBE = Files.newBufferedReader(Paths.get("ut.txt"), StandardCharsets.UTF_8)) {
            // 1. feladat - adatok beolvasása --> CLASS használattal oldjuk meg
            // Első sor beolvasása
            String sor;
            sor = FBE.readLine();
            int hossz = Integer.parseInt(sor);
            // További sorok beolvasása
            while ((sor = FBE.readLine()) != null) {
                sor = sor.trim();

                if (!sor.isEmpty()) {
                    String[] mezok = sor.split("\\s+");
                    int tavolsag = Integer.parseInt(mezok[0]);
                    String info = mezok[1];
                    ADATOK.add(new adat(tavolsag, info));
                }
            }
            // ---------------------------------------------------------------------------
            // 2. Írja ki az úton található települések nevét! Minden település neve új sorban jelenjen meg!
            System.out.println("2. feladat");
            System.out.println("A telepulesek neve:");
            for (adat Adat : ADATOK) {
                if (Adat.info.length() > 3) {
                    System.out.println(Adat.info);
                }
            }
            // ---------------------------------------------------------------------------
            // 3. Távolság bekérése: ezen a távon mi volt a legalacsonyabb sebességhatár
            System.out.println("3. feladat");
            Scanner scanner = new Scanner(System.in);
            scanner.useLocale(Locale.US);               // tizedespontra térek át
            System.out.print("Adja meg a vizsgalt szakasz hosszat km-ben! ");
            double km = scanner.nextDouble();
            double meter = km * 1000;
            int MINIMUM = 90;
            boolean varosban = false;   // 5. feladatban is használjuk
            String info;                // 5. és 6. feladatban is használjuk
            int S = 0;
            for (adat Adat : ADATOK) {
                info = Adat.info;
                if (Adat.tavolsag < meter) {
                    int SebessegTabla = csakszamok(info);
                    if (SebessegTabla > -1) S = SebessegTabla;       // stoi - string to integer
                    if (info.length() > 3) {
                        varosban = true;
                        S = 50;
                    }
                    if ("]".equals(Adat.info)) {
                        varosban = false;
                        S = 90;
                    }
                    if ("#".equals(Adat.info) || "%".equals(Adat.info)) {
                        S = varosban ? 50 : 90;
                    }
                    if (S < MINIMUM) MINIMUM = S;
                }
            }
            System.out.printf("Az elso %.2f km-en %d km/h volt a legalacsonyabb megengedett sebesseg.%n", km, MINIMUM);
            // ---------------------------------------------------------------------------
            // 4. Az út hány %-a vezet városon keresztül?
            System.out.println("4. feladat");
            int VarosonKeresztul = 0;
            int start = 0;                          // 5. és 6. feladatban is használjuk
            int vege = 0;                           // 5. és 6. feladatban is használjuk
            for (adat Adat: ADATOK) {                
                if (Adat.info.length() > 3) {
                    // városba érünk
                    start = Adat.tavolsag;
                    
                }
                if ("]".equals(Adat.info)) {
                    vege = Adat.tavolsag;
                    VarosonKeresztul += (vege - start);
                }
            }
            double Szazalek = ((double) VarosonKeresztul / (double) hossz) * 100;
            System.out.printf("Az ut %.2f szazaleka vezet telepulesen belul.%n", Szazalek);
            // ---------------------------------------------------------------------------
            // 5. Egy adott településen hány korlátozás van, és milyen hossz a település
            System.out.println("5. feladat");
            System.out.print("Adja meg egy telepules nevet! ");
            scanner = new Scanner(System.in);
            String VAROS = scanner.nextLine();
            int db = 0, VarosHossz = 0;
            varosban = false;
            for (adat Adat : ADATOK) {
                info = Adat.info;
                if (info.equals(VAROS)) {
                    start = Adat.tavolsag;
                    varosban = true;
                }
                if(csakszamok(info) > -1 && varosban) db++;
                if(info.equals("]") && varosban) {
                    vege = Adat.tavolsag;
                    break;
                }
            }
            VarosHossz = vege - start;
            System.out.printf("A sebessegkorlatozo tablak szama: %d%n", db);
            System.out.printf("Az ut hossza a telepulesen belul %d meter.%n", VarosHossz);
            // ---------------------------------------------------------------------------
            // 6. Az előzőleg megadott településhez legközelebbi település neve
            System.out.println("6. feladat");
            ArrayList<varosInfo> VAROSOK = new ArrayList<>();
            String LegkozelebbiVaros;
            String varosnev = "";
            for (adat Adat : ADATOK) {
                info = Adat.info;
                if(info.length() > 3) {
                    varosnev = info;
                    start = Adat.tavolsag;
                }
                if ("]".equals(info)) {
                    vege = Adat.tavolsag;
                    VAROSOK.add(new varosInfo(varosnev, start, vege));
                }
            }
            int index = 0;
            varosInfo varosInfok, ElozoVarosInfok, KovetkezoVarosInfok;
            for (int i = 0; i < VAROSOK.size(); i++) {
                varosInfok = VAROSOK.get(i);
                if (VAROS.equals(varosInfok.varosNev)) {
                    index = i;
                    break;
                }
            }
            if (index == 0) {
                // első várost adtuk meg
                varosInfok = VAROSOK.get(index + 1);
                LegkozelebbiVaros = varosInfok.varosNev;
            }
            else if(index == (VAROSOK.size() - 1)) {
                // utolsó várost adtuk meg
                varosInfok = VAROSOK.get(index - 1);
                LegkozelebbiVaros = varosInfok.varosNev;
            }
            else {
                // "belső" várost adtunk meg
                varosInfok = VAROSOK.get(index);
                ElozoVarosInfok = VAROSOK.get(index - 1);
                KovetkezoVarosInfok = VAROSOK.get(index + 1);
                int elozo = varosInfok.k - ElozoVarosInfok.v;
                int kovetkezo = KovetkezoVarosInfok.k - varosInfok.v;
                LegkozelebbiVaros = (elozo <= kovetkezo) ? ElozoVarosInfok.varosNev : KovetkezoVarosInfok.varosNev;
            }
            System.out.printf("A legkozelebbi telepules: %s%n", LegkozelebbiVaros);
        }
        
        // Beolvasott adatok kiírása
        // for (adat Adat : ADATOK) {
        //    System.out.println(Adat);
        // }
    }
    // Saját függvény
    static int csakszamok(String szoveg) {
        try {
            return Integer.parseInt(szoveg.trim());
        } catch (NumberFormatException e) {
            return -1;
        }
    }
}

class adat {
    int tavolsag;
    String info;

    adat(int tavolsag, String info) {
        this.tavolsag = tavolsag;
        this.info = info;
    }

    public String toString() {
        return tavolsag + " " + info;
    }
}

class varosInfo {
    String varosNev;
    int k;
    int v;
    
    varosInfo(String varosNev, int k, int v) {
        this.varosNev = varosNev;
        this.k = k;
        this.v = v;
    }
    
    public String toString() {
        return varosNev + " " + k + " " + v;
    }
}

