P2 - 2021/22 - DN08 Poleti v Planici - resitev Aljaz Starc¶
Vsebina | Download link |
---|---|
Viri za vse teste | viri.zip |
Source resene naloge | DN08.java |
Naloga na eucilnici | ucilnica.fri.uni-lj.si |
Prepping for shitstorm¶
Vsi razni importi¶
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Entity classes¶
Ker se naloga vlece tja v en dan sem si zelel, vsaj na dolg rok, poenostavit situacijo. Zato sem si naredil class
-e za vsak ti. entity.
Tekmovalec¶
class Tekmovalec {
public int bib;
public String fullname;
public String club;
public String birthdate;
public String country;
/**
*
* @param bib - id tekmovalca
* @param fullname - polno ime tekmovalca
* @param club - ime kluba
* @param birthdate - tekmovalcev datum rostva
* @param country - drzava
*/
public Tekmovalec (int bib, String fullname, String club, String birthdate, String country) {
this.bib = bib;
this.fullname = fullname;
this.club = club;
this.birthdate = birthdate;
this.country = country;
}
/**
* Get a player result from a provided list of results
*
* @param results - lista razultatov iz katere naj izlocimo tekmovalcev rezultat
* @return tekmovalcev rezultat
*/
public Result getResultFrom (ArrayList<Result> results) {
// https://www.baeldung.com/find-list-element-java#5-java-8-stream-api
return results.stream().filter(res -> res.bib == this.bib).findAny().orElse(null);
}
/**
* Get a player Mark from a provided list of marks
*
* @param marks - lista tock iz katere naj izlocimo tekmovalceve ocene
* @return tekmovalceve ocene
*/
public Mark getMarkFrom (ArrayList<Mark> marks) {
return marks.stream().filter(mark -> mark.bib == this.bib).findAny().orElse(null);
}
/**
* Get points from given list of Mark objects
* if -1.0 the player was disqualified
* if 0.0 there is no Mark in given ArrayList
*
* @param marks
* @return
*/
public Double getPointsFrom (ArrayList<Mark> marks) {
Mark mark = this.getMarkFrom(marks);
if (mark == null) return 0.0;
return mark.getPoints();
}
/**
* Get formatted string of points in given ArrayList
* if disqualified, retuns "DSQ "
* if Mark not in list, returns " - "
* else returns the value formatted to ###.#
*
* @param marks
* @return
*/
public String getPointStrFrom (ArrayList<Mark> marks) {
Double points = this.getPointsFrom(marks);
if (points == -1.0) return "DSQ ";
else if (points == 0.0) return " - ";
else return String.format("%5.1f", points);
}
/**
* Returns the calculated sum of points from both, first and second round.
* invluding the ramp, wind and other compensations
*
* @param marks1
* @param marks2
* @return
*/
public Double getTotalPoints (ArrayList<Mark> marks1, ArrayList<Mark> marks2) {
Double ptotal = 0.0;
Double p1 = this.getPointsFrom(marks1);
if (p1 != null && p1 > 0) ptotal += p1;
Double p2 = this.getPointsFrom(marks2);
if (p2 != null && p2 > 0) ptotal += p2;
return ptotal;
}
public java.util.Date getBirthdayDate () throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy");
return formatter.parse(this.birthdate.replace("SEP", "SEPT"));
}
}
Result - rezultat¶
class Result {
public Integer bib;
public Double speed;
public Double distance;
public Integer gate;
public Double jump_points;
public Double wind_mps;
public Double wind_points;
public Boolean disqalified;
public ArrayList<Mark> marks;
/**
*
* @param bib - id tekmovalca
* @param speed - hitrost skoka
* @param distance - dolzina skoka
* @param gate - ID vrat od koder je skakalec skocil
* @param jump_points - pridobljene tocne
* @param wind_mps - hitrost vetra
* @param wind_points - modifikacija tock na podlagi hitrosti vetra
* @param disqalified
* @param marks - lista ocen iste serije kot ta rezultat
*/
public Result (int bib, double speed, double distance, int gate, double jump_points, double wind_mps, double wind_points, Boolean disqalified, ArrayList<Mark> marks) {
this.bib = bib;
this.speed = speed;
this.distance = distance;
this.gate = gate;
this.jump_points = jump_points;
this.wind_mps = wind_mps;
this.wind_points = wind_points;
this.disqalified = disqalified;
this.marks = marks;
}
/**
* Get a player Mark for this result
*
* @return tekmovalceve ocene
*/
public Mark getMark() {
return this.marks.stream().filter(mark -> mark.bib == this.bib).findAny().orElse(null);
}
}
Mark - ocene¶
class Mark {
public Integer bib;
public Double a;
public Double b;
public Double c;
public Double d;
public Double e;
public Boolean disqualified;
private ArrayList<Result> results;
/**
*
* @param bib - id tekmovalca
* @param a - ocena sodnika a
* @param b - ocena sodnika b
* @param c - ocena sodnika c
* @param d - ocena sodnika d
* @param e - ocena sodnika
* @param results - lista rezultatov iste serije kot ta Mark
* e
*/
public Mark (Integer bib, Double a, Double b, Double c, Double d, Double e, Boolean disqualified, ArrayList<Result> results) {
this.bib = bib;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.disqualified = disqualified;
this.results = results;
}
/**
* Get Result of this Mark
*
* @return tekmovalceve ocene
*/
public Result getResult () {
return this.results.stream().filter(r -> r.bib == this.bib).findAny().orElse(null);
}
/**
* Get the sum of points, without the max and min ones
*
* If there is no result linked to this Mark, returns 0.0
* If disqualified, returns -1.0
*
* @return
*/
public Double getPoints () {
Result r = this.getResult();
if (r == null) return 0.0;
if (r.disqalified) return -1.0;
Double finalPoints = DN08.FLYING_HILL_POINTS + 0.0;
finalPoints += (r.distance - DN08.K_POINT) * DN08.METER_VALUE + r.jump_points + r.wind_points;
ArrayList<Double> ocene = new ArrayList<Double>(Arrays.asList(this.a, this.b, this.c, this.d, this.e));
Collections.sort(ocene);
finalPoints += ocene.stream().skip(1).limit(3).reduce(0.0, Double::sum);
return finalPoints;
}
}
DN08¶
class DN08 {
public static final int K_POINT = 200; // K-tocka letalnice
public static final int FLYING_HILL_POINTS = 120; // stevilo tock za dosezeno K-tocko
public static final double METER_VALUE = 1.2; // faktor za dodatne tocke za vsak meter pod/nad K-tocko
private static ArrayList<Tekmovalec> tekmovalci = new ArrayList<Tekmovalec>();
private static ArrayList<Result> results1st = new ArrayList<Result>();
private static ArrayList<Result> resultsFinal = new ArrayList<Result>();
private static ArrayList<Mark> judMarks1st = new ArrayList<Mark>();
private static ArrayList<Mark> judMarksFinal = new ArrayList<Mark>();
public static void main (String[] a) throws Exception {
if (a.length == 2 && a[0].equals("1")) part1(a[1]);
else if (a.length == 3 && a[0].equals("2")) part2(a[1], a[2]);
else if (a.length == 4 && a[0].equals("3")) part3(a[1], a[2], a[3]);
else if (a.length == 4 && a[0].equals("4")) part4(a[1], a[2], a[3]);
else if (a.length == 6 && a[0].equals("5")) part5(a[1], a[2], a[3], a[4], a[5]);
else if (a.length == 8 && a[0].equals("6")) part6(a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
else if (a.length == 4 && a[0].equals("7")) part7(a[1], a[2], a[3]);
else if (a.length == 4 && a[0].equals("8")) part8(a[1], a[2], a[3]);
}
Helper functions¶
Branje file-ov¶
Ker je blo lepo razvidno, da bo treba pri vsaki nalogi brat iz vsaj ene datoteke - in redundanta koda je zabita, saj se pojavi tu ali tam, a se jo je dobro cimbolj izogibati - sem si spisal funkcijo, kateri podam String filePath
ki predstavlja path do datoteke, in ta mi vrne String[]
array String-ov.
public static String[] readFileToLines (String filePath) throws Exception {
try (Stream<String> linesStream = Files.lines(Paths.get(filePath))) {
List<String> lines = linesStream.collect(Collectors.toList());
return lines.toArray(new String[0]);
}
}
Parsing startne liste¶
public static void loadStartsList (String fileName, ArrayList<Tekmovalec> saveTo) throws Exception {
String[] ls = readFileToLines(fileName);
saveTo.clear();
for (int i = 2; i + 5 <= ls.length; i += 6) {
saveTo.add(new Tekmovalec(Integer.parseInt(ls[i]), ls[i + 1], ls[i + 2], ls[i + 3], ls[i + 4]));
}
}
Parsing liste rezultatov¶
private static void loadResults (
String loadFrom,
ArrayList<Result> saveTo,
ArrayList<Mark> marks
) throws Exception {
saveTo.clear();
Arrays.asList(readFileToLines(loadFrom)).stream().skip(1).forEach((String line) -> {
String[] p = line.split(";");
if (p[1].equals("DSQ")) saveTo.add(new Result(Integer.parseInt(p[0]), 0.0, -1.0, 0, 0.0, 0.0, 0.0, true, marks));
else saveTo.add(new Result(
Integer.parseInt(p[0]),
Double.parseDouble(p[1]),
Double.parseDouble(p[2]),
Integer.parseInt(p[3]),
p[4].equals("") ? 0.0 : Double.parseDouble(p[4]),
Double.parseDouble(p[5]),
Double.parseDouble(p[6]),
false,
marks
));
});
}
Parsing liste tockovanj¶
private static void loadJudMarks (
String loadFrom,
ArrayList<Mark> saveTo,
ArrayList<Result> results
) throws Exception {
saveTo.clear();
Arrays.asList(readFileToLines(loadFrom)).stream().skip(1).forEach((String line) -> {
String[] p = line.split(";");
if (p[1].equals("DSQ")) saveTo.add(new Mark(Integer.parseInt(p[0]), -1.0, -1.0, -1.0, -1.0, -1.0, true, results));
else saveTo.add(new Mark(
Integer.parseInt(p[0]),
Double.parseDouble(p[1]),
Double.parseDouble(p[2]),
Double.parseDouble(p[3]),
Double.parseDouble(p[4]),
Double.parseDouble(p[5]),
false,
results
));
});
}
Zapisovanje podatkov v file¶
Tako kot pri branju iz file-ov, sem si spisal fukcijo kateri podam nekaj parametrov, pot do datoteke, vsebino, ter dolocilo, ki doloca naj bo vrstica append-ana na konec datoteke, ali naj prepise cez trenutno vsebino.
public static void writeToFile(String writeTo, String content, Boolean append) {
try { Files.writeString(Paths.get(writeTo), content + System.lineSeparator(), StandardOpenOption.CREATE, append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING); }
catch (Exception e) { /* EXCEPTION OCCURED, we - the naughty, lazy, bastards that we are - ignore it >:} */ }
}
Naloga 1¶
public static void part1 (String fileName) throws Exception {
loadStartsList(fileName, tekmovalci);
System.out.println("Start List 1st Round:\nBIB NAME (NSA) [DATE OF BIRTH, CLUB]");
for (Tekmovalec t : tekmovalci) System.out.format("%3d %-25s (%s) [%11s, %s]\n", t.bib, t.fullname, t.country, t.birthdate, t.club);
}
Naloga 2¶
public static void part2 (String startFile, String resultsFile) throws Exception {
loadStartsList(startFile, tekmovalci);
loadResults(resultsFile, results1st, judMarks1st);
System.out.println("Results first round:\nBIB NAME (NSA) [DATE OF BIRTH, CLUB] DISTANCE [m]");
for (Tekmovalec t : tekmovalci) {
Result r = t.getResultFrom(results1st);
String p1 = String.format("%3d %-25s (%s) [%11s, %s]", t.bib, t.fullname, t.country, t.birthdate, t.club);
String p2 = r.disqalified ? "Disqualified" : String.format("%5.1f", r.distance);
System.out.format("%-83s %s\n", p1, p2);
}
}
Naloga 3¶
public static void part3 (String startFile, String resultsFile, String resultsFinalFile) throws Exception {
loadStartsList(startFile, tekmovalci);
loadResults(resultsFile, results1st, judMarks1st);
loadResults(resultsFinalFile, resultsFinal, judMarksFinal);
System.out.println("Results final round:\nBIB NAME (NSA) [DATE OF BIRTH, CLUB] DISTANCE [m] (DISTANCE [m])");
for (Tekmovalec t : tekmovalci) {
String p1 = String.format("%3d %-25s (%s) [%11s, %s]", t.bib, t.fullname, t.country, t.birthdate, t.club);
String p2, p3 = "";
Result rFin = t.getResultFrom(resultsFinal);
Result r1st = t.getResultFrom(results1st);
if (rFin == null) p2 = "Not qualified";
else if (rFin.disqalified) p2 = "Disqualified";
else p2 = String.format("%5.1f", rFin.distance);
if (r1st == null) p3 = "";
else if (r1st.disqalified) p2 = "Disqualified";
else p3 = String.format("(%5.1f)", r1st.distance);
System.out.format("%-83s %-13s %s\n", p1, p2, p3);
}
}
Naloga 4¶
public static void part4 (String startFile, String resultsFile, String judgesMarksFile) throws Exception {
loadStartsList(startFile, tekmovalci);
loadResults(resultsFile, results1st, judMarks1st);
loadJudMarks(judgesMarksFile, judMarks1st, results1st);
System.out.println("Points first round:\nBIB NAME (NSA) POINTS");
tekmovalci.forEach(t -> {
System.out.format(
"%3d %-25s (%s) %s\n",
t.bib,
t.fullname,
t.country,
t.getPointStrFrom(judMarks1st)
);
});
}
Naloga 5¶
public static void part5 (
String startFile,
String resultsFile1,
String judgesMarksFile1,
String resultsFile2,
String judgesMarksFile2
) throws Exception {
loadStartsList(startFile, tekmovalci);
loadResults(resultsFile1, results1st, judMarks1st);
loadResults(resultsFile2, resultsFinal, judMarksFinal);
loadJudMarks(judgesMarksFile1, judMarks1st, results1st);
loadJudMarks(judgesMarksFile2, judMarksFinal, resultsFinal);
System.out.println("Points final round:\nBIB NAME (NSA) POINTS (1st) POINTS (final) TOTAL");
tekmovalci.forEach(t -> {
System.out.format(
"%3d %-25s (%s) %5s %5s %5s\n",
t.bib,
t.fullname,
t.country,
t.getPointStrFrom(judMarks1st),
t.getPointStrFrom(judMarksFinal),
t.getTotalPoints(judMarks1st, judMarksFinal) > 0 ? String.format("%5.1f", t.getTotalPoints(judMarks1st, judMarksFinal)) : " - "
);
});
}
Naloga 6¶
{ insert harmful disease here } od naloge. Bi optimiziral, ce bi imel se kaj volje - a verjamem da vsi vemo da je nihce nima.
public static void part6 (
String start1File,
String res1File,
String judMarks1File,
String res2File,
String judMarks2File,
String izhodStarts,
String izhodResults
) throws Exception {
loadStartsList(start1File, tekmovalci);
loadResults(res1File, results1st, judMarks1st);
loadResults(res2File, resultsFinal, judMarksFinal);
loadJudMarks(judMarks1File, judMarks1st, results1st);
loadJudMarks(judMarks2File, judMarksFinal, resultsFinal);
ArrayList<Tekmovalec> tekmovalciSorted = new ArrayList<Tekmovalec>(tekmovalci);
tekmovalciSorted.sort((Tekmovalec t0, Tekmovalec t1) -> {
Double t0p = t0.getPointsFrom(judMarks1st);
Double t1p = t1.getPointsFrom(judMarks1st);
if (t0p < t1p) return 1;
else if (t0p > t1p) return -1;
else {
Double t0d = t0.getResultFrom(results1st).distance;
Double t1d = t1.getResultFrom(results1st).distance;
if (t0d < t1d) return 1;
if (t0d > t1d) return -1;
else return 0;
}
});
Tekmovalec[] tekms2s = tekmovalciSorted.stream()
.filter((Tekmovalec t) -> !t.getResultFrom(results1st).disqalified)
.limit(30)
.toArray(a -> new Tekmovalec[a]);
ArrayList<String> startsLines = new ArrayList<String>();
int rankPrevious = 1;
for (int i = 0; i < tekms2s.length; i++) {
Tekmovalec t1 = tekms2s[i];
Double points = t1.getPointsFrom(judMarks1st);
int rankNow = points.equals(tekms2s[ i==0 ? 0 : i-1].getPointsFrom(judMarks1st)) ? rankPrevious : i + 1;
rankPrevious = rankNow;
Double behind = tekms2s[0].getPointsFrom(judMarks1st) - points;
startsLines.add(String.format(
"%d;%d;%s;%s;%5.1f;%d;%.1f",
tekms2s.length - i,
t1.bib,
t1.fullname,
t1.country,
points,
rankNow,
behind
));
}
Collections.reverse(startsLines);
writeToFile(izhodStarts, "START ORD.;BIB;NAME;NSA;POINTS;RANK;BEHIND POINTS", false);
startsLines.forEach((String s) -> writeToFile(izhodStarts, s, true));
ArrayList<Tekmovalec> tekSortedByTotal = new ArrayList<Tekmovalec>(tekmovalci);
ArrayList<String> resultsLines = new ArrayList<String>();
Tekmovalec[] resultsTotalTekmovalci = tekSortedByTotal.stream().sorted((Tekmovalec t0, Tekmovalec t1) -> {
Double t0p = t0.getTotalPoints(judMarks1st, judMarksFinal);
Double t1p = t1.getTotalPoints(judMarks1st, judMarksFinal);
if ( t0p < t1p) return 1;
else if (t0p > t1p) return -1;
else {
if (t0p > 0.0) return 0;
if (t0.bib < t1.bib) return 1;
if (t0.bib > t1.bib) return -1;
return 0;
}
}).toArray(a -> new Tekmovalec[a]);
int resultsTotalRankPrev = 1;
for (int i=0; i<resultsTotalTekmovalci.length;i++) {
Tekmovalec t = resultsTotalTekmovalci[i];
Result r1raw = t.getResultFrom(results1st);
Result r2raw = t.getResultFrom(resultsFinal);
String dist1 = "DSQ";
String dist2 = "-";
String points1 = "-";
String points2 = "-";
if (!r1raw.disqalified) {
dist1 = String.format("%.1f", r1raw.distance);
points1 = String.format("%.1f", t.getPointsFrom(judMarks1st));
if (r2raw == null) dist2 = "-";
else if (r2raw.disqalified) dist2 = "DSQ";
else if (!r2raw.disqalified) {
dist2 = String.format("%.1f", r2raw.distance);
points2 = String.format("%.1f", t.getPointsFrom(judMarksFinal));
}
}
Double points = t.getTotalPoints(judMarks1st, judMarksFinal);
int rankNow = points.equals(resultsTotalTekmovalci[ i==0 ? 0 : i-1].getTotalPoints(judMarks1st, judMarksFinal)) ? resultsTotalRankPrev : i + 1;
resultsTotalRankPrev = rankNow;
resultsLines.add(String.format(
"%d;%d;%s;%s;%s;%s;%s;%s;%.1f",
rankNow,
t.bib,
t.fullname,
t.country,
dist1,
dist2,
points1,
points2,
t.getTotalPoints(judMarks1st, judMarksFinal)
));
}
writeToFile(izhodResults, "RANK;BIB;NAME;NSA;DIST-1;DIST-2;POINTS-1;POINTS-2;TOTAL", false);
resultsLines.forEach((String s) -> writeToFile(izhodResults, s, true));
}
Naloga 7¶
public static void part7 (String startFile, String resultsFile, String resultsFinalFile) throws Exception {
loadStartsList(startFile, tekmovalci);
loadResults(resultsFile, results1st, judMarks1st);
loadResults(resultsFinalFile, resultsFinal, judMarksFinal);
List<Tekmovalec> kpointTekmovalci = tekmovalci.stream()
.filter((Tekmovalec t) -> {
try {
if (t.getResultFrom(results1st) != null && (
t.getResultFrom(results1st).distance >= DN08.K_POINT ||
t.getResultFrom(resultsFinal).distance >= DN08.K_POINT
)) return true;
} catch (Exception e) { /* Neomo nc nrdili, ker smo leni :> */ }
return false;
}).sorted((Tekmovalec t0, Tekmovalec t1) -> {
try { return t0.getBirthdayDate().compareTo(t1.getBirthdayDate()) * -1; }
catch (Exception e) { return 0; }
}).collect(Collectors.toList());
if (kpointTekmovalci.size() == 0) { System.out.println("All flights are below K-point."); }
else {
Tekmovalec najmlajsi = kpointTekmovalci.get(0);
kpointTekmovalci.stream()
.filter((Tekmovalec t) -> {
try { return t.getBirthdayDate().equals(najmlajsi.getBirthdayDate()); }
catch (Exception e) { return false; }
})
.map((Tekmovalec t) -> t.fullname)
.forEach(System.out::println);
}
}
Naloga 8¶
public static void part8 (String startFile, String marks1File, String marks2File) throws Exception {
loadStartsList(startFile, tekmovalci);
loadJudMarks(marks1File, judMarks1st, results1st);
loadJudMarks(marks2File, judMarksFinal, resultsFinal);
Mark[] marks = Stream.concat(judMarks1st.stream(), judMarksFinal.stream()).filter((Mark m) -> !m.disqualified).toArray(mark -> new Mark[mark]);
// vem da je nonsense, se da lepse nrdit, se mi trenutno ne da ke imam pun kufr te jave <3
// Imamo 5 itemov (5 sodnikov);
// vsak item ima dva property-ja;
// prvi predstavlja "indeks crke sodnika" (65 + jm[i][0])
// drugi predstavlja sestevek tock
Double[][] jm = new Double[][]{{ 0.0, 0.0 }, { 1.0, 0.0 }, { 2.0, 0.0 }, { 3.0, 0.0 }, { 4.0, 0.0 }};
for (Mark m: marks) {
jm[0][1] += m.a;
jm[1][1] += m.b;
jm[2][1] += m.c;
jm[3][1] += m.d;
jm[4][1] += m.e;
}
Double[] min = Stream.of(jm).sorted((Double[] a0, Double[] a1) -> a0[1].compareTo(a1[1])).findFirst().orElseThrow(IllegalStateException::new);
Double[] max = Stream.of(jm).sorted((Double[] a0, Double[] a1) -> a0[1].compareTo(a1[1]) * -1).findFirst().orElseThrow(IllegalStateException::new);
System.out.format("Best marks: %s (%.1f)\n", (char) (max[0].intValue() + 65), max[1] / marks.length);
System.out.format("Worst marks: %s (%.1f)\n", (char) (min[0].intValue() + 65), min[1] / marks.length);
}
}