Digitando com teclas mexidas

16

Seu amigo não é muito bom com computadores, então, como uma piada prática, alguém embaralhou as letras (az) em seu teclado. Quando ele se sentou e tentou digitar seu nome olhando para o teclado, percebeu que as letras estavam embaralhadas e pediu sua ajuda.

Você é esperto e sabe que, se ele digitar seu nome e digitar repetidamente o que aparece na tela, em vez de seu nome, ele poderá digitar seu nome eventualmente. Você também é gentil e reorganiza as teclas, mas quer saber quantas voltas seriam necessárias para ter sucesso.

Sua tarefa é escrever um programa ou função que, dada a ordem aleatória das letras e o nome do amigo, calcule o número de turnos.

Detalhes da entrada:

  • Duas cordas são fornecidas como entrada em uma estrutura conveniente para o seu idioma.
  • A primeira string é a lista das novas letras minúsculas em ordem alfabética das antigas. (O primeiro caractere é aquele que está na posição de a, o último está na posição de z.) Alguma mudança sempre ocorrerá na string.
  • A segunda string é o nome. Ele pode conter qualquer caractere ascii imprimível, mas apenas os caracteres alfabéticos maiúsculos e minúsculos serão embaralhados, se houver. O nome em si pode não ser embaralhado.

Detalhes da saída:

  • A saída é um único número inteiro o número de voltas minimamente necessário. Nova linha é opcional.

Exemplos:

Entrada: 'abcfdeghijklmnopqrstuvwxyz' 'Mr. John Doe'(posições d, e, f alteradas)

Saída: 3(Os nomes mostrados são: Mr. John Fod=> Mr. John Eof=> Mr. John Doe)

Entrada: 'nopqrstuvwxyzabcdefghijklm' 'Mr. John Doe'(a cifra ROT13 )

Saída: 2(Qualquer nome de entrada que contenha letras será 2arredondado para produzir o nome original.)

Entrada: 'aebcdjfghiqklmnopzrstuvwxy' 'John Doe'

Resultado: 140

Este é o código-golfe, portanto a entrada mais curta vence.

randomra
fonte
11
Você provavelmente deve incluir este caso de teste: aebcdjfghiqklmnopzrstuvwxy(saída 1260 para Mr John Doe). Esse é o máximo possível - consiste em ciclos de ordem 4, 5, 7, 9 (e um inalterado a), e todo nome que contém pelo menos uma letra de cada ciclo gera 1260. E eu acho que pegar o próprio alfabeto como entrada ou usar um nome não afetado também são casos importantes.
Martin Ender
@ MartinBüttner Adicionado com modificação.
randomra
Estou um pouco confuso sobre como você apresenta o número de turnos.
FUZxxl
@FUZxxl Em geral, você pode decompor a permutação em ciclos e depois verificar quais ciclos incluem caracteres do nome. O resultado é o LCM dos comprimentos desses ciclos (os ciclos através de caracteres que não estão no nome são irrelevantes, é claro). No entanto, para esse desafio, isso não é realmente necessário ... basta realizar as substituições até você acertar o nome original e contar quantas vezes você teve que substituí-lo.
Martin Ender
11
Como uma nota lateral, John File Marker aka EOFé totalmente incrível!
Rev

Respostas:

9

Pitão, 16 bytes

JGfqzuXGJrQ0UTz1

Experimente aqui.

A entrada deve ser dada em duas linhas, nome e permutação. A permutação deve ser citada. O nome pode ser citado ou não. Por exemplo:

"John Doe"
"aebcdjfghiqklmnopzrstuvwxy"

Dá 140.

Explicação:

                            Implicit:
                            z = input()              z is the name.
                            Q = eval(input())        Q is the permutation.
                            G = 'abcdefghijklmnopqrstuvwxyz'

JG                          J = G
  f             1           Starting at 1 and counting upwards, find
                            the first case where the following is true:
   qz                       z ==
     u       UTz            reduce, where the accumulator, G, is initialized to z on
      XG                    translate G
        J                   from the normal alphabet, J
         rQ0                to Q.lower().
isaacg
fonte
O método de entrada deve ser idêntico para as seqüências de caracteres.
randomra 31/01
10

CJam, 31 27 25 24 bytes

l:A;lel:N{_A_$er_N#}g;],

Recebe entrada na forma de:

aebcdjfghiqklmnopzrstuvwxy
Mr. John Doe

ou seja, primeira linha - alfabetos, segunda linha - nome.

Como funciona :

l:A;lel:N{_A_$er_N#}g;],
l:A;                         "Read the alphabets from the 1st line in A and pop from stack";
    lel:N                    "Read the name in small caps from 2nd line and store in N";
         {         }g        "Run a while loop until we have the original name back again";
          _                  "Put a dummy string on stack just to keep count of times";
           A                 "Put the alphabets on stack";
            _$               "Copy them and sort the copy to get the correct order";
              er             "Transliterate the right keys with the wrong ones";
                _N#          "Copy the result and see if its equal to the original name";
                     ;]      "Pop the last name and wrap everything in an array";
                       ,     "Get the length now. Since we were putting a dummy string";
                             "on stack in each iteration of the while loop, this length";
                             "represents the number of times we tried typing the name";

Experimente online aqui

Optimizer
fonte
5

Ruby, 58

->a,n{t=""+n
(1..2e3).find{t.tr!("a-zA-Z",a+a.upcase)==n}}

Explicação

  • A entrada é tomada como argumento para uma lambda.
  • Use Enumerable#find(obrigado @Ventero!) E String#tr!para substituir caracteres até que o substituto Stringcorresponda ao nome real.
britishtea
fonte
""+né um pouco mais curto que n.dup, e você pode salvar outro byte usando de forma criativa, em Enumerable#findvez de usar um contador explícito:(1..1e4).find{t.tr!(...)==n}
Ventero
Além disso, você pode salvar muitos bytes, tornando a entrada n em minúscula
Otimizador
@ Optimizer Isso não parece me salvar nada, o método de Ruby para converter para minúsculas é bastante demorado (eu precisaria usar n.downcase!).
britishtea
sim, mas então você não precisa fazer A-Ze+a.upcase
Optimizer
A-Z+a.upcasee n.downcase!\ntem o mesmo comprimento :)
britishtea 31/01
2

CJam, 32 31 bytes

llel_2e3,{;'{,97>3$er_2$=}#)p];

Teste aqui. Leva a permutação na primeira linha e o nome na segunda linha da entrada.

Explicação

llel_2e3,{;'{,97>3$er_2$=}#)p];
ll                              "Read both lines into strings.";
  el_                           "Convert the name to lower-case and duplicate.";
     2e3,                       "Get a range from 0 to 1999 to cover all possible results.";
         {               }#     "Find the first index where the block yields a true result.";
          ;                     "Discard the number, it's just a dummy.";
           '{,97>               "Create a string of the lower-case alphabet.";
                 3$             "Copy the permutation.";
                   er           "Substitute letters in the second copy of the name.";
                     _2$=       "Duplicate and check for equality with original name.";
                           )p   "Increment by 1 and print.";
                             ]; "Clear the stack to prevent extraneous output.";
Martin Ender
fonte
2

Pitão 26

KGJ@GrQZfqJusm@zxKdGUTJ!!J

Experimente online aqui.

Existem algumas conseqüências infelizes que custam bytes de programa, como ter que armazenar G em K para usá-lo na redução, além de precisar usar não (não (J)) para iniciar o filtro. Por causa disso, espero que isso ainda possa ser praticado.

Este é um programa que recebe entradas como:

aebcdjfghiqklmnopzrstuvwxy
'John Doe'

(Observe a falta de aspas no primeiro argumento)

Explicação para vir após exaustão incapacitante;)

FryAmTheEggman
fonte
Devo repetir o meu comentário anterior ')
Optimizer
@Optimizer: PI perdeu o último;)
FryAmTheEggman
Você estava dizendo ? ;)
Otimizador
1

Haskell 131 bytes

import Data.Char
h n=(!!((ord n)-97))
g s n m|n==m=1|0<1=1+g s(h n s)m
f s=foldr1 lcm.map((\x->g s(h x s)x).toLower).filter isAlpha

Ligue fcom a string de permutação e o nome para obter o resultado

Explicação

-- h finds the mapping of a character given the permutation
h :: Char   -> -- Character to map
     String -> -- Character permutation
     Char      -- Mapped character

-- g finds the number of character mappings required to reach a given character
-- by calling h on the given character every time it calls itself.
g :: String -> -- The character permutation
     Char   -> -- The current character
     Char   -> -- The character to find
     Int       -- The number of mapped to find the character

-- f finds the number of mappings required to return the given string back to itself
-- by finding the lowest common multiple of the period of all the characters in the
-- given string
g :: String -> -- The permutation string
     String -> -- The string to get back
     Int       -- The final answer
Jmac
fonte
1

GolfScript (33 bytes)

~{32|}%\:A&{.{A$?A=}%.-1$=!}do],(

Recebe entrada como duas seqüências de caracteres entre aspas (simples ou duplas), separadas por qualquer quantidade de espaço em branco; por exemplo

'abcfdeghijklmnopqrstuvwxyz' 'Mr. John Doe'

Demonstração online

Dissecação

~           # Eval. Stack: perm name
{32|}%      # Lower-case name (also affects non-alphabetic characters but...)
\:A&        # Store perm in A and filter name to alphabetic characters, giving str_0
{           # do-while loop. Stack: str_0 str_1 ... str_i
  .         #   Duplicate str_i
  {A$?A=}%  #   tr 'a-z' perm   giving str_{i+1}
  .-1$=!    #   Loop while str_{i+1} != str_0
}do         # end do-while loop
],(         # Gather the sequence of permuted strings in an array and take its length - 1
            # to account for containing str_0 twice

A transliteração se baseia no fato de que todos os caracteres são afetados (é {'ABC'?'abc'=}%com a sequência classificada A$substituindo 'ABC'e a permutação Asubstituindo 'abc'); as alternativas mais gerais não economizam o suficiente, porque o filtro para caracteres alfabéticos é muito barato.

Isso também depende do -1$acesso à parte inferior da pilha, o que é um truque GS relativamente raro.

Peter Taylor
fonte