Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.*;
- import java.util.ArrayList;
- import java.util.DoubleSummaryStatistics;
- import java.util.List;
- import java.util.Objects;
- import java.util.stream.Collectors;
- import java.util.Arrays;
- import java.util.Comparator;
- public class MojDDVTest {
- public static void main(String[] args) {
- MojDDV mojDDV = new MojDDV();
- //In IntelliJ we must use CTRL+D in order to break the INPUT STREAM.
- System.out.println("===READING RECORDS FROM INPUT STREAM===");
- mojDDV.readRecords(System.in);
- System.out.println("===PRINTING TAX RETURNS RECORDS TO OUTPUT STREAM ===");
- mojDDV.printTaxReturns(System.out);
- System.out.println("===PRINTING SUMMARY STATISTICS FOR TAX RETURNS TO OUTPUT STREAM===");
- mojDDV.printStatistics(System.out);
- }
- }
- class MojDDV {
- private List<Receipt> receipts;
- public MojDDV() {
- receipts= new ArrayList<Receipt>();
- }
- //for every line we try to make a receipt, if it throws an exception we simply mark it as null.
- //then we filter out the null objects and collect them into a list, which represents the receipts of the actual MojDDV object.
- public void readRecords(InputStream in) {
- this.receipts = new BufferedReader(new InputStreamReader(in))
- .lines()
- .map(i -> {
- try {
- return Receipt.createReceipt(i);
- } catch (AmountNotAllowedException e) {
- System.out.println(e.getMessage());
- return null;
- }
- })
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
- }
- //First we sort the receipts and then we print every single one.
- public void printTaxReturns(OutputStream out) {
- PrintWriter printWriter = new PrintWriter(out);
- this.receipts.stream().
- // sorted().
- forEach(i -> printWriter.println(i));
- printWriter.flush();
- }
- //if we need statistics such as min,max,avg... we can use the
- // DoubleSummaryStatistcs class that generates them for our data.
- public void printStatistics(OutputStream out) {
- PrintWriter printWriter = new PrintWriter(out);
- DoubleSummaryStatistics summaryStatistics = receipts.stream()
- .mapToDouble(i-> i.taxReturns())
- .summaryStatistics();
- printWriter.format("min:\t%.3f\nmax:\t%.3f\nsum:\t%.3f\ncount:\t%d\navg:\t%.3f\n",
- summaryStatistics.getMin(),
- summaryStatistics.getMax(),
- summaryStatistics.getSum(),
- summaryStatistics.getCount(),
- summaryStatistics.getAverage());
- printWriter.flush();
- }
- }
- class Receipt implements Comparable<Receipt> {
- private long id;
- private List<Item> items;
- public Receipt(long id) {
- this.id = id;
- this.items = new ArrayList<>();
- }
- public Receipt(long id, List<Item> items) {
- this.id = id;
- this.items = items;
- }
- //We create objects through this method where we cut down the input line.
- //We through an exception which we try and match in the readData method.
- public static Receipt createReceipt(String line) throws AmountNotAllowedException {
- String[] parts= line.split("\\s+");
- long id= Long.parseLong(parts[0]);
- List<Item> items = new ArrayList<>();
- Arrays.stream(parts)
- .skip(1)
- .forEach(i -> {
- if(Character.isDigit(i.charAt(0))){
- items.add(new Item(Integer.parseInt(i)));
- }
- else{
- items.get(items.size()-1).setTaxType(TaxType.valueOf(i));
- }
- });
- if(totalAmount(items)>30000)
- throw new AmountNotAllowedException(totalAmount(items));
- return new Receipt(id,items);
- }
- //We get all the items into a stream and map to Int or Double their adequate amount, and then we sum them all.
- public static int totalAmount(List<Item> items){
- return items.stream().mapToInt(i -> i.getAmount()).sum();
- }
- public int totalAmount(){
- return items.stream().mapToInt(i -> i.getAmount()).sum();
- }
- public double taxReturns(){
- return items.stream().mapToDouble(i -> i.getTaxReturn()).sum();
- }
- //We compare the order of listing/sorting for 2 receipts, first through their taxReturn,
- // and then through their totalAmount attribute.
- @Override
- public int compareTo(Receipt other) {
- return Comparator.comparing(Receipt::taxReturns)
- .thenComparing(Receipt::totalAmount)
- .compare(this,other);
- }
- @Override
- public String toString() {
- return String.format("%10d\t%10d\t%10.5f",id,totalAmount(),taxReturns());
- }
- }
- class Item {
- private int amount;
- private TaxType taxType;
- private static double TAX_V=0.0;
- private static double TAX_A=0.18;
- private static double TAX_B=0.05;
- public Item(int amount) {
- this.amount = amount;
- }
- public double getTaxReturn(){
- if(taxType==TaxType.V)
- return 0.15*amount*TAX_V;
- else if(taxType==TaxType.B)
- return 0.15*amount*TAX_B;
- else
- return 0.15*amount*TAX_A;
- }
- public int getAmount() {
- return amount;
- }
- public void setAmount(int amount) {
- this.amount = amount;
- }
- public TaxType getTaxType() {
- return taxType;
- }
- public void setTaxType(TaxType taxType) {
- this.taxType = taxType;
- }
- }
- enum TaxType {
- A,
- B,
- V
- }
- class AmountNotAllowedException extends Exception{
- public AmountNotAllowedException(int totalAmount) {
- super(String.format("Receipt with amount %d is not allowed to be scanned",totalAmount));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment