Quais são algumas abordagens inteligentes (breves e idiomáticas) para obter uma lista de cadeias e retornar uma única cadeia adequadamente pontuada criada a partir da lista, com cada elemento citado.
Isso surgiu para mim ao experimentar o Groovy , para o qual minha solução muito literal, mas ilustrativa, é
def temp = things.collect({"\'${it}\'"})
switch (things.size()) {
case 1:
result = temp[0]
break
case 2:
result = temp.join(" and ")
break
default:
result = temp.take(temp.size()-1).join(", ") + ", and " + temp[-1]
break
}
Ou seja, ['1']
deve ceder '1'
, ['1','2']
deve ceder '1 and 2'
[veja o que eu fiz lá?] E ['1','2','3']
deve ceder '1, 2, and 3'
.
Tenho boas respostas para o Groovy, mas gostaria de ver o que outros idiomas podem fazer.
Quais são algumas abordagens inteligentes e compactas em vários idiomas que tiram proveito dos recursos e idiomas desses idiomas?
['we invited the stripper','JFK','Stalin']
Respostas:
CSS,
132116115 bytesMostrar snippet de código
O CSS não é visto com muita frequência no código golf porque ele pode apenas formatar texto, mas na verdade funciona para esse desafio e achei que seria divertido fazer isso. Veja-o em ação usando o snippet acima (clique em "Mostrar snippet de código").
A lista deve estar em um arquivo HTML vinculado com cada elemento cercado por
<a>
tags e separado por quebras de linha. Os itens da lista devem ser os únicos elementos em seu elemento pai, por exemploExplicação
Vamos considerar a versão não destruída acima. Se você não estiver familiarizado com o funcionamento do CSS, tudo fora dos chavetas é um seletor que determina o conjunto de elementos HTML aos quais as declarações dentro dos chavetas se aplicam. Cada par de seletor-declaração é chamado de regra . (É mais complicado que isso, mas será suficiente para esta explicação.) Antes de aplicar qualquer estilo, a lista aparece separada apenas por espaços.
Queremos adicionar vírgulas após cada palavra, exceto a última, exceto as listas de duas palavras, que não possuem vírgulas. O primeiro seletor,,
a:not(:last-child):nth-child(n+2):after
seleciona todos os elementos, exceto o primeiro e o último.:nth-child(n+2)
é uma maneira mais curta de dizer:not(:first-child)
, e basicamente funciona selecionando elementos cujo índice (começando em 1) é maior ou igual a 2. (Sim, ainda me confunde um pouco. Os documentos do MDN podem ajudar.)Agora só precisamos selecionar o primeiro elemento para obter uma vírgula se houver três ou mais elementos no total.
a:nth-last-child(n+3):after
funciona como:nth-child
, mas contando pela parte de trás, por isso seleciona todos os elementos, exceto os dois últimos. A vírgula aceita a união dos dois conjuntos e usamos o:after
pseudoelemento para adicionarcontent
imediatamente após cada elemento selecionado.A segunda regra é mais fácil. Precisamos adicionar "e" antes do último elemento da lista, a menos que seja um único elemento. Em outras palavras, precisamos selecionar o último elemento que é precedido por outro elemento.
+
é o seletor de irmão adjacente em CSS.fonte
<li>
.<li>
seria ideal, mas isso adicionaria dois caracteres extras aos seletores. Eu escolhi<a>
porque é uma letra e não aplica sua própria formatação.Haskell:
81, 7774 caracteresRecursos de Haskell: Correspondência de padrões
fonte
f[x,y,z]
f["a","b","c"]
é suposto ser"a, b, and c"
, mas é"a,b and c"
y++", and "++z
porf[y++",",z]
:)Ruby, 47 bytes
Explicação
$*
).$*
tiver um terceiro elemento ($*[2]
não retorna nulo), pegue todos os elementos menos o último e transforme-os em uma String separada por vírgula usandoArray#*
. Por fim, adicione uma vírgula extra, a string" and "
e o último argumento da linha de comando.$*
não tem terceiro elemento, dois, um ou zero argumentos foram dados. Os argumentos podem ser unidos com segurança à string" and "
e produzir o resultado correto.fonte
Python 2 (61)
O principal truque é cortar parte do marceneiro final
", and "
para um e dois elementos. Por um lado, tudo é cortado e, por dois, a vírgula é removida. Isso é feito cortando[8-7*len(s):]
(observando ques
é um menor após opop
).Infelizmente,
d
não pode ser substituído apenas por sua expressão oupop
isso aconteceria tarde demais.fonte
s
pors=input()
e remover a primeira linha, se não me engano. Salva 2 caracteres.s
várias vezes.CSS,
62 caracteres112 caracteresInspirado pelas outras entradas, ainda mais curtas. Observe que isso requer que os elementos A não sejam separados por espaços em branco:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Correção para o "um e dois", como apontado por Dennis:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
fonte
Perl (v 5.10+) -
37353428para ser executado
perl -ape
, com a lista fornecida com o espaço separadoSTDIN
.Saída para várias entradas:
fonte
s/(\S+)$/and $1/
$
âncora em sua edição, portanto, uma entrada defoo bar baz
torna-sefoo, and bar, baz
. Além disso, você pode remover um dos espaços, fazendos/( \S+)$/ and$1/
$#F>1
como@F>2
para raspar mais uma. Desculpe por todas as sugestões de melhorias micro, eu realmente gosto desta resposta :)echo -n ... | wc -c)
. Se você perder o espaço antes,(\S+)
você chegaria a 33 caracteres, mas se você colocartest this
, receberátest and this
(dois espaços depoistest
)), sem mais Eu acho que está errado.Javascript (63)
l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')
Casos:
a = [1]
=>1
a = [1, 2]
=>1 and 2
a = [1, 2, 3]
=>1, 2, and 3
Advertência: isso modificará o último elemento em uma matriz com comprimento> 2.
fonte
&&
GNU sed - 69 caracteres, incluindo 1 para a
-r
bandeiraLeva uma lista separada por espaço (bastante idiomática para scripts de shell).
Exemplo
fonte
1 and 2
vez de1, 2
Python
2-71, 7068Contagem de caracteres, incluindo ambos,
input
eprint
.fonte
Ruby, 57 bytes
Estou ingressando na string
,
e, em seguida, substituindo a última vírgula na string por umaand
(e opcional, dependendo do tamanho da lista).fonte
Cobra - 60
A
List<of T>.join
função Cobra permite especificar um separador diferente para os dois elementos finais da lista, que é o que torna isso tão curto.fonte
Perl - 59
Une a lista com vírgulas e, se a lista tiver mais de um elemento, adiciona
' and'
após a última vírgula (se comprimento> = 3) ou substitui a última vírgula por ela (se comprimento == 2).fonte
PHP,
192167146136 136 caracteres:Com base em uma função que escrevi anos atrás em http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/
fonte
Lote - 151 bytes
Nota; você precisa chamar o script
cmd
com a/v
opção definida comoon
, para não precisar incluir o longosetLocal enableDelayedExpansion
no script. Caso contrário, adicione 30 à contagem de bytes e chame o script normalmente.fonte
Groovy,
47 4357 caracteres, JavaScript ES6 56 caracteresGroovy:
Como a matriz é preenchida com caracteres, podemos substituir
a.size>1
pora[1]
JavaScript, ES6:
Ambos os casos assumem que a variável a tem a matriz em questão.
fonte
PHP,
8684 caracteresCom a matriz inicializada, começamos a contar:
Pré-especificado:
O último item da lista é modificado. Isso deve ser bom, porque no PHP, a atribuição de matriz e as chamadas de função executam cópias.
fonte
CJam,
35302827 bytesEste é um programa que lê de STDIN e imprime em STDOUT. Experimente online.
Como funciona
Exemplo de execução
fonte
Planilhas Google,
67686792 bytesA entrada começa na célula
A1
e continua inativa por várias entradas.JOIN
mescla todos eles em uma cadeia de caracteres com um espaço de vírgula entre cada um.FILTER
remove todos os espaços em branco para que você não termine com vírgulas infinitas no final.SUBSTITUTE
substitui a última vírgula (encontradaCOUNTA
contando as entradas que não estão em branco).Não é muito emocionante, mas é factível em uma única célula.
fonte
)
dessa fórmula para -1 Byte; Bem, caramba, essa foi a edição mais rápida que eu já vi +1A:A>""
devem ser convertidos paraA:A<>""
e este não implementa omitindo a vírgula oxford sobre casos de apenas 2 objetos>""
. A correção rápida que fiz anteriormente claramente não foi testada. Eu não gosto da direção que foi ...JavaScript (ES6) 60
Supondo que não haja cadeias vazias na matriz de entrada
Teste no console do FireFox / Firebug
Saída
fonte
node --harmony
com uma série de stringsvar a = 'abcdefgh'.split('');
, mas ele fica lá com um...
e parece não fazer nada. Também +1 para usar o recurso exclusivo do ES6()=>
.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:b
também está correto e 13 bytes mais curto.JavaScript -
6056716763Não é exatamente uma abordagem idiomática, mas me diverti escrevendo e gosto de regex.
Supondo que a matriz esteja armazenada em
var a
:Encurtado simplesmente verificando o índice
[2]
: (yay coerção booleana)Aparentemente, sou péssimo nos testes e pulei um teste de entrada única. Aqui está a versão fixa:
Raspei 2 caracteres invertendo meus booleanos e mais 3 movendo o espaço da concatenação para o então / outro do primeiro ternário:
Obrigado a @tomsmeding por me lembrar que não tenho que coagir meus booleanos porque JS faz isso por mim. Também percebi que esqueci de remover os parênteses que separam o primeiro ternário da concatenação dentro do
join()
:Eu fiz isso certo? Novo pedido de desculpas obrigatório.
fonte
!!
;a[2]?A:B
já funciona. Pode ter que inverter seus booleanos novamente .a[i]
equivale a true . Bem, quase. Estou assumindo que, se você receber 2 entradas, sua matriz terá o comprimento dois. Entãoa[2]===undefined
eundefined
avalia comofalse
. EDIT: sua edição é o que eu quis dizer :)Golfscript -
31393430Olá Mundo! Sou muito espreita, pôster da primeira vez. Aqui está minha solução de 30 bytes no Golfscript (dado o array como [1 2 3] já está na pilha).
Os resultados são adequados para todos os casos de teste.
EDIT: Pegue isso, CJam!
fonte
Xojo,
527183 caracteresObserve que UBound é um a menos que o comprimento da matriz.
fonte
Excel VBA, 108 bytes
Função de janela imediata VBE anônima que recebe entrada como matriz delimitada por espaço do intervalo
A1
e sai para a janela imediata VBE.fonte
Raquete 87
fonte
Python 62 chars
Supondo que i seja a lista de strings:
fonte
C # 102 Chars
fonte
Julia (53)
Leva args de STDIN e sai para STDOUT
Solução usando Base.join (itens, delim [, último])
Editar:
Casos de teste
1 1
1 e 2
1, 2 e 3
fonte
1, 2, and 3
, não1, 2 and 3
.Rant (108)
Ungolfed:
Uso:
Experimente online
fonte
Pyth, 28
Exemplos:
fonte
TypeError: can only concatenate list (not "str") to list
). Funciona bem com a versão mais recente.PHP - 72
Configure a entrada:
E então o processo:
fonte