Esta string é uma carta que faz uma roda estrelada?

35

A inspiração do desafio foi essa que vi em algum lugar:

A palavra "freira" é apenas a letra n fazendo uma roda de carroça

Seu desafio é pegar uma corda e determinar se é a primeira letra que faz uma roda estrelada.

Regras

Uma string é uma letra que roda uma roda se:

  • A primeira letra é igual à última letra. (A carta não pode cair de cabeça para baixo.)
  • A sequência alterna entre letras de roda giratória a cada caractere.

As letras cartwheeling são ne u, me w, be q. Observe que ne wjuntos não são letras giratórias e nem são we b.

  • Você pegará uma string usando qualquer um dos nossos métodos de entrada padrão.
  • Você produzirá um valor verdadeiro se a sequência for uma letra de roda giratória e um valor falso se não for. A saída pode ser feita usando qualquer método de saída padrão.

Regras adicionais:

  • Somente letras em minúsculas n/ u/ m/ w/ b/ qprecisam ser manuseadas.
  • Você pode assumir que a entrada nunca está vazia.
  • Uma cadeia de um caractere não é uma roda dentada válida.

Casos de teste

Input        -> Output
nun          -> truthy
nunun        -> truthy
nunununu     -> falsy
wmw          -> truthy
wmwun        -> falsy
bqbqbqbqbqb  -> truthy
v^v^v        -> falsy
AVAVA        -> falsy
OOO          -> falsy
ununununu    -> truthy
nunwmwnun    -> falsy
nun unun     -> falsy
nunwmw       -> falsy
nnuunnuunnuu -> falsy
nwnwnwnwn    -> falsy
m            -> falsy
nunuuunun    -> falsy

Vencedora

Como no , o código mais curto (em cada idioma) vence!

MD XF
fonte
29
Eu acho que bestraga tudo q, não é? de ptambém são amigos de roda dentada. A chave é que eles giram, não giram.
Engenheiro Toast
Outra sugestão do testcase:uwuwuwuwuwu
Kritixi Lithos 2/17/17
19
Por que bqbmas não pdp?
aschepler
@aschepler eu errei.
MD XF
2
Uma vez que dpd, pdp e tais não funcionam, acho que você deveria tê-los nos casos de teste com uma resposta falsa.
trlkly

Respostas:

2

Gelatina , 23 bytes

Isso levou mais trabalho do que se poderia pensar!

“nmbuwq”iЀo⁵IAs2⁼€3,3Ȧ

Um link monádico que pega uma lista de caracteres e retorna 1(verdade) ou 0(falsey).

Experimente online! ou veja uma suíte de testes .

Quão?

Localiza o índice de cada caractere da entrada na lista de caracteres indexados em 1 nmbuwq. Essa sequência é organizada de modo que os índices dos pares sejam separados por três, portanto, a diferença incremental dos índices para cartwheels válidos será repetições de um de [-3,3]ou [3,-3].

Quando um item não é encontrado em uma lista pelo átomo "index of" i, ele retorna 0, o qual emparelharia caracteres não encontrados b, fazendo com que a entrada fosse realmente verdade bxbxb. Portanto, 0s são substituídos por 10um valor a mais de três de qualquer outro valor antes de verificar a validade.

“nmbuwq”iЀo⁵IAs2⁼€3,3Ȧ - Link: list of characters, s
         Ѐ             - map across c in s:
        i               -   first index of c in (1-indexed; 0 if not present)
“nmbuwq”                -   literal "nmbuwq"
            ⁵           - literal 10
           o            - logical or (vectorises - replace any 0s with 10s)
             I          - incremental differences (i.e. deltas)
              A         - absolute value (vectorises)
               s2       - split into chunks of 2 (possibly with a single remainder)
                   3,3  - pair three with three = [3,3]
                 ⁼€     - equals? for €ach (1 if so, otherwise 0 - including a single 3)
                      Ȧ - any and all? (0 if any 0s or if empty, 1 otherwise)
Jonathan Allan
fonte
13

sed 4.2.2 , 30 + 1 -r= 43 31 bytes

Economizou 12 bytes graças a @Neil, encurtando a primeira linha

/nu|wm|qb/!d
/^((.).)\1*\2$/!d

Experimente online!

Exclui a entrada se falsey, caso contrário, não faz nada na entrada.

Explicação

Com o -rsinalizador, não precisamos usar \(e \)para capturar grupos e isso economiza bytes.

/nu|wm|qb/!                # On every line that does not match this regex
           d               # Delete
/^((.).)\1*\2$/!           # On every line that does not math
 ^((.).)                   #  the first two characters at the beginning of the line
        \1*                #  repeated
           \2$             #  with the first character at the end of the line
                d          # Delete
Kritixi Lithos
fonte
Aí vem o sedassistente ...
MD XF
@MDXF Estou longe de ser um assistente, ainda um iniciante :)
Kritixi Lithos
Tudo sedparece mágico para mim. : P
MD XF
11
Você só precisa verificar a contenção de metade dos pares de letras, por exemplo, ambos unue nuncontains nue a segunda linha garante que o restante das letras corresponda a esses dois.
Neil
8

JavaScript (ES6), 82 78 77 bytes

Economizou 1 byte usando dois valores falsy, conforme sugerido por ThePirateBay e MD XF.

([c,...s],S='bqwmun')=>s.reduceRight((r,a)=>r&a==S[S.search(c)^++k&1],k=s>'')

Casos de teste

Arnauld
fonte
Alguma razão para sair em &&vez de &?
@ThePirateBay Bem, o único motivo é a consistência do valor falsy retornado, embora não pareça realmente ser um requisito para esse desafio. (Usando &produziria quer falseou 0.)
Arnauld
@ Arnauld Você pode remover o segundo &; Especifiquei (no chat) em algum momento que valores inconsistentes de falsidade são permitidos.
MD XF
5

Python 3 , 111 bytes

-2 bytes graças ao Sr. Xcoder.

lambda s:s[0]==s[-1]and any(any({*s[::2]}=={i[j]}and{*s[1::2]}=={i[j<1]}for j in[0,1])for i in['nu','mw','bq'])

Experimente online!

totalmente humano
fonte
2
suspira como você me passar em rep novamente
MD XF
Não me sinto bem com isso, já que você está prestes a atingir minha contagem de bytes novamente, mas -2 bytes .
Mr. Xcoder
BTW, sua solução é inválida, assim como a minha era no começo. Falha em nunununu.
Mr. Xcoder
Corrigido ao custo de muitos bytes. ; -;
totallyhuman
5

Python 2 , 63 bytes

lambda s:s[:3]in'ununqbqbwmwm'and s==s[:2]*max(len(s)/2,1)+s[0]

Experimente online!

Harrichael
fonte
Boa resposta, bem-vindo ao site! Algumas dicas: você pode fazer "nu un nm mn bp pb".split()para salvar 4 bytes e remover alguns espaços em branco. 75 bytes:lambda s:any(s==c[-1]+c*max(len(s)/2,1)for c in"nu un nm mn bp pb".split())
DJMcMayhem
Você pode economizar 1 byte ao s[0]invés de c[-1].
DJMcMayhem
A resposta de 61 bytes retorna True para unmnue unmwnu. Realmente retorna falso positivo quando (s==s[::-1])+len(set(s))é 4, o que é fácil de forçar. Mesmo apenas 4 caracteres diferentes fazem com que retorne True.
Arnold Palmer
Os 59 bytes são interrompidos com entradas de caracteres únicos. Desculpe para escolher em um presente, eu gosto de Python :)
Arnold Palmer
As exceções não são falsas? Essa pausa é intencional
Harrichael
5

Python 3 , 71 bytes

lambda n:''.join(sorted({*n[1::2]}|{*n[::2]}))in"nu,mw,bq"*(n==n[::-1])

Experimente online!

-1 graças a @HyperNeutrino e -13 graças a @ovs

Se o que foi dito acima falhar em qualquer caso de teste, há uma alternativa:

lambda n:(sorted(list({*n[1::2]}.union({*n[::2]})))in[[*'nu'],[*'mw'],[*'bq']])*n[0]==n[-1]

Experimente online!


Explicação

  • ''.join(sorted(list({*n[1::2]}).union({*n[::2]})))) - Obtém os caracteres em índices ímpares e os caracteres em índices pares, desduplica-os e classifica a lista formada por sua união.

  • in'nu,mw,bq' - Verifica se são combinações válidas de cart-carta.

  • n[0]==n[-1] - Verifica se o primeiro caractere é o mesmo que o último.

Mr. Xcoder
fonte
Não tem caso de teste, bom trabalho +1
MD XF
@MDXF Oh thanks! Estou tão aliviado rn ...> _ <
Sr. Xcoder
11
uwuwuwuwuwuresulta em true
Kritixi Lithos
11
Inválido: nunuuunun
Harrichael
11
nuuun -> True. Isto não está certo.
recursivo
5

JavaScript (ES6), 40 bytes

s=>/^(nu|un|bq|qb|wm|mw)+$/.test(s+s[1])

Verifica se a sequência de entrada concatenada com o segundo caractere da sequência de entrada é uma sequência repetida do mesmo par de caracteres de roda dentada.

Testes:

[
  "nun",
  "nunun",
  "nunununu",
  "wmw",
  "wmwun",
  "bqbqbqbqbqb",
  "v^v^v",
  "AVAVA",
  "OOO",
  "ununununu",
  "nunwmwnun",
  "nun unun",
  "nunwmw",
  "nnuunnuunnuu",
  "nwnwnwnwn",
  "m",
  "nunuuunun"
].forEach( x=>console.log( x, (s=>/^(nu|un|bq|qb|wm|mw)+$/.test(s+s[1]))(x) ) )

MT0
fonte
Realmente amo a lógica aqui! Eu nunca teria pensado em adicionar um personagem no final e testar. Código legal e limpo também, mesmo quando jogado.
trlkly
4

Clojure, 156 bytes

(fn[w](let[s["nu""wm""bq"]c #(= 1(count(set %)))e #(take-nth 2 %)r #(and(c(e %))(c(e(drop 1 %))))](and(=(first w)(last w))(r w)(some #(=(set w)(set %))s))))

Isso foi enganosamente difícil! Acabei tendo que dividi-lo em três sub problemas:

  • A primeira letra é igual à última?
  • As letras se repetem?
  • Todas as letras fazem parte de um dos conjuntos válidos?

Certamente não ganhei, mas este foi um bom dia de exercício! Explicação completa abaixo:

(defn cartwheel? [word]
  (let [; Valid Character Sets
        cs ["nu" "wm" "bq"]

        ; Is the list composed of only a single character?
        count-1? #(= 1 (count (set %)))

        ; Grabs every other element of the list
        every-other #(take-nth 2 %)

        ; Do the characters repeat? Works by checking if every other element is the same, then drops the first letter
        ; to check all the odd indexed characters
        repeating? #(and (count-1? (every-other %))
                         (count-1? (every-other (drop 1 %))))]

    ; Do all the predicates hold?
    (and (= (first word) (last word))
         (repeating? word)
         ; Is the set of letters in the word part of some set of the valid characters?
         (some #(= (set word) (set %)) cs))))
Carcinigenicado
fonte
4

Haskell, 80 78 bytes

f s|l<-length s=odd l&&l>1&&any((==s).take l.cycle)(words"un nu mw wm bq qb")

Experimente online!

Como funciona:

l<-length s        -- let l be the length of the input string

f s         =      -- return True, if
    odd l          -- l is odd and
    l > 1          -- l is greater than 1 and 
    any            -- any of the following is also True
      (     )(words "  ...  ")
                   -- apply the function to each of the words "un", "nu" ... "qb"
           cycle   --  infinitely repeat the word
      take l       --  take the first l characters
     (==s)         --  and compare to s
nimi
fonte
4

Python 2 , 45 bytes

lambda s:s[2:]+s[1:3]==s>s[:2]in'bqbunuwmw'

Experimente online!

Os espaços na sequência são DELcaracteres.

xnor
fonte
|u|é interpretado como uma roda de carroça.
Harrichael
@Harrichael eu coloquei DELcaracteres para ficar claro.
Xnor
Os caracteres DEL ainda podem ser caracteres de entrada. Eu gosto da sua solução, mas você deve pegar emprestado um truque da minha resposta:s[:3]in'bqbqnunuwmwm'
Harrichael
4

Retina , 24 bytes

G`nu|mw|bq
^((.).)\1*\2$

Saídas 1 para verdade, 0 para falsidade.

Resposta do charlatão do Porto de Vacas.

Experimente online!

Okx
fonte
A versão mais recente gera verdade para nunwmwnun(quando deveria ser falso), e foi por isso que tive a \1*resposta na minha sed.
Kritixi Lithos
@ Cowsquack Ah, eu vejo.
Okx 02/08/19
A primeira linha pode ser G`nu|mw|bpuma vez que todos cordas truthy conter um desses pares de letras ea segunda linha irá assegurar que todo o resto da cadeia contém essas letras também ..
Neil
@Neil que falha o caso de testeununununu
Okx
A sugestão da @Okx Neil ainda parece funcionar para esse testcase Experimente online!
Kritixi Lithos
3

Grime , 28 bytes

e`..-#!"nu\|bq\|mw"oTv&..v+.

Experimente online! Imprime 1para entradas 0verdadeiras e falsas.

Explicação

A sintaxe do Grime se parece com expressões regulares e um programa Grime especifica um padrão que pode ou não corresponder a um retângulo de caracteres.

e`..-#!"nu\|bq\|mw"oTv&..v+.
e`                            Match input against pattern:
      !                       Does not
     #                        contain
  ..                          a 2-character substring
    -                         which is not
       "nu\|bq\|mw"           any of these strings
                   oT         potentially reversed,
                     v&       AND
                       ..     two characters
                         v+   one or more times
                           .  then one more character.

Alguns recursos do Grime que ajudaram a diminuir isso:

  • Normalmente, um literal de caractere deve ser escapado com uma barra invertida, mas ""altera isso: os elementos de sintaxe são escapados, mas os literais não. Sem as aspas, a parte que enumera os pares de caracteres seria (\n\u|\b\p|\m\w)oT.
  • Operadores unários que seguem um operador binário (aqui -) agem sobre seu resultado: ..-#!"…"oTé equivalente a (..-"…"oT)#!.
  • Eles vdiminuem a precedência dos elementos de sintaxe que os seguem. Um solitário &tem maior precedência do que -, mas v&menor. Da mesma forma, ..+é analisado como .(.+), mas ..v+é equivalente a (..)+.
Zgarb
fonte
2

Pitão , 27 bytes

&qeQhQ/"nu,mw,bq"S+{%2tQ{%2

Suíte de teste.

Saídas 1para verdade e / Falseou 0falsidade, conforme o OP permitido no bate-papo.

Mr. Xcoder
fonte
2

Gelatina , 27 bytes

Ḋm2Qµ³m2Q;Ṣe“nu“mw“bq”ȧ³⁼U¤

Experimente online!

Como funciona

Ḋm2Qµ³m2Q;µṢe“nu“mw“bq”ȧ³⁼U¤  Main link; z is the argument
Ḋ                             z[1:]
 m2                           z[1::2]
   Q                          deduplicate(z[1::2])
    µ                         New Chain
     ³                        z
      m2                      z[::2]
        Q                     deduplicate(z[::2])
         ;                    deduplicate(z[1::2]) + deduplicate(z[::2])
          Ṣ                  Sort the result
           e                 Is it an element of the following?
            “nu“mw“bq”       ["nu", "mw", "bq"]
                      ȧ      It has the correct characters and:
                       ³  ¤  Nilad followed by links as nilad
                       ³     z
                        ⁼      == 
                         U        z[::-1]
                          ¤  [End chain]
HyperNeutrino
fonte
Geléia ... mais que Pyth ?!
Mr. Xcoder
@ Mr.Xcoder shhhh Eu estou trabalhando nisso ... xD
HyperNeutrino
Hah bem, eu estou amarrado com você agora xD
HyperNeutrino
2

Python 2 , 103 bytes

lambda x:len(x)>1and{x[0],x[1]}in[{i,j}for i,j in zip('ubw','nqm')]and x==(-~len(x)/2*(x[0]+x[1]))[:-1]

Experimente online!

officialaimm
fonte
2

Japt , 47 bytes

g ¦U¬o ª`q¿nwm`ò má c aU¯2)<0?0:UÅë ä¥ ©Uë ä¥ e

Experimente online!

Oliver
fonte
Você pode compactar a string para salvar bytes?
Shaggy
nwnwn é verdade quando se ahould ser falsa
Harrichael
@Harrichael Obrigado, corrigido!
Oliver
1

Python 3 , 88 bytes

lambda x:[len(x)%2,x[:2]in'nu,un,bq,qb,mw,wm',len(set(x[::2])),len(set(x[1::2]))]==[1]*4

len(x)%2: uma sequência de comprimento par não pode terminar no primeiro caractere

x[:2] in: verifique se há um dos 6 pares iniciais válidos

len(set()): obtém o comprimento dos conjuntos de caracteres em 0,2,4 ... e 1,3,5 ...

Retorna Truese a lista de avaliações for igual a [1,1,1,1], caso contrário False.

Experimente online!

nocturama
fonte
1

Perl 5 , 55 + 1 (-p) = 56 bytes

$c={"nuunmwwmbppb"=~/./g}->{$l=chop};$_=/^($l$c)+$/&&$c

Experimente online!

Imprime a versão "invertida" do primeiro caractere para true, nada para false.

Xcali
fonte
Bata-me por sólidos 18 bytes. Boa resposta!
Silvio Mayolo
Agora não são tantos. O original estava retornando verdadeiro para qualquer sequência do mesmo caractere.
Xcali
1

PHP, 59 + 1 bytes

<?=preg_match('#^(nu|un|mw|wm|bq|qb)\1+$#',$argn.$argn[1]);

Corra como cano com -F.

solução parcialmente regex, 101 + 1 bytes:

for($s=$argn;$c=$s[$i++];$p=$c)$c!=$p||die;echo$i%2<1&&preg_match("#^(nu|mw|bq)#",count_chars($s,3));

Saída vazia por falsidade. Corra como cano com -nR.

Titus
fonte
1

Java 8, 57 bytes

s->s.matches("(nu)+n|(un)+u|(mw)+m|(wm)+w|(bq)+b|(qb)+q")

Experimente aqui.

Regex simples para combinar com todos os seis casos. Observe que o Java String#matchescorresponde automaticamente a toda a String, portanto, não há necessidade ^...$.

Kevin Cruijssen
fonte
1

MATL , 25 bytes

'nuwmbq'&mq2&\d~wdts~Gnqv

A saída é um vetor de coluna numérica não vazio, que é verdadeiro se todas as suas entradas são diferentes de zero e, caso contrário , falsas . Experimente online!

Para verificar todos os casos de teste , ifé adicionada uma ramificação no rodapé que substitui qualquer valor verdadeiro pela sequência 'truthy'ou qualquer valor falso pela sequência 'falsy'e, em seguida, exibe a sequência.

Explicação

'nuwmbq'  % Push this string
&m        % Implicit input. For each char, push index of membership in the above
          %  string, or 0 if not member
q         % Subtract 1
2         % Push 2
&\        % Divmod. Pushes remainders, then quotients
d~        % Consecutive differences negated. Gives an array of ones iff all
          % quotients were equal
w         % Swap. Moves remainders to top
d         % Consecutive differences. Gives nonzeros iff no consecutive
          % remainders were equal
ts~       % Duplicate, sum, negate. Gives true iff sum was 0. For unequal
          % consecutive differences of remainders, this corresponds to an odd
          % number of remainders
Gnq       % Push input, length, subtract 1. True iff input longer than 1
v         % Concatenate into column vector. Truthy iff all entries are nonzero
Luis Mendo
fonte
0

Python 2 , 74 bytes

import re
re.compile('(n(un)+|u(nu)+|m(wm)+|w(mw)+|b(pb)+|p(bp)+)$').match

Experimente online! Esta opinião sobre o problema é surpreendentemente competitiva.

Lynn
fonte
0

Clojure, 115 bytes

(apply some-fn(map(fn[r]#(re-matches r %))(map(fn[[x y]](re-pattern(str x"("y x")+")))["nu""un""mw""wm""bq""qb"])))

Crie uma regex com cada par de letras e veja se a entrada corresponde a um. Muitas maneiras mais elegantes de fazer todas essas partes, mas são todas mais detalhadas. Tal é a vida com o golfe Clojure.

MattPutnam
fonte
0

Perl 5, 68 + 1 = 69 bytes

if(/../&&$&=~/nu|un|bq|qb|mw|wm/){s/^($&)*//;$&=~/./;print if/^$&$/}

Corra com -n.

Explicação:

# Match the first two characters, and if they exist, then...
if (/../ &&
 # Make sure they are a pair of compatible cartwheel characters.
 $&=~/nu|un|bq|qb|mw|wm/) {
  # If that's true, then eliminate as many of that pair of characters
  # from the beginning of the string as possible.
  s/^($&)*//;
  # Then get the first character out of the match (the first character
  # of the original string).
  $&=~/./;
  # Print the text (which is truthy since it's nonempty) if the original
  # first character matches exactly the remaining string.
  print if/^$&$/
  # Otherwise, print nothing (the empty string in Perl is falsy).
}
Silvio Mayolo
fonte
0

TXR Lisp , 50 bytes

(f^$ #/n(un)+|u(nu)+|m(wm)+|w(mw+)|b(qb)+|q(bq)+/)

Corre:

1> (f^$ #/n(un)+|u(nu)+|m(wm)+|w(mw+)|b(qb)+|q(bq)+/)
#<intrinsic fun: 1 param>
2> [*1 "nun"]
"nun"
3> [*1 "nuns"]
nil
4> [*1 "mwm"]
"mwm"
5> [*1 "wmw"]
"wmw"
6> [*1 "abc"]
nil

f^$é um combinador que pega um objeto regex e retorna uma função que corresponde a esse regex de maneira ancorada. (Por si só, um objeto regex é um objeto que pode ser chamado de função que pega uma string e pesquisa por ela mesma.)

Kaz
fonte
0

TXR : 78 74 bytes

@{x 2}@(rep :gap 0)@x@(end)@y
@(bind(x y)(#"nu un mw wm bq qb"@[x 0..1]))

Execute, a partir do prompt do sistema. O número no prompt é o status de encerramento: 0 = êxito, 1 = falha:

0:$ ./txr cart.txr 
nun
0:$ ./txr cart.txr 
abc
1:$ ./txr cart.txr 
bab
1:$ ./txr cart.txr 
mwm
1:$ ./txr cart.txr 
nununununun
0:$

Explicação:

  • @{x 2}: corresponde a dois caracteres, vincula à xvariável.
  • @(rep :gap 0)@x@(end): correspondência repetida sem intervalos ignorados: zero ou mais ocorrências do xdígrafo correspondente anteriormente.
  • @y: restante da linha correspondente, capturado em y.
  • @(bind(x y)(foo bar)): vincular xa foo, y a bar. Como xe yjá estão vinculados, eles precisam corresponder fooe bar, caso contrário, há uma falha.
  • fooé #"nu un mw wm bq qb"uma lista literal de palavras, açúcar sintático para a lista Lisp ("nu" "un" ... "qb"). Uma bindcorrespondência entre uma variável e uma lista significa que a variável deve corresponder a um elemento.
  • baré @[x 0..1]: a substring de um caractere xdesde o início. A bindcorrespondência entre ye isso força a última letra da linha a corresponder à primeira.
Kaz
fonte
0

C ++, 268 bytes

#include<map>
#include<string>
std::map<char,char>c{{'n','u'},{'m','w'},{98,'q'},{'w','m'},{'u','n'},{'q',98}};
int w(std::string s){if(s[0]!=s[s.size()-1]||c.find(s[0])==c.end()||s.size()<3)return 0;for(int i=0;i<s.size()-1;i+=2)if(s[i+1]!=c[s[i]])return 0;return 1;}
HatsuPointerKun
fonte
Salve 10 bytes usando os valores ASCII para todos os caracteres em vez de apenas dois.
MD XF
@MDXF n= 110, u= 117, m= 109, w= 119, q= 113. Então, usando valores ASCII ou não, não importa para quaisquer caracteres superiores c(99)
HatsuPointerKun
0

JavaScript (ES6), 63 bytes

s=>/bq|wm|un/.test(s)&s.replace(RegExp(s[0]+s[1],'g'),'')==s[0]

Retorna 1ou 0.

Explicação

Todas as seqüências de roda dentada terão um ou mais de bq , wm ou un . Testamos isso com:

/bq|wm|un/.test(s)

Se você substituir todas as instâncias das duas primeiras letras de uma sequência de caracteres estrelada por nada, ficará com a primeira letra da sequência. Testamos isso com:

s.replace(RegExp(s[0]+s[1],'g'),'')==s[0]

Rick Hitchcock
fonte