Asta di offerta pubblica iniziale

Aug 16 2020

Trascrizione dell'immagine:

Una società si registra per una IPO. Tutte le azioni sono disponibili sul sito Web per le offerte durante un periodo di tempo chiamato finestra di offerta. Alla fine della finestra di offerta, viene utilizzata una logica d'asta per decidere quante azioni disponibili vanno a ciascun offerente fino a quando tutte le azioni non sono state assegnate o tutti gli offerenti hanno ricevuto le azioni per cui hanno offerto, a seconda di quale evento si verifichi per primo.

Le offerte arrivano dagli utenti sotto forma di [userid, # condivisioni, prezzo di offerta, timestamp] fino alla chiusura della finestra di offerta.

La logica dell'asta assegna le quote come segue:

  1. L'offerente con il prezzo più alto ottiene il numero di azioni per cui ha offerto

  2. Se più offerenti fanno un'offerta allo stesso prezzo, agli offerenti vengono assegnate le azioni nell'ordine in cui piazzano le loro offerte (prima le offerte precedenti)

Elenca gli ID utente di tutti gli utenti che non hanno ottenuto nemmeno 1 condivisione dopo che tutte le condivisioni sono state assegnate.

Ingresso

  • bids
    elenco di elenchi di interi che rappresentano [userid, # condivisioni, $bid, timestamp]
  • totalShares
    n. totale di azioni da distribuire.

Da fare

distribuire le condivisioni tra gli offerenti e restituire gli ID utente degli offerenti che hanno ottenuto 0 condivisioni.

Condividi logica di distribuzione:

  1. l'offerente con l'offerta più alta ottiene tutte le azioni per cui ha offerto, e poi
  2. se ci sono pareggi nel prezzo di offerta in $, assegna le azioni all'offerente precedente.

Sento che la soluzione che ho trovato è relativamente semplice. Sembra superare tutti i casi limite a cui riesco a pensare.

Domanda

Ho riscontrato una situazione discutibile:
il prezzo di offerta e gli orari sono gli stessi e non ci sono abbastanza condivisioni per tutti gli offerenti, ad esempio: bidsis [[0,2,10,0], [1,2,10,0]]e totalSharesis 2. Non è chiaro se a ciascuno debba essere assegnata 1 condivisione o se l'id utente 0 ottiene entrambi.

Codice

La mia soluzione può essere comunque ottimizzata?

def getUnallocatesUsers(bids, totalShares):
  s = 0
  for b in bids:
      s += b[1]  
  if totalShares >= s: return []  # no losers because enough shares to go around

  bids.sort(key = lambda x: (-x[2],x[3]))  # sort by highest bid, then timestamp for ties
  losers = []
  for b in bids:
    if totalShares <= 0: losers.append(b[0])
    else:
      totalShares -= b[1]
  return losers

Risposte

2 RootTwo Aug 18 2020 at 09:39

Utilizzare il nome della funzione fornito nel problema:

def getUnallottedUsers(bids, totalShares):

Il problema non fornisce alcuna informazione sulla probabilità che ci siano condivisioni sufficienti per tutti gli offerenti, quindi IMO il primo ciclo for è un esempio di ottimizzazione prematura.

Usa costanti invece di "numeri magici". Usa nomi significativi. Dai un'occhiata a PEP8 sulle convenzioni di formattazione comuni. Queste cose fanno molto per rendere il codice leggibile.

USERID = 0
SHARES = 1
PRICE = 2
TIME = 3

bids.sort(key=lambda bid:(-bid[PRICE], bid[TIME]))

for index, bid in enumerate(bids):
    totalShares -= bid[SHARES]

    if totalShares <= 0:
        break

Rispondere alla domanda che è stata posta: "La funzione deve restituire un elenco di numeri interi, ciascuno un id per quegli offerenti che non ricevono quote, ordinati in ordine crescente "

return sorted(bid[USERID] for bid in bids[index + 1:])

Tutti insieme:

USERID = 0
SHARES = 1
PRICE = 2
TIME = 3

def getUnallottedUsers(bids, totalShares):
    bids.sort(key=lambda bid:(-bid[PRICE], bid[TIME]))

    for index, bid in enumerate(bids):
        totalShares -= bid[SHARES]

        if totalShares <= 0:
            break

    return sorted(bid[USERID] for bid in bids[index + 1:])

Oppure usa un iteratore:

    bids = iter(bids)
    while totalShares > 0:
        price = next(bid)[PRICE]
        totalShares -= price

    return sorted(bid[USERID] for bid in bids)