¡Ingresos de precios variables!

16

Introducción y crédito

Asume que eres un barman. Tienes muchas personas felices en tu bar la mayoría de las veces, pero muchas solo beben la misma bebida y muy pocas para tu gusto y quieres cambiar eso. Entonces, introduce un sistema en el que el precio de una bebida es variable, dependiendo de cuántos ya se hayan vendido, pero nunca más o menos costoso que ciertos umbrales. Por alguna extraña razón, siempre se olvida de realizar un seguimiento adecuado de todas las bebidas y precios vendidos y, por lo tanto, debe pensar en un código breve (¡= memorable!) Que haga los cálculos matemáticos por la cantidad de bebidas consumidas.

Este desafío ya apareció en el examen de mitad de período en 2012 en el curso de programación funcional en mi universidad y tengo la autorización de mi profesor para publicarlo aquí. Se nos ha proporcionado una solución de ejemplo en el idioma del examen.

Entrada

Su entrada será una lista de cadenas que no contienen espacios: estos son los nombres de las bebidas vendidas. Tome la entrada usando su método de entrada preferido, generalmente aceptado.

Salida

Su producción será un solo número: este es el ingreso que ha generado esta noche. Dé la salida utilizando su método de salida preferido, generalmente aceptado.

¿Qué hacer?

Esto aplica para cada bebida individualmente:

  • El precio inicial es 10.
  • Cada vez que se compra la bebida, su precio aumenta en 1 para el próximo comprador.
  • El precio máximo es 50. Si la bebida se ha comprado por 50, el nuevo precio será 10 nuevamente.

Su tarea es encontrar el ingreso general, generado por la lista de entrada de bebidas dadas las reglas anteriores.


En caso de que se pregunte: "¡50 dólares es realmente caro para una bebida!", Esto es 50 dólares deci, por lo que 50 * 0.1 * Unidad, pero he optado por 10-50 para no excluir idiomas sin aritmética de coma flotante.

¿Quién gana?

Este es el , por lo que gana el código más corto en bytes. Aplican reglas estándar.

Casos de esquina potenciales

Si la lista de entrada está vacía, la salida será 0.
No se puede suponer que la lista de entrada está ordenada por bebida.

Ejemplos

[] -> 0
["A"] -> 10
["A","B"] -> 20
["A","A","B"] -> 31
["A","B","A"] -> 31
["A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A"] -> 1240
["A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","B","C","C","D"] -> 1304 
["D","A","A","C","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","C"] -> 1304
["A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","B","C","C","D","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A"] -> 1304
SEJPM
fuente
1
Consejos para preguntarle a tu profesor antes de publicar, todo el movimiento OG.
Magic Octopus Urn

Respuestas:

4

JavaScript (ES6), 50 bytes

a=>a.map(x=>t+=d[x]=d[x]<50?d[x]+1:10,t=0,d={})&&t
ETHproducciones
fuente
¿Dónde inicias d[x]a 10?
Titus
@Titus Si d[x]no se ha configurado, es undefined; esto hace que d[x]<50return sea falso, por lo que se d[x]=d[x]<50?d[x]+1:10establece d[x]en 10.
ETHproductions
Debo olvidar que JS tiene undefined. :)
Titus
4

Python 2, 79 74 54 48 Bytes

El recuento masivo de bytes aumenta al repensar el problema. Me gustaría deshacerme del intyeso pero mi cerebro no funciona . Haciendo uso de l.pop()para evitar recortar la lista dos veces y alguna buena repetición lambda :)

f=lambda l:l and l.count(l.pop())%41+10+f(l)or 0

gracias a Jonathan Allan por guardar 6 bytes :)

Mi antigua versión de 54 bytes estaba bastante orgullosa :)

f=lambda l:int(l>[])and~-l.count(l[0])%41+10+f(l[1:])
Kade
fuente
...l>[]and 1*~...para guardar esos 3 bytes que sabía que podía.
Jonathan Allan
De hecho 1 menos con:f=lambda l:l and~-l.count(l[0])%41+10+f(l[1:])or 0
Jonathan Allan
Oooh y otros dos con:f=lambda l:l and l.count(l.pop())%41+10+f(l)or 0
Jonathan Allan
@ JonathanAllan gracias por los consejos! Actualizaré mi publicación pronto :)
Kade
2

Pyth, 15 bytes

ssm<*lQ}T50/Qd{

Un programa que toma la entrada de una lista e imprime el resultado.

Conjunto de pruebas (primera línea para permitir entradas múltiples)

Cómo funciona

ssm<*lQ}T50/Qd{   Program. Input: Q
ssm<*lQ}T50/Qd{Q  Implicit input fill
              {Q  Deduplicate Q
  m               Map over that with variable d:
       }T50        Yield [10, 11, 12, ..., 48, 49, 50]
    *lQ            Repeat len(Q) times
   <       /Qd     First Q.count(d) elements of that
 s                Flatten
s                 Sum
                  Implicitly print
TheBikingViking
fuente
2

Jalea , 14 11 10 bytes

50⁵rṁЀĠSS

TryItOnline!

¿Cómo?

50⁵rṁЀĠSS - Main link: list of drink names                e.g. ['d', 'a', 'b', 'a', 'c']
       Ġ   - group indices by values                       e.g. [[2, 4], [3], [5], [1]]
  ⁵        - 10
50         - 50
   r       - inclusive range, i.e. [10, 11, 12, ..., 48, 49, 50]
    ṁЀ    - mould left (the range) like €ach of right(Ð)  e.g. [[10, 11], [10], [10], [10]]
                 note: moulding wraps, so 42 items becomes [10, 11, 12, ..., 48, 49, 50, 10]
        S  - sum (vectorises)                              e.g. [40, 11]
         S - sum                                           e.g. 51
Jonathan Allan
fuente
2

05AB1E , 16 15 bytes

¡Gracias a Emigna por guardar un byte!

ÎÙv¹y¢L<41%T+OO

Utiliza la codificación CP-1252 . Pruébalo en línea!

Adnan
fuente
ÎÙv¹y¢L<41%T+OOdebería funcionar por 1 byte guardado
Emigna
@Emigna ¡Eso es bueno! Gracias :)
Adnan
1

Perl 41 Bytes

Incluye +1 para -p

$\+=$H{$_}+=$H{$_}?$H{$_}>49?-40:1:10;}{

Toma aportes en las nuevas líneas.

Incrementa un valor hash en: 10 si es undef, -40si > 49es 50, o de lo 1contrario. Esto luego se agrega al $\separador de salida, que -pimprime.

Ejemplo:

$ echo -e 'A\nB\nA' | perl -pe '$\+=$H{$_}+=$H{$_}?$H{$_}>49?-40:1:10;}{'
31
Riley
fuente
1

05AB1E , 13 bytes

{.¡€gL<41%T+O

Explicación

["A","B","A"] usado como ejemplo.

{               # sort input
                # STACK: ["A","A","B"]
 .¡             # split on different
                # STACK: [["A","A"],["B"]]
   €g           # length of each sublist
                # STACK: [2,1]
     L          # range [1 ... x] (vectorized)
                # STACK: [1,2,1]
      <         # decrease by 1
                # STACK: [0,1,0]
       41%      # mod 41
                # STACK: [0,1,0]
          T+    # add 10
                # STACK: [10,11,10]
            O   # sum
                # OUTPUT: 31
Emigna
fuente
1

C ++ 14, 105 bytes

Como lambda genérico sin nombre que regresa a través del parámetro de referencia. Requiere entrada para ser un contenedor de stringque tiene push_back, como vector<string>.

Usando el %41+10truco de la respuesta Python de Kade .

[](auto X,int&r){r=0;decltype(X)P;for(auto x:X){int d=0;for(auto p:P)d+=x==p;r+=d%41+10;P.push_back(x);}}

Crea un contenedor vacío Pcomo memoria de lo que ya se ha servido. El precio se calcula contando el xde P.

Sin golf y uso:

#include<iostream>
#include<vector>
#include<string>

using namespace std;

auto f=
[](auto X, int& r){
  r = 0;
  decltype(X) P;
  for (auto x:X){
    int d = 0;
    for (auto p:P)
      d += x==p;
    r += d % 41 + 10;
    P.push_back(x);
  }
}
;

int main(){
 int r;
 vector<string> V;
 f(V,r);cout << r << endl;
 V={"A"};
 f(V,r);cout << r << endl;
 V={"A","B"};
 f(V,r);cout << r << endl;
 V={"A","B","C"};
 f(V,r);cout << r << endl;
 V={"A","A"};
 f(V,r);cout << r << endl;
 V={"A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A"};
 f(V,r);cout << r << endl;
 V={"A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","B","B","C","C","D"};
 f(V,r);cout << r << endl;
 V={"A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","A","B","C"};
 f(V,r);cout << r << endl;
}
Karl Napf
fuente
0

Mathematica, 64 bytes

Parece que debería ser más corto.

Tr[(19+#)#/2&/@(Length/@Gather@#//.z_/;z>41:>Sequence[41,z-41])]&

Length/@Gather@#cuenta las repeticiones de cada bebida. //.z_/;z>41:>Sequence[41,z-41]divide cualquier número entero zsuperior a 41 en esto 41y z-41, para reflejar la caída del precio. Luego, cada uno de los recuentos se conecta a la fórmula (19+#)#/2, que es el costo total de las #bebidas siempre que #sea ​​como máximo 41. Finalmente, Trresume esos costos.

Greg Martin
fuente
0

k, 22 bytes

El argumento puede ser cualquier lista: cadenas, números, etc.

{+/,/10+(#:'=x)#\:!41}

La qtraducción es más fácil de leer:

{sum raze 10+(count each group x)#\:til 41}
skeevey
fuente
0

C #, 193 bytes + 33

33 bytes adicionales para using System.Collections.Generic;

void m(string[]a){int t=0;Dictionary<string,int>v=new Dictionary<string,int>();foreach(string s in a){if(v.ContainsKey(s)){v[s]=v[s]==50?10:v[s]+1;}else{v.Add(s,10);}t+=v[s];}Console.WriteLine(t);}

Estoy seguro de que esto puede llevarse al olvido, los diccionarios definitivamente no son la mejor manera de hacerlo y probablemente podría incluir un ternario en mi if. ¡Aparte de eso, creo que está bien!

Ejemplos:

a = {"A", "A", "A", "B", "B", "C"};
//output = 64

a = {"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A",, "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A", "A" ,"A" "A" ,"A", "A" ,"A", "B", "B", "C"};
//output 727

Sin golf

void m(string[] a)
{
    int t=0;
    Dictionary<string,int> v = new Dictionary<string,int>();
    foreach(string s in a)
    {
        if(v.ContainsKey(s))
        {
            v[s]=v[s]==50?10:v[s]+1;
        }
        else
        {
            v.Add(s,10);
        }
        t+=v[s];
    }
    Console.Write(t);
}
Alfie Goodacre
fuente
0

Clojure, 79 bytes

#(apply +(mapcat(fn[l](for[i(range l)](+(mod i 41)10)))(vals(frequencies %)))))

Cuenta las frecuencias de las bebidas, luego calcula el precio base como 10 + (i % 41). mapcatlos concatena y apply +calcula la suma.

NikoNyrh
fuente
0

PHP, 47 bytes

while($k=$argv[++$i])$s+=10+$p[$k]++%41;echo$s;

toma datos de los argumentos de la línea de comandos; correr con -r.

Titus
fuente