From 0eb4a53b68c6d41c58896a13c35e56a3a26dfcba Mon Sep 17 00:00:00 2001 From: tripparsugo Date: Sun, 6 Nov 2022 19:31:47 +0100 Subject: [PATCH] ex3 --- hw2/.idea/.gitignore | 8 + hw2/.idea/hw2.iml | 9 + hw2/.idea/modules.xml | 8 + hw2/.idea/vcs.xml | 6 + hw3/code/Assignment3.iml | 13 + .../src/main/java/ch/usi/inf/ajp22/Album.java | 18 +- .../src/main/java/ch/usi/inf/ajp22/Main.java | 228 +++++++++++------- .../classes/ch/usi/inf/ajp22/Album.class | Bin 0 -> 3989 bytes .../classes/ch/usi/inf/ajp22/Artist.class | Bin 0 -> 912 bytes .../classes/ch/usi/inf/ajp22/Main.class | Bin 0 -> 17554 bytes .../classes/ch/usi/inf/ajp22/SampleData.class | Bin 0 -> 3123 bytes .../ch/usi/inf/ajp22/Track$Genre.class | Bin 0 -> 1267 bytes .../classes/ch/usi/inf/ajp22/Track.class | Bin 0 -> 2516 bytes 13 files changed, 206 insertions(+), 84 deletions(-) create mode 100644 hw2/.idea/.gitignore create mode 100644 hw2/.idea/hw2.iml create mode 100644 hw2/.idea/modules.xml create mode 100644 hw2/.idea/vcs.xml create mode 100644 hw3/code/Assignment3.iml create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/Album.class create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/Artist.class create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/Main.class create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/SampleData.class create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/Track$Genre.class create mode 100644 hw3/code/target/classes/ch/usi/inf/ajp22/Track.class diff --git a/hw2/.idea/.gitignore b/hw2/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/hw2/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/hw2/.idea/hw2.iml b/hw2/.idea/hw2.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/hw2/.idea/hw2.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/hw2/.idea/modules.xml b/hw2/.idea/modules.xml new file mode 100644 index 0000000..b3c4100 --- /dev/null +++ b/hw2/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/hw2/.idea/vcs.xml b/hw2/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/hw2/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/hw3/code/Assignment3.iml b/hw3/code/Assignment3.iml new file mode 100644 index 0000000..1f742ef --- /dev/null +++ b/hw3/code/Assignment3.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw3/code/src/main/java/ch/usi/inf/ajp22/Album.java b/hw3/code/src/main/java/ch/usi/inf/ajp22/Album.java index 809bb9e..6da28a6 100644 --- a/hw3/code/src/main/java/ch/usi/inf/ajp22/Album.java +++ b/hw3/code/src/main/java/ch/usi/inf/ajp22/Album.java @@ -3,6 +3,7 @@ package ch.usi.inf.ajp22; import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; public class Album { @@ -44,19 +45,30 @@ public class Album { /** * 3 Points - * TODO: create a public Optional method called "searchLongestSong" that - * return the longest Track in the album. + * create a public Optional method called "searchLongestSong" that + * return the longest Track on the album. * input: void * output: an Optional */ + public Optional searchLongestSong() { + return this.tracks.stream() + .max(Comparator.comparingInt(Track::getLength)); + } /** * 3 Points - * TODO: create a public List method called "orderSongByTitle" that + * create a public List method called "orderSongByTitle" that * return the track list ordered lexicographically using the title field. * input: void * output: a List */ + public List orderSongByTitle() { + // note: we assume lexicographical order requires letter case to be ignored + return this.tracks.stream() + .sorted((a, b) -> String.CASE_INSENSITIVE_ORDER.compare(a.getTitle(), b.getTitle())) + .collect(Collectors.toList()); + } + @Override public String toString() { diff --git a/hw3/code/src/main/java/ch/usi/inf/ajp22/Main.java b/hw3/code/src/main/java/ch/usi/inf/ajp22/Main.java index 3fab808..f9bdb15 100644 --- a/hw3/code/src/main/java/ch/usi/inf/ajp22/Main.java +++ b/hw3/code/src/main/java/ch/usi/inf/ajp22/Main.java @@ -5,136 +5,197 @@ import java.io.FileWriter; import java.io.IOException; import java.time.LocalDate; import java.util.*; -import java.util.function.BiFunction; -import java.util.function.BinaryOperator; -import java.util.function.IntFunction; -import java.util.function.Predicate; +import java.util.function.*; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; public class Main { /** * 3 Points - * TODO: create a public static Album method called "longestTitle". - * If the maximum is not found throw a RuntimeException. - * input: a list of Album - * output: the Album with the longest title. + * create a public static Album method called "longestTitle". + * If the maximum is not found throw a RuntimeException. + * input: a list of Album + * output: the Album with the longest title. */ + public static Album longestTitle(List albums) { + return albums.stream() + .max(Comparator.comparingDouble(a -> a.getTitle().length())) + .orElseThrow(RuntimeException::new); + } + /** * 4 Points - * TODO: create a public static int method called "sumOfRatingReduce". - * input: an Album instance. - * output: int that is the sum of all the tracks ratings in the album. + * create a public static int method called "sumOfRatingReduce". + * input: an Album instance. + * output: int that is the sum of all the tracks ratings on the album. * Use the method getTracks from the Album class to get the List of tracks. * You MUST use the reduce method, in the variant which takes as input an identity, an accumulator and a combiner. * If possible use method references. */ + public static int sumOfRatingReduce(Album album) { + return album.getTracks().stream() + .map(Track::getLength) + .reduce(0, Integer::sum, Integer::sum); + } /** * 4 Points - * TODO: create a public static int method called "sumOfRatingCollection". - * input: an Album instance. - * output: int that is the sum of all the tracks ratings in the album + * create a public static int method called "sumOfRatingCollection". + * input: an Album instance. + * output: int that is the sum of all the tracks ratings on the album * Use the method getTracks from the Album class to get the List of tracks. * You MUST use one variant of the collect method. If possible use method references. */ + public static int sumOfRatingCollection(Album album) { + //noinspection SimplifyStreamApiCallChains + return album.getTracks().stream().map(Track::getRating) + .collect(Collectors.reducing(0, Integer::sum)); + } + /** * 4 Points - * TODO: create a public static int method called "sumOfRatingMap" - * input: an ch.usi.inf.ajp22.Album instance. - * output: int that is the sum of all the tracks ratings in the album. + * create a public static int method called "sumOfRatingMap" + * input: a ch.usi.inf.ajp22.Album instance. + * output: int that is the sum of all the tracks ratings on the album. * Use the method getTracks from the Album class to get the List of tracks. * You MUST use the mapToInt method. If possible use method references. */ + public static int sumOfRatingMap(Album album) { + return album.getTracks().stream().mapToInt(Track::getRating).sum(); + } /** * 4 Points - * TODO: create a public static Map method called "countTrackOccurrence" - * input: a list of Track - * output: a Map where the key is the track title and the value is, how many times - * the same song occurs in the list. - * Two songs can be considered the same if they have the same title. + * create a public static Map method called "countTrackOccurrence" + * input: a list of Track + * output: a Map where the key is the track title and the value is, how many times + * the same song occurs in the list. + * Two songs can be considered the same if they have the same title. */ + public static Map countTrackOccurrence(List tracks) { + return tracks.stream().collect(Collectors.groupingBy(Track::getTitle, Collectors.counting())); + } /** * 4 Points - * TODO: create a public static Map> method called "groupAlbumByArtist". - * input: a list of Album - * output: a Map> where the key is an Artist and the value is a List of Album which - * this artist had produced. + * create a public static Map> method called "groupAlbumByArtist". + * input: a list of Album + * output: a Map> where the key is an Artist and the value is a List of Album which + * this artist had produced. */ + public static Map> groupAlbumByArtist(List albums) { + return albums.stream().collect(Collectors.groupingBy(Album::getArtist, Collectors.toList())); + } /** * 4 Points - * TODO: create a public static List method called "trackFilteredWithPredicate". - * input: a stream of tracks and a predicate to apply to the track stream. - * output: a List of Track that has been filtered according to the predicate taken as input. + * create a public static List method called "trackFilteredWithPredicate". + * input: a stream of tracks and a predicate to apply to the track stream. + * output: a List of Track that has been filtered according to the predicate taken as input. */ + public static List trackFilteredWithPredicate(Stream tracks, Predicate predicate) { + return tracks.filter(predicate).collect(Collectors.toList()); + } /** * 5 Points - * TODO: create a public static Stream method called getAlbumWithAtLeastNTracks - * input: a list of Album AND an int called "n" - * output: a List where every album in this stream has at least "n" tracks. + * create a public static Stream method called getAlbumWithAtLeastNTracks + * input: a list of Album AND an int called "n" + * output: a List where every album in this stream has at least "n" tracks. */ + public static Stream getAlbumWithAtLeastNTracks(List albums, int n) { + return albums.stream().filter(a -> a.getTracks().size() >= n); + } /** * 5 Points - * TODO: create a public static void method called "printTrackStatistics". - * input: an Album instance + * create a public static void method called "printTrackStatistics". + * input: an Album instance * Print Track Statistics based on the length of the tracks of an album taken as input in the following format: * === - * "Stat for: %s\n", album.getTitle()) + * "Stat for: %s\n", album.getTitle() * "Max: %d\nMin: %d\nAve: %f\n" * === * Use the method getTracks from the Album class to get the List of tracks. * Input: an Album */ + public static void printTrackStatistics(Album album) { + final Supplier tracksStreamSupplier = () -> album.getTracks().stream().mapToInt(Track::getLength); + final Supplier whenZero = () -> { + throw new IllegalArgumentException("Album has no tracks"); + }; + + System.out.printf("===\nStat for: %s\nMax: %d\nMin: %d\nAve: %f\n===\n", + album.getTitle(), + tracksStreamSupplier.get().max().orElseThrow(whenZero), + tracksStreamSupplier.get().min().orElseThrow(whenZero), + tracksStreamSupplier.get().average().orElseThrow(whenZero)); + } /** * 5 Points - * TODO: create a public static String method called "getArtistNameAndNickNameFromAlbum". - * Each author should appear only once. - * input: a list of Album - * output: a String in the following format: - * [artist1.name - artist1.nickname, artist2.name - artist2.nickname, ...] + * create a public static String method called "getArtistNameAndNickNameFromAlbum". + * Each author should appear only once. + * input: a list of Album + * output: a String in the following format: + * [artist1.name - artist1.nickname, artist2.name - artist2.nickname, ...] */ + public static String getArtistNameAndNickNameFromAlbum(List albums) { + return albums.stream().map(Album::getArtist).distinct() + .map(a -> String.format("%s - %s", a.getName(), a.getNickname())) + .collect(Collectors.joining(",", "[", "]")); + } /** * 5 Points - * TODO: create a public Track method called "combineAllTrackInAlbum" - * input: a stream of track - * output: return a new ch.usi.inf.ajp22.Track with the following values: - * title -> "fake title" - * releaseDate -> LocaleDate.now() - * genre -> DISCO - * length -> the sum of all the lengths in the input track stream. - * The pipeline processing must be done in parallel. - * You MUST use the collect method, in the variant which takes as input a supplier, an accumulator and a - * combiner. + * create a public Track method called "combineAllTrackInAlbum" + * input: a stream of track + * output: return a new ch.usi.inf.ajp22.Track with the following values: + * title -> "fake title" + * releaseDate -> LocaleDate.now() + * genre -> DISCO + * length -> the sum of all the lengths in the input track stream. + * The pipeline processing must be done in parallel. + * You MUST use the collect method, in the variant which takes as input a supplier, an accumulator and a + * combiner. */ + public static Track combineAllTrackInAlbum(Stream tracks) { + return tracks.parallel().collect( + () -> new Track("fake title", LocalDate.now(), Track.Genre.DISCO, 0), + (acc, track) -> acc.setLength(acc.getLength() + track.getLength()), + (acc, other) -> acc.setLength(acc.getLength() + other.getLength())); + } /** * 5 Points - * TODO: create a public static Map> method called "groupTrackByArtist". - * input: a list of Album - * output: a Map> where the key is an Artist and the value is a List of Track which - * this artist had produced. + * create a public static Map> method called "groupTrackByArtist". + * input: a list of Album + * output: a Map> where the key is an Artist and the value is a List of Track which + * this artist had produced. */ + public static Map> groupTrackByArtist(List albums) { + return albums.stream().collect( + Collectors.groupingBy( + Album::getArtist, + Collectors.flatMapping(a -> a.getTracks().stream(), Collectors.toList()))); + } /** * 5 Bonus Points - * TODO: create a public static T[] method called "createArray". - * This method must create a generic array where the elements are in the same order as in the - * input Collection. - * In this function you need neither streams nor lambda. - * input: a Collection and an IntFunction - * output: an array of generic type + * create a public static T[] method called "createArray". + * This method must create a generic array where the elements are in the same order as in the + * input Collection. + * In this function you need neither streams nor lambda. + * input: a Collection and an IntFunction + * output: an array of generic type */ - + public static T[] createArray(Collection collection, IntFunction generator) { + return collection.toArray(generator); + } private static void writeToFile(String s) throws IOException { BufferedWriter fw = new BufferedWriter(new FileWriter("artist.txt", true)); @@ -145,46 +206,51 @@ public class Main { public static void main(String[] args) { Random random = new Random(); - /** + /* * Initializing some SampleData */ SampleData.appetiteForDestruction - .getTracks().forEach(track -> + .getTracks().forEach(track -> track.setRating(random.nextInt(5))); SampleData.randomAccessMemories - .getTracks().forEach(track -> + .getTracks().forEach(track -> track.setRating(random.nextInt(5))); - /** + /* * 2 Points - * TODO: Replace the Anonymous class below with a lambda expression. + * Replace the Anonymous class below with a lambda expression. */ - BinaryOperator mixTrack = new BinaryOperator<>() { - @Override - public Track apply(Track t1, Track t2) { - return new Track(t1.getTitle(), - t1.getReleasedDate(), - t2.getGenre(), - t2.getLength()); - } - }; + BinaryOperator mixTrack = (t1, t2) -> new Track(t1.getTitle(), + t1.getReleasedDate(), + t2.getGenre(), + t2.getLength()); - /** + /* * 3 Points - * TODO: Create a stream pipeline that: + * Create a stream pipeline that: * 1) filter all the tracks that have at least 4 as rating * 2) sort the filtered tracks using the title field * 3) print the tracks */ + SampleData.getShuffledTrack().stream().filter(t -> t.getRating() >= 4) + .sorted(Comparator.comparing(Track::getTitle)) + .forEach(System.out::println); - /** + /* * 4 Points - * TODO: Print on file the artist's name, obtained with the method SampleData.getArtistList(), + * Print on file the artist's name, obtained with the method SampleData.getArtistList(), * using the writeToFile method. Use a lambda expression and handle * the throw exception from the writeToFile method. If there is an IOException you must throw a * RuntimeException with the same event. */ + SampleData.getArtistList().stream().map(Artist::getName).forEach(n -> { + try { + writeToFile(n); + } catch (final IOException e) { + throw new RuntimeException(e); + } + }); System.out.printf("Longest track in %s is %s\n", SampleData.appetiteForDestruction.getTitle(), @@ -229,13 +295,13 @@ public class Main { Map> artistListMap1 = groupTrackByArtist(SampleData.getAlbumList()); for (Map.Entry> entry : artistListMap1.entrySet()) { System.out.println("ch.usi.inf.ajp22.Artist: " + entry.getKey().getName()); - for (Track track: entry.getValue()) { + for (Track track : entry.getValue()) { System.out.println("\t" + track.toString()); } } List trackPOPinGuns = trackFilteredWithPredicate(SampleData.appetiteForDestruction.getTracks().stream() - ,(t -> !t.getGenre().equals(Track.Genre.HIP_HOP))); + , (t -> !t.getGenre().equals(Track.Genre.HIP_HOP))); trackPOPinGuns .forEach(System.out::println); diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/Album.class b/hw3/code/target/classes/ch/usi/inf/ajp22/Album.class new file mode 100644 index 0000000000000000000000000000000000000000..cdae949cf8c7843812e930775e5e38b699bdda3c GIT binary patch literal 3989 zcmcInTU!%X6kUf~APx$MAeDN>0uhOqR$HUA7*JCqT7zh7TOGm(1IbJ}GqF;uz2EP5 zd;JA{X!})LeCXHbe*I1Ty3Wi%PDr4>^dXru=j^lh+G}63^VdIj{{V0VKSWW3+6d}2 z)T2S5Wmdnc$8)+h9X~xeYh*ovhQp?1dP4%Wef<+nXhc&4Q4MRL33Oy<;zieto7R=M zK3mwgFFu@`EarL1bM)+-OND7)W6?8n@wDlB38`VNhIMG6lD zk&)kte{v0TvA1Q51==KJ`Med33Qh1m3hUu<@IX<1F9uOjjH{0 zLHecV$OJEF*o{GfNPw8UZ!Duh(IKJi(Xbc$B-6Iz8B+p#@4;Xh(nJ&w;-Lr*XgG+6 z8LA48l6Ee~oU|P#R)c5Dd=l7PhAPy!B5=bhR%6Qxmm~^){km6vwC}ug@7t+sf+RdDENW%Jp>1qjM)z zcz)SbrhMg&3Of_jMH5aS6~W^gP9j}a-hlv1I60gdy_6cujE-eeN)5lwjdb&W{vXY)oW^S-DyAVb%LXmDH~g>x6yts-va@<_LU&C09&XloGbRJRvC<{KlhUDj*S4l9(vdE^K3`Z= zabY>)Rs5@BCg`)(eQAzBh$NcMIw-(AHSDK8NY zhrc4Sx33f{O49bCWOv_+f>LRtgcv4j8GXFOU+bv z8e37wXv~u)m6LL3vdA9PG<_6MEGo z3iU(sb#pBGq@SKt0txeqS|22SYKRL*dF(zZQUEL15(C7sJI zj+11_Y^!f-cnfa_Ih{7FX>Z0K zx>7B8R}L;Khpz?WWc-6DN2?DtxbRxwapRLHKE-Ddd@g@)zTg;B5rQC}f}fyci$S>c z|I;3}%Zo~w7THj?mQ&b>uLKTeX9hWP4szri^heG?KNGJr`#5kO5d&L;q4G$t=pESV zPmFSTgQHi ztHA_69D4mVr&&IuIFIzw`2|X|+2cvdJ;l?TeAe;V9{UX8Vy{Z;<>`kX6@bVjkU%Wh1TPs$@hOAXDTB9w z4FY$`Hh#yJ1?;Rr3EEob7I1*MbddRVK!Mm<7S;mQJ-3t_=R);c6!p7+1;lG;WB&pk zsllJjZc!r2)z|nI-=phalndfO literal 0 HcmV?d00001 diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/Artist.class b/hw3/code/target/classes/ch/usi/inf/ajp22/Artist.class new file mode 100644 index 0000000000000000000000000000000000000000..59ad5c5aec3643c1ce673be8719dc4d90b5f69d1 GIT binary patch literal 912 zcmZ{iTTk0S5QWb=iJgnVCgo0B(x)aVswG~zNL3}CB0!>w)JMm4!-lY_9EbibDiu}g zLw`VjRMoTV;2_e$!dMr?CcltF{QFBmt(SR$k5nTqesSKq08ib>7`}@I%B$ZQEl~s5h3p9HR;6<89 zH9V+dS-_d8D>eD9G|zXjqG44fqpPfJt^KsF(3u>&r{-Q7`aIv&FDA1j zich3g-N>f(Ue5?`I0}oGV)5Z{%^T;!)rR2hG#OuTcWyEOzxxZK`|b`-x4Co&?}w>a zWo)9%SY@p7sly|0jVJ4d?{nSYjs(+382aX%{+T%?e)AUey#n|W;md@3jJ|=lva%em zo4SM&rLUJ*-UPPiZ33?PTc!IG&MjXoXyw`|=u)fAiYs%Vz)n7aV`l3~*~b0CxBizw vZxw7l@N4Ii?A-6mLLuH`Av=XaUKI;@Z~>W+T?%PEBScR`PvA8LTiE>%wJL|} literal 0 HcmV?d00001 diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/Main.class b/hw3/code/target/classes/ch/usi/inf/ajp22/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..0a29d31aea7880344681d7d14f43c7e9c0dc1a58 GIT binary patch literal 17554 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 boB`fI8`P&|xO+;w)MrOjsm}utB31nldMI8u literal 0 HcmV?d00001 diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/SampleData.class b/hw3/code/target/classes/ch/usi/inf/ajp22/SampleData.class new file mode 100644 index 0000000000000000000000000000000000000000..9b167e00292f6230119887e5f7648302da5e616f GIT binary patch literal 3123 zcma)8-E$LF6#s2$vzxG`NeYERp{szj1sVheGzBS*Ey1*frh)~(w%eOz+s$s--4qc& zQ1A=Czwy<-Kw4+Y$jFQ13p38(qYwJ#jPH))o8!56leRRe@{ruU_jk_kp8LD!?AhD@ ze0K}LA$%1<9ahPxSJ8lwgy^I`qbDrg&L@V)Cz;_(2=$n@=^vJ`s-yE%7z)BNA}Urx zm9WVuBubu{FzsAIpPb&iH<8tg(-uqVzAho6yT0l98Tt`(Mo^c0(@OA_B&S-VqKWf_ zb!)s-`156ok6sB8<5c5NXXcu;z8_{&{jK&Z3E19iLHKQxbF!GTdI#D zf(^`)5p2anT(*ZLq*s(}Ss?#SnGS?KpyD7Nkq|#02r}x77FeK$gbgcDBo!p-E{4o} zLGxYRw0W`|QgN6wg>71<;7wb>5eaJs-EQru>zube-?16DJgTCPTdGBO5s>kCtt;#0 znHs?Wj>$-?I1Umks2Y*ly{@ZYpi~IyUXb_OJI*f2p`fUe<%?P@1_gt3y58w&=9@m# za*nH|nCH7C!#5o}f)s|i+9xC&E~~xhTdhfu`77q`h>9#m>2P{^zkbJEvRh4=#j#1| zQ>14~&-vPkl0C(X=P4f77$tCxEC_D&tcs_3sVEcV$K4b>OZ7Tn&M+-w=9qSrs+;Hi zAiYWqo~_TT(0Qshq|({GVSYn~iV1#0&3W?TPTXhI5grOC{~ObEox1I7eQwDsaF>D# zQ(USUAOcV@MF$vQzLqH&Qx~{hQH9OzlsxmrqJnAS8@8D?=(tQ9rE=qTt_qLat)`^m z0AE*7qO9q2nP)J2!m%umTb@_(g4o#zfD{K5yhw_V=ww#ZdJThlo;Jvej%zaE^pc8~ z`K7FNg-KvhF;MU-*WL6CXNI{V?AKJh&h5h!l~sDqnt5CIOT3P|f~;Felb-4{5e1z* zOqFvF#z6vbK?<;^Gx{N_R~@FE7^n1(T|0 zb9JzbjfF@X>8^r3f+CA|R8^FO-BpVmHuTf6+7*@IaMzT)HHCVsNwQE{bqnq~xO2V{lGq=yuJ<*98#M_)<TR-h#|t; z6+K1x+f|J8ZWJTE`DhIDSAv*Rt%{NAO^j4TVx%IWG0clVjFjSHq^uPqWh0FndFzIR z%k*4_E3_Xq_=Wi!G^Y=Th54H_r-r^Tzk(1w)0YVSzeNlQ8YLPVy5=EW7nE<)KZgMs z@6bPYCIei>yEKOJ9^R*oxpSL9fcja;-_TsbqVJJ%fFF>@hqXK!mwTkj9v_j%$F)47 z%RP>jJw73iPiuKJFZakScqsU+B0}91J@N4Wyor{v_=fn#d9=-;{U)}K#ka@gAEM!C z+YRiP#qO9Co5#L6>=)RhG5N=6DB4=VRDtyf>@n^aiZ+!o{4TKGn@Ej?z9-^Uv)G>< zBjtLsV-2(D&E7!&EZXClc?`|rq=@9nd7PfZ8Nv5VO#ZDt+AipxtAsHwAQqEhRaWlOn3N`sNonFIX2CC*n|aCyX`4eUJ*!xQMr@-0E<|yF>bf7z zRJm(0PObPVRo@qs_FrQ&u0z8us`;O=4ZmPJ{-7_(ztAbw(|2SPyQOyQkp{3&GU*HM h8V*X|Qp3899x9#BX`edc`I5#6?cPnFde@G${tG)={P+L> literal 0 HcmV?d00001 diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/Track$Genre.class b/hw3/code/target/classes/ch/usi/inf/ajp22/Track$Genre.class new file mode 100644 index 0000000000000000000000000000000000000000..543f53bbf5be42036c990adad2c1487e5764ae2e GIT binary patch literal 1267 zcmah}ZBNrs7(I7y?dnD5Py`(Bs2eB+1Qj=7IHp^ij96T<_`#G>pg20yb^I`Uhe7Xe*OOT6Toxi6a*L&wSB$Sv~}Cr)y;!X3k&*|Yt}wa zy|NtFih?1;5k`dK+j8zT!$_%HL0VL(98pmbev{u?D+%Np2bait(a4nra-E}BAWEUQ z`JqtW6xa=pxMUSK){A+8+~l~0eqv2k)=Ka42E*w4?(;PaU{FCn#}Mw&3blH}v8Yip zRXQ+_OucS8dwO~Mz^Zv^4Z|2wFv>B8aa!qukat>#H1)`=x2*Cm!&0)NI#)NF&2$G~ zc&_d2r8_5x2D1Mo#}w`|L^8Hxdn*k6ovr-JVydDdtkH!hRYX;A6}>9r0(i(V3tcE6 zmuWJLCsY5?fTsN=hjNV_x_)oTcC3xo;kM;&ncHVKc&Sk{>lM?rMH9bM z$T1J8Vf?Zn+Nun^=s1=uAEZV5g{9fE^Q8AMy&941ps+kZk&G-O z*;hs~t&C(;AT}iINflw@%|WO7dCDdzijUSt-&fo|!@y_CNOSs)$TNlbV|e8A7ZH%C z7H89^NSuKQe&8SeA|d>og(WgE0O`=yLZS)vbrHz<9VcBoA<2NdNr#|s} z!4up+Mo=cnkW3Vrq{1@MWHKF*Nsmls6q&?M@!%MJ;zH;8X>?;i#Tpcvaej$3GK2-_ UFKtD}RXQd0se)k@FS3Jw0H0m@A^-pY literal 0 HcmV?d00001 diff --git a/hw3/code/target/classes/ch/usi/inf/ajp22/Track.class b/hw3/code/target/classes/ch/usi/inf/ajp22/Track.class new file mode 100644 index 0000000000000000000000000000000000000000..731cb129a9bbf8b19000c197d7604bf411065886 GIT binary patch literal 2516 zcma)-%~Bgj5Xb)`^z8)!u>fIWLy%)3Y;S^{I6)YH$ic`FkQfD5DyKzEqy@1{?GCQ; zEsv3h$RVi;PL&UNfIL(x-Lne_X{E|Rn%+Ac3U7 z_@VXIGCP*jGI#b5Wm5?x*KEgD>jERCrM(Q&$fS@pa1DmQRI_cK`nG91KbzL!$;yh^ z@T}&MKtkE7BLybwmj-v0XFIJ5n;0{Y!?=Lq$&R#qdGNwgq@546m3=JDy4$omJgqlO z8u$p;$!<$J9%5EW zouu5{GjJcK!1S?oB&)8|wA340wMp`o?T>1R0 z=hc(lbx*yf+^{*&S$*y9^Ia3Twk>_NB{>fi=ke#Rt9<2ICtFgr-2*?D1eM(@e49d@ zYivuPczH=}=dF7r&7g9FvfHql%Jtp}{MsGNP%$vNX*mZS=@;v+dvtnI>94}BnJXI` z?@nZd`cGZ@K_9AgS8-^fYIQohHg$+Jb_5o6%2(&bypAXf6f4PNP#+{w$Ei7v^r{`p z_a#Lqp>U`1DBqOpny0^hjNa z#!(OyKBNE7>FXELPtZ79{tKeKe1=r{?iohQ_s%d;&d1M?|3mLxVI3ste-d%(lo_%; zhCE4AC{P=GKr0UeOEi8#U#!nWLQBlVoU`0zF`^~riffuLLz*8+hu3mfX)Y1iImlt0 z3}vXzj$ux_o)5NNxXxX;&gpQ($N{y$(2YqWVOLGrQmjK(xt0WU|*4`%`VVFSc-9S&L#g1HfZDvxPX@=rAgYP X-!{IZuSwG2=JNg10$!tmJrw=}9k1JI literal 0 HcmV?d00001