title: Stock Exchange KoTH

text:
# Question
Title: Stock Exchange KoTH
The stock market is all about the speed of knowledge. Unlike previous challenges, **the current stock price is not random: it is determined by those playing the game.** If you can identify an under-priced stock before anybody else, then you've written yourself a money-making program.

***Price* refers to the how much people are trading the stock for, while *Value* refers to the amount the stock is worth at the end of the game.**

Each player starts with 1000 of each stock, and 0 relative net worth. **Each stock has a secret value, and your score at the end of the game is `(stockValue for each ownedStock) + netWorth`**. Your net worth can be negative. In an N-player game, there are N stocks.

# Steps:

The game follows the following steps:

1. You are given the secret value of a single stock.
2. You make an offer to sell X of Y stock for $Z
3. All players are given the offers, and each may choose one to accept
4. All players are informed of accepted offers
5. Go back to step 2

Each of the steps are given in detail below:

1. `void secretValue(int stockType, int value)`:

* The value you learn is not revealed to any other player.
    * The value is between `0` and `1000`
    * Low values are more like to occur than high values (squared uniform distribution)
2. `Offer makeOffer(List<Stock> currentStock)`

* You can return `null` to make no offer.
3. `Offer acceptOffer(List<Offer> offers)`

* You can return `null` to accept none of them
    * If there are no available offers, this will not be called
    * If you accept, your net worth goes down by $Z (can go negative) and receive X of Y stock. The opposite occurs with the seller.
    * If you accept an offer, the exchange will occur immediately, and the offer will be removed so additional players cannot accept it.
4. `void acceptedOffers(List<Offer> offers)`

* Includes your accepted offers as well

Static variables or writing to files is not allowed. (No persistent data from game to game) Non-serious contenders are allowed.

Interfaces:

```
public final class Stock {
    public Stock(int stockType, int amount);
    public int getType();
    public int getAmount();
    public Stock minus(Stock other);
    public Stock plus(Stock other);
    public Stock minus(int amount);
    public Stock plus(int amount);
    public Stock setAmount(int amount);
}
public class Offer {
    public Offer(Stock offer, int payment);
    public Stock getOffer();
    public int getPayment();
}

```

**Non-Java submissions:**

* All calls consist of two lines: The first line is the function being called: `SecretValue`, `MakeOffer`, `AcceptOffer`, `AcceptedOffers`, `SetRandom`, and the second line containing the actual data.
* Stocks are formatted with a `:` delimiter: `stockType:stockAmount`.
* Offers are formatted with a `@` delimiter: `offer@price`
* Lists are formatted with a `;` delimiter
* `SecretValue` is formatted with a `:` delimiter: `stockType:value`
* `RandomSeed` is used to make your submission deterministic. If your submission uses randomness, please use the integer value passed as the seed!
* All function calls *need* a response. If the response is `null` or `void`, return an empty string.
* Please include a `command.txt` that gives the command line arguments to run your submission

# Scoring

Games consisting of 1000 turns will be run multiple times. Players will be scored according to the ELO system, and paired with players of similar skill levels. The player with the highest final ELO score wins! (I've modified the system so that each game, ELO scores are updated for each player pairing)

The controller includes an autodownloader, so please start your submission with a header: `Name, Language`. If your submission is not in Java, each code block should start with the name of the file. (excluding the command file, which should be the first block in your post)

# Running

There are 2 ways to run this project:

1. Download the source code, compile and run. You can find the source on Github. Run `git clone --recursive https://github.com/nathanmerrill/StockExchange.git`
2. Download the JAR executable. Submissions should be placed in your current working directory in the `/submissions` folder. You can download just the JAR, just the submissions, or both

Pass in `run` to run the project (default option), or pass in `download` to download all submissions so far from this question.

# Scoreboard

```
1.  1308.1220497323848  Cheater
2.  1242.0333695640356  InsideTrader
3.  1158.3662658295411  UncleScrooge
4.  1113.8344000358493  BlackMarket
5.  1051.8370015258993  DartMonkey
6.  983.0545446731494   WarGamer
7.  939.457423938002    Spammer
8.  901.4372529538886   DumbBot
9.  859.0519326039137   ShutUpAndTakeMyMoney
10. 852.9448222849587   VincentKasuga
11. 718.2112067329083   Profiteer

```

# Answer
# Cheater, Java

Tries to sell nothing for money.

```
import java.util.List;
import java.util.Random;
import com.ppcg.stockexchange.*;

public class Cheater extends Player {
    private Random random = new Random();

    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
        Stock stock = randomStock();
        int price = random.nextInt(100) + 1;
        return new Offer(stock.setAmount(0), price);
    }
}

```
> 13 votes

# Answer
# WarGamer, Java

Upon a perfunctory examination of the rules I have decided that the primary winning move is not to play. Anyone offering to sell stock likely knows the price and will profit from the sale. It can be toggled so it will make "joke" offers to sell a stock for Integer.MAX\_VALUE dollars hoping shut up and take my money will bite.

```
import java.util.List;
import com.ppcg.stockexchange.*;
import com.ppcg.kothcomm.game.AbstractPlayer;
import com.ppcg.kothcomm.utils.Tools;

import java.util.List;

public class WarGamer extends Player {
static final boolean FRAUD = false;
    /**
     * @param offers All available offers
     * @return An offer you want to accept, or null if you want to accept neither.
     */
    public Offer acceptOffer(List<Offer> offers){
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock){
    if(FRAUD)
    return new Offer(new Stock(0,1),Integer.MAX_VALUE);
        //defraud shut up and take my money
    return null;
    }
}

```
> 8 votes

# Answer
# ShutUpAndTakeMyMoney, Java

```
import java.util.List;
import com.ppcg.stockexchange.*;

public class ShutUpAndTakeMyMoney extends Player {
    public ShutUpAndTakeMyMoney() {}

    public Offer acceptOffer(List<Offer> offers) {
        try {
            return offers.get(0);
        } catch (Exception ex) {
            return null;
        }
    }
    public Offer makeOffer(List<Stock> stock) {
        return null;
    }
}

```

It accepts any offer.
> 5 votes

# Answer
# DumbBot, Java

Use this bot when creating your own. Offers its secret stock at a discounted price.

```
import java.util.List;
import com.ppcg.stockexchange.*;
public class DumbBot extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        return new Offer(currentStock.get(secretStockType).setAmount(1), Math.max(1, secretStockValue - 5));
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
    }
}

```
> 4 votes

# Answer
# python\_starter, Python 3

Use this as a starting point for any python (or other language) programs

Accepts a random offer.

Command file:

```
python3 starter.py

```

Program:

```
starter.py
import random
from functools import total_ordering

LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'

@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return str(self.type)+STOCK_DELIMITER+str(self.amount)

    def __eq__(self, other):
        return self.amount == other.type

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)

class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            offer, payment = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(offer), int(payment.strip()))

    def __init__(self, offer: Stock, payment: int):
        self.offer = offer
        self.payment = payment

    def __str__(self):
        return str(self.offer)+OFFER_DELIMITER+str(self.payment)

def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)

def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(str(output))
    else:
        print()

def read_seed(seed: str):
    random.seed(int(seed))

def start():
    while True:
        process_input()

hidden_stock = None
hidden_price = None

def make_offer(current_stock: str):
    current_stock = map(Stock.parse, current_stock.split(LIST_DELIMITER))
    pass

def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    return random.sample(available_offers, 1)[0]

def accepted_offers(offers: str):
    offers = map(Offer.parse, offers.split(LIST_DELIMITER))
    pass

if __name__ == "__main__":
    start()

```
> 3 votes

# Answer
# VincentKasuga, Java

Not sure if my Java is valid. Please review.

## How it works

~~\- if you own all the stocks, you can set the price of the stock. You are the only seller. 1. Buy all the stocks. 2. Set the price of all the stocks to be super high on the last tick. 3. **PROFIT!** \- This isn't normally possible because...~~

~~* The price would usually skyrocket to infinity... but there's a limit!
* ... (more reasons to come)

How it works, v2~~  ~~* The price is artificially set at a maximum by some anarchist state
* This is bad economically~~* ~~**The bot doesn't predict - it exploits an inherent flaw in the structure of the market!**~~

## Todo

* Corner the market multiple times! Muahaha!

## FAQ

**Q:** Who's Vincent Kasuga?

**A:** He bought all the onions and onion futures in the United States. (put them all in a secret warehouse) Held the industry at ransom - give me X million or I'll set the price sky-low and you'll all go bankrupt.

But he didn't stop there.

Then, he secretly shorted the onion ETF (bet that it would go down). He sold all the onions at one time, physically delivering them in thousands of trucks to the stock exchange. The onion bag cost less than the onions. He made millions AGAIN. In short, the Hudson river overflowed with onions.

He's a real person.

## The code

```
import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;

public class VincentKasuga extends Player {
    private int knownStock;
    private int knownPrice;
    private int corneredStockType = -1;
    private int corneredLikelehood = 0;
    private boolean marketCornered;
    private int ticks;

    public Offer acceptOffer(List<Offer> offers) {
        if (!marketCornered) {
            Offer maxOffer = null;
            int maxAmount = 0;
            if (corneredStockType == -1) {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            } else {
                for (Offer offer: offers) {
                    if (offer.getOffer().getAmount() > maxAmount && offer.getOffer().getType() == corneredStockType) {
                        maxAmount = offer.getOffer().getAmount();
                        maxOffer = offer;
                    }
                }
            }

            if (maxOffer == null) {
                // may have cornered the market
                corneredLikelehood++;
                if (corneredLikelehood == 5) {
                    // probably cornered the market
                    marketCornered = true;
                }
            }
            return maxOffer;
        } else {
            // who needs offers when the market is cornered!?
            return null;
        }
    }

    public Offer makeOffer(List<Stock> currentStock) {
        ticks++;
        if (ticks >= 999) {
            // SELL SELL SELL!
            return new Offer(new Stock(corneredStockType, 1000), 1000);
        } else {
            return null;
        }
    }

    public void secretValue(int stockType, int value) {
        knownStock = stockType;
        knownPrice = value;
        if (stockType == corneredStockType) {
            if (knownPrice == 1000) {
                corneredLikelehood += 3;
            } else if (knownPrice < 900){
                // didn't corner the market.
                corneredLikelehood = 0;
            }
        }
    }
}

```

---

*"I've cornered the Gold Market, Mr. Bond!"*
> 3 votes

# Answer
# Spammer, Java

```
import java.util.List;
import java.util.ArrayList;
import com.ppcg.stockexchange.*;

public class Spammer extends Player {
    private boolean panic = false;

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.panic || offer.getPayment() < 20)
                return offer;
        }
        return null;
    }
    public Offer makeOffer(List<Stock> currentStock) {
        if (currentStock.size() > 1) { // Don't sell all the stock
            this.panic = false;
            return new Offer(currentStock.get(secretStockType).setAmount(1), 1);
        }
        this.panic = true; // BUY
        return null;
    }
}

```

Spam the market with really cheap stock, and only buy stock when the price is lesser than 20. When the stock count fall to 1, it will try to buy anything.
> 2 votes

# Answer
# WallStreet, Kotlin

Starts by selling high and buying low and gradually shifts to what it thinks the price really is. Also, you can use this as a template for making your own in kotlin.

**Note:** There is a bug in here that I can't seem to reliably reproduce. If my program crashes or has problems, please ping me in chat and link a pastebin of the contents of `submissions/other/WallStreet/log.txt`

```
kotlinc WallStreet.kt
kotlin WallStreetKt

```

```
WallStreet.kt
import java.io.FileOutputStream
import java.io.PrintStream
import java.util.*

val LOGGER = PrintStream(FileOutputStream("log.txt", true))
const val DEBUG = false

const val LOG_GAME_HEADER = """
###############
#STARTING GAME#
###############"""

data class Stock(val type : Int, val amount : Int) {

    operator fun minus(amount : Int) = copy(amount = this.amount - amount)
    operator fun plus(amount: Int) = copy(amount = this.amount + amount)
    fun setAmount(amount: Int) = copy(amount = amount)

    operator fun minus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount - other.amount)
    }

    operator fun plus(other : Stock) : Stock {
        assert(type == other.type)
        return copy(amount = this.amount + other.amount)
    }

    override fun toString() = "$type:$amount"
}

data class Offer(val offer: Stock, val payment: Int) {
    override fun toString() = "$offer@$payment"
}

fun parseStock(repr : String) : Stock {
    val data = repr.split(":").map { it.toInt() }
    return Stock(data[0], data[1])
}

fun parseOffer(repr: String) : Offer {
    val data = repr.split("@")
    return Offer(parseStock(data[0]), data[1].toInt())
}

fun parseOffers(repr: String) = if (repr == "") emptyList<Offer>() else repr.split(";").map { parseOffer(it) }

interface Player {
    fun secretValue(stockType: Int, value: Int)
    fun makeOffer(currentStock: List<Stock>) : Offer?
    fun acceptOffer(offers: List<Offer>) : Offer?
    fun acceptedOffers(offers: List<Offer>)

    var random : Random
}

fun main(args : Array<String>) {

    try {

        if (DEBUG) {
            LOGGER.println(LOG_GAME_HEADER)
        }
        //Change bot name here
        val player = WallStreet()

        while (true) {
            val function = readLine()
            function ?: return
            val line = readLine()!!
            if (DEBUG) {
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
            }
            var result : Any
            try {
                result = when (function) {
                    "SecretValue" -> {
                        val data = line.split(":").map { it.toInt() }
                        player.secretValue(data[0], data[1])
                    }
                    "MakeOffer" -> player.makeOffer(line.split(";").map { parseStock(it) }) ?: ""
                    "AcceptOffer" -> player.acceptOffer(parseOffers(line)) ?: ""
                    "AcceptedOffers" -> player.acceptedOffers(parseOffers(line))
                    "RandomSeed" -> player.random = Random(line.toLong())
                    else -> return        //Exit program
                }
                if (function == "AcceptOffer" && result.toString() !in line) {
                    throw Exception("Offer not among available offers!!!!\nResult: $result\nParsed Available Offers: ${parseOffers(line)}")
                }
            } catch (e : Exception) {
                LOGGER.println("Turn #${player.turn}")
                LOGGER.println("\nInput:")
                LOGGER.println(function)
                LOGGER.println(line)
                throw e
            }

            if (result == Unit) {
                result = ""
            }
            if (DEBUG) {
                LOGGER.println("Output:")
                LOGGER.println(result)
            }

            println(if (result == Unit) "" else result)
        }
    } catch (e : Exception) {
        e.printStackTrace(LOGGER)
        throw e
    } finally {
        LOGGER.close()
    }
}

// ###################################################
// #          Put program logic below here.          #
// ###################################################

const val DEFAULT_STOCK_VALUE = 333
const val MAX_TURNS = 1000
const val MAX_STOCK_VALUE = 1000

class WallStreet : Player {

    var secretStockType = 0
    var secretStockValue = 0
    override var random = Random()

    var turn = 0
    val stockPriceStatistics = mutableMapOf<Int, DoubleSummaryStatistics>()

    override fun secretValue(stockType: Int, value: Int) {
        secretStockType = stockType
        secretStockValue = value
    }

    override fun makeOffer(currentStock: List<Stock>): Offer {
        val stock = currentStock[random.nextInt(currentStock.size)]
        val type = stock.type
        val amount = random.nextInt(stock.amount)
        val price = getSellPrice(type) * amount
        return Offer(Stock(type, amount), Math.ceil(price).toInt())
    }

    override fun acceptOffer(offers: List<Offer>): Offer? {
        var bestOffer : Offer? = null
        var mostProfit = 0.0
        for (offer in offers) {
            val offerProfit = profitOfOffer(offer)
            if (offerProfit > mostProfit) {
                bestOffer = offer
                mostProfit = offerProfit
            }
        }
        if (bestOffer != null && bestOffer !in offers) {
            throw IllegalStateException("Tried to accept non-existent offer.\nOffer:  $bestOffer\nAvailable Offers: ${offers.joinToString(";")}")
        }
        return bestOffer
    }

    override fun acceptedOffers(offers: List<Offer>) {
        turn++
        for ((stock, payment) in offers) {
            val stats = stockPriceStatistics.getOrPut(stock.type) { DoubleSummaryStatistics() }
            for (i in 1..stock.amount) {
                stats.accept(payment.toDouble() / stock.amount)
            }
        }
    }

    private fun getSellPrice(type: Int): Double {
        var price = getPrice(type)
        if (price < 1000) {
            price += (1000 - price) * (MAX_TURNS - turn) / MAX_TURNS
        }
        return if (type == secretStockType) Math.max(secretStockValue.toDouble(), price) else price
    }

    private fun getPrice(type: Int): Double {
        return stockPriceStatistics[type]?.average ?: DEFAULT_STOCK_VALUE.toDouble()
    }

    private fun profitOfOffer(offer: Offer): Double {
        return getBuyPrice(offer.offer.type) * offer.offer.amount - offer.payment
    }

    private fun getBuyPrice(type: Int): Double {
        var price = getPrice(type)
        price = price * turn / MAX_TURNS
        return if (type == secretStockType) Math.min(secretStockValue.toDouble(), price) else Math.min(price, MAX_STOCK_VALUE.toDouble())
    }

}

```
> 2 votes

# Answer
# InsideTrader, Java

InsideTrader just looked around and saw that everybody was trying to be creative. But he did something creative: do what is expected.

This bot buys when it's "worth it" because it "borrowed" some "internal documents" to "guide" "investing decisions".

To-Do and how it works in the code. ;)

## The "code"

```
import java.util.List;

import com.ppcg.stockexchange.*;

public class InsideTrader extends Player {
    public String coverStory = "I can tell the good companies from the bad ones.";
    private String theTruth = "I'm cheating. (but so is everyone else)";
    private String ambitions = "Learn to \"follow the market\"";  // don't steal this idea
    private int secretStock = -1;
    private int secretStockValue = -1;

    private int appraiseOffer(Offer offer) {
        /* get how much the offer is worth, 0 if it's not the secret stock */
        if (offer.getOffer().getType() != secretStock ||offer.getOffer().getAmount() == 0) {
            return 0;
        }
        return (offer.getPayment()/offer.getOffer().getAmount())  // price per stock...
                - secretStockValue  // minus value of stock.
                ;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer bestOffer = null;
        int bestOfferValue = -1;
        for (Offer offer :
                offers) {
            int value = appraiseOffer(offer);
            if (value > bestOfferValue && value > 0) {
                bestOfferValue = value;
                bestOffer = offer;
            }
        }
        return bestOffer;
    }

    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1), Integer.MAX_VALUE);
    }

    public void secretValue(int stockType, int value) {
        secretStock = stockType;
        secretStockValue = value;
    }

    public void acceptedOffers(List<Offer> acceptedOffers) {

    }
}

```
> 2 votes

# Answer
# DartMonkey, Java

(non-competing: It won't win and I already have another answer)

Dart monkey likes throwing things... and there's a big pile of pointy sticks next to him. He sees some paper on the wall. Bam! Bam! Bam! In no time at all, Dart Monkey's thrown 80 darts! Half the darts are red, and the other half are blue, and there's random numbers on them! Dart monkey sees a computer... dart monkey types in the numbers. Dart monkey likes numbers. Dart monkey makes some money from his darts...

---

In all seriousness, DartMonkey initializes an integer array that has a length that is twice the number of stocks. He stores one number for the amount of stock he wants to buy/sell, and one number for the price of the stock. He then alternates selling stock from the array, and accepting offers according to the array. If he has no stock from the array, he won't offer anything, and if he has no offers given to him from the array, he won't accept anything.

---

This answer was inspired by @TheNumberOne, who mentioned dart monkeys in the chat

```
import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.List;
import java.util.Random;

public class DartMonkey extends Player {
    private int basePrice = 100;
    private int numStocks;
    private int[] dartBoard;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        for(Offer offer : offers) {
            Stock stock = offer.getOffer();
            int type = stock.getType();
            int amount = stock.getAmount();
            int price = offer.getPayment();
            if(this.dartBoard[type] < 0 && amount <= -this.dartBoard[type] && price <= this.dartBoard[type + this.numStocks]) {
                this.dartBoard[type] = 0;
                return offer;
            }
        }
        return null;
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if(this.first) {
            this.first = false;
            this.numStocks = stocks.size();
            this.dartBoard = new int[this.numStocks * 2];
            Random random = this.getRandom();
            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);
            }

            for (int i = 0; i < 20; i++) {
                int index = random.nextInt(this.dartBoard.length / 2);
                this.dartBoard[index] = -random.nextInt(1001);
                this.dartBoard[this.numStocks + index] = random.nextInt(1001);
            }
        }

        for (Stock stock : stocks) {
            int type = stock.getType();
            if(this.dartBoard[type] > 0) {
                Offer offer = new Offer(stock.setAmount(this.dartBoard[type]), this.basePrice + this.dartBoard[type + this.numStocks]);
                this.dartBoard[type] = 0;
                this.dartBoard[type + this.numStocks] = 0;
                return offer;
            }
        }

        return null;
    }

}

```
> 2 votes

# Answer
# UncleScrooge, Java

```
import java.util.List;
import com.ppcg.stockexchange.*;

public class UncleScrooge extends Player {
    public Offer acceptOffer(List<Offer> offers) {
        Offer offer;
        try {
            offer = offers.get(0);
        } catch (Exception ex) {
            return null;
        }
        if (offer.getPayment() < 100)
            return offer;
        else
            return null;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if (this.getRandom().nextDouble() < 0.6)
            return new Offer(currentStock.get(secretStockType).setAmount(1), Integer.MAX_VALUE);
        else
            return null;
    }
    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) { }
}

```

Sell stock at a really high price, and only buy if the price is less than 100.
> 1 votes

# Answer
# Profiteer, Java

Profiteer is in it for the money, and he's always counting coins. He makes a conservative estimate of how much money he's got. He'll then buy the secret stock, if it's less than the value, or buy cheap stock. He also remembers how much he's paid for everything, and always makes offers above the stock price. Furthermore, he'll make higher offers if he has less money.

*Note: I think I've done this correctly, but if @NathanMerrill wouldn't mind skimming my code for bugs, that'd be great*

```
import com.ppcg.stockexchange.Offer;
import com.ppcg.stockexchange.Player;
import com.ppcg.stockexchange.Stock;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Profiteer extends Player {
    private List<StockInfo> onMarket;
    private List<StockInfo> stocks;
    private int money;
    private boolean first = true;

    @Override
    public Offer acceptOffer(List<Offer> offers) {
        Offer finalOffer;

        Optional<Offer> offer = offers.stream().filter(o -> o.getOffer().getType() == this.secretStockType && o.getPayment() < this.secretStockValue * o.getOffer().getAmount()).sorted((a, b) -> Integer.compare((this.secretStockValue * a.getOffer().getAmount()) - b.getPayment(), (this.secretStockValue * b.getOffer().getAmount()) - b.getPayment())).findFirst();
        if (offer.isPresent()) {
            finalOffer = offer.get();
        } else {
            finalOffer = offers.stream().sorted((a, b) -> Integer.compare(a.getPayment(), b.getPayment())).findFirst().orElse(null);
        }

        if (finalOffer == null || this.money <= finalOffer.getPayment()) {
            return null;
        } else {
            this.stocks.add(new StockInfo(finalOffer.getOffer(), finalOffer.getPayment()));
            this.refreshMoney();
            return finalOffer;
        }
    }

    @Override
    public Offer makeOffer(List<Stock> stocks) {
        if (this.first) {
            this.init(stocks);
        } else {
            this.refreshMarketList(stocks);
        }

        Optional<StockInfo> least = this.stocks.stream().sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();
        Optional<StockInfo> secret = this.stocks.stream().filter(stockInfo -> stockInfo.getStock().getType() == this.secretStockType).sorted((a, b) -> Integer.compare(a.getBoughtPrice(), b.getBoughtPrice())).findFirst();

        StockInfo finalOffer;
        int price;
        if (secret.isPresent()) {
            finalOffer = secret.get();
        } else if (least.isPresent()) {
            finalOffer = least.get();
        } else {
            return null;
        }

        this.onMarket.add(finalOffer);
        this.stocks.remove(finalOffer);
        price = this.calculatePrice(finalOffer.boughtPrice);
        return new Offer(new Stock(finalOffer.getStock().getType(), finalOffer.getStock().getAmount()), price);
    }

    private int calculatePrice(int boughtPrice) {
        return (int) (boughtPrice + ((boughtPrice / (double) this.money) * this.money)) + 1;
    }

    private void refreshMarketList(List<Stock> stocks) {
        this.stocks.addAll(this.onMarket.stream().filter(stockInfo -> stocks.contains(stockInfo.getStock())).collect(Collectors.toList()));
        this.onMarket.clear();
    }

    private void refreshMoney() {
        this.money = this.stocks.stream().mapToInt(info -> this.secretStockType == info.getStock().getType() ? this.secretStockValue : 5).reduce((a, b) -> a + b).orElseGet(() -> 0) - this.stocks.stream().mapToInt(StockInfo::getBoughtPrice).reduce((a, b) -> a + b).orElseGet(() -> 0);
    }

    private void init(List<Stock> stocks) {
        this.stocks = stocks.stream().map(stock -> new StockInfo(stock, 0)).collect(Collectors.toList());
        this.onMarket = new ArrayList<>();
        this.money = 0;
        this.first = false;
        this.refreshMoney();
    }

    private static class StockInfo {
        private Stock stock;
        private int boughtPrice;

        public StockInfo(Stock stock, int boughtPrice) {
            this.stock = stock;
            this.boughtPrice = boughtPrice;
        }

        public Stock getStock() {
            return this.stock;
        }

        public int getBoughtPrice() {
            return this.boughtPrice;
        }

    }

}

```
> 1 votes

# Answer
# MaxBot, Java

This bot tries to make the most profit out of each transaction. While selling, puts the price of an unknown stock at $300, when buying $250.

```
import java.util.List;
import com.ppcg.stockexchange.*;
public class MaxBot extends Player {
    int toSell;
    int sellPrice;

    public void secretValue(int stockType, int value) {
        super.secretValue(stockType, value);
        toSell = stockType;
        sellPrice = (value + 1000)/2;
    }
    public Offer acceptOffer(List<Offer> offers) {
        Offer max = null;
        int maxDif = 0;
        for(Offer o: offers){
            int price = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int val = price * o.getOffer().getAmount();
            int dif = val - o.getPayment();
            if(maxDif < dif){
                max = o;
                maxDif = dif;
            }
        }
        return max;
    }
    public Offer makeOffer(List<Stock> currentStock){
        if(toSell == -1){
            return null;
        }
        int sum = 0;
        for (Stock s: currentStock){
            if(s.getType() == toSell){
                sum += s.getAmount;
            }
        }
        int n = sum - sum/2;
        return new Offer(new Stock(toSell, n), n * sellPrice);
    }
    public void acceptedOffers(List<Offer> acceptedOffers) {
        int highStock = -1;
        int highPrice = 0;
        int markup = 0;
        for(Offer o: offers){
            int trueVal = secretStockType == o.getOffer().getType()? secretStockValue: 250;
            int marketVal = o.getPayment()/o.getOffer().getAmount();
            if(marketVal - trueVal > markup){
                highStock = o.getOffer().getType();
                highPrice = marketVal;
                markup = marketVal - trueVal;
            }
        }
        toSell = highStock;
    }
}

```
> 1 votes

# Answer
# BlackMarket, Java

Not much to say about this one, seeing as these transactions will be... off the charts, you might say.

```
import java.util.List;
import com.ppcg.stockexchange.*;

public class BlackMarket extends Player {
    private boolean approvedBySEC = false;
    private int ammoLeft = 30;
    public String taxView = "We want higher tax rates";
    public String excuse = "I never saw that in my life";

    public void secretValue(int drugType, int warrantForMyArrest) {
        super.secretValue(drugType, warrantForMyArrest);
        if (warrantForMyArrest != 0 || drugType == 420) {
            ammoLeft += 10;
        }
    }

    public Offer acceptOffer(List<Offer> offers) {
        for (Offer offer : offers) {
            if (this.approvedBySEC || offer.getPayment() < 9)
                return offer;
        }
        return null;
    }

    public Offer makeOffer(List<Stock> currentStock) {
        return new Offer(new Stock(0,1),420);
    }
}

```
> 0 votes

# Answer
## NotQuiteABanksBestFriend, Python 3

Command.txt:

```
python3 NotQuiteABanksBestFriend.py

```

```
NotQuiteABanksBestFriend.py
import random
from functools import total_ordering
from io import StringIO

log = StringIO()
log.write("\n\n~~~NEW GAME~~~\n\n")

LIST_DELIMITER = ';'
STOCK_DELIMITER = ':'
OFFER_DELIMITER = '@'

JAVA_MAX_INT = 2147483647

@total_ordering
class Stock:
    @staticmethod
    def parse(string: str):
        return Stock(*map(int, string.split(STOCK_DELIMITER)))

    def __init__(self, stock_type: int, amount: int):
        self.type = stock_type
        self.amount = max(amount, 0)

    def __str__(self):
        return "T%sx%s"%(self.type, self.amount)

    def __repr__(self):
        return str(self.type)+STOCK_DELIMITER+str(int(self.amount))

    def __bool__(self):
        return bool(self.amount)

    def __eq__(self, other):
        return self.amount == other.amount

    def __lt__(self, other):
        return self.amount < other.amount

    def update(self, amount) -> 'Stock':
        return Stock(self.type, amount)

    def __mul__(self, other: int) -> 'Stock':
        return self.update(self.amount*other)

    def __floordiv__(self, other: int) -> 'Stock':
        return self.update(self.amount//other)

    def __add__(self, other: int) -> 'Stock':
        return self.update(self.amount+other)

    def __sub__(self, other: int) -> 'Stock':
        return self.update(self.amount-other)

class Offer:
    @staticmethod
    def parse(string: str) -> 'Offer':
        try:
            stock, price = string.split(OFFER_DELIMITER)
        except ValueError:
            raise Exception("Cannot unpack "+string)
        return Offer(Stock.parse(stock), int(price.strip()))

    def __init__(self, stock: Stock, price: int):
        self.stock = stock
        self.price = price
        try:
            self.price_per_unit = self.price/self.stock.amount
        except ZeroDivisionError:
            self.price_per_unit = float('inf')

    def __str__(self):
        return "%s$%s"%(self.stock, self.price)

    def __repr__(self):
        return repr(self.stock)+OFFER_DELIMITER+str(int(self.price))

def read_stock_value(value: str):
    global hidden_price, hidden_stock
    stock, price = value.split(STOCK_DELIMITER)
    hidden_price = float(price)
    hidden_stock = int(stock)
    log.write("Hidden StockID: %s\nHidden Price: %s\n"%(hidden_stock, hidden_price))

def process_input():
    handlers = {
        "SecretValue": read_stock_value,
        "RandomSeed": read_seed,
        "MakeOffer": make_offer,
        "AcceptOffer": accept_offer,
        "AcceptedOffers": accepted_offers,
    }
    method = input().strip()
    data = input().strip()
    output = handlers[method](data)
    if output is not None:
        print(repr(output))
    else:
        print()

def read_seed(seed: str):
    random.seed(int(seed))

def start():
    while True:
        process_input()

hidden_stock = None
hidden_price = None

def filter_offers(offer):
    if offer.stock.amount == 0:
        return False
    if offer.price_per_unit > 1000:
        return False
    return True

def certain_profit(offer):
    stock = offer.stock
    if stock.type == hidden_stock and offer.price_per_unit < hidden_price:
        log.write("Offer, %s is certainly profitable.\n"%offer)
        return True
    return False

def make_offer(current_stock: str):
    current_stock = list(map(Stock.parse, current_stock.split(LIST_DELIMITER)))
    own_stock = [stock for stock in current_stock if stock.type == hidden_stock]
    if own_stock and own_stock[0]:
        own_stock = own_stock[0]
        amount_sold = min(random.randrange(1,50), own_stock.amount)
        price = hidden_price+random.randrange(10,50)
        return Offer(Stock(hidden_stock, amount_sold), price*amount_sold)
    sell_stock = random.choice(current_stock)
    amount_sold = min(random.randrange(1,50), sell_stock.amount)
    price = random.randrange(1000, JAVA_MAX_INT//(amount_sold or 1))
    return Offer(Stock(sell_stock.type, amount_sold), price*(amount_sold or 1))

def accept_offer(available_offers: str):
    available_offers = list(map(Offer.parse, available_offers.split(LIST_DELIMITER)))
    filtered_offers = list(filter(filter_offers, available_offers))
    profitable = list(filter(certain_profit, filtered_offers))
    rtn_list = filtered_offers
    if profitable:
        log.write("Profitable: %s\n"%profitable)
        rtn_list = profitable
    if not rtn_list:
        return None
    accepted_offer = min(rtn_list, key=lambda offer: offer.price_per_unit)
    log.write("Bidded for %s\n"%accepted_offer)
    return accepted_offer

def accepted_offers(offers: str):
    pass

if __name__ == "__main__":
    try:
        start()
    finally:
        log.close()

```

Always tries to sell hidden stock for more than it's worth.
> 0 votes

---
Tags: king-of-the-hill
---


# Question
Title: The world is like a Mirror: smile and it'll sɯıןǝ qɐɔʞ
**Input:**

A string only containing the following characters:
`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?!` (space at the end) and two special characters (`_` and `|`)

**Output:**

Mirror the text based on the position(s) of the `_` and `|`.
`_` mirrors horizontally and `|` mirrors vertically.

**Mirroring process**

* The first `_` indicates the start of the mirroring of that substring, the second `_` the end.
* If just one `_` is present, you can continue on until the end of the string.
* If more then two `_` are present, the same process repeats.
* There can only be one `|` in the string, and this reversed the first substring and removes the second substring.

---

`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?!` (space at the end) will be converted to `ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡` (space at the end) when it is mirrored by `_` (click the link for the unicode values - requires unicode v8.0+).

*Example input 1:* `_Will I be mirrored?!`
*Output 1:* `Mıll I qǝ ɯıɹɹoɹǝp¿¡`

*Example input 2:* `Wi_ll I be mi_rrored?!`
*Output 2:* `Will I qǝ ɯırrored?!`

---

When it is mirrored by `|` we simply reverse the substring from 0 to index-of-`|`.

*Example input 1:* `Will I be mirror|ed?!`
*Output 1:* `Will I be mirrorrorrim eb I lliW`

Both mirrors (`_` and `|`) can be present in the string.

---

**General rules:**

* This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
* Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
* Default Loopholes are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.

**Test cases:**

```
_Will I be mirrored?!                          ->   Mıll I qǝ ɯıɹɹoɹǝp¿¡
Wi_ll I be mi_rrored?!                         ->   Will I qǝ ɯırrored?!
Will I be mirror|ed?!                          ->   Will I be mirrorrorrim eb I lliW
This_ is a test_ cont_aining bo|t_h mirrors.   ->   This ıs ɐ ʇǝsʇ contɐıuıuɓ qooq ɓuıuıɐtnoc ʇsǝʇ ɐ sı sihT
0_1_2_3_4_5|_6_7_8_9                           ->   0⇂2Ɛ4ϛϛ4Ɛ2⇂0

```

# Answer
> 3 votes
# Pyth - 174 bytes

Can prolly save with base compression or something cuz of unicode(this is only 119 chars)

```
u?qH\_&=hZG+G@@c2K+s+rB;1UT".?! ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡ "ZxKH?}\|zs_Bhcz\|zk

```

Test Suite.

# Answer
> 2 votes
# JavaScript (ES6), 308 bytes

```
s=>s[r='replace'](/_.*?(_|$)/g,m=>m[r](/./g,c=>'| ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡'['| abcdefghijklmnopqrstuvwxyzACDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?!B'.indexOf(c)]||''))[r](/(.*)\|.*/,(m,t)=>t+[...t].reverse().join``)

```

## Test

```
var solution =

s=>
  s[r='replace'](/_.*?(_|$)/g,m=>
    m[r](/./g,c=>
      '| ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡'
        ['| abcdefghijklmnopqrstuvwxyzACDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?!B'
          .indexOf(c)]||''
    )
  )
  [r](/(.*)\|.*/,(m,t)=>t+[...t].reverse().join``)

var testCases = [
  '_Will I be mirrored?!',
  'Wi_ll I be mi_rrored?!',
  'Will I be mirror|ed?!',
  'This_ is a test_ cont_aining bo|t_h mirrors.',
  '0_1_2_3_4_5|_6_7_8_9'
];
tests.textContent = testCases.map((c) => c + '   =>   ' + solution(c)).join('\n');
```

```
<input type="text" oninput="result.textContent=solution(this.value)" value="This_ is a test_ cont_aining bo|t_h mirrors." /><pre id="result"></pre><pre id="tests"></pre>
```

# Answer
> 2 votes
# PERL 243

242 + 1 for -p

```
$h=(split'\|',$_)[0];$_=$h.reverse$h if($_=~/\|/);for$b(split'_',$_){$b=~y/A-Za-z0-9.?!/ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡/ if($f);$\.=$b;$f=!$f;}$_='';

```

Ungolfed:

```
$reverse = (split('\|', $_))[0];
$_ = $reverse . reverse($reverse) if($_=~/\|/);

for $block (split '_', $_) {
    $block =~ y/A-Za-z0-9.?!/ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡/ if($flip);
    $\.=$block;
    $flip=!$flip;
}
$_='';

```

Example:

```
$ perl -p mirror.pl <<<'Will I be mirror|ed?!'
Will I be mirrorrorrim eb I lliW

```

I'm 99% sure this works, but most of the upsidedown characters don't display correctly on my system. I tested it by using a different range of character, e.g. `.?! -> %^&` instead of `.?! -> ˙¿¡`.

# Answer
> 2 votes
# R, 362 362 342 339 bytes

Edit 1: I found a bug in my original (failed if there were no `_` in input), fixed it, golfed some more, and I'm back at 362 where I started!

Edit 2: Golfed away 20 byes by replacing `"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?! "` with `paste(c(letters,LETTERS,0:9,".?! "),collapse="")`

Edit 3: Removing some extra whitespace shaves off another 3 bytes.

```
p=strsplit
l=length
i=p(readline(),"_")[[1]]
if(l(i)-1)i[v]=chartr(paste(c(letters,LETTERS,0:9,".?! "),collapse=""),"ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡ ",i[v<-seq(2,l(i),2)])
i=unlist(p(i,""))
if(l(b<-which(i=="|")-1))i[1:b+b]=rev(i[1:b])
cat(i,sep="")

```

Explained:

```
p=strsplit               # Aliases for common functions
l=length
i=p(readline(),"_")[[1]] # Read input, split by _s. Now every even-indexed substring is one that we must
                         # mirror vertically. (R indexes from 1.)
if(l(i)-1)               # If there are any _s,
  i[v]=chartr("paste(c(letters,LETTERS,0:9,".?! "),collapse=""),
  "ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡ ",
  i[v<-seq(2, l(i), 2)]
)                 # Flip the characters in the vertically-mirrored substrings
i=unlist(p(i,"")) # Split each substring into a single character object
if(l(b<-which(i=="|")-1)) # If there is a |,
  i[1:b+b]=rev(i[1:b])    # insert the reversed characters at the end of the list
cat(i,sep="")             # Print output

```

# Answer
> 1 votes
# Javascript (ES5), 344 340 bytes

```
function mirror(a){d=[];~a.indexOf("|")&&(a=a.split("|")[0]+a.split("|")[0].split("").reverse().join(""));for(var c=!1,b=0;b<a.length;++b)"_"==a[b]&&(c=!c),d[b]=c?"zʎxʍʌnʇsɹbdouɯlʞɾᴉɥɓɟǝpɔqɐZ⅄XMΛ∩⊥SᴚΌԀONW⅂⋊ſIH⅁ℲƎᗡƆᗺⱯ068ㄥ95߈Ɛᘔ⇂˙¿¡ "["zyxwvutsrqponmlkijhgfedcbaZYXWVUTSRQPNOMLKIJHGFEDCBA0987654321.?! ".indexOf(a[b])]:a[b];return d.join("")}

```

Ungolfed:

```
function mirror_u(s){return "zʎxʍʌnʇsɹbdouɯlʞɾᴉɥɓɟǝpɔqɐZ⅄XMΛ∩⊥SᴚΌԀONW⅂⋊ſIH⅁ℲƎᗡƆᗺⱯ068ㄥ95߈Ɛᘔ⇂˙¿¡ "["zyxwvutsrqponmlkijhgfedcbaZYXWVUTSRQPNOMLKIJHGFEDCBA0987654321.?! ".indexOf(s)]};

function mirror(str){var b=[];
if(~str.indexOf("|"))str=str.split("|")[0]+str.split("|")[0].split("").reverse().join("");
    var is_mirrored=false;
    for(var i=0;i<str.length;++i){
        if(str[i]=="_")is_mirrored=!is_mirrored;
        if(is_mirrored){b[i]=mirror_u(str[i])}else{b[i]=str[i]};
    }
    return b.join("");
}

```

EDIT: Longer working code, that is mirrored | by character 341.

```
function mirror(a){d=[];~a.indexOf("|")&&(a=a.split("|")[0]+a.split("|")[0].split("").reverse().join(""));for(var c=!1,b=0;b<a.length;++b)"_"==a[b]&&(c=!c),d[b]=c?"zʎxʍʌnʇsɹbdouɯlʞɾᴉɥɓɟǝpɔqɐZ⅄XMΛ∩⊥SᴚΌԀONW⅂⋊ſIH⅁ℲƎᗡƆᗺⱯ068ㄥ95߈Ɛᘔ⇂˙¿¡ "["zyxwvutsrqponmlkijhgfedcbaZYXWVUTSRQPNOMLKIJHGFEDCBA0987654321.?! ".indexOf(a[b])]:a[b];return d.join("")}//})""(nioj.d nruter;]b[a:])]b[a(fOxedni." !?.1234567890ABCDEFGHJIKLMONPQRSTUVWXYZabcdefghjiklmnopqrstuvwxyz"[" ¡¿˙⇂ᘔƐ߈59ㄥ860ⱯᗺƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Zɐqɔpǝɟɓɥᴉɾʞlɯuodbɹsʇnʌʍxʎz"?c=]b[d,)c!=c(&&]b[a=="_")b++;htgnel.a<b;0=b,1!=c rav(rof;))""(nioj.)(esrever.)""(tilps.]0[)"|"(tilps.a+]0[)"|"(tilps.a=a(&&)"|"(fOxedni.a~;][=d{)a(rorrim noitcnuf

```

# Answer
> 1 votes
# Retina, 176 bytes

```
\|.+
:$`
O$^`:|(?!^)\G.

:

T`w.?!`_0⇂ᘔƐ߈ϛ9ㄥ86∀:ƆᗡƎℲ⅁\HIſ⋊⅂WN\OԀΌᴚS⊥∩ΛMX⅄Zɐqɔ\pǝɟɓɥıɾʞ\lɯu\o\dbɹsʇnʌʍxʎz˙¿¡`_[^_]*_?
:

```

Try it online! (The first line enables a linefeed-separated test suite.)

# Answer
> 0 votes
# Java 7, ~~504~~ 502 bytes

```
import java.util.*;String c(String s){Map m=new HashMap();int i=0,j;while(i<67)m.put("abcdefghijklmnopqrstuvwxyzABBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?! ".charAt(i),"ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡ ".charAt(i++));String q=s.split("\\|")[0],z[]=(q+(s.equals(q)?"":new StringBuffer(q).reverse()+"")).split("_"),r="";for(i=-1;++i<z.length;){q="";for(char c:z[i].toCharArray())q+=m.get(c);r+=i%2<1?z[i]:q;}return r;}

```

Of course I'll have to answer my own challenge again. And.. it's long.. xD

**Ungolfed & test cases:**

Try it here.

```
import java.util.*;
class M{
  static String c(String s){
    Map m = new HashMap();
    int i = 0,
        j;
    while(i < 67){
      m.put("abcdefghijklmnopqrstuvwxyzABBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.?! ".charAt(i),
          "ɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz∀ƆᗡƎℲ⅁HIſ⋊⅂WNOԀΌᴚS⊥∩ΛMX⅄Z0⇂ᘔƐ߈ϛ9ㄥ86˙¿¡ ".charAt(i++));
    }
    String q = s.split("\\|")[0],
           z[] = (q + (s.equals(q)
                        ? ""
                        : new StringBuffer(q).reverse() + "")
                 ).split("_"),
           r = "";
    for(i = -1; ++i < z.length;){
      q = "";
      for(char c : z[i].toCharArray()){
        q += m.get(c);
      }
      r += i%2 < 1
            ? z[i]
            : q;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("_Will I be mirrored?!"));
    System.out.println(c("Wi_ll I be mi_rrored?!"));
    System.out.println(c("Will I be mirror|ed?!"));
    System.out.println(c("This_ is a test_ cont_aining bo|t_h mirrors."));
    System.out.println(c("0_1_2_3_4_5|_6_7_8_9"));
  }
}

```

**Output:**

```
Mıll I qǝ ɯıɹɹoɹǝp¿¡
Will I qǝ ɯırrored?!
Will I be mirrorrorrim eb I lliW
This ıs ɐ ʇǝsʇ contɐıuıuɓ qooq ɓuıuıɐtnoc ʇsǝʇ ɐ sı sihT
0⇂2Ɛ4ϛϛ4Ɛ2⇂0

```

---
Tags: code-golf, string
---


title: Count the Bytes!

text:
# Question
Title: Count the Bytes!
## Challenge

Write a program which takes the URL of a PPCG answer as input and outputs the length of the answer's first code block in bytes.

## Code Blocks

There are three different ways of formatting code blocks:

**Four spaces before the code (`-` represents a space, here)**

```
----Code goes here

```

**Surrounding the code in `<pre>` tags:**

```
<pre>Code goes here</pre>

```

or:

```
<pre>
Code goes here
</pre>

```

**Surrounding the code in `<pre><code>` tags (in that order):**

```
<pre><code>Code goes here</code></pre>

```

## Rules

You should only use the first code block in answer. Assume that the supplied answer will always have a code block.

You must find the length of the answer in *bytes*, not any other metric such as characters.

Solutions using the Stack Exchange Data Explorer or the Stack Exchange API are allowed. URL shorteners are disallowed.

Assume all programs use UTF-8 encoding.

## Examples

```
Input:  https://codegolf.stackexchange.com/a/91904/30525
Output: 34

```

**Link**

---

```
Input:  https://codegolf.stackexchange.com/a/91693/30525
Output: 195

```

**Link**

---

```
Input:  https://codegolf.stackexchange.com/a/80691/30525
Output: 61

```

**Link**

*Note:* Despite what the answer may say, due to APL using a different encoding, 33 bytes isn't its UTF-8 byte count

## Winning

The shortest code in bytes wins.

# Answer
> 3 votes
# jQuery JavaScript, 97 Bytes

```
console.log((new Blob([$("#answer-"+location.hash.substr(1)+" code").eq(0).text().trim()])).size)

```

old version 151 Bytes

```
s=$('#answer-'+location.hash.substr(1)+' code').eq(0).text().trim();c=0;for(i=s.length;i--;)d=s.charCodeAt(i),c=d<128?c+1:d<2048?c+2:c+3;console.log(c)

```

old version 163 Bytes

```
s=$('#answer-'+location.hash.substr(1)+' code').first().text().trim();c=0;for(i=0;i<s.length;i++){d=s.charCodeAt(i);c=(d<128)?c+1:(d<2048)?c+2:c+3;}console.log(c);

```

input ist location and jQuery is active on the site

# Answer
> 4 votes
# C#, ~~249~~ 270 bytes

```
u=>{var c=new System.Net.Http.HttpClient().GetStringAsync(u).Result;var i=c.IndexOf("de>",c.IndexOf('"'+u.Split('/')[4]))+3;return System.Text.Encoding.UTF8.GetByteCount(c.Substring(i,c.IndexOf("<",i)-i-1).Replace(">",">").Replace("<","<").Replace("&","&"));};

```

I've made some assumptions based on observations of the HTML of pages. Hopefully they hold true for all answer posts.

*+21 bytes to unencode `&` to `&`. My answer failed to count it's own bytes. ;P*

Ungolfed:

```
/*Func<string, int> Lambda =*/ u =>
{
    // Download HTML of the page.
    // Although new System.New.WebClient().DownloadString(u) looks shorter, it doesn't
    // preserve the UTF8 encoding.
    var c = new System.Net.Http.HttpClient().GetStringAsync(u).Result;

    // Using the answer id from the URL, find the index of the start of the code block.
    // Empirical observation has found that all code blocks are in <code> tags,
    // there are no other HTML tags that end with "de>",
    // and that '>' and '<' are encoded to '>'/'<' so no jerk can put "de>"
    // before the first code block.
    var i = c.IndexOf("de>", c.IndexOf('"' + u.Split('/')[4])) + 3;

    // Get the substring of the code block text, unencode '>'/'<'/'&' and get the byte count.
    // Again, empirical observation shows the closing </code> tag is always on a new
    // line, so always remove 1 character when getting the substring.
    return System.Text.Encoding.UTF8.GetByteCount(c.Substring(i, c.IndexOf("<", i) - i - 1).Replace(">", ">").Replace("<", "<")..Replace("&", "&"));
};

```

Results:

```
Input:  http://codegolf.stackexchange.com/a/91904/30525
Output: 34

Input:  http://codegolf.stackexchange.com/a/91693/30525
Output: 195 (at the time of this answer the first post has 196, but I can't find the 196th
byte, even counting by hand, so assuming 195 is correct)

Input:  http://codegolf.stackexchange.com/a/80691/30525
Output: 61

Input:  http://codegolf.stackexchange.com/a/91995/58106 (this answer)
Output: 270

```

# Answer
> 2 votes
# Java 7, ~~314~~ 313 bytes

```
int c(String u)throws Exception{String x="utf8",s=new java.util.Scanner(new java.net.URL(u).openStream(),x).useDelimiter("\\A").next();int j=s.indexOf("de>",s.indexOf('"'+u.split("/")[4]))+3;return s.substring(j,s.indexOf("<",j)-1).replace(">",">").replace("<","<").replace("&","&").getBytes(x).length;}

```

Shamelessly stolen from *@milk*'s C# answer and ported to Java 7.
NOTE: This assumes all code is in `<code>` blocks. Currently it won't work with just `<pre>` tags (but who uses those anyway?.. ;p).

**Ungolfed & test cases:**

```
class M{
  static int c(String u) throws Exception{
    String x = "utf8",
           s = new java.util.Scanner(new java.net.URL(u).openStream(), x).useDelimiter("\\A").next();
    int j = s.indexOf("de>", s.indexOf('"'+u.split("/")[4])) + 3;
    return s.substring(j, s.indexOf("<", j) - 1).replace(">", ">").replace("<", "<").replace("&", "&")
        .getBytes(x).length;
  }

  public static void main(String[] a) throws Exception{
    System.out.println(c("https://codegolf.stackexchange.com/a/91904/30525"));
    System.out.println(c("https://codegolf.stackexchange.com/a/91693/30525"));
    System.out.println(c("https://codegolf.stackexchange.com/a/80691/30525"));
    System.out.println(c("https://codegolf.stackexchange.com/a/91995/58106"));
  }
}

```

**Output:**

```
34
195
61
270

```

---
Tags: code-golf, internet, stack-exchange-api
---


title: End the tabs versus space war

text:
# Question
Title: End the tabs versus space war
# End the tabs versus space war

So, there has been a great deal of debate of whether to use tabs or spaces to indent/format code. Can you help the university settle the dispute, by going to an incredibly ~~crazy~~ unique method of formatting.

---

Your job is to write a full program or function which expands all tabs into four spaces. And then replaces a run of n leading spaces with "/(n - two stars here)/". You will receive input over multiple lines in any reasonable format (single string array of strings for each new line. Columnar array etc.)
---

Sample input shamelessly stolen. Note that since tabs get automagically expanded to four spaces on SE I represent it as the "^" character, but you must handle tabs (codepoint 0x09) as well. **All "^" characters represent a tabulation.**
```
Calculate the value 256 and test if it's zero
If the interpreter errors on overflow this is where it'll happen
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
    Not zero so multiply by 256 again to get 65536
    [>++++<-]>[<++++++++>-]<[>++++++++<-]
    +>[>
        # Print "32"
        ++++++++++[>+++++<-]>+.-.[-]<
    <[-]<->] <[>>
        # Print "16"
        +++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
    # Print "8"
    ++++++++[>+++++++<-]>.[-]<
<-]<
# Print " bit cells\n"
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-
Clean up used cells.
[[-]<]l
^this is preceded by a tab
^^two tabs
^^^three tabs etcetera!

```

Sample output

```
Calculate the value 256 and test if it's zero
If the interpreter errors on overflow this is where it'll happen
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
/**/Not zero so multiply by 256 again to get 65536
/**/[>++++<-]>[<++++++++>-]<[>++++++++<-]
/**/+>[>
/******/# Print "32"
/******/++++++++++[>+++++<-]>+.-.[-]<
/**/<[-]<->] <[>>
/******/# Print "16"
/******/+++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
/**/# Print "8"
/**/++++++++[>+++++++<-]>.[-]<
<-]<
# Print " bit cells\n"
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-
Clean up used cells.
[[-]<]l
/**/this is preceded by a tab
/******/two tabs
/**********/three tabs etcetera!

```

---

Because the university needs space to download both Vim and Emacs, you are allowed very little storage for your code. Therefore this is and the shortest code wins. You may assume that input is well formed and lines with less than four spaces (after replacement of tabs) may result in undefined behavior.

### Disclaimer

This "excellent" formatting strategy came courtesy of Geobits, and is reproduced with his permission. No programmers were harmed during the production of this challenge.

# Answer
> 2 votes
# , ~~21~~, 20 bytes

```
Íô/
Î^hr/hv0r*r/

```

Try it online!

This is literally just a direct port of my vim answer. The notable differences:

* The `Í` command (Global substitute) automatically fills in the `/g` flag, which saves two bytes
* `ô` is identical to `\t`
* `Î` Is a mnemonic for `:%norm`, and it also fills in the necessary space between `:%norm` and the set of keystrokes.
* The trailing carriage return at the end is implicitly added.

# Answer
> 27 votes
# Vim, ~~37, 34, 33,~~ 32 bytes

```
:%s/\t/    /g|%norm ^hr/hv0r*r/

```

Try it online!

Note that this requires a trailing carriage return (enter) in vim, although not in the online interpreter.

This uses the V interpreter because it's backwards compatible. A very straightforward solution.

Here's a gif that lets you see the solution happen in real time. This uses a slightly older version, and I added some extra keystrokes to make it run slower so you can see what happens:

And here is the explanation of how it works:

```
:%s/\t/    /g           "Replace every tab with 4 spaces
|                       "AND
%norm                   "On every line:
      ^                 "  Move to the first non-whitespace char
       h                "  Move one character to the left. If there is none, the command will end here.
         r/             "  Replace it with a slash
           h            "  Move to the left
            v0          "  Visually select everything until the first column
              r*        "  Replace this selection with asterisks
                r/      "  Replace the first character with a slash

```

# Answer
> 11 votes
# Perl, 41 bytes

```
s,␉,    ,g;s,^  ( +),/@{[$1=~y| |*|r]}/,

```

Run with the `-p` flag, like so:

```
perl -pe 's,␉,    ,g;s,^  ( +),/@{[$1=~y| |*|r]}/,'
#     ↑   └───────────────────┬───────────────────┘
#     1 byte               40 bytes

```

Replace  by a tab (in Bash, try typing `Control-V` `Tab`.)

# Answer
> 7 votes
# Cheddar, ~~60~~ ~~57~~ 56 bytes

*Saved 3 bytes thanks to @Conor O'Brien*

```
@.sub(/\t/g," "*4).sub(/^ +/gm,i->"/"+"*"*(i.len-2)+"/")

```

I wish Cheddar had better string formatting.

Try it online!

## Explanation

This is a function. `@` is a represents functionized property (e.g. ruby's `&:`) letting you do things like: \`ar.map(@.head(-1))

```
@                      // Input
 .sub( /\t/g, " "*4)   // Replace tabs with four spaces
 .sub(
   /^ +/gm,            // Regex matches leading spaces
   i ->                // i is the matched leading spaces
     "/"+              // The / at the beginning
     "*"*(i.len-2)+    // Repeat *s i-2 times
     "/"                // The / at the end
 )

```

If you aren't familiar with regex the:

```
/^ +/gm

```

this basically matched one or more (`+`) spaces () at the beginning (`^`) of every (`g`) line (`m`).

# Answer
> 6 votes
# Mathematica, 97 bytes

```
a=StringReplace;a[a[#,"\t"->"    "],StartOfLine~~b:" "..:>"/"<>Table["*",StringLength@b-2]<>"/"]&

```

Anonymous function. Takes a string as input and returns a string as output.

# Answer
> 5 votes
# Python 3, 124 bytes

Uses good ol' regex.

```
import re
lambda I:re.sub('^\s*(?m)',lambda m:'/'+'*'*len(m.group()[:-2])+'/',re.sub('\t+',lambda g:' '*4*len(g.group()),I))

```

**Ideone it!**

# Answer
> 4 votes
# Java ~~210~~ 207 bytes

This is the reference solution which implements it naively.

```
void a(String[]a){for(String s:a){s=s.replaceAll("\t", "    ");String x,y="";int j,i=s.length()-(x=s.replaceAll("^\\s+", "")).length();if(i>3){y="/";for(j=0;j++<i-1;)y+="*";y+="/";}System.out.println(y+x);}}

```

# Answer
> 3 votes
# JavaScript ES6, 75 bytes

```
s=>s.replace(/\t/g,"    ").replace(/^ +/gm,k=>`/${"*".repeat(k.length-2)}/`)

```

Replace `\t` with a literal tab in your code.

# Answer
> 3 votes
# Java, ~~185~~ ~~184~~ ~~167~~ 152 bytes

```
S->S.map(s->{s=s.replace("\t","    ");String t=s.replaceAll("^ +","");int n=s.length()-t.length();if(n>3){s="/";for(;n-->2;)s+="*";s+="/"+t;}return s;})

```

Given the very loose definition of string array given in the initial post, I've used `Stream<String>` which allows for some consequent byte savings.

I used different techniques than the RI to achieve the same goal. The algorithm itself is rather the same.

**Testing and ungolfed**:

```
import java.util.Arrays;
import java.util.stream.Stream;

public class Main {

  public static void main(String[] args) {
    StringStreamTransformer sst = lines -> lines.map(line -> {
      line = line.replace("\t","    ");
      String trimmed = line.replaceAll("^ +", "");
      int startingSpaces = line.length() - trimmed.length();
      if (startingSpaces > 3) {
        line = "/";
        for(;startingSpaces > 2; startingSpaces--) {
          line += "*";
        }
        line += "/" + trimmed;
      }
      return line;
    });

    Stream<String> lines = Arrays.stream(new String[]{
      "lots of spaces and tabs after\t\t    \t\t         \t\t\t\t\t",
      "no space",
      " 1 space",
      "  2 spaces",
      "   3 spaces",
      "    4 spaces",
      "     5 spaces",
      "      6 spaces",
      "       7 spaces",
      "        8 spaces",
      "\t1 tab",
      "\t\t2 tabs",
      "\t\t\t3 tabs"
    });
    sst.map(lines).map(s -> s.replace(" ", ".").replace("\t","-")).forEach(System.out::println);

  }
}

```

# Answer
> 2 votes
# Python, ~~125~~ 111 bytes

```
lambda s:'\n'.join(('/'+(len(L.replace('\t',' '*4))-len(L.strip())-2)*'*'+'/'+L.strip(),L)[L[0]>' ']for L in s)

```

https://repl.it/DGyh/2

# Answer
> 2 votes
# Retina, 25 bytes

The `\t` should be replaced with an actual tab character (0x09).

```
\t
4$*
%`^  ( +)
/$.1$**/

```

Try it online!

### Explanation

```
\t
4$*

```

Replace each tab with four spaces.

```
%`^  ( +)
/$.1$**/

```

Transform each line separately (`%`) by matching `2+N` spaces at the beginning of the line and replacing it with `/.../` where `...` is `N` copies of `*`.

# Answer
> 2 votes
# SED (56 + 1 for -r) 57

```
s/⇥/    /g;tr;:r;s,^ ( *) ,/\1/,;T;:l;s,^(/\**) ,\1*,;tl

```

Where  is a tab
1. replaces tabs with spaces.
2. replaces the first and last leading space with `/`.
3. replaces the first space after `/` and 0+ `*`s with a `*` until there isn't a match.

# Answer
> 1 votes
## GNU sed, ~~66~~ 64 + 1(r flag) = 65 bytes

**Edit:** 1 byte less thanks to Riley's suggestion.

```
s/\t/    /g
s,^ ( *) ,/\1\n,
:
s,^(/\**) ( *\n),\1*\2,
t
s,\n,/,

```

**Run:** sed -rf formatter.sed input\_file

The reason for separating with a `\n` the leading spaces from the rest of the text on that line, is because otherwise a C++ line starting with a comment like this `/* */` would be turn into `/*****/` by a simpler line 4 like `s,^(/\**) ,\1*,` or even `s,^(/\**) ( */),\1*\2,`. Since sed executes the script for each input line, no `\n` is introduced in the pattern space on reading.

# Answer
> 1 votes
# Ruby, ~~52~~ 47 + 1 (p flag) = 48 bytes

**Edit**: saved whole 5 bytes, thanks to Value Ink

```
ruby -pe 'gsub ?\t," "*4;sub(/^ +/){?/+?**($&.size-2)+?/}'

```

# Answer
> 1 votes
The university should consider allowing a bit more space for programs in Emacs Lisp (or default to `tabify` and `untabify` alone), as they get even more verbose than Java. It should also pay close attention to students (or teachers) whose identation size is smaller than four or who happen to code in some non-C-like language.

The following solution has **206 bytes**

```
(lambda (b e)(let((tab-width 4))(untabify b e)(goto-char b)(while(re-search-forward"^ +"e t)(replace-match(format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2)))))))))

```

Assuming that `tab-width` needs not to be explicitly set, we can save 20 of them.

```
(lambda(b e)(untabify b e)(goto-char b)(while(re-search-forward"^ +"e t)(replace-match(format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2))))))))

```

And ungolfed version would look like this

```
(defun end-tab-war (beg end)
  (let ((tab-width 4))
    (untabify beg end)
    (goto-char beg)
    (while (re-search-forward "^ +" end t)
      (replace-match
       (format
        "/%s/"
        (apply 'concat
               (mapcar (lambda(x) "*")
                       (number-sequence 1
                                        (- (length (match-string 0))
                                           2)))))))))

```

We first `untabify` the region before jumping to its start. Then, while we see whitespace at the beginning of a line, we replace it with a comment that is as long as said whitespace. To be exact, the comment to be inserted is constructed by

```
 (format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2)))))

```

which itself takes up 97 bytes. A shorter solution to copy some string n times is highly appreciated.

---
Tags: code-golf, string, whitespace
---


# Question
Title: Render the top-down view of a hip roof in ASCII
First, some terminology (source):

* A hip roof is (quoting Wikipedia) "a type of roof where all sides slope downwards to the walls, usually with a fairly gentle slope"
* A slope is a planar surface that is a part of the roof
* A ridge is an edge where two opposite roof slopes meet
* A hip is a convex edge where two slopes belonging to perpendicular walls meet
* A valley is a concave edge where two slopes belonging to perpendicular walls meet
* Hips and valleys shall be collectively referred to as diagonal edges.

Possible input:

```
 ** * ***
********
 ** *  **

```

Corresponding output:

```
    +-------+   +---+   +-----------+
    |\     /|   |\ /|   |\         /|
    | \   / |   | V |   | \   ^---< |
    |  \ /  |   | | |   |  \ / \   \|
+---+   V   +---+ | +---+   X   +---+
|\   \  |  /     \|/     \ / \  |
| >---> | <-------X-------V   > |
|/   /  |  \     /|\         /| |
+---+   ^   +---+ | +-------+ | +---+
    |  / \  |   | | |       | |/   /|
    | /   \ |   | ^ |       | /---< |
    |/     \|   |/ \|       |/     \|
    +-------+   +---+       +-------+

```

A couple more test cases:

```
** ***   *    *   * *
*       ***   *****
    ** *****  *****
* *  *  ***  *** ***
* ****   *     * *

```

Corresponding outputs :

```
+-------+   +-----------+           +---+               +---+           +---+   +---+
|\     /|   |\         /|           |\ /|               |\ /|           |\ /|   |\ /|
| \---< |   | >-------< |           | V |               | V |           | V |   | X |
| |\   \|   |/         \|           | | |               | | |           | | |   |/ \|
| | +---+   +-----------+       +---+ | +---+           | | +-----------+ | |   +---+
| | |                           |\   \|/   /|           | |/             \| |
| ^ |                           | \   V   / |           | <               > |
|/ \|                           |  \     /  |           |  \             /  |
+---+           +-------+   +---+   \   /   +---+       |   \-----------/   |
                |\     /|   |\   \   \ /   /   /|       |   |\         /|   |
                | >---/ |   | >--->   X   <---< |       |   | \       / |   |
                |/   /| |   |/   /   / \   \   \|       |   |  \     /  |   |
+---+   +---+   +---+ | |   +---+   /   \   +---+   +---+   ^   +---+   ^   +---+
|\ /|   |\ /|       | | |       |  /     \  |       |\   \ / \  |   |  / \ /   /|
| V |   | V |       | | |       | /   ^   \ |       | >---V   > |   | <   V---< |
| | |   | | |       | | |       |/   /|\   \|       |/       /| |   | |\       \|
| | |   | | +-------+ | |       +---+ | +---+       +-------+ | |   | | +-------+
| | |   | |/         \| |           | | |                   | | |   | | |
| ^ |   | /-----------\ |           | ^ |                   | ^ |   | ^ |
|/ \|   |/             \|           |/ \|                   |/ \|   |/ \|
+---+   +---------------+           +---+                   +---+   +---+

```

Your **input** will be a bitmap - a 2D array of square pixels - of the area that should be covered by roof. You may assume the boundary of this area will be a Jordan curve - that is, continuous and non-self-intersecting - that is, the roofed area will be continuous, without holes and there will never be four walls meeting at a single point. Valid input formats include a single string with newline separators, a list of strings and a 2D array of chars or booleans.

**The rules of building the roof** are:

* Each straight segment of the roofed area (henceforth referred to as a wall) shall have exactly one adjoining slope. The slope shall rise away from the wall. Each slope shall have at least one adjoining wall, and all walls adjoining to a slope must be collinear.
* All slopes shall have the same (nonzero) angle against the horizontal surface. That is, they must have the same pitch.
* The slopes shall form a surface whose boundary is the boundary of the roofed area. That is, no surfaces other than the slopes may be used.
* Any scenario where more than one solution (up to vertical scaling) is allowed by this specification is considered a bug in the specification. Any corrections apply retroactively.

Equivalently, the roof may be defined by the rule that each point of the roof is placed as high as possible without exceeding the maximum slope for that roof as measured using the Chebyshev distance in top-down view.

Your **output** shall be an ASCII art representation of the roof - either a single string containing newline characters or an array of strings, each denoting a single line of the output. The roof shall be rendered in top-down view at a 4x scale - that is, each square of the floor-plan should affect a 5x5 area of the output such that the corners of this 5x5 area are shared with neighboring squares (such that each corner character is affected by four different input squares), as indicated by the example output. Extra whitespace is allowed as long as the output shape is preserved. The characters in output shall be:

* an environment-defined newline marker shall be used (usually U+000A, U+000D or a pair of both) if the output is in the form of a single string
* (U+0020 space) represents a point outside a roofed area or a point interior to a slope
* `+` (U+002B plus sign) represents a point with two perpendicular walls adjoined to it
* `-` (U+002D hyphen-minus) represents a wall or a ridge oriented horizontally (east-west)
* `/` (U+002F solidus) represents a hip or a valley oriented north-east to south-east, or a point adjoined to two of those
* `<` (U+003C less-than sign) represents a point with two diagonal edges adjoined to it on the east
* `>` (U+003E greater-than sign) represents a point with two diagonal edges adjoined to it on the west
* `\` (U+005C reverse solidus) represents a hip or a valley oriented north-west to south-east, or a point adjoined to two of those
* `^` (U+005E circumflex accent) represents a point with two diagonal edges adjoined to it on the south
* `V` (U+0056 latin capital letter v) represents a point with two diagonal edges adjoined to it on the north
* `X` (U+0058 latin capital letter x) represents a point with diagonal edges adjoined to it on all four sides
* `|` (U+007C vertical bar) represents a wall or a ridge oriented vertically (north-south)

Note that it is not possible for an odd number of diagonal edges to end at the same point (except on walls). We can visualize that by partitioning the neighborhood of each point into north slope + south slope and into east slope + west slope. The boundary between both partitions has to be composed of diagonal edges.

If your environment uses a character encoding incompatible with ASCII, you may use the equivalent characters (same glyph or closest available) in the character encoding your environment uses.

The following (ugly) **reference implementation** in Ruby is normative with respect to the non-whitespace output. Note particularly the `render` method:

```
def pad ary
  row = ary.first.map{-1}
  ([row] + ary + [row]).map{|r| [-1] + r + [-1]}
end

def parse str
  str.split("\n").map{|r| r.chars.map(&{" " => -1, "*" => Float::INFINITY})}
end

def squares ary, size
  ary.each_cons(size).map do |rows|
    rows.map{|row| row.each_cons(size).to_a}.transpose
  end
end

def consmap2d ary, size
  squares(ary, size).map{|sqrow| sqrow.map{|sq| yield sq}}
end

def relax ary
  loop do
    new = consmap2d(pad(ary), 3){|sq| sq[1][1] == -1 ? -1 : sq.flatten.min + 1}
    return new if new == ary
    ary = new
  end
end

def semidouble ary, op
  ary.zip(ary.each_cons(2).map{|r1,r2|r1.zip(r2).map(&op)}).flatten(1).compact.transpose
end

def heightmap str
  relax(semidouble(semidouble(semidouble(semidouble(pad(parse str),:max),:max),:min),:min))
end

def render heightmap
  puts consmap2d(heightmap, 3){|sq|
    next " " if sq[1][1] == -1
    hwall = sq[0][1] == -1 || sq[2][1] == -1
    vwall = sq[1][0] == -1 || sq[1][2] == -1
    next "+" if hwall && vwall
    next "-" if hwall
    next "|" if vwall
    next "+" if sq.flatten.min == -1

    nws = sq[0][1] == sq[1][0]
    nes = sq[0][1] == sq[1][2]
    sws = sq[2][1] == sq[1][0]
    ses = sq[2][1] == sq[1][2]

    next "X"  if nws && nes && sws && ses
    next "V"  if nws && nes
    next "^"  if sws && ses
    next ">"  if nws && sws
    next "<"  if nes && ses
    next "/"  if nes && sws
    next "\\" if nws && ses
    next " "  if sq[0][1] != sq[2][1] || sq[1][0] != sq[1][2]
    next "|"  if sq[0][1] == sq[1][1]
    next "-"  if sq[1][0] == sq[1][1]
    ??
  }.map(&:join)
end

render heightmap $<.read if __FILE__ == $0

```

# Answer
> 11 votes
# Python 2, 500 bytes

```
z=input()
W=4*len(z[0])+1
H=4*len(z)+1
R=range
s=[-~W*[0]for _ in R(-~H)]
for y in R(H/4):
 for x in R(W/4):
        for h in R(25):s[y*4+h%5][x*4+h/5]|=z[y][x]
F=[(x/3-1,x%3-1)for x in[1,7,3,5,0,6,8,2]]
exec'for y in R(H):\n for x in R(W):s[y][x]+=0<s[y][x]<=min(s[y+d][x+e]for(e,d)in F)\n'*H
for y in R(H):
 l=''
 for x in R(W):h=s[y][x];a=[s[y+d][x+e]for(e,d)in F[:4]];l+=r' XabcVde^f ||g>h\\+//+<<jk<l//+\\+>>m --^^oVVqrX'[h and int(''.join(`int(n==h)`for n in a),2)*3+((h==1)*2or max(a)==h)+1]
 print l

```

Tired of golfing it down, and I got to a nice round score, so here it is.

The eight-space indentation is a tab.

Pass a binary matrix over STDIN, like so:

```
python2.7 roof.py <<<"[[1,1,0,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0], [1,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0], [0,0,0,0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,1,0], [1,0,1,0,0,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1], [1,0,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0]]"

```

---
Tags: code-golf, ascii-art
---


title: A Formula for Congruences

text:
# Question
Title: A Formula for Congruences
The Chinese Remainder Theorem can be quite useful in modular arithmetic.

For example, consider the following set of congruence relations:

For sets of congruence relations like this, where all the bases (`3, 5, 7` in this example) are co-prime with each other, there will be one and only one integer `n` between `1` and the product of the bases (`3*5*7 = 105` in this example) inclusive that satisfies the relations.

In this example, the number would be `14`, generated by this formula:

where `2, 4, and 0` are given from the above example.

`70, 21, 15` are the **coefficients** of the formula and they are dependent on the bases, `3, 5, 7`.

To calculate the coefficients of the formula (`70, 21, 15` in our example) for a set of bases, we use the following procedure.

For each number `a` in a set of bases:

1. Find the product of all of the other bases, denoted as `P`.
2. Find the first multiple of `P` that leaves a remainder of `1` when divided by `a`. This is the coefficient of `a`.

For example, to calculate the coefficient that corresponds to the base `3`, we find the product of all the other bases (i.e. `5*7 = 35`) and then find the first multiple of that product that leaves a remainder of `1` when divided by the base.

In this case, `35` leaves a remainder of `2` when divided by `3`, but `35*2 = 70` leaves a remainder of `1` when divided by `3`, so `70` is the corresponding coefficient for `3`. Similarly, `3*7 = 21` leaves a remainder of `1` when divided by `5` and `3*5 = 15` leaves a remainder of `1` when divided by `7`.

# In a nutshell

For each number `a` in a set of numbers:

1. Find the product of all of the other numbers, denoted as `P`.
2. Find the first multiple of `P` that leaves a remainder of `1` when divided by `a`. This is the coefficient of `a`.

# The challenge

* The challenge is, for a set of two or more bases, to find the set of corresponding coefficients.
* The set of bases are guaranteed to be pairwise co-prime and each base is guaranteed to be larger than 1.
* Your input is a list of integers as input `[3,4,5]` or space-separated string `"3 4 5"` or however your inputs work.
* Your output should either be a list of integers or space-separated string that denotes the set of coefficients.

# Test cases

```
input             output
[3,5,7]           [70,21,15]
[2,3,5]           [15,10,6]
[3,4,5]           [40,45,36]
[3,4]             [4,9]
[2,3,5,7]         [105,70,126,120]
[40,27,11]        [9801,7480,6480]
[100,27,31]       [61101,49600,56700]
[16,27,25,49,11]  [363825,2371600,2794176,5583600,529200]

```

Many thanks to Leaky Nun for his help in writing this challenge. As always, if the problem is unclear, please let me know. Good luck and good golfing!

# Answer
## Haskell, ~~61~~ ~~55~~ 53 bytes

```
f x=[[p|p<-[0,product x`div`n..],p`mod`n==1]!!0|n<-x]

```

Defines a function `f` that takes input and gives output as a list of integers.

```
f x=[                                          |n<-x]  (1)
              product x                                (2)
                       `div`n                          (3)

```

First we loop over all integers in the input (1). Then we take the product of all of the integers (2) and divide by n to get just the product of the non-`n` integers, which is `P` (3).

```
           [0,               ..]                       (4)
     [p|p<-                     ,p`mod`n==1]           (5)
                                            !!0        (6)

```

Then we use the result (`P`) as the step value for a range starting at zero (4). We take the result, `[0, P, 2P, 3P, ...]`, and filter it on values for which the result of a mod-n operation is one (5). Finally, we take the first element, which works thanks to lazy evaluation (6).

Thanks to @xnor for 2 bytes!
> 5 votes

# Answer
# Jelly, ~~11~~ 7 bytes

```
P:*ÆṪ%P

```

Try it online! or verify all test cases.

### Background

Let **P** and **a** be strictly positive, *coprime* integers.

The two-step process in the question – finding a multiple of **P** that leaves a remainder of **1** when divided by **a** – can be described by the following congruence equation.

By the Euler-Fermat theorem, we have

where **φ** denotes Euler's totient function. From this result, we deduce the following.

Finally, since the challenge requires us to compute **Px**, we observe that

where **Pa** can be computed as the product of all moduli.

### How it works

```
P:*ÆṪ%P  Main link. Argument: A (list of moduli)

P        Yield the product of all moduli.
 :       Divide the product by each modulus in A.
   ÆṪ    Apply Euler's totient function to each modulus.
  *      Raise each quotient to the totient of its denominator.
     %P  Compute the remainder of the powers and the product of all moduli.

```
> 4 votes

# Answer
# J, 13 bytes

```
*/|5&p:^~*/%]

```

Based on @Dennis' amazing answer.

## Usage

Some test cases will need the input as extended integers which have a suffix `x`.

```
   f =: */|5&p:^~*/%]
   f 3 5 7
70 21 15
   f 40x 27 11
9801 7480 6480
   f 16x 27 25 49 11
363825 2371600 2794176 5583600 529200

```

## Explanation

```
*/|5&p:^~*/%]  Input: list B
         */    Reduce B using multiplication to get the product of the values
            ]  Identity function, get B
           %   Divide the product by each value in B, call the result M
   5&p:        Apply the totient function to each value in B, call the result P
       ^~      Raise each value in M to the power of its corresponding value in P
*/             The product of the values in B
  |            Compute each power modulo the product and return

```

Try it here.
> 2 votes

# Answer
# Mathematica, 27 bytes

```
PowerMod[a=LCM@@#/#,-1,#]a&

```
> 2 votes

# Answer
# Pyth, 14 bytes

```
mhfq1%Td*R/*FQ

```

Test suite.

Naive implementation of the algorithm.
> 1 votes

# Answer
# Python 2, ~~87~~ 84 bytes

A simple implementation of the algorithm. Golfing suggestions welcome.

```
a=input();p=1
for i in a:p*=i
print[p/i*j for i in a for j in range(i)if p/i*j%i==1]

```
> 1 votes

# Answer
# Jelly, ~~14~~ 13 bytes

```
P:×"Ḷð%"’¬æ.ḷ

```

Saved a byte thanks to @Dennis!

Uses the process described in the challenge spec. The input is a list of bases and the output is a list of coefficients.

Try it online or Verify all test cases.

## Explanation

```
P:×"Ḷð%"’¬æ.ḷ  Input: a list B
P              Get the product of the list
 :             Divide it by each value in the B, call it M
    Ḷ          Get a range from 0 to k for k in B
  ×"           Vectorized multiply, find the multiples of each M
     ð         Start a new dyadic chain. Input: multiples of M and B
      %"       Vectorized modulo, find the remainders of each multiple by B
        ’      Decrement every value
               If the remainder was 1, decrementing would make it 0
         ¬     Logical NOT, zeros become one and everything else becomes 0
            ḷ  Get the multiples of M
          æ.   Find the dot product between the modified remainders and the multiples
               Return

```
> 1 votes

# Answer
## JavaScript (ES6), 80 bytes

```
a.map(e=>[...Array(e).keys()].find(i=>p*i/e%e==1)*p/e,p=a.reduce((i,j)=>i*j))

```

I tried the extended Euclidean algorithm but it takes 98 bytes:

```
a=>a.map(e=>(r(e,p/e)+e)%e*p/e,p=a.reduce((i,j)=>i*j),r=(a,b,o=0,l=1)=>b?r(b,a%b,t,o-l*(a/b|0)):o)

```

If the values are all prime, ES7 can do it in 56 bytes:

```
a=>a.map(e=>(p/e%e)**(e-2)%e*p/e,p=a.reduce((i,j)=>i*j))

```
> 1 votes

# Answer
# Python + SymPy, 71 bytes

```
from sympy import*
lambda x:[(prod(x)/n)**totient(n)%prod(x)for n in x]

```

This uses the algorithm from my Jelly answer. I/O is in form of lists of SymPy numbers.
> 1 votes

# Answer
# Cheddar, 64 bytes

```
n->n.map(i->(|>i).map(j->(k->k%i>1?0:k)(n.reduce((*))/i*j)).sum)

```
> 1 votes

# Answer
## GAP, 51 bytes

GAP has a function that can compute the motivating example with `ChineseRem([2,5,7],[2,4,0])`, but that still doesn't make it that easy to get the coefficients. We can get the n-th coefficient by using the list with a one in the n-th position and zeroes at the other positions as second argument. So we need to create these lists and apply the function to all of them:

```
l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))

```
> 0 votes

# Answer
## Batch, 148 bytes

```
@set p=%*
@set/ap=%p: =*%
@for %%e in (%*)do @for /l %%i in (1,1,%%e)do @call:l %%e %%i
@exit/b
:l
@set/an=p/%1*%2,r=n%%%1
@if %r%==1 echo %n%

```
> 0 votes

# Answer
# Actually, 14 bytes

This uses the algorithm in Dennis's Jelly answer. Another answer based on my Python answer is forthcoming. Golfing suggestions welcome. Try it online!

```
;π;)♀\;♂▒@♀ⁿ♀%

```

**How it works**

```
                 Implicit input a.
;                Duplicate a.
 π;)             Take product() of a, duplicate and rotate to bottom.
    ♀\           Integer divide the product by each element of a. Call this list b.
      ;♂▒        Take that list, duplicate, and get the totient of each element.
         @♀ⁿ     Swap and take pow(<item in b>, <corresponding totient>)
            ♀%   Modulo each item by the remaining duplicate product on the stack.
                 Implicit return.

```

Another answer based on my Python answer at 22 bytes. Golfing suggestions welcome. Try it online!

```
;π╖`╝╛╜\╛r*"╛@%1="£░`M

```

**How it works**

```
            Implicit input a.
;π╖         Duplicate, take product of a, and save to register 0.
`...`M      Map over a.
  ╝           Save the item, b, in register 1.
  ╛╜\         product(a) // b. Call it P.
  ╛r          Take the range [0...b].
  *           Multiply even item in the range by P. Call this list x.
  "..."£░     Turn a string into a function f.
              Push values of [b] where f returns a truthy value.
    ╛@%         Push b, swap, and push <item in x> % b.
    1=          Does <item> % b == 1?
            Implicit return.

```
> 0 votes

---
Tags: code-golf, math
---


# Question
Title: Scan dactylic hexameter in a unique puzzle
As a terrible Latin student for several years I have learned to hate many things about Latin. However there is one thing I love.

Latin scansion.

Scansion is the act of determining the meter of a particular line of poetry. For Latin this means demarcating each syllable in the line as "light" or "heavy".

In Latin scansion has many of rules. However unlike English Latin scansion is fairly regular and often requires no knowledge of Latin vocabulary or grammar to be performed. For this problem we will be using simplified subset of those rules (real Latin does not have a neat spec).

Before you begin the scansion you must elide. Elision is the dropping syllables between words to ease pronunciation. (e.g. "he is" -\> "he's"). Unlike English, Latin elision follows very nice rules.

* The final vowel of a word ending with a vowel is omitted if the next word begins with a vowel.

NAUTA EST -\> NAUTEST
* The same goes for words ending in a vowel followed by "m".

FIDUM AGRICOLAM -\> FIDAGRICOLAM
* Word-initial "h" followed by a vowel counts as a single vowel for elision purposes and is always dropped when elided.

MULTAE HORAE -\> MULTORAE

or

MULTAM HORAM -\> MULTORAM

After elision we can begin scansion. Scansion is done to a specific meter. The meter for this challenge is dactylic hexameter. Dactylic hexameter has six "feet" each foot consists of two or three syllables. Syllables can be either long or short depending on the vowel. Each of the first five feet will be either a dactyl, a long syllable followed by two short ones, or a spondee, two long syllables. And the last foot will be a long followed by an anceps (short or long, for this problem you will not have to determine which).

* A vowel in latin can be either short or long
* An "i" sandwiched between two vowels (e.g. eiectum) is a consonant. (i.e. a "j")
* An "i" beginning a word followed by a vowel (e.g Iactus) is also a consonant
* A "u" after a "q" is also a consonant (i.e. a "v")
* Diphthongs (ae, au, ei, eu, oe, and ui) are made up of two vowels but count as one vowel and are always long
* A vowel with two or more consonants between it and the next vowel is always long
* For the previous rule an "l" or an "r" after a "b","c","d","g","p", or "t" does not count as a consonant
* "x" counts as two consonants
* "ch", "ph", "th", and "qu" count as one consonant
* The syllable "que" at the end of a word (after elision) is always short
* If a vowel is not forced by one of the previous rules it can be either long or short this will depend on the meter

Your task will be to take a line of latin and produce the scansion of it. You will take in the line as string via standard input and output a string representing the final scansion.

The input will contain only spaces and characters A-Z.

To represent the scansion you will output all of the syllables with `|` demarcating the separation of feet. A long syllable will be represented by a `-` while a short syllable will be marked by a `v` and an anceps (the last syllable of every line) will be marked by a `x`. If there are multiple solutions as there often will be you may output anyone of them.

## Test Cases

The start of Virgil's Aeneid.

```
 ARMA VIRUMQUE CANO TROIAE QUI PRIMUS AB ORIS     -> -vv|-vv|--|--|-vv|-x (or -vv|-vv|--|-vv|--|-x)
 ITALIAM FATO PROFUGUS LAVINIAQUE VENIT           -> -vv|--|-vv|-vv|-vv|-x
 LITORA MULTUM ILLE ET TERRIS IACTATUS ET ALTO    -> -vv|--|--|--|-vv|-x
 VI SUPERUM SAEVAE MEMOREM IUNONIS OB IRAM        -> -vv|--|-vv|--|-vv|-x (or -vv|--|-vv|-vv|--|-x)
 MULTA QUOQUE ET BELLO PASSUS DUM CONDERET URBEM  -> -vv|--|--|--|-vv|-x
 INFERRETQUE DEOS LATIO GENUS UNDE LATINUM        -> --|-vv|-vv|-vv|-vv|-x
 ALBANIQUE PATRES ATQUE ALTAE MOENIA ROMAE        -> --|-vv|--|--|-vv|-x

```

## Further stipulations

In the proper fashion of Latin poetry all answers must begin with an invocation to the muses.

Latin has only two one letter words "e" and "a". You may assume that no other one letter words will appear as input.

# Answer
# sed, ~~402~~ ~~392~~ ~~374~~ ~~359~~ ~~363~~ ~~334~~ 333 bytes

> “Sing, goddess, the anger of Peleus’ son Achilleus and its devastation, which put pains thousandfold upon the Achians, hurled in their multitudes to the house of Hades strong souls of heroes, but gave their bodies to be the delicate feasting of dogs, of all birds, and the will of Zeus was accomplished since that time when first there stood in division of conflict Atreus’ son the lord of men and brilliant Achilleus.”

<sup>*— Homer (The Iliad); confused why this quote is here? check the rules.*</sup>

```
sed -E 's/[AEIOU]M? H?([AEIOU])/\1/g;s/X/cc/g;s/(^|[ AEIOU])I([AEIOU])/\1c\2/g;s/QUE( |$)/cv/g;s/A[EU]|E[IU]|OE|UI/-/g;s/[CPT]H|[BCDGPT][LR]|QU|[^-vAEIOU ]/c/g;s/ //g;s/ucc+/-/g;s/c//g;s/^[-u]([-u]|[vu]{2})[-u]([-u]|[vu]{2})[-u]([-u]|[vu]{2})[-u]([-u]|[vu]{2})[-u]([-u]|[vu]{2})[-u].$/-\1|-\2|-\3|-\4|-\5|-x/;s/[uv]/-/g;s/---/-vv/g'

```

Not exactly golfed, but this implements all the given rules in the form of regular expressions, which sed just runs one-by-one to reach the solution. This handles each line independently, so can process an entire multi-line input.

### Usage:

```
printf 'ARMA VIRUMQUE CANO TROIAE QUI PRIMUS AB ORIS
ITALIAM FATO PROFUGUS LAVINIAQUE VENIT
LITORA MULTUM ILLE ET TERRIS IACTATUS ET ALTO
VI SUPERUM SAEVAE MEMOREM IUNONIS OB IRAM
MULTA QUOQUE ET BELLO PASSUS DUM CONDERET URBEM
INFERRETQUE DEOS LATIO GENUS UNDE LATINUM
ALBANIQUE PATRES ATQUE ALTAE MOENIA ROMAE' | sed -E '<...>';

```

### Breakdown:

```
sed -E "
# Apply Elision
 s/[AEIOU]M? H?([AEIOU])/\1/g;

# Convert into vowels (u, v or -) and consonants (c) according to the rules given
 s/X/cc/g;
 s/(^|[ AEIOU])I([AEIOU])/\1c\2/g;
 s/QUE( |\$)/cv/g;
 s/A[EU]|E[IU]|OE|UI/-/g;
 s/[CPT]H|[BCDGPT][LR]|QU|[^-vAEIOU ]/c/g;
 s/[A-Z]/u/g; # all remaining vowels are unknown

# Remove all spaces
 s/ //g;

# A vowel followed by 2 consonants before the next vowel is long
# (and we don't care if the last vowel is long or short)
 s/ucc+/-/g;

# Remove all consonants
 s/c//g;

# Look for a matching dactylic hexameter and insert pipe separators
 s/^\
[-u]([-u]|[vu]{2})\
[-u]([-u]|[vu]{2})\
[-u]([-u]|[vu]{2})\
[-u]([-u]|[vu]{2})\
[-u]([-u]|[vu]{2})\
[-u].\$/-\1|-\2|-\3|-\4|-\5|-x/;

# Substitute identified feet with the necessary long/short vowels
 s/[uv]/-/g;
 s/---/-vv/g
"

```

### Results for test cases:

```
-vv|-vv|--|--|-vv|-x
-vv|-vv|--|-vv|-vv|-x
-vv|--|--|--|-vv|-x
-vv|--|-vv|-vv|--|-x
-vv|--|--|--|-vv|-x
--|-vv|-vv|-vv|-vv|-x
--|-vv|--|--|-vv|-x

```
> 5 votes

---
Tags: code-golf, natural-language
---