| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Nibbles | 240716T140628Z | Dominic |
| 066 | Haskell | 240710T211107Z | DPD- |
| 054 | Python | 240708T170630Z | Mukundan |
| 013 | Jelly | 240710T020442Z | Jonathan |
| 019 | 05AB1E | 240709T080208Z | Kevin Cr |
| nan | Vyxal | 240709T051457Z | lyxal |
| 051 | JavaScript ES6 | 240708T161437Z | Arnauld |
| 023 | Charcoal | 240708T225518Z | Neil |
| 076 | Google Sheets | 240708T184726Z | z.. |
| 076 | Python 3.8 prerelease | 240708T160948Z | squarero |
| 030 | sed r | 240708T164928Z | guest430 |
| 031 | Perl 5 p | 240708T162921Z | Xcali |
Nibbles, 23 nibbles (11.5 bytes)
`^,`'`=@=$`D2~ fe00f740
Outputs 0 (falsy) if the input is a ping-pong string, or a nonzero value (truthy) if it isn't.
Can be adapted for various keyboard layouts by adjusting the 32-bit mask (here fe00f740 for left-hand keys on a QWERTY layout). This can't be shortened, even if all the left-hand keys are bunched together, as it needs to be 32 bits long to achieve case-insensitivity by modular indexing.
`^,`'`=@=$`D2~ fe00f740
`=@ # split input into chunks of same
= # modular index of
$ # codepoint of each character
# in
`D2 fe00f740 # binary digits of fe00f740
# (1 for left-hand letters, 0 otherwise);
`' # now transpose this
, # and get the length
# (0 if input was empty,
# 1 if input was ping-pong string,
# >1 if any adjacent input characters were typed with the same hand)
`^ ~ # and bitwise-xor it with 1
Haskell, 70 66 bytes
- -4 bytes thanks to xnor
h=(`elem`"yuiophjklnm").toLower
f(x:y:z)=h x/=h y&&f(y:z)
f x=x>[]
- First we map each letter to a boolean based on the hand (the helper function)
- Then we assert the sequence is alternate
- The base cases of 0 and 1 elements are handled by the last line
Python, 69 62 60 58 55 54 bytes
-7 bytes thanks to @xnor. I independently arrived at a similar solution (only the first -4 though) since I didn't notice their comment for a while.
-1 byte thanks to @Albert.Lang
Takes input as a bytestring
lambda x,n=35782400:len({(n:=~n)>>j%32&1for j in x})%2
Jelly, 13 bytes
ŒlØqiþ§>5IẠ«L
A monadic Link that accepts a list of characters from A-Za-z and yields 1 if ping-pong or 0 otherwise.
Try it online! Or see the test-suite.
05AB1E, 20 19 bytes
žV5δôøJIlδå€üαßIgΘM
Input as a list of characters.
Uses the QWERTY keyboard.
Try it online or verify all test cases.
Explanation:
žV # Push ["qwertyuiop","asdfghjkl","zxcvbnm"]
δ # Map over each string:
5 ô # Split it into parts of size 5
ø # Zip/transpose; swapping rows/columns
J # Join the inner lists together:
# ["qwertasdfgzxcvb","yuiophjklnm"]
I # Push the input-list
l # Lowercase each inner character
δ # Double-vectorized over the two lists:
å # Contains-check
€ # Map over each inner list:
ü # For each overlapping pair in this list:
α # Take the absolute difference of the pair
ß # Pop and push the flattened minimum
# (1 if all are truthy; 0 if any are falsey; "" if empty)
Ig # Push the length of the input-list
Θ # Check whether this length is exactly 1
M # Push a copy of the largest value of the stack
# (which is output implicitly as result)
Vyxal, 121 bitsv2, 15.125 bytes
[⇩ƛk•5vẇ∑vFT;f¯AI
Bitstring:
0110100000110010000101110000101100010110000010110110100110101011010101011111000101101010010111000001110111100000010110110
Outputs a space for true, an empty string for false. The footer in the link converts the result to 0 or 1 for convenience. Uses the qwerty layout.
Explained
[⇩ƛk•5vẇ∑vFT;f¯AI
[ # Only execute the following if the input isn't the empty string.
# Why else do you think false is represented as the empty string? :p
# It was easier to special case it
⇩ƛ # To each character in the lowercased input:
k• # Push a list of each row of qwerty
5vẇ # Split each into [first 5 characters, rest]
∑ # And fold the list by addition. This gives a list of [left keys, right keys]
vFT # Determine whether the character is a left or right key.
vF # Filter out the key from each side
f¯ # Flatten that and get the forward differences
# This will be used to determine whether there's a pattern of left/right or right/left.
# A 0 in this list means that two characters in a row are from the same side.
A # Check whether all numbers are non-0, as per the above explanation of why. This will return either 0 or 1
I # Push that many spaces. This is to be consistent with the empty string output.
💎
Created with the help of Luminespire.
JavaScript (ES6), 51 bytes
Expects an array of characters. Returns 0 for "ping-pong" or 1 for "empty or not ping-pong".
a=>a<1|a.some(q=c=>q-(q=/[h-puy]/i.test(c)^(a^=1)))
JavaScript (ES6), 39 bytes
@Xcali used a much more straightforward solution which can be ported as follows. Expects a string and returns a Boolean value (false for "ping-pong").
s=>/^$|[h-puy]{2}|[^h-puy]{2}/i.test(s)
Charcoal, 23 bytes
∧θ№…01⊕Lθ⭆θ№⁺⪫…h¦qωuy↧ι
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - if the word is ping-pong, nothing if not. Explanation:
θ Input word
∧ Logical And
№ Count of
θ Input word
⭆ Map over characters and join
№ Count of
ι Current letter
↧ Lowercased
…h q In range `h`...`q` (exclusive)
⪫ ω Joined
⁺ Concatenated with
uy Literal string `uy`
01 In literal string `01`
… Cyclically extended to length
θ Input word
L Length
⊕ Incremented
Implicitly print
Google Sheets, 76 bytes
=SORT(AND(1=LEN(IFERROR(SPLIT(REGEXREPLACE(A2,"(?i)[h-puy]"," $0 ")," ")))))
Google Sheets, 47 bytes
Using @Xcali's idea
=REGEXMATCH(A2,"(?i)[h-puy]{2}|[^h-puy]{2}|^$")
Python 3.8 (pre-release), 89 83 76 bytes
-6 bytes by walrusing 'yuiophjklnm'.
-7 bytes by Mukundan314.
lambda x:x and all((i in(r:='yuiophjklnm'))^(j in r)for i,j in zip(x,x[1:]))
sed -r, 30 bytes
/[^h-puy]{2}|[h-puy]{2}|^$/IQ1
nearly a port of @Xcali's answer. I originally had my own but my regex was worse. errors with exit code of 1 if it's invalid, exits normally if it's ping pong
I just saw that we can use any keyboard we want, so here's my keyboard, colemak:
sed, 30 bytes
/[^eh-uy]{2}|[eh-uy]{2}|^$/IQ1
here's dvorak, the most popular alternate layout:
sed, 42 bytes
/[aeijkopquxy]{2}|[^aeijkopquxy]{2}|^$/IQ1
and here's workman, the third choice for weird people:
sed, 40 bytes
/[^efi-lnopuy]{2}|[efi-lnopuy]{2}|^$/IQ1

