import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

/**
 * 自动售货系统
 * @author zhuyq
 * @date 2020-12-12
 */
public class AutoSellGoodsSystem {
    private static ArrayList<Goods> goodsList = new ArrayList<>();
    private static ArrayList<Money> savingBox = new ArrayList<>();
    private static Integer balance = 0;
    /******************************成功码开始*****************************/
    private static String S001 = "S001:Initialization is successful";
    private static String S002 = "S002:Pay success,balance=X";
    private static String S003 = "S003:Buy success,balance=X";
    /******************************成功码结束*****************************/
    /******************************错误码开始*****************************/
    private static String E002 = "E002:Denomination error";
    private static String E003 = "E003:Change is not enough, pay fail";
    private static String E005 = "E005:All the goods sold out";
    private static String E006 = "E006:Goods does not exist";
    private static String E007 = "E007:The goods sold out";
    private static String E008 = "E008:Lack of balance";
    private static String E009 = "E009:Work failure";
    private static String E010 = "E010:Parameter error";
    /******************************错误码结束*****************************/

    public static void main(String[] args){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        try {
            while((str = br.readLine())!= null){
                String[] strArr = str.split(";");
                for(int i=0; i<strArr.length; i++){
                    strArr[i] += ";";
                    execute(strArr[i]);
                }
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 命令执行控制器
     * @author zhuyq
     * @date 2020-12-12
     */
    public static void execute(String command){
        String commandType = command.substring(0, 1);
        if(commandType.equals("r")){
            init(command);
        }
        else if(commandType.equals("p")){
            coin(command);
        }
        else if(commandType.equals("b")){
            buy(command);
        }
        else if(commandType.equals("c")){
            refund();
        }
        else{
            query(command);
        }
    }


    /**
     * 系统初始化
     * 初始化规格和数量
     * @author zhuyq
     * @date 2020-12-12
     */
    public static void init(String command){
        String msg = "";
        //余额清零
        balance = 0;
        //初始化规格
        goodsList.add(new Goods("A1", 2, 0));
        goodsList.add(new Goods("A2", 3, 0));
        goodsList.add(new Goods("A3", 4, 0));
        goodsList.add(new Goods("A4", 5, 0));
        goodsList.add(new Goods("A5", 8, 0));
        goodsList.add(new Goods("A6", 6, 0));
        savingBox.add(new Money(10, 0));
        savingBox.add(new Money(5, 0));
        savingBox.add(new Money(2, 0));
        savingBox.add(new Money(1, 0));

        //初始化数量
        command = command.substring(2, command.length()-1);
        String[] strArr = command.split(" ");
        String[] goodsQtyArr = strArr[0].split("-");
        String[] moneyAmountOfSheetsArr = strArr[1].split("-");
        goodsList.get(0).setQuantity(Integer.valueOf(goodsQtyArr[0]));
        goodsList.get(1).setQuantity(Integer.valueOf(goodsQtyArr[1]));
        goodsList.get(2).setQuantity(Integer.valueOf(goodsQtyArr[2]));
        goodsList.get(3).setQuantity(Integer.valueOf(goodsQtyArr[3]));
        goodsList.get(4).setQuantity(Integer.valueOf(goodsQtyArr[4]));
        goodsList.get(5).setQuantity(Integer.valueOf(goodsQtyArr[5]));
        savingBox.get(0).setAmountOfSheets(Integer.valueOf(moneyAmountOfSheetsArr[0]));
        savingBox.get(1).setAmountOfSheets(Integer.valueOf(moneyAmountOfSheetsArr[1]));
        savingBox.get(2).setAmountOfSheets(Integer.valueOf(moneyAmountOfSheetsArr[2]));
        savingBox.get(3).setAmountOfSheets(Integer.valueOf(moneyAmountOfSheetsArr[3]));
        msg = S001;
        System.out.println(msg);
    }


    /**
     * 投币
     * @author zhuyq
     * @date 2020-12-12
     */
    public static Integer coin(String command){
        String msg = "";
        command = command.substring(2, command.length()-1);
        Integer denomination = Integer.valueOf(command);
        Integer amountOfOneAndTwoDenomination = savingBox.get(0).getDenomination()*savingBox.get(0).getAmountOfSheets()+savingBox.get(1).getDenomination()*savingBox.get(1).getAmountOfSheets();
        Integer totalQuantyOfGoods = 0;
        for(int i=0; i<goodsList.size(); i++){
            totalQuantyOfGoods += goodsList.get(i).getQuantity();
        }

        if(balance+denomination>10){
            return balance;
        }
        else if( !denomination.equals(1) && !denomination.equals(2) && !denomination.equals(5) && !denomination.equals(10) ){
            msg = E002;
        }
        else if( amountOfOneAndTwoDenomination<denomination && (!denomination.equals(1) && !denomination.equals(2)) ){
            msg = E003;
        }
        else if( totalQuantyOfGoods.equals(0) ){
            msg = E005;
        }
        else{
            balance += denomination;
            for(int i=0; i<savingBox.size(); i++){
                if(savingBox.get(i).getDenomination().equals(denomination)){
                    savingBox.get(i).setAmountOfSheets(savingBox.get(i).getAmountOfSheets()+1);
                }
            }
            msg = S002.substring(0, S002.length()-1)+balance;
        }
        System.out.println(msg);
        return balance;
    }


    /**
     * 购买商品
     * @author zhuyq
     * @date 2020-12-12
     */
    public static Integer buy(String command){
        String msg = "";
        command = command.substring(2, command.length()-1);
        String goodsName = command;
        Integer quantyOfGoods = 0;
        Integer price = 0;

        boolean isExist = false;
        for(int i=0; i<goodsList.size(); i++){
            String name = goodsList.get(i).getName();
            if(goodsName.equals(name)){
                isExist = true;
                quantyOfGoods=goodsList.get(i).getQuantity();
                price=goodsList.get(i).getPrice();
                break;
            }
        }

        if(!isExist){
            msg = E006;
        }
        else if(quantyOfGoods.equals(0)){
            msg = E007;
        }
        else if( balance<price ){
            msg = E008;
        }
        else{
            balance -= price;
            for(int i=0; i<goodsList.size(); i++){
                String name = goodsList.get(i).getName();
                if(goodsName.equals(name)){
                    goodsList.get(i).setQuantity(goodsList.get(i).getQuantity()-1);
                }
            }
            msg = S003.substring(0, S003.length()-1)+balance;
        }
        System.out.println(msg);
        return balance;
    }


    /**
     * 退币
     * @author zhuyq
     * @date 2020-12-12
     */
    public static void refund(){
        String msg = "";
        if(balance==0){
            msg = E009;
        }
        else{
            //按钱币总张数最少的原则进行退币
            ArrayList<Money> refundDenominationAmountOfSheetsList = refundByMinAmountOfSheets(balance, 10);
            //如果因零钱不足导致不能退币,则尽最大可能退币
            for(int i=0; i<savingBox.size(); i++){
                Integer denomination = savingBox.get(i).getDenomination();
                Integer amountOfSheets = savingBox.get(i).getAmountOfSheets();
                Integer refundDenominationAmountOfSheets = refundDenominationAmountOfSheetsList.get(i).getAmountOfSheets();
                if(amountOfSheets<refundDenominationAmountOfSheets){
                    refundDenominationAmountOfSheetsList.get(i).setAmountOfSheets(amountOfSheets);
                    if(!denomination.equals("1")){
                        Integer balance1 = (refundDenominationAmountOfSheets-amountOfSheets)*denomination;
                        Integer maxDenomination = savingBox.get(i+1).getDenomination();
                        ArrayList<Money> refundDenominationAmountOfSheetsList1 = refundByMinAmountOfSheets(balance1, maxDenomination);
                        for(int j=0; j<refundDenominationAmountOfSheetsList.size(); j++){
                            Integer denominationAmountOfSheets = refundDenominationAmountOfSheetsList.get(i).getAmountOfSheets();
                            Integer denominationAmountOfSheets1 = refundDenominationAmountOfSheetsList1.get(i).getAmountOfSheets();
                            refundDenominationAmountOfSheetsList.get(i).setAmountOfSheets(denominationAmountOfSheets+denominationAmountOfSheets1);
                        }
                    }
                }
            }
            //退币成功后,投币余额清零,同时扣除存钱盒相应的金额
            balance = 0;
            for(int i=0; i<savingBox.size(); i++){
                Integer amountOfSheets = savingBox.get(i).getAmountOfSheets();
                Integer denominationAmountOfSheets = refundDenominationAmountOfSheetsList.get(i).getAmountOfSheets();
                savingBox.get(i).setAmountOfSheets(amountOfSheets-denominationAmountOfSheets);
            }

            for(int i=refundDenominationAmountOfSheetsList.size()-1; i>=0; i--){
                Integer denomination = refundDenominationAmountOfSheetsList.get(i).getDenomination();
                Integer amountOfSheets = refundDenominationAmountOfSheetsList.get(i).getAmountOfSheets();
                if(i==0){
                    msg += denomination+" yuan coin number="+amountOfSheets;
                }
                else{
                    msg += denomination+" yuan coin number="+amountOfSheets+"\n";
                }
            }
        }
        System.out.println(msg);
    }


    /**
     * 按钱币总张数最少且不超过指定面额的原则分解钱币获得的面额张数列表
     * @author zhuyq
     * @date 2020-12-12
     */
    public static ArrayList<Money> refundByMinAmountOfSheets(Integer balance, Integer maxDenomination){
        ArrayList<Money> refundDenominationAmountOfSheetsList = new ArrayList<>();

        //按钱币总张数最少的原则进行退币
        for(int i=0; i<savingBox.size(); i++){
            Integer denomination = savingBox.get(i).getDenomination();
            if(denomination<=maxDenomination){
                Integer refundDenominationAmountOfSheets = balance / denomination;
                refundDenominationAmountOfSheetsList.add(new Money(denomination, refundDenominationAmountOfSheets));
                balance = balance % denomination;
            }
        }

        return refundDenominationAmountOfSheetsList;
    }


    /**
     * 查询
     * 查询商品信息、查询存钱盒信息
     * @author zhuyq
     * @date 2020-12-12
     */
    public static void query(String command){
        String msg = "";
        if( command.length()!=4){
            msg = E010;
        }
        else{
            command = command.substring(2, command.length()-1);
            Integer queryType = Integer.valueOf(command);

            if(queryType.equals(0)){
                goodsList.sort(new GoodsComparator());
                for(int i=0; i<goodsList.size(); i++){
                    Goods goods = goodsList.get(i);
                    if(i==goodsList.size()-1){
                        msg += goods.getName() + " " +goods.getPrice() + " " + goods.getQuantity();
                    }
                    else{
                        msg += goods.getName() + " " +goods.getPrice() + " " + goods.getQuantity() + "\n";
                    }
                }
            }
            else if(queryType.equals(1)){
                for(int i=savingBox.size()-1; i>=0; i--){
                    Money money = savingBox.get(i);
                    if(i==0){
                        msg += money.getDenomination() + " yuan coin number=" + money.getAmountOfSheets();
                    }
                    else{
                        msg += money.getDenomination() + " yuan coin number=" + money.getAmountOfSheets() + "\n";
                    }
                }
            }
            else{
                msg = E010;
            }
        }
        System.out.println(msg);
    }


}

实体-商品

import lombok.Data;

/**
 * 商品
 * @author zhuyq
 * @date 2020-12-12
 */
@Data
public class Goods {
    private String name;
    private Integer price;
    private Integer quantity;
    public Goods(String name, Integer price, Integer quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
}

实体-钱币

import lombok.Data;

/**
 * 存钱盒
 * @author zhuyq
 * @date 2020-12-12
 */
@Data
public class Money {
    private Integer denomination;    //单位元
    private Integer amountOfSheets;
    public Money(Integer denomination, Integer amountOfSheets) {
        this.denomination = denomination;
        this.amountOfSheets = amountOfSheets;
    }
}

比较器-商品

import java.util.Comparator;
/**
 * goods1表示后面的对象,goods2表示前面的对象
 * 返回1即true
 * @author Admin
 *
 */
public class GoodsComparator implements Comparator<Goods>{

    @Override
    public int compare(Goods goods1, Goods goods2) {

        if(goods1.getQuantity()<goods2.getQuantity()){    //左边的小于右边的,即后面的小于前面的,所以按数量降序
            return 1;
        }
        else if(goods1.getQuantity()==goods2.getQuantity()){
            //左边的大于右边的,即后面的大于前面的,所以数量相同按名称中数字升序
            if( Integer.valueOf(goods1.getName().substring(1, 2)) > Integer.valueOf(goods2.getName().substring(1, 2)) ){
                return 1;
            }
            else{
                return -1;
            }
        }
        else{
            return -1;
        }
    }
}