Gewinne aus Spielwarengeschäften

15

Die Geschichte

"2016? Alles klar", grummelte Spielzeugverkäufer Hilbert. Er öffnete die Augen, wischte sich die Salatsauce aus dem Ohr und aß morgens eine Cremeschnitte. Vorbildliche Ferien. Er muss jetzt aber zur Arbeit gehen und die Jahresabrechnung abschließen.

Weihnachten ist eine sehr ertragreiche Zeit des Jahres, vor allem für seine Verkäufe. Hilbert weiß genau, wie es geht: Eine Person kommt in einen Laden und kauft das erste Geschenk, das ihr angeboten wird. Sie bezahlen dafür und rennen zu einem anderen Geschäft. In der Praxis macht es keinen großen Unterschied, was das Geschenk eigentlich ist. Der Preis ist auch irrelevant, sofern er nicht zu hoch ist. Alles hängt von der verbleibenden Zeit bis Weihnachten ab - je kürzer die Zeit, desto größer die Reue der Kunden, desto höher der Preis, den sie zu zahlen bereit sind.

Für Hilbert reicht ein Blick auf die Uhr - und er weiß sofort, wie viel seine Kunden ausgeben können. Diese Tatsache kann er leicht ausnutzen: Er findet nur das teuerste Geschenk, das er einem bestimmten Kunden verkaufen kann, und bietet es ihm an. Erst jetzt hat er gemerkt, dass er letztes Jahr vergessen hat, diese Liststrategie anzuwenden. Das wird sich aber ändern!

Trotzdem würde Hilbert gerne wissen, wie sehr sein Geschäft gediehen wäre, wenn er tatsächlich von seinem großen Plan Gebrauch gemacht hätte. Er hat es geschafft, eine Liste der Leute zusammenzustellen, die in sein Geschäft gekommen sind, er ist sich jedoch nicht sicher, wie viel Geld er damit hätte verdienen können.

Deine Aufgabe (TL; DR)

Die Eingabe besteht aus einer aufsteigenden Preisliste der verfügbaren Geschenke und einer Liste der Kundenbudgets. Die Liste der Budgets entspricht der Reihenfolge, in der die Kunden in den Shop gekommen sind - mit der Bedingung, dass jeder Kunde bereit ist, mindestens so viel wie der vorherige zu zahlen, was bedeutet, dass auch die Reihenfolge steigt.

Finden Sie für jeden Kunden das teuerste Geschenk, für das er bereit ist zu zahlen, und geben Sie dessen Preis aus. Wenn keine Geschenke innerhalb des Budgets verfügbar sind, geben Sie a aus 0.

Sie erhalten einen -40%Zeichenbonus, wenn die asymptotische Zeitkomplexität Ihres Algorithmus O(n+m)(und nicht die triviale O(n*m)) ist. Wo n, msind die Längen der Eingabelisten?

Dies ist , kürzeste Bytes gewinnt. Standardlücken sind verboten.

Beispiel

Eingang:

1 2 2 2 5 7 10 20
1 1 2 3 6 6 15 21 21 22

Ausgabe:

1 0 2 2 5 2 10 20 7 0

Diese Aufgabe wurde von einem lokalen Programmierwettbewerb übernommen und von mir ins Englische übersetzt. Hier ist die ursprüngliche Aufgabe: https://www.ksp.sk/ulohy/zadania/1131/

sammko
quelle
9
Boni sind eine Sache, die Sie beim Schreiben von Herausforderungen vermeiden sollten . Ich denke jedoch, dass es hier in Ordnung sein könnte. Wenn Sie es behalten möchten, empfehle ich, es in einen prozentualen Bonus umzuwandeln. Ein 20-Zeichen-Bonus bedeutet für eine Java-Einsendung nichts, ist jedoch für Lösungen in einer Golfsprache grundsätzlich obligatorisch.
Denker
Kann ich OP eine Prämie nur für die Hintergrundgeschichte gewähren? Ehrlich gesagt brachte mich das zum Lächeln; Jede Herausforderung braucht eine davon.
Katze
@tac Danke, aber wie im kleinen Text unten angegeben, habe ich die Hintergrundgeschichte nicht erfunden - ich habe sie nur übersetzt.
Sammko
@sammko ja, das habe ich gesehen, aber mein obiger Kommentar gilt immer noch :)
Katze

Antworten:

5

Pyth, 17 16 Bytes

1 Byte danke an Pietu1998

VE=.-Q]
e|fgNTQ0

Demonstration

Erläuterung:

VE=.-Q]<\n>e|fgNTQ0
                        Implicit: Q is the list of prices.
VE                      For N in the list of budgets
             f   Q      Filter the list of prices
              gNT       On the current person's budget being >= that price
            |     0     If there aren't any, use 0 instead.
          e             Take the last (most expensive) value.
      <\n>              Print it out.
  =.-Q                  Remove it from the list of prices.
isaacg
quelle
Ich denke, Sie können 1 Byte mit VE=.-Q]\ n speichern e|fgNTQ0. Im Grunde das gleiche, aber mit einer Schleife.
PurkkaKoodari
4

Haskell, 67 Bytes

a#(b:c)|(h,t)<-span(<=b)a=last(0:h):(init(h++[0|h==[]])++t)#c
_#x=x

Anwendungsbeispiel: [1,2,2,2,5,7,10,20] # [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Teilen Sie die Preise in zwei Teile auf: (h,t)Wo hsind alle Preise <= das Budget des nächsten Kunden und talle anderen. Nehmen Sie den letzten Preis von hund fahren Sie rekursiv mit allen außer dem letzten hPlus tund den verbleibenden Budgets fort. last(0:h)Wertet aus, 0wenn hleer ist. Ähnlich: init (h++[0|h==[]]) ++ tFügt ein Dummy-Element 0zu hif hinzu h, damit initetwas gelöscht werden kann ( initFehler in der leeren Liste).

nimi
quelle
3

Java, 154 * 0,6 = 92,4 Bytes

-13 Bytes, weil das Lambda tatsächlich verwenden kann int[], nicht Integer[](danke BunjiquoBianco )

Dies sollte O (n + m) Zeit und O (n + m) zusätzlichen Raum beanspruchen (vorausgesetzt, ich verstehe die große O-Notation) .

g->b->{int l=g.length,L=b.length,G=0,B=0,A=0;int[]a=new int[l],s=new int[L];for(;B<L;){while(G<l&&g[G]<=b[B])a[A++]=g[G++];s[B++]=A>0?a[--A]:0;}return s;}

Eingerückt: ( Online ausprobieren ! )

static int[] toyStore(int[]g,int[]b) {
    int gl=g.length,bl=b.length,gp=0,bp=0,ap=0;
    int[] a=new int[gl],s=new int[bl];
    for (;bp<bl;) {
        while(gp<gl&&g[gp]<=b[bp])a[ap++]=g[gp++];
        s[bp++]=ap>0?a[--ap]:0;
    }
    return s;
}

public static void main(String[] args)
{
    System.out.println(Arrays.toString(
        toyStore(new int[] {1,2,2,2,5,7,10,20},
                 new int[] {1,1,2,3,6,6,15,21,21,22})
        ));
}

Ich zeige hier die Nicht-Lambda-Erweiterung, weil die Typdeklaration sauberer ist und genau dieselbe Logik hat. Das Lambda ist an der ideone Verbindung anwesend.

Erläuterung:

Verwendete Variablen:

  • gist die Liste der Geschenkpreise, bist die Liste der Budgets.
  • glist die Länge von gund blist die Länge von b.
  • aist ein Stapel für erschwingliche Geschenke, sder Ausgabebereich für verkaufte Geschenke.
  • gp, bpUnd apsind Zeiger für g, bund ajeweils. bpist auch der Zeiger für s.

Algorithmus:

  • Für jedes Budget in der Länge des Budgets
    • Während dieses Budget kann das Geschenk zu kaufen g[gp]
      • Schieben Sie das Budget auf den Stapel aund erhöhen Sie esgp
    • Pop oben ain, s[bp]wenn es existiert, sonst setzen 0.
CAD97
quelle
Kannst du nicht das Lambda curry? (dh (g,b)->zu g->b->?
Nur ASCII
@ jemand anscheinend ja. Aus irgendeinem Grund hat es noch nie für mich funktioniert, aber jetzt wird es funktionieren. 0.o (Sie haben nach dem Bonus 0,6 Byte gespart.)
CAD97
Sie können einige Bytes sparen, indem Sie longs verwenden, wenn die Eingabe als long [] angenommen wird (bringt Sie auf 158 Bytes) - ideone.com/invHlc
BunjiquoBianco
1
@ BunjiquoBianco in der Tat kann ich nur int [] verwenden. Aus irgendeinem Grund hatte ich den Eindruck, intdass ich ein Array von Referenztypen verwenden musste , da die Typargumente Referenztypen verwenden (also nicht die Primitiven mit Werttyp ). Aber ich kann ein Array von Int ganz gut verwenden. Ich werde aktualisieren, sobald ich eine Chance habe.
CAD97
@ CAD97 Ha! Ich kann nicht glauben, dass ich diesen Link nicht hergestellt habe ...
BunjiquoBianco
2

Haskell, 87 * 0,6 = 52,2 Bytes

g s(p:q)d@(b:c)|p<=b=g(p:s)q d
g[]p(b:c)=0:g[]p c
g(s:t)p(b:c)=s:g t p c
g _ _ _=[]
g[]

Völlig anders als meine andere Antwort , weil ich für den Bonus gehe.

Die letzte Zeile (-> g[]) ist nicht Teil der Definition, sondern ruft Overhead auf. Anwendungsbeispiel: g [] [1,2,2,2,5,7,10,20] [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Funktioniert im Wesentlichen wie die Antwort von @ CAD97 , dh es wird ein (anfangs leerer) Hilfsstapel verwendet, um den Überblick über die käuflichen Artikel zu behalten. Im Detail: Check in Reihenfolge:

  • Wenn der erste Preis kleiner oder gleich dem ersten Budget ist, verschieben Sie den Preis in den Stapel. Erneut aufrufen.
  • Wenn der Stapel leer ist, geben Sie eine 0 zurück, gefolgt von einem rekursiven Aufruf, bei dem das Budget gesunken ist.
  • Wenn sowohl der Stapel als auch die Budgetliste nicht leer sind, geben Sie den Anfang des Stapels zurück, gefolgt von einem rekursiven Aufruf mit Stapel & Budget.
  • Andernfalls wird die leere Liste zurückgegeben.

Dies funktioniert m+nzeitlich, da a) Operationen auf dem Hilfsstapel eine konstante Zeit verwenden und b) in jedem der rekursiven Aufrufe eine der Listen um ein Element verkürzt wird.

nimi
quelle
2

Gelee , 15 Bytes

ṀṄ;©®œ^
Rf@€ç/Ṁ

Probieren Sie es online!

Wie es funktioniert

ṀṄ;©®œ^  Helper link. Arguments: G, H (lists of affordable gifts)

Ṁ        Compute the maximum of G (0 if the list is empty).
 Ṅ       Print it.
  ; ®    Concatenate it with the register (initially 0).
   ©     Save the result in the register.
     œ^  Compute the multiset symmetric difference of the updated register and H.

Rf@€ç/Ṁ  Main link. Arguments: B (budgets), P (prices)

R        Range; replace each t in B with [1, ..., t].
 f@€     Intersect the list of prices with each budget range, obtaining, for each
         customer, the list of all gifts he's willing to pay for.
    ç/   Reduce the array of lists by the helper link.
         In each iteration, this computes and prints the most expensive gift for
         a customer, than removes the selected gift (and all previously
         selected gifts) from the next list.
      Ṁ  Compute the maximum of the resulting list, which corresponds to the last
         customer.
Dennis
quelle
1

JavaScript, 85 * 0,6 = 51 Bytes

f=(a,b,s=[],[t,...u]=a,[v,...w]=b)=>v?t<=v?f(u,b,[...s,t]):[s.pop()|0,...f(a),w,s)]:[]

Ein weiterer Klon der Antwort von @ CAD97.

Neil
quelle