m | Y bR | ain é Nós | iRd. F (o) RT (h) E La | sT fi (v) e YE | ars O | R s | o, (I) ha | ve C (u) T dois em h (a) lf wh | En (I) s (e) e Th | em. Quando eu comecei a fazê-lo, ele me esforça para me esforçar - B (u) TI quase não pode (N) fazer N (o) T-lo. No entanto, eu o coloquei na parte de trás da minha cabeça, e (n) dificilmente nem o vi. No entanto, pensei que isso seria um grande desafio.
Definições
Para esse desafio, cada letra recebe uma pontuação, com base no meu julgamento de sua largura em uma fonte sem serifa. Você usará essa largura para cortar uma palavra em duas metades da mesma largura. Os caracteres que esse desafio usará são o alfabeto em maiúsculas e minúsculas, apóstrofo e hífen.
Width Characters
1 i l I '
2 f j r t -
3 a b c d e g h k n o p q s u v x y z
4 m w A B C D E F G H J K L N O P Q R S T U V X Y Z
5 M W
Para minhas explicações e casos de teste, |
denota o local em que uma palavra pode ser dividida ao meio.(
e)
nos dois lados de uma carta, indique que ela será dividida ao meio para criar uma divisão limpa.
Entrada
A entrada consistirá em uma única "palavra" (que não precisa estar no dicionário). Você pode usar esta palavra em qualquer entrada de texto que desejar (String, char array, etc.). Esta palavra conterá apenas letras,, '
e -
(veja a tabela acima). Por causa do que você fará com esta palavra (veja abaixo), o caso de entrada é deixado a critério do desenvolvedor. Novas linhas à direita são permitidas, se necessário.
A tarefa
Permute através de todas as formas da entrada (todas as letras em todas as posições possíveis em maiúsculas ou minúsculas). Por exemplo, para entrada it's
, a seguir estão todas as permutações:
it's
it'S
iT's
iT'S
It's
It'S
IT's
IT'S
Para dividir uma permutação de uma palavra ao meio, os pontos de um lado da palavra devem ser os mesmos que os do outro lado da palavra. No entanto, se uma carta estiver presa entre duas seções pares, você também poderá cortá-la ao meio.
Observe que "metade" não significa que você se moveu até a metade da string. "Metade" significa que os pontos de ambos os lados são iguais.
Exemplos:
W
é de 5 pontos. i
é 1 ponto. Dividir a permutação Wiiiii
ao meio resultará em W | iiiii
, com 5 pontos em cada lado do |
.
T
é de 3 pontos. Dividir a permutação TTTT
ao meio resultará em TT | TT
, com 6 pontos em cada lado do|
.
w
é de 4 pontos. a é 3 pontos. Dividir a permutação waw
ao meio resultará em w (a) w
, com 5,5 pontos em cada lado. Os pontos de a
são distribuídos para ambos os lados, comoa
é dividido ao meio.
Resultado
Sua saída é um número inteiro do número de permutações exclusivas da entrada que podem ser divididas ao meio de maneira limpa. Novas linhas à direita são permitidas, se necessário.
Casos de teste
Eu emitirei todas as permutações válidas da entrada para os casos de teste. Lembre-se de que isso não faz parte das especificações para você.
Na minha saída intermediária, os números indicam o valor em pontos da letra acima deles, portanto a saída é um pouco mais fácil de visualizar.
Input: a
( a )
3
( A )
4
Output: 2
Input: in
Output: 0
Input: ab
A | B
4 4
a | b
3 3
Output: 2
Input: abc
A ( B ) C
4 4 4
A ( b ) C
4 3 4
a ( B ) c
3 4 3
a ( b ) c
3 3 3
Output: 4
Input: will
W ( I ) L l
5 1 4 1
W ( I ) l L
5 1 1 4
W ( i ) L l
5 1 4 1
W ( i ) l L
5 1 1 4
w I | L l
4 1 4 1
w I | l L
4 1 1 4
w i | L l
4 1 4 1
w i | l L
4 1 1 4
Output: 8
Input: stephen
S T E ( P ) H E N
4 4 4 4 4 4 4
S T E ( p ) H E N
4 4 4 3 4 4 4
S T E | p h e n
4 4 4 3 3 3 3
S T e ( P ) H E n
4 4 3 4 4 4 3
S T e ( P ) H e N
4 4 3 4 4 3 4
S T e ( P ) h E N
4 4 3 4 3 4 4
S T e ( p ) H E n
4 4 3 3 4 4 3
S T e ( p ) H e N
4 4 3 3 4 3 4
S T e ( p ) h E N
4 4 3 3 3 4 4
S t E ( P ) H e n
4 2 4 4 4 3 3
S t E ( P ) h E n
4 2 4 4 3 4 3
S t E ( P ) h e N
4 2 4 4 3 3 4
S t E ( p ) H e n
4 2 4 3 4 3 3
S t E ( p ) h E n
4 2 4 3 3 4 3
S t E ( p ) h e N
4 2 4 3 3 3 4
S t e ( P ) h e n
4 2 3 4 3 3 3
S t e p | H E N
4 2 3 3 4 4 4
S t e ( p ) h e n
4 2 3 3 3 3 3
s T E ( P ) H E n
3 4 4 4 4 4 3
s T E ( P ) H e N
3 4 4 4 4 3 4
s T E ( P ) h E N
3 4 4 4 3 4 4
s T E ( p ) H E n
3 4 4 3 4 4 3
s T E ( p ) H e N
3 4 4 3 4 3 4
s T E ( p ) h E N
3 4 4 3 3 4 4
s T e ( P ) H e n
3 4 3 4 4 3 3
s T e ( P ) h E n
3 4 3 4 3 4 3
s T e ( P ) h e N
3 4 3 4 3 3 4
s T e ( p ) H e n
3 4 3 3 4 3 3
s T e ( p ) h E n
3 4 3 3 3 4 3
s T e ( p ) h e N
3 4 3 3 3 3 4
s t E ( P ) h e n
3 2 4 4 3 3 3
s t E p | H E N
3 2 4 3 4 4 4
s t E ( p ) h e n
3 2 4 3 3 3 3
s t e P | H E N
3 2 3 4 4 4 4
s t e p | H E n
3 2 3 3 4 4 3
s t e p | H e N
3 2 3 3 4 3 4
s t e p | h E N
3 2 3 3 3 4 4
Output: 37
Input: splitwords
S P L I T | W O r d s
4 4 4 1 4 5 4 2 3 3
<snip>
s p l i t w | o R d S
3 3 1 1 2 4 3 4 3 4
Output: 228
Input: 'a-r
' a ( - ) R
1 3 2 4
' a | - r
1 3 2 2
Output: 2
Input: '''''-
' ' ' ( ' ) ' -
1 1 1 1 1 2
Output: 1
Vitória
Isso é código-golfe , então a resposta mais curta em bytes vence. Você deve poder produzir todos os casos de teste (portanto, todas as entradas com até 10 caracteres) em um período de tempo razoável. Não limite artificialmente sua entrada.
Recompensa
Não sei se isso está no campo da possibilidade. No entanto, você é jogador de golfe - você fará qualquer coisa para o representante. Estou oferecendo uma recompensa de 200 repetições (vou iniciá-la quando essa condição de recompensa for cumprida, como parece basicamente impossível para mim) para um programa que produz a saída correta por antidisestablishmentarianism
menos de 15 segundos em um computador comum (também conhecido como meu). Observe que este caso de teste não deve ser codificado de forma alguma.
@DigitalTrauma esmagou minha recompensa, chegando bem menos de dois segundos. Confira a resposta dele aqui .
antidisestablishmentarianism
(não-golfy) é83307040
(e corresponde a todos os casos de teste), mas leva ~ 37 segundos no meu laptop (lembre-se de que é Python). Alguém também tem uma conta para isso?Respostas:
Pitão ,
75747370 bytesExperimente online!
Pelo amor de Deus, por favor, nem tente
antidisestablishmentarianism
no intérprete. Você vai travar.Explicação
Vamos dividir esse código em X partes.
A primeira parte: gerando versões casadas e mapeando para os valores
Sejamos claros aqui. Em nenhuma parte do processo as letras são maiúsculas. Apenas precisamos mapear uma letra para dois valores (e os sinais de pontuação para um valor), sem a necessidade de capitalizá-los. Decidiremos quais caracteres precisaremos de dois valores e para quais caracteres precisaremos de um:
Como você vê, até a primeira parte é muito longa.
O primeiro valor é para a versão em minúscula, que inclui
'
e-
. O segundo valor é para versão maiúscula, com'
e-
não será necessário.O primeiro valor:
A primeira string contém
"mw"
no índice 0. Tem um valor de 4, o que explica a necessidade do lógico ou. Observe que o Pyth usa a indexação 0. Além disso, o espaço antes do4
é separá-lo de1
.O segundo valor (maiúsculo):
Se
d
for"i"
, então ele dá1
o primeiro passo. Caso contrário, continua. Sed
for"m"
ou"w"
, então o terceiro passo dá1
, que é adicionado4
a dar5
. Sed
não é"m"
ou"w"
, então o terceiro passo dá0
, que é adicionado4
a dar4
.A segunda parte: fazendo o trabalho
Isso é anexado à primeira parte, que tecnicamente não é separada da segunda parte (ainda é um comando). Portanto, o valor da primeira parte é passado para a direita.
Recapitulando: na primeira parte, mapeamos as letras para seus valores possíveis (minúsculas e maiúsculas para letras, apenas um valor para os dois sinais de pontuação). Para entrada
"ab"
, seria possível obter[[3,4],[3,4]]
.Para gerar as diferentes versões em caixa (que deveriam ter sido feitas na primeira parte, mas que estourariam), usamos o produto cartesiano repetidamente e depois aplainamos o resultado. Os problemas surgem quando existe apenas uma letra (primeira caixa de teste), porque o produto cartesiano não nos forneceria uma matriz e o comando flatten (
.n
) é excedido para fornecer resultados estranhos aos números. Vamos ver como contornei esse problema.Se é uma divisão no meio por
|
, o prefixo terá a soma dobrada, sendo a soma do total.Se for dividido por
()
, a soma do prefixo dobrou menos o valor entre parênteses seria a soma do total.fonte
c, 378 bytes; cerca de 0,6s para
antidisestablishmentarianism
Resposta atualizada . Eu li o comentário de @ JonathanAllan sobre
i
s, e no começo eu não entendi essa otimização, mas agora vejo que desde tantoi
eI
ter uma largura de 1, então podemos contar as permutações associadas duas vezes com apenas ter que validar uma vez. Anteriormente, minha solução usava vários threads para espalhar a carga por várias CPUs e com isso eu era capaz de passar por todas as 2 28 possibilidades da minha máquina. Agora com oi
otimização, não há necessidade de mexer nos threads - um único thread faz o trabalho facilmente dentro da restrição de tempo.Sem mais delongas - a função c golfed:
A função recursiva
f
usa 3 parâmetros - um ponteiro para a sequência de entrada, o comprimento da sequência e o deslocamento na sequência para iniciar o processamento (deve ser 0 para a chamada de nível superior). A função retorna o número de permutações.Experimente online . Normalmente, o TIO parece ser executado em todos os casos de teste (inclusive
antidisestablishmentarianism
em menos de 2 segundos.Observe que existem alguns não imprimíveis na string que é
bcopy()
editadam[]
. O TIO parece lidar com isso corretamente.Ungolfed:
Eu tenho um MacBook Pro de meados de 2015 executando o MacOS 10.12.4. O compilador é o clang padrão do MacOS. Estou compilando com:
A execução de todos os casos de teste, incluindo
antidisestablishmentarianism
:Isto não é de forma alguma o ideal. O algoritmo simplesmente abre caminho através de todas as possibilidades (módulo
i
- veja os comentários acima) e conta as palavras que podem ser divididas de acordo com os critérios.fonte
i
,-
,'
,l
,mw
,fjrt
, eabcdeghknopqsuvxyz
, mas que seria necessário um pedido do Pólya enumeração teorema (ou um método de enumeração combinatória equivalente), no qual não sou bem versado.JavaScript (ES6),
199169167 bytesEspera a sequência de entrada em minúsculas. Muito lento para a recompensa.
Casos de teste
Mostrar snippet de código
fonte
C,
403394 bytes,Obrigado Kevin!
Experimente online
Código não destruído:
fonte
f(char* w, int l){
->f(char*w,int l){