Skip to content

Instantly share code, notes, and snippets.

@mageddo
Last active September 18, 2018 02:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mageddo/c53ed9be260d55b5c67707eed8f574bd to your computer and use it in GitHub Desktop.
Save mageddo/c53ed9be260d55b5c67707eed8f574bd to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
public class WeightSort {
private static final ObjectMapper instance = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
@Test
public void case1() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 5.5, 0.7, 101),
new Item(2, 5.0, 0.6, 100),
new Item(3, 5.0, 0.5, 100)
));
// act
sortToBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(List.of(2, 3, 1), toIdList(offers));
}
@Test
public void sortByEscrowCausePriceAndWearAreEquivalent() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 5.1, 0.05, 99),
new Item(2, 5.3, 0.03, 100),
new Item(3, 5.5, 0.1, 101)
));
// act
sortToBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(List.of(1, 2, 3), toIdList(offers));
}
@Test
public void wontSortAllPropsAreEquivalent() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 5.5, 0.05, 100),
new Item(2, 5.9, 0.06, 100),
new Item(3, 5.1, 0.07, 100)
));
// act
sortToBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(List.of(1, 2, 3), toIdList(offers));
}
@Test
public void sortIgnoringOthersPropsCausePriceHasNoAmbiguousValues() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 6, 0.5, 100),
new Item(2, 7, 0.3, 200),
new Item(3, 5, 0.1, 150)
));
// act
sortToBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(List.of(3, 1, 2), toIdList(offers));
}
@Test
public void findFirstItemCauseOthersHaveVeryDifferentPrice() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 6, 0.5, 100),
new Item(2, 7, 0.3, 200),
new Item(3, 5, 0.1, 150)
));
// act
final Item bestOffer = findBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(3, bestOffer.getId());
}
@Test
public void mustFindItemWithLowestWear() throws Throwable {
// arrange
final List<Item> offers = new ArrayList<>(List.of(
new Item(1, 5.5, 0.05, 100),
new Item(2, 5.9, 0.056, 100),
new Item(3, 5.1, 0.057, 100)
));
// act
final Item bestOffer = findBestOffer(offers);
// assert
System.out.println(instance.writeValueAsString(offers));
assertEquals(1, bestOffer.getId());
}
public List<Integer> toIdList(List<Item> items){
return items.stream().map(Item::getId).collect(Collectors.toList());
}
/**
* Vai pegar os items de melhor preco, wear e escrow.
* Para no primeiro item que nao tiver outros items semelhantes
*/
public void sortToBestOffer(List<Item> items){
items.sort(completeComparator());
}
/**
* Vai pegar o item de melhor preco, wear e escrow. Exclui os items que mais divergem e vai sorteando os mais parecidos
*
*/
public Item findBestOffer(List<Item> items){
items.sort(Comparator.comparing(Item::getPrice));
final AtomicReference<Item> first = new AtomicReference<>(items.get(0));
items = items.stream().filter(v -> v.price - first.get().price <= 1.0).collect(Collectors.toList());
if(items.isEmpty()){
return first.get();
}
if(items.size() == 1){
return items.get(0);
}
items.sort(Comparator.comparing(Item::getWear));
first.set(items.get(0));
items = items.stream().filter(v -> v.wear - first.get().wear <= 0.1).collect(Collectors.toList());
if(items.isEmpty()){
return first.get();
}
if(items.size() == 1){
return items.get(0);
}
items.sort(Comparator.comparing(Item::getEscrow));
first.set(items.get(0));
return items.stream().filter(v -> v.escrow - first.get().escrow <= 1).findFirst().orElse(first.get());
}
/**
* Return items sorted by the cheapest, best quality then escrow
*/
public static Comparator<Item> completeComparator(){
return (a, b) -> {
int cmp = itemPriceComparator().compare(a, b);
if(cmp == 0){
cmp = wearComparator().compare(a, b);
if(cmp == 0){
return escrowComparator().compare(a, b);
}
}
return cmp;
};
}
public static Comparator<Item> itemPriceComparator(){
return (a, b) -> {
final double diff = Math.max(a.price, b.price) - Math.min(a.price, b.price);
return diff >= 1.0 ? Double.compare(a.price, b.price) : 0;
};
}
public static Comparator<Item> wearComparator(){
return (a, b) -> {
final double diff = Math.max(a.wear, b.wear) - Math.min(a.wear, b.wear);
return diff >= 0.1 ? Double.compare(a.wear, b.wear) : 0;
};
}
public static Comparator<Item> escrowComparator(){
return (a, b) -> {
final double diff = Math.max(a.escrow, b.escrow) - Math.min(a.escrow, b.escrow);
return diff >= 1.0 ? Double.compare(a.escrow, b.escrow) : 0;
};
}
public static class Item {
private final int id;
private final double price;
/**
* Desgaste do item
*/
private final double wear;
/**
* Second epoch when item will be instantly withdrawable
*/
private final long escrow;
public Item(int id, double price, double wear, long escrow) {
this.id = id;
this.price = price;
this.wear = wear;
this.escrow = escrow;
}
public double getPrice() {
return price;
}
public double getWear() {
return wear;
}
public long getEscrow() {
return escrow;
}
public int getId() {
return id;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment