Czy ten ciąg jest literą robiącą koło zamachowe?

35

Inspiracją do wyzwania było to, co gdzieś widziałem:

Słowo „zakonnica” to tylko litera n robiąca koło zamachowe

Twoim zadaniem jest wziąć ciąg i ustalić, czy jest to pierwsza litera robiąca koło zamachowe.

Zasady

Łańcuch to litera wykonująca koło zamachowe, jeżeli:

  • Pierwsza litera jest taka sama jak ostatnia litera. (List nie może wylądować na głowie.)
  • Łańcuch naprzemiennie zmienia litery każdego koła.

Koła w kartach są ni u, moraz w, bi q. Należy pamiętać, że ni wrazem są nie cartwheeling litery, a nie są wi b.

  • Weźmiesz ciąg znaków przy użyciu dowolnej z naszych standardowych metod wprowadzania.
  • Wypisujesz wartość prawdy, jeśli ciąg znaków jest literą koła, a fałszem, jeśli nie jest. Dane wyjściowe można wykonać przy użyciu standardowych metod wyjściowych.

Dodatkowe zasady:

  • Należy obchodzić się tylko z małymi literami n/ u/ m/ w/ b/ q.
  • Możesz założyć, że dane wejściowe nigdy nie są puste.
  • Ciąg jednoznakowy nie jest prawidłowym kołem zamachowym.

Przypadki testowe

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

Zwycięzca

Podobnie jak w przypadku kodowego, wygrywa najkrótszy kod (w każdym języku)!

MD XF
źródło
29
Myślę, że bcartwheels w q, prawda? di psą także kumplami z koła. Kluczem jest to, że obracają się, a nie odwracają.
Engineer Toast
Kolejna sugestia dotycząca przykładu:uwuwuwuwuwu
Kritixi Lithos
19
Dlaczego bqbjednak nie pdp?
aschepler
@aschepler Pomieszałem.
MD XF
2
Ponieważ dpd, pdp i tak nie działa, myślę, że trzeba mieć je w przypadkach test z falsy odpowiedzi.
trlkly

Odpowiedzi:

2

Galaretka , 23 bajty

Zajęło to więcej pracy, niż mogłoby się wydawać!

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

Monadyczny link zawierający listę znaków i powracający 1(prawda) lub 0(falsey).

Wypróbuj online! lub zobacz zestaw testowy .

W jaki sposób?

Znajduje indeks każdego znaku wejścia na 1-indeksowej liście znaków nmbuwq. Ciąg ten jest ułożony w taki sposób, że indeksy par są oddalone od siebie o trzy, jako że przyrostowa różnica indeksów dla prawidłowych kartwheli będzie powtórzeniami jednego z [-3,3]lub [3,-3].

Gdy element nie znajduje się na liście według „indeksu” atomu, izwraca 0, co sparowałoby nieuzasadnione znaki b, wprowadzając dane jak bxbxbprawdziwe. Tak więc 0s są zastępowane 10wartością większą niż trzy od jakiejkolwiek innej wartości przed sprawdzeniem ważności.

“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
źródło
13

sed 4.2.2 , 30 + 1 -r= 43 31 bajtów

Zaoszczędź 12 bajtów dzięki @Neil, skracając pierwszą linię

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

Wypróbuj online!

Usuwa dane wejściowe, jeśli falsey, w przeciwnym razie nic nie robi na danych wejściowych.

Wyjaśnienie

Z -rflagą nie musimy używać \(i \)do przechwytywania grup, a to oszczędza bajty.

/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
źródło
Nadchodzi sedkreator ...
MD XF
@MDXF Jestem daleki od bycia czarodziejem, wciąż początkującym :)
Kritixi Lithos
Wszystko w mnie sedwygląda na magię. : P
MD XF
1
Musisz tylko sprawdzić, czy zawiera połowę par liter, np. Oba unui nunzawierają, nua drugi wiersz zapewnia, że ​​reszta liter pasuje do tych dwóch.
Neil
8

JavaScript (ES6), 82 78 77 bajtów

Zapisano 1 bajt przy użyciu dwóch wartości fałszowania, jak sugerują ThePirateBay i MD XF.

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

Przypadki testowe

Arnauld
źródło
Jakikolwiek powód porzucenia &&zamiast &?
@ThePirateBay Cóż, jedynym powodem jest spójność zwróconej wartości falsy, chociaż tak naprawdę nie wydaje się, aby była wymagana do tego wyzwania. (Używanie &spowoduje albo falsealbo 0.)
Arnauld
@Arnauld Możesz usunąć drugi &; Podałem (na czacie), że dozwolone są niespójne wartości fałszowania.
MD XF
5

Python 3 , 111 bajtów

-2 bajty dzięki Mr. 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'])

Wypróbuj online!

całkowicie ludzki
źródło
2
wzdycha, gdy znów mi podajesz w rep
MD XF
Nie czuję się z tym dobrze, ponieważ wkrótce osiągniesz liczbę moich bajtów, ale -2 bajty .
Pan Xcoder,
BTW, twoje rozwiązanie jest nieprawidłowe, tak jak moje na początku. Nie działa na nunununu.
Pan Xcoder,
Naprawiono kosztem wielu bajtów. ; -;
całkowicie ludzki,
5

Python 2 , 63 bajty

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

Wypróbuj online!

Harrichael
źródło
Ładna odpowiedź, witamy na stronie! Kilka wskazówek: Możesz zrobić, "nu un nm mn bp pb".split()aby zaoszczędzić 4 bajty i usunąć trochę białych znaków. 75 bajtów:lambda s:any(s==c[-1]+c*max(len(s)/2,1)for c in"nu un nm mn bp pb".split())
DJMcMayhem
Możesz zapisać 1 bajt, wykonując s[0]zamiast c[-1].
DJMcMayhem
61-bajtowa odpowiedź zwraca wartość True dla unmnui unmwnu. Naprawdę zwraca fałszywe alarmy, gdy (s==s[::-1])+len(set(s))ma 4, co jest łatwe do wymuszenia. Nawet tylko 4 różne postacie sprawiają, że zwraca True.
Arnold Palmer
59 bajtów dzieli się na pojedyncze znaki. Przepraszam za wybranie tego, lubię Python :)
Arnold Palmer
Czy wyjątki nie są falsey? Ta przerwa jest zamierzona
Harrichael
5

Python 3 , 71 bajtów

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

Wypróbuj online!

-1 dzięki @HyperNeutrino i -13 dzięki @ovs

Jeśli powyższe badanie zakończy się niepowodzeniem dla dowolnego przypadku testowego, istnieje alternatywa:

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

Wypróbuj online!


Wyjaśnienie

  • ''.join(sorted(list({*n[1::2]}).union({*n[::2]})))) - Pobiera znaki o indeksach nieparzystych i znaki o indeksach parzystych, usuwa duplikaty i sortuje listę utworzoną przez ich związek.

  • in'nu,mw,bq' - Sprawdza, czy są to prawidłowe kombinacje kart-list.

  • n[0]==n[-1] - Sprawdza, czy pierwszy znak jest taki sam jak ostatni.

Pan Xcoder
źródło
Nie kończy się testem, dobra robota +1
MD XF
@MDXF O dzięki!
Ulżyło
1
uwuwuwuwuwuwyniki są prawdziwe
Kritixi Lithos
1
Nieprawidłowy: nunuuunun
Harrichael
1
nuuun -> True. To nie jest w porządku.
rekurencyjny
5

JavaScript (ES6), 40 bajtów

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

Sprawdza, czy łańcuch wejściowy połączony z drugim znakiem łańcucha wejściowego jest łańcuchem powtarzającym się z tej samej pary znaków koła zamachowego.

Testy:

[
  "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
źródło
Naprawdę kocham logikę tutaj! Nigdy bym nie pomyślał o dodaniu postaci na końcu i testowaniu. Przyjemny, czysty kod, nawet podczas gry w golfa.
trlkly
4

Clojure, 156 bajtów

(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))))

To było zwodniczo trudne! Skończyło się na podzieleniu go na 3 problemy podrzędne:

  • Czy pierwsza litera jest taka sama jak ostatnia?
  • Czy litery się powtarzają?
  • Czy wszystkie litery są częścią jednego z prawidłowych zestawów?

Z pewnością nie wygrałem, ale było to ćwiczenie na poranek! Pełne wyjaśnienie poniżej:

(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))))
Carcigenicate
źródło
4

Haskell, 80 78 bajtów

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

Wypróbuj online!

Jak to działa:

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
źródło
4

Python 2, 45 bytes

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

Try it online!

The spaces in the string are DEL characters.

xnor
źródło
|u| is interpreted as a cartwheel.
Harrichael
@Harrichael I put in DEL characters to be clear.
xnor
DEL characters can still be input characters though. I like your solution but you should borrow a trick from my answer: s[:3]in'bqbqnunuwmwm'
Harrichael
4

Retina, 24 bytes

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

Outputs 1 for truthy, 0 for falsy.

Port of Cows quack's answer.

Try it online!

Okx
źródło
The newer version outputs truthy for nunwmwnun (when it should be false), which was why I had the \1* in my sed answer.
Kritixi Lithos
@Cowsquack Ah I see.
Okx
The first line can be G`nu|mw|bp since all truthy strings contain one of those letter pairs and the second line will ensure that all of the rest of the string contains those letters too..
Neil
@Neil That fails the test case ununununu
Okx
@Okx Neil's suggestion still seems to work for that testcase Try it online!
Kritixi Lithos
3

Grime, 28 bytes

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

Try it online! Prints 1 for truthy inputs and 0 for falsy ones.

Explanation

Grime syntax resembles regular expressions, and a Grime program specifies a pattern that may or may not match a rectangle of characters.

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.

Some features of Grime that helped shorten this:

  • Normally a character literal must be escaped with a backslash, but "" changes this: syntax elements are escaped but literals are not. Without the quotes, the part that enumerates the character pairs would be (\n\u|\b\p|\m\w)oT.
  • Unary operators that follow a binary operator (here -) act on its result: ..-#!"…"oT is equivalent to (..-"…"oT)#!.
  • The vs lower the precedence of the syntax elements that follow them. A lone & has higher precedence than -, but v& has lower. Similarly, ..+ is parsed as .(.+), but ..v+ is equivalent to (..)+.
Zgarb
źródło
2

Pyth, 27 bytes

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

Test Suite.

Outputs 1 for truthy and False or 0 for falsy, as the OP allowed in chat.

Mr. Xcoder
źródło
2

Jelly, 27 bytes

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

Try it online!

How it works

Ḋ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
źródło
Jelly... longer than Pyth?!
Mr. Xcoder
@Mr.Xcoder shhhh I'm working on it... xD
HyperNeutrino
Hah well I'm tied with you now 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]

Try it online!

officialaimm
źródło
2

Japt, 47 bytes

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

Try it online!

Oliver
źródło
Can you compress the string to save any bytes?
Shaggy
nwnwn is true when it ahould be false
Harrichael
@Harrichael Thanks, fixed!
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: an even-length string can't end on the first character

x[:2] in: check for any of the 6 valid beginning pairs

len(set()): get the length of the sets of characters at 0,2,4... and 1,3,5...

Returns True if the list of evaluations is equal to [1,1,1,1], else False.

Try it online!

nocturama
źródło
1

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

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

Try it online!

Prints the "upside down" version of the first character for true, nothing for false.

Xcali
źródło
Beat me by a solid 18 bytes. Nice answer!
Silvio Mayolo
Not quite so many now. The original was returning true for any string of all the same character.
Xcali
1

PHP, 59+1 bytes

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

Run as pipe with -F.

partly regex solution, 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));

Empty output for falsy. Run as pipe with -nR.

Titus
źródło
1

Java 8, 57 bytes

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

Try it here.

Simple regex to match all six cases. Note that Java's String#matches automatically matches the entire String, so there is no need for ^...$.

Kevin Cruijssen
źródło
1

MATL, 25 bytes

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

The ouput is a non-empty numeric column vector, which is truthy if all its entries are nonzero, and falsy otherwise. Try it online!

To verify all test cases, an if branch is added in the footer that replaces any truthy value by the string 'truthy', or any falsy value by the string 'falsy', and then displays the string.

Explanation

'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
źródło
0

Python 2, 74 bytes

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

Try it online! This take on the problem is surprisingly competitive.

Lynn
źródło
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"])))

Build a regex out of each letter pair and see if the input matches one. Lots of more elegant ways to do all of these parts, but they're all more verbose. Such is life with Clojure golfing.

MattPutnam
źródło
0

Perl 5, 68 + 1 = 69 bytes

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

Run with -n.

Explanation:

# 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
źródło
0

TXR Lisp, 50 bytes

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

Run:

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^$ is a combinator which takes a regex object and returns a function which matches that regex in an anchored way. (By itself, a regex object is function-callable object which takes a string and searches for itself through it.)

Kaz
źródło
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]))

Run, from system prompt. Number in prompt is termination status: 0 = success, 1 = failure:

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:$

Explanation:

  • @{x 2}: match two characters, bind to x variable.
  • @(rep :gap 0)@x@(end): repeated match with no skipped gaps: zero or more occurrences of x, the previously matched digraph.
  • @y: remainder of line matched, captured into y.
  • @(bind(x y)(foo bar)): bind x to foo, y to bar. Since x and y are already bound, they have to match foo and bar, or else there is a failure.
  • foo is #"nu un mw wm bq qb", a word list literal, syntactic sugar for the Lisp list ("nu" "un" ... "qb"). A bind match between a variable and a list means that the variable must match an element.
  • bar is @[x 0..1]: the one-character substring of x from its beginning. The bind match between y and this forces the last letter of the line to match the first.
Kaz
źródło
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
źródło
Save 10 bytes by using the ASCII values for all the characters instead of just two.
MD XF
@MDXF n = 110, u = 117, m = 109, w = 119, q = 113. So using ASCII values or not does not matter for any chars higher than c ( 99 )
HatsuPointerKun
0

JavaScript (ES6), 63 bytes

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

Returns 1 or 0.

Explanation

All cartwheel strings will have one or more of bq, wm, or un. We test for that with:

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

If you replace all instances of the first two letters of a cartwheel string with nothing, you're left with the first letter of the string. We test for that with:

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

Rick Hitchcock
źródło