Starbucks al Inglés

12

En los días clásicos de Starbucks, antes de estas nuevas e innovadoras impresoras de adhesivos y unidades de escáner inalámbrico con auriculares inalámbricos, en los embriagadores días del 2000, Starbucks tenía un sistema conciso para describir bebidas con una sintaxis estricta y una forma codificada.

Verticalmente en la taza hay una serie de cajas etiquetadas que pueden contener ciertos valores .:

Decaf
[   ]     -blank-  X  1/2  1/3  2/3
Shots
[   ]     -blank-  0 1 2 3 ... 20    followed by    S T G V
Syrup
[   ]     -blank-  V M C H
Milk
[   ]     -blank-  Wh % N B
Custom
[    ]    -blank- ((-|x)?(F|WC|M|CR) )+
Drink
[   ]     E EM ECP A L C CM

Pero usaremos una forma horizontal para una manipulación más fácil. Estos son los nombres de los 6 campos de la entrada que pueden ser cualquier forma conveniente. Los ejemplos aquí son CSV simples. El campo personalizado y los campos de jarabe pueden ser una concatenación de varios valores. Puede usar cualquier subdelimitador conveniente. Los ejemplos aquí usan espacio. El campo Disparos también es una concatenación de un número (posible) y una designación del tamaño de la copa (que está implícito en la copa física pero que naturalmente encaja en este lugar en la codificación).

Los valores del campo Decaf se traducen en palabras como esta

-blank-   -nothing-
X         "decaf"
1/2       "half-caf"
1/3       "one-third-caf"
2/3       "two-thirds-caf"

Lógicamente, los valores fraccionales solo están permitidos cuando el número de disparos es divisible por el denominador; pero para este desafío no es necesario detectar o diagnosticar este error.

El campo Disparos debe dividirse en su componente numérico (si está presente) y el identificador de tamaño. El número debe mostrarse en forma de tupla latina: simple, doble, triple, cuádruple, quíntuple, más allá de 5 simplemente imprima el número y el sufijo "-tupla", es decir. 7-tuple,16-tuple . Las designaciones de tamaño son:

S  short
T  tall
G  grande
V  venti

P.ej.

2T  double tall
3G  triple grande

El campo Jarabe puede contener uno o más de varios tokens de números / letras opcionales. La cantidad máxima de un jarabe es 20. Incluso eso es demasiado. Jajaja

V  vanilla
C  caramel
M  mocha
H  hazelnut

P.ej.

2V 2C     two vanilla two caramel
H         hazelnut
M H 1V    mocha hazelnut one vanilla

El campo Leche puede contener uno de los siguientes.

Wh  whole-milk
%   two-percent
N   skim
B   breve

El campo Personalizado puede contener uno o más de varios modificadores con opcional xo -signo.

x  extra     F   foam
-  no        WC  whip
             M   mocha drizzle
             CR  caramel drizzle

El campo Bebida contiene una identificación de bebida.

E    espresso
EM   espresso macchiato
ECP  espresso con panna
A    americano
L    latte
C    cappuccino
CM   caramel macchiato

Cualquier campo puede estar en blanco, excepto la designación del tamaño y la identificación de la bebida.

Ejemplos.

,3G,V,Wh,,L    =>   triple grande vanilla whole-milk latte
X,2T,,N,,L     =>   decaf double tall skim latte
1/2,V,,,,CM    =>   half-caf venti caramel macchiato
2/3,3V,3V,B,WC,L  => two-thirds-caf triple venti three vanilla breve whip latte
,G,,,xCR,CM    =>   grande extra caramel drizzle caramel macchiato
X,4T,2M 2C,B,xWC -F xM,C  =>
  decaf quadruple tall two mocha two caramel breve extra whip no foam extra mocha drizzle cappuccino

No es necesario diagnosticar brebajes erróneos o ilógicos, como un "capuchino sin espuma ...".

Complicación adicional

Solo para las bebidas con la palabra espresso, el número singledebe ser reemplazado por soloy doubledebe ser reemplazado por doppio. Y el tamaño puede ser no especificado y omitido. Además, solo para la espressobebida en sí, si la única otra especificación es uno de estos dos números de disparos especialmente reemplazados, entonces la palabra en espressosí debe omitirse.

,2,1V,B,,EM   =>  doppio one vanilla breve espresso macchiato
,1,,,,E       =>  solo
,2,,,,E       =>  doppio
,3,,,,E       =>  triple espresso

Observaciones adicionales sobre 'leer una copa'

Esta parte no es un requisito para este desafío, pero puede ser un refinamiento útil en la aplicación de este tipo de sistema verbalizado en otros dominios.

Mencioné la sintaxis al principio, y al aplicar el esquema a las corrientes entrantes de palabras, varios encargados de pedidos podían transmitir verbalmente las órdenes al barista que hacía las bebidas. El marco general SIZE .... DRINKproporciona la demarcación entre varias órdenes pronunciadas a la vez. Por lo tanto, existe una tendencia a hacer que todos los atributos interiores sean frases adjetivas, por lo que el orden también tiene una estructura válida de sustantivos en inglés. Por whiplo tanto, a menudo se habla with whipo whippedy a foammenudo se habla foamyo with foam.

Por lo tanto, para algunos baristas de la antigüedad , no te "corrigen" cuando repiten el orden en el formato adecuado ( bueno, ... a veces ). Simplemente están organizando la información con el propósito de recordar todos los detalles exactamente. Al esquematizar la información, un pedido completo de bebidas se convierte en una sola unidad con el fin de aplicar el número mágico 7 más o menos 2 . Por lo tanto, un barista con esta habilidad puede mantener 5-9 órdenes en su cabeza siempre que otras distracciones no consuman demasiado espacio para la cabeza. :)

luser droog
fuente
55
Me alegra que te refieras a ellas como bebidas, en lugar de café.
Neil
¿Qué quieres decir con novedad? A menos que haga un pedido desde el móvil, todos los baristas de Starbucks que he visto todavía lo escriben con un marcador negro.
Joe Z.
@JoeZ. Solo mi frustración porque la simplicidad de la vieja forma se erosiona continuamente. Los propios baristas tienen que traducir a una tercera forma en la forma de ingresar el orden al sistema. Y para una tienda con drive-thru, el pedido se imprime en una cuarta forma en la etiqueta. Mientras que el listado en la lista de espera tiene un quinto formato distinto (omitiendo todos los números de jarabe).
luser droog
1
s / frustración / lamentación /
luser droog

Respuestas:

3

Retina 0.8.2 , 640 bytes

Realiza una serie de sustituciones para transformar la entrada en la salida esperada.

-
no 
x
extra 
Wh
whole-milk
%
2-percent
N
skim
B
breve
X
deJ
1/2
half-J
1/3
1Q-J
2/3
2Qs-J
Q
-third
J
caf 
^,
 ,
 ,1(?=\D.*E)
,soloZ
 ,2(?=\D.*E)
,doppioZ
Z,,,,E$
Z
 ,(\d+)
,$1UleZ
,1U
,sing
,2U
,doub
,3U
,trip
\d+(?!\d*U)
$&Y 
U
-tup
,4-.
,quadr
,5-
,quin
 ,
Z
S
short
T
tall
G
grande
ZV
 venti
M(?=[^,]*,\w*$)
MR
E
espresso
M$
 macchiato
CP
 con panna
A
americano
L
latte
C$
cappuccino
F
foam
WC
whip
R
 drizzle
4Y
fourY
6Y
sixY
7Y
sevenY
9Y
nineY
10Y
ten
11Y
eleven
12Y
twelve
13Y
thirK
15Y
fifK
18Y
eighK
20Y
twenty
1Y
one
2Y
two
3Y
three
5Y
five
8Y
eight
1(\w*)Y
$1K
K
teen
V
vanilla
C
caramel
M
mocha
H
hazelnut
 -
-
Z,*| ?,+
 
^ |Y

Pruébalo en línea!

La mayor parte son reemplazos bastante sencillos. Algunas partes interesantes son:

 ,1(?=\D.*E)
,soloZ
 ,2(?=\D.*E)
,doppioZ

Maneja los casos especiales para bebidas que contienen la palabra "espresso". Transforma el 1 y 2 en "solo" y "doppio" antes de llegar al escenario donde transformamos esos números en forma de tupla latina.

Z,,,,E$
Z

Elimina la palabra "espresso" si "solo" o "doppio" es el único otro modificador.

M(?=[^,]*,\w*$)
MR

Agrega un Ra cualquiera Mcon solo una coma entre él y el final de la cadena. Esto nos permite transformar todos los Rs en "llovizna" más adelante.

1(\w*)Y
$1K
K
teen

Nos permite transformar 14,16,17 y 19 en sus formas de palabras de una sola vez, ya que reemplazamos 4,6,7 y 9 de antemano.

adicto a las matemáticas
fuente
6

Javascript ES6, 902 900 bytes

s=>(R=(l,r)=>(l.split`.`.map((e,i,l)=>!(i%2)&&(r=r.split(e).join(l[i+1]+" "))),r),R("-.no.!.-tuple.1/2.half-caf.1/3.one-third-caf.2/3.two-thirds-caf.ECP.Econ panna.CM.RY.CR.RZ.EM.EY.WC.whip.Wh.whole-milk.A.americano.B.breve.C.cappuccino.D.extra.E.espresso.F.foam.G.grande.H.hazelnut.I.venti.L.latte.M.OZ.N.skim.O.mocha.R.caramel.S.short.T.tall.V.vanilla.X.decaf.Y.macchiato.Z.drizzle.%.two-percent",R(",1,,,,E.solo.,2,,,,E.doppio",s).split`,`.map((e,i)=>(`1VI.2MO.2CR.4xD`.split`.`.map(k=>k[0]==i&&(e=e.split(k[1]).join(k[2]))),i==1?(e=R("1!.single.2!.double.3!.triple.4!.quadruple.5!.quintuple",e.replace(/(\d+)/,"$1!"))):i==2?(e=R("10.ten.20.twenty.11.eleven.12.twelve.13.thir0.14.four0.15.fif0.16.six0.17.seven0.18.eigh0.19.nine0.0.teen.1.one.2.two.3.three.4.four.5.five.6.six.7.seven.8.eight.9.nine",e)):s.includes`E`&&(e=R("single.solo.double.doppio",e)),e)).join` `).replace(/\s+/g," ").trim())

"Ungolfed":

s=>(
  R=(l,r)=>(l.split`.`.map((e,i,l)=>!(i%2)&&(r=r.split(e).join(l[i+1]+" "))),r),                                   // consecutive string replacement function
  R("-.no.!.-tuple.1/2.half-caf.1/3.one-third-caf.2/3.two-thirds-caf.ECP.Econ panna.CM.RY.CR.RZ.EM.EY.WC.whip.     // replace all symbols with appropriate values
     Wh.whole-milk.A.americano.B.breve.C.cappuccino.D.extra.E.espresso.F.foam.G.grande.H.hazelnut.I.venti.L.latte.
     M.OZ.N.skim.O.mocha.R.caramel.S.short.T.tall.V.vanilla.X.decaf.Y.macchiato.Z.drizzle.%.two-percent",
    R(",1,,,,E.solo.,2,,,,E.doppio",s)                                                                             // if special espresso cases, directly replace entire string
    .split`,`.map((e,i)=>(                                                                                         // split input at commas
      `1VI.2MO.2CR.4xD`.split`.`.map(k=>k[0]==i&&(e=e.split(k[1]).join(k[2]))),                                    // substitute duplicate symbols with unique symbols
      i==1?(e=R("1!.single.2!.double.3!.triple.4!.quadruple.5!.quintuple",e.replace(/(\d+)/,"$1!"))):              // if in shots section, expand all numbers
      i==2?(e=R("10.ten.20.twenty.11.eleven.12.twelve.13.thir0.14.four0.15.fif0.16.six0.17.seven0.18.eigh0.        // if in syrup section, expand all numbers
                  19.nine0.0.teen.1.one.2.two.3.three.4.four.5.five.6.six.7.seven.8.eight.9.nine",e)):
      s.includes`E`&&(e=R("single.solo.double.doppio",e)),                                                         // replace single,double with solo,doppio if espresso is in the string
    e)).join` `).replace(/\s+/g," ").trim())                                                                       // join sections, cleanup whitespaces

Ejecuciones de ejemplo:

f(",3G,V,Wh,,L")              -> triple grande vanilla whole-milk latte
f("X,2T,,N,,L")               -> decaf double tall skim latte
f("1/2,V,,,,CM")              -> half-caf venti caramel macchiato
f("2/3,3V,3V,B,WC,L")         -> two-thirds-caf triple venti three vanilla breve whip latte
f(",G,,,xCR,CM")              -> grande extra caramel drizzle caramel macchiato
f("X,4T,2M 2C,B,xWC -F xM,C") -> decaf quadruple tall two mocha two caramel breve extra whip no foam extra mocha drizzle cappuccino
f(",2,1V,B,,EM")              -> doppio one vanilla breve espresso macchiato
f(",1,,,,E")                  -> solo
f(",2,,,,E")                  -> doppio
f(",3,,,,E")                  -> triple espresso
Dendrobium
fuente
Pruebe esto: (R=...)("=-.no.!...(defina R en línea y luego use el resultado como una función)
Conor O'Brien
4

Pitón, 824 815 807 805 bytes

f=lambda s,a=0:a==0and" ".join(" ".join(f(" "+s.split(",")[i],(["X,deC,1/2,half-C,1/3,oneT-C,2/3,twoTs-C,C,caf,T,-third","".join(" %i"%i+f(",%i-tupL,"%i,["1","x","2","y"])for i in range(6,21))+"1,solo,2,doppio,"*('E'in s)+"1,singL,2,doubL, 3,tripL, 4,quadrupL, 5,quintupL,x,1,y,2,S,short,T,tall,G,grande,V,Vnti","V, vanilla,H, hazelnut,10,ten,11,eleVn,12,twelV,13,thirT,14,4T,15,fifT,16,6T,17,7T,18,8een,19,9T,20,twenty,1,one,2,two,3,three,4,four,5,fiV,6,six,7,seVn,8,eight,9,nine,T,teen","Wh,whole-milk,%,two-percent,N,skim,B,breV","x,extra ,-,no ,F,foam,WC,whip,M,MR,R, drizzL","CM,xM,E,espresso,M, macchiato,CP, con panna,A,americano,L,latte,C,cappuccino,x,C"][i]+",C, caramel,M, mocha,L,le ,V,ve").split(","))for i in range(6-(s in",1,,,,E,2,,,,E"))).split())or a and f(s.replace(a[0],a[1]),a[2:])or s

Ligeramente más legible:

def f(s,a=0):
 if a==0:
  a=["X,deC,1/2,half-C,1/3,oneT-C,2/3,twoTs-C,C,caf,T,-third"]
  a+=["".join(" %i"%i+f(",%i-tupL,"%i,["1","x","2","y"])for i in range(6,21))+"1,solo,2,doppio,"*('E'in s)+"1,singL,2,doubL, 3,tripL, 4,quadrupL, 5,quintupL,x,1,y,2,S,short,T,tall,G,grande,V,Vnti"]
  a+=["V, vanilla,H, hazelnut,10,ten,11,eleVn,12,twelV,13,thirT,14,4T,15,fifT,16,6T,17,7T,18,8een,19,9T,20,twenty,1,one,2,two,3,three,4,four,5,fiV,6,six,7,seVn,8,eight,9,nine,T,teen"]
  a+=["Wh,whole-milk,%,two-percent,N,skim,B,breV"]
  a+=["x,extra ,-,no ,F,foam,WC,whip,M,MR,R, drizzL"]
  a+=["CM,xM,E,espresso,M, macchiato,CP, con panna,A,americano,L,latte,C,cappuccino,x,C"]
  return" ".join(" ".join(f(" "+s.split(",")[i],(a[i]+",C, caramel,M, mocha,L,le ,V,ve").split(","))for i in range(6-(s in",1,,,,E,2,,,,E"))).split())
 elif a:
  return f(s.replace(a[0],a[1]),a[2:])
 else:
  return s

Demostración en https://repl.it/C8Hz/3

Chuck Morris
fuente
3

Rubí -plaF, , 975 870 bytes

Recibí un voto al azar sobre mi respuesta anterior de casi cuatro años a esta pregunta, y debido a mis comentarios sobre lo horrible que fue (puedes consultar el historial de publicaciones si quieres ver lo que escribí antes) estaba inspirado para mejorarlo (también conocido como: reescribir la mayor parte desde cero) y logró jugar más de cien bytes. Todavía más largo que la respuesta de Python, pero estoy mucho más feliz con cómo resultaron las cosas ahora.

Se guardaron unos 20 bytes al pasar de intentar ejecutar patrones de expresiones regulares para afectar partes específicas de la estructura de coma a usar el -aF,indicador para dividir automáticamente una línea de entrada en comas y guardarla $F, lo que me permite modificar algunos elementos antes de volver a unirlos y finalmente modificando la variable de salida con los últimos sub/ gsubcomandos.

Honestamente, la cantidad de reemplazos de expresiones regulares realizadas aquí significa que la mayor parte de esto podría ser un programa de Retina, pero no sé Retina lo suficientemente bien como para eso.

g=->n,c{n.grep(/^ ?#{c}/i)[0]}
n=%w"0 one two three four five six seven eight nine ten eleven twelve thir four fif";n+=n[6,4]<<'twenty'
$F[1].sub!(/(\d*)(\w)?/){i=eval$1;"#{i&&(%w"0 sing doub trip quadrup quintup"[i]||$1+"-tup")+"le"} #{g[%w"short tall grande venti",$2]if$2}"}
$F[2].gsub!(/(\d*)(\w)/){i=eval$1;"#{i&&n[i]}#{'teen'if(13..19)===i} #{g[%w"vanilla caramel mocha hazelnut",$2]}"}
$F[3].sub!(/.+/){%w"skim whole-milk breve two-percent"[$&.sum%26%4]}
$F[4].gsub!(/(x|-)?(\w+)/){"#{%w"extra no"[$1.ord%2]if$1} #{g[%w"caramelD mochaD whip foam",$2[0]].sub ?D,' drizzle'}"}
$_=$F*' '
sub(/^\S+/){%w"de - half- one-third- two-thirds-"[$&.sum%8]+"caf"}
sub'CP',' con pana'
sub'CM','caramel'+m=' macchiato'
e='espresso'
gsub(/[A-Z]/){g[%w"americano latte cappuccino"+[m,e],$&]}
gsub(/ +/,' ')
$_.strip!
sub(/[sd]...le/){g[%w"doppio solo",$&[0]]}if$_[e]
sub'o '+e,?o

Pruébalo en línea!

Tinta de valor
fuente
¡Actualizaré la aceptación si el estado cambia!
luser droog
1
¿Tal vez? Simplemente no soy muy bueno en la compresión de información como las otras dos respuestas; tal vez alguien más sea el que venza a Python ya que esta es una solución muy ingenua
Value Ink el