Starbucks para inglês

12

Nos dias clássicos da Starbucks antes dessas novas impressoras de adesivos e drivers sem fio através do scanner de palmtop, nos dias inebriantes da década de 2000, a Starbucks tinha um sistema conciso para descrever bebidas com uma sintaxe estrita e o formulário codificado que a acompanha.

Verticalmente no copo, há uma série de caixas rotuladas que podem conter certos 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

Mas usaremos uma forma horizontal para facilitar a manipulação. Estes são os nomes dos 6 campos da entrada que podem ser de qualquer forma conveniente. Exemplos aqui são simples CSV. Os campos Custom e Syrup podem ser uma concatenação de vários valores. Você pode usar qualquer subdelimitador conveniente. Exemplos aqui usam espaço. O campo Tiros também é uma concatenação de um número (possível) e uma designação do tamanho do copo (que está implícito no copo físico, mas naturalmente se encaixa nesse local na codificação).

Os valores do campo Descafeinado são traduzidos em palavras como esta

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

Logicamente, os valores fracionários são permitidos apenas quando o número de disparos é divisível pelo denominador; mas para esse desafio, não é necessário detectar ou diagnosticar esse erro.

O campo Tiros deve ser dividido em seu componente numérico (se presente) e no identificador de tamanho. O número deve ser exibido na forma de tupla em latim: único, duplo, triplo, quádruplo, quintuplo, além de 5, apenas imprima o número e o sufixo "-tuple" ie. 7-tuple,16-tuple . As designações de tamanho são:

S  short
T  tall
G  grande
V  venti

Por exemplo.

2T  double tall
3G  triple grande

O campo Xarope pode conter um ou mais dentre vários tokens de número opcional / código de letra. O número máximo de xarope é 20. Mesmo isso é demais. RI MUITO.

V  vanilla
C  caramel
M  mocha
H  hazelnut

Por exemplo.

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

O campo Leite pode conter um dos seguintes.

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

O campo Personalizado pode conter um ou mais dos vários modificadores com opcional xou -sinal.

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

O campo Bebida contém um ID de bebida.

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

Qualquer campo pode ficar em branco, exceto a designação do tamanho e o ID da bebida.

Exemplos.

,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

Não há necessidade de diagnosticar misturas errôneas ou ilógicas, como um "cappuccino" sem espuma ...

Complicação Adicional

Para apenas as bebidas com a palavra espresso, o número singledeve ser substituído por soloe doubledeve ser substituído por doppio. E o tamanho pode ser não especificado e omitido. Além disso, apenas para a espressobebida em si, se a única outra especificação for um desses dois números de fotos especialmente substituídos, a palavra em espressosi deve ser omitida.

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

Observações adicionais sobre 'ler um copo'

Esta parte não é um requisito para esse desafio, mas pode ser um refinamento útil na aplicação desse tipo de sistema verbalizado em outros domínios.

Mencionei sintaxe no início, e aplicando o esquema de fluxos de entrada de palavras, ordens poderiam ser transmitido verbalmente por vários tomadores de ordem para o bebidas barista fazer. A estrutura aproximada SIZE .... DRINKfornece demarcação entre várias ordens faladas ao mesmo tempo. Existe, portanto, uma tendência a tornar todos os atributos interiores como frases adjetivas, de modo que a ordem também tenha uma estrutura de frase substantiva em inglês válida. Então, whipé freqüentemente falado with whipou whippede foamfrequentemente falado foamyou with foam.

Assim, para alguns baristas dos velhos tempos , eles não estão "corrigindo você" quando repetem a ordem no formato adequado ( bem, ... às vezes ). Eles estão simplesmente organizando as informações com o objetivo de lembrar exatamente todos os detalhes. Ao esquematizar as informações, um pedido inteiro de bebida se torna uma única unidade com a finalidade de aplicar o número mágico 7 mais ou menos 2 . Portanto, um barista com essa habilidade pode manter de 5 a 9 ordens em suas cabeças, desde que outras distrações não consumam muito espaço. :)

luser droog
fonte
5
Estou feliz que você se referiu a eles como bebidas, em vez de café.
Neil
O que você quer dizer com newfangled. A menos que eu faça pedidos pelo celular, todos os baristas da Starbucks que eu já vi ainda anotam com um marcador preto.
Joe Z.
@JoeZ. Apenas minha frustração de que a simplicidade da maneira antiga é continuamente corroída. Os próprios baristas precisam traduzir para uma terceira forma na forma de inserir a ordem no sistema. E para uma loja com drive-thru, o pedido é impresso em um quarto formulário no adesivo. Enquanto a listagem na fila de heads-up tem um quinto formato distinto (omitindo todos os números de xarope).
Luser droog
11
s / frustração / lamentação /
luser droog

Respostas:

3

Retina 0.8.2 , 640 bytes

Executa uma série de substituições para transformar a entrada na saída 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

Experimente online!

A maioria são substituições bastante diretas. Algumas partes interessantes são:

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

Lida com os casos especiais de bebidas que contêm a palavra "espresso". Ele transforma o 1 e o 2 em "solo" e "doppio" antes de chegarmos ao estágio em que transformamos esses números em forma de tupla latina.

Z,,,,E$
Z

Remove a palavra "espresso" se "solo" ou "doppio" for o único outro modificador.

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

Anexa um Ra qualquer um Mcom apenas uma vírgula entre ele e o final da sequência. Isso nos permite transformar todos os Rs em "garoa" posteriormente.

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

Permite transformar 14,16,17 e 19 em suas formas de palavras de uma só vez, pois substituímos 4,6,7 e 9 de antemão.

viciado em matemática
fonte
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

Exemplo é executado:

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
fonte
Tente o seguinte: (R=...)("=-.no.!...(R definir em linha, em seguida, usar o resultado como uma função)
Conor O'Brien
4

Pitão, 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

Um pouco mais legível:

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

Demonstração em https://repl.it/C8Hz/3

Chuck Morris
fonte
3

Ruby -plaF, , 975 870 bytes

Recebi uma votação aleatória da minha antiga resposta de quase quatro anos para esta pergunta e, por causa dos meus comentários sobre o quão horrível foi (você pode verificar o histórico do post, se quiser ver o que escrevi antes). inspirado para torná-lo melhor (também conhecido como: reescrever a maior parte do zero) e conseguiu jogar mais de cem bytes nele. Ainda mais do que a resposta do Python, mas estou muito mais feliz com o resultado.

Cerca de 20 bytes foram salvos ao passar da tentativa de executar padrões regex para afetar partes específicas da estrutura de vírgulas e usar o -aF,sinalizador para dividir automaticamente uma linha de entrada em vírgulas e salvá-la $F, permitindo que eu modifique alguns elementos antes de costurá-los novamente e finalmente modificando a variável de saída com os últimos sub/ gsubcomandos.

Honestamente, o número de substituições regex feitas aqui significa que a maior parte disso pode ser um programa Retina, mas não conheço o Retina suficientemente bem para isso.

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

Experimente online!

Value Ink
fonte
Atualizarei a aceitação se o status mudar!
Luser droog
11
Talvez? Só não sou muito bom em compactação de informações como as outras duas respostas; talvez outra pessoa seja a única a derrotar o Python, já que esta é uma solução muito ingênua
Value Ink