Como não consigo me concentrar em nenhuma tarefa por mais de 5 segundos, geralmente me pego dividindo as palavras em uma sub-string, cada uma com um comprimento diferente e não contém caracteres repetidos. Por exemplo, a palavra "macarrão" pode ser dividida em "passado" e "a", "pas" e "ta" ou "pa" e "sta" e você obtém a imagem.
No entanto, como lembrar de todas as combinações é difícil, geralmente seleciono apenas uma e gosto de selecionar a melhor. Consideramos a melhor maneira de ser a que tem a menor "pontuação". Sua tarefa será, dada uma palavra, imprimir sua pontuação, considerando as seguintes regras complicadas.
Pontuação
Descrição de como marcar uma palavra:
Uma palavra é uma sequência de caracteres latinos; as letras maiúsculas devem ser substituídas por 2 da mesma letra minúscula (para que "Caixa" se torne "bbox")
Um segmento é uma substring contígua (estrita) de uma palavra e não deve conter nenhum caractere duas vezes ("her", "re", "h" são todos segmentos válidos de "Here" ("hhere"), mas "hh" e "antes" não são)
Uma segmentação é um conjunto de segmentos de diferentes comprimentos que, quando unidos, formam a palavra original ("tre" e "e" makes "tree") e que não podem mais ser segmentados dentro da segmentação (ou seja, "ba" possui um único segmentação, "ba" e "alp" e "habet" não são uma segmentação válida de "alfabeto", porque qualquer um desses itens pode ser segmentado posteriormente (por exemplo, em "a" & "lp" & "habet", que agora é uma segmentação válida ("habet" não pode ser segmentado sem formar um segmento de comprimento 2 ou 1)).
A pontuação de uma segmentação é a soma das pontuações de cada caractere distinto que aparece na palavra original (depois que as maiúsculas são substituídas)
A pontuação dos personagens é explicada abaixo
A pontuação de uma palavra é a pontuação da sua melhor segmentação possível (aquela com a pontuação mais baixa)
Se não existir nenhuma segmentação válida para uma palavra (por exemplo, "Brass" ("bbrass"), que não pode ser segmentada porque o primeiro "b" e o último "s" teriam que estar em seus próprios segmentos, o que resultaria em em dois segmentos do mesmo comprimento), então você deve exibir o texto "evil", caso contrário, você deve exibir a pontuação da palavra.
Pontuação dos personagens
A pontuação dos caracteres é baseada em quantas vezes o caractere aparece e nas ponderações dos segmentos em que aparece. As ponderações dos segmentos dependem dos comprimentos do segmento e do menor múltiplo comum comum dos comprimentos de todos os segmentos em a segmentação.
segment weighting = lowest common multiple of lengths segments / length of segment
Considere a palavra "azeitona", que pode ser segmentada como "ol" e "ive" e visualizada como 2 caixas da mesma área, uma de "ol" com peso 3 e uma de "ive" com peso 2 (LCM de 6).
ol
ol ive
ol ive
Isso pretende representar as duas caixas, uma feita com 3 "ol" s e outra com 2 "ive" s. Como alternativa, pode ser "o" e "ao vivo" (LCM de 4)
o
o
o
o live
A pontuação de cada caractere é então a soma dos pesos dos segmentos em que aparece, multiplicada pelo número de vezes que aparece após a substituição de maiúsculas (portanto, se aparecer duas vezes, você será cobrado duas vezes cada vez que precisar dizer) )
character score = character count * sum(segment weights in which character appears)
Exemplo de pontuação
Pegamos a palavra "cair", que só pode ser segmentada em "fal" e "l". O menor múltiplo comum de 3 e 1 é 3, então "fal" tem peso 1 e "l" tem peso 3.
l
l
fal l
Passando por cada personagem ...
"f" aparece uma vez e está no segmento "fal" com peso 1, então tem pontuação 1 * 1 = 1
"a" também aparece apenas uma vez, tem soma de pesos de 1, então possui pontuação 1 * 1 = 1
"l" aparece duas vezes e aparece em "fal" (peso 1) e "l" (peso 3); portanto, possui pontuação 2 * (1 + 3) = 8
A soma destes é 10 (a pontuação da segmentação e da palavra, pois essa é a segmentação mais agradável). Aqui está isso no mesmo formato que os exemplos abaixo:
fall = fal l
2*1 [fa] + 2*(1+3) [ll] = 10
Pontuações de exemplo
Estes exemplos de pontuações podem ou não ajudar:
class -> clas s
3*1 [cla] + 2*(4+1) [ss] = 13
fish -> fis h
3*1 [fis] + 1*3 [h] = 6
eye -> e ye
1*1 [y] + 2*(1+2) [ee] = 7
treasure -> treas u re
3*2 [tas] + 2*2*(2+5) [rree] + 1*10 [u] = 44
Wolf -> w wolf
3*1 [olf] + 2*(1+4) = 13
book
evil
"livro" é uma palavra do mal, então não tem pontuação.
Observe que "tesouro" pode ser segmentado de várias maneiras, mas a segmentação mostrada se beneficia de ter as letras mais frequentes ("r" e "e") nos segmentos mais longos, para que não tenham tanto peso. A segmentação "t" e "re" e "asure" dariam o mesmo resultado, enquanto "treas" e "ur" e "e" sofreriam, com "e" tendo uma pontuação de 2 * (1 + 10 + 2 ) = 24 por conta própria. Essa observação é realmente o espírito de todo o exercício. Um exemplo de uma pontuação incorreta de "tesouro" (incorreta porque não é derivada da pontuação da segmentação mais agradável (aquela com a pontuação mais baixa)):
treasure = treas ur e
3*2 [tas] + 2*(2+5) [rr] + 1*5 [u] + 2*[2+10] = 49
Entrada
Uma única cadeia contendo apenas caracteres latinos de ambos os casos ("horse", "Horse" e "hOrSe" são todos dados válidos) que podem ser aceitos por STDIN, argumento de linha de comando, argumento de função ou de outra forma, se seu idioma for A escolha não suporta nenhum dos itens mencionados acima.
Resultado
Você deve gerar a pontuação da palavra, que é um número inteiro positivo único maior que 0, ou "mal" se não houver segmentação. A saída deve ser STDOUT ou o argumento de retorno de uma função, a menos que seu idioma de escolha não suporte nenhum deles, nesse caso, faça algo esportivo.
Exemplos
Eu não espero que você imprima todas essas coisas, tudo o que eu quero é a pontuação da palavra ou a saída "evil", por exemplo (entrada seguida por saída)
eye
7
Eel
evil
a
1
Establishments
595
antidisestablishmentarianism
8557
Não estou preocupado com o desempenho, se você consegue pontuar qualquer palavra de 15 letras (depois de substituir maiúsculas) em menos de um minuto em uma máquina sensata (intencionalmente deixada vaga), isso é bom o suficiente para mim.
Este é o código-golfe, que ganhe o menor código.
Agradecemos a PeterTaylor, MartinBüttner e SP3000 por sua ajuda neste desafio
fonte
Respostas:
Mathematica, 373 bytes
Isso é bastante longo ... e também bastante ingênuo. Ele define uma função sem nome que pega a string e retorna pontuação. Demora cerca de 1 segundo para lidar
"Establishments"
, por isso está dentro do prazo. Eu tenho uma versão um pouco mais curta que usaCombinatorica`SetPartitions
, mas já leva um minuto para"Establishme"
.Aqui está uma versão com espaço em branco:
Eu poderia adicionar uma explicação mais detalhada mais tarde. Este código usa a segunda solução desta resposta para obter todas as partições e esta solução para garantir que todas estejam segmentadas ao máximo.
fonte
Java 8,
15101485 bytesEste é caminho muito longo. Combinatória nunca é fácil em java. Definitivamente, pode ser reduzido bastante. Ligue com
a(string)
. Isso usa um algoritmo exponencial de memória e tempo; portanto, não espere que ele funcione para entradas longas. Demora cerca de meio segundo para processarEstablishments
. Falha com um erro de falta de memória paraantidisestablishmentarianism
.Tente aqui
Recuado com explicação:
Isso também abusa bastante dos genéricos para reduzir a contagem de bytes. Estou bastante surpreso por ter conseguido compilar tudo isso.
Obrigado Ypnypn :)
fonte
i.put...
linha e no loop while; Eu acho quewhile(d!=0)
pode serwhile(d>0)
; não há necessidadenew ArrayList
no final, poisArrays.asList
dá um deArrayList
qualquer maneira; no método final, você pode definirb
como uma planícieList
.Arrays.asList
retorna um modificávelArrayList
, então não posso usá-lo sem obter umOperationNotSupportedException
.b
pode ser uma lista simples, masc
precisa permanecer aList<List<String>>
. Vou verificar sewhile(d>0)
funciona amanhã.C # 679 bytes
Essa solução é basicamente baseada na estrutura da minha implementação de teste original e, inicialmente, era apenas uma reescrita de golfe, mas então eu descrevi todas as funções, e agora é horrível. É razoavelmente rápido, resolvendo estabelecimentos em menos de um segundo. É um programa completo que aceita a palavra de entrada como um único parâmetro de ARGV.
o
Main
método começa criando uma cópia da entrada com as maiúsculas substituídas. Em seguidaS
, chama o "solucionador", que retorna a pontuação de uma determinada segmentação (a primeira segmentação é aquela com um único segmento que é a palavra inteira). Em seguida, ele imprime "mal" ou a pontuação, dependendo da pontuação.O "solucionador" (
S
) faz todo o material interessante e foi originalmente dividido em quatro métodos, que foram agrupados. Ele funciona primeiro pontuando a segmentação atual, anotando se ela é inválida (e crucialmente, se é tão inválida que não devemos tentar segmentá-la ainda mais (por desempenho), ignorando o restante da computação, se for) . Então, se não tiver sido ignorado, ele divide cada segmento da segmentação em todos os lugares em que pode ser dividido e encontra a melhor pontuação de todos eles (chamada recursivamenteS
). Por fim, ele retorna a melhor pontuação das segmentações subordinadas; caso contrário, é sua própria pontuação ou é inválida se sua própria segmentação for inválida.Código com comentários:
fonte