/** * Stock picking algorithm * Copyright (C) 2022 Michael Hunteman * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ import java.lang.*; import java.util.*; class Backpointer { static Stock NOTHING = new Stock(1, 0, ""); int totalValue; Stock stock; public Backpointer(int previousValue, Stock stock) { this.stock = stock; this.totalValue = previousValue + stock.getValue(); } public static Backpointer chooseBackpointer(Stock[] stocks, ArrayList backpointers) { int currentPrice = backpointers.size(); Backpointer best = new Backpointer(backpointers.get(currentPrice - 1).totalValue, NOTHING); for (Stock stock : stocks) { int previousPrice = currentPrice - stock.getPrice(); if (previousPrice >= 0) { Backpointer candidate = new Backpointer(backpointers.get(previousPrice).totalValue, stock); if (candidate.totalValue > best.totalValue) best = candidate; } } return best; } public static ArrayList chooseStocks(Stock[] stocks, int priceLimit) { // TODO: assert stock values are integers // create backpointers ArrayList backpointers = new ArrayList(); backpointers.add(new Backpointer(0, NOTHING)); while (backpointers.size() <= priceLimit) { backpointers.add(chooseBackpointer(stocks, backpointers)); } // postprocess backpointers ArrayList result = new ArrayList(); for (int price = priceLimit; price > 0; price -= backpointers.get(price).stock.getPrice()) { Stock stock = backpointers.get(price).stock; if (stock != NOTHING) result.add(stock); } Collections.reverse(result); return result; } public static void main(String[] args) { int input; Scanner scanner = new Scanner(System.in); ArrayList choices = new ArrayList(); int priceLimit = 0; boolean run = false; do { System.out.println("1. Add a stock"); System.out.println("2. Buying power"); System.out.println("3. Display stocks and buying power"); System.out.println("4. Run"); System.out.println("5. Exit"); input = scanner.nextInt(); scanner.nextLine(); switch (input) { case 1: System.out.println("Type 'Stock Ticker, Price (USD), " + "Value'"); String stockInput = scanner.nextLine(); String[] stockTraits = stockInput.trim() .split("\\s*,\\s*"); try { choices.add(new Stock(Integer.parseInt(stockTraits[1]), Integer.parseInt(stockTraits[2]), stockTraits[0])); } catch (NumberFormatException e) { System.out.println("Invalid input - must enter: " + "ticker, #, #"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Wrong number of inputs - must " + "enter: ticker, #, #"); } break; case 2: System.out.println("How much money do you have to " + "allocate?"); priceLimit = Integer.parseInt(scanner.nextLine()); break; case 3: System.out.println(choices); System.out.println(priceLimit); break; case 4: run = true; break; case 5: System.exit(0); break; default: System.out.println("Invalid input - must enter a number " + "between 1 and 5"); break; } } while (!run); scanner.close(); // Stock stocks[] = {new Stock(3, 10, "A"), new Stock(4, 14, "B")}; ArrayList result = chooseStocks(choices.toArray( new Stock[choices.size()]), priceLimit); int totalValue = 0; for (Stock stock : result) { System.out.println(stock); totalValue += stock.getValue(); } System.out.println("\nBuying power: " + priceLimit); System.out.println("Total value: " + totalValue); } } class Stock { private int price, value; private String ticker; public Stock() { price = 0; value = 0; ticker = ""; } public Stock(int price, int value, String ticker) { this.price = price; this.value = value; this.ticker = ticker; } public int getPrice() { return price; } public int getValue() { return value; } @Override public String toString() { return "Ticker: " + ticker + " price: " + price + " value: " + value; } }