(Note: this is an easier spin-off of my previous challenge Find the Infinity Words!, which is a spin-off of my other previous challenge Find the Swirling Words! :) )
Definition of a Wavy Word:
- If you connect with curves all the characters of a Wavy Word on the alphabet (A-Z) you obtain the path of a wave continuously going toward right or toward left and never changing direction, like in the diagrams below.
- A Wavy Word can be:
- Raising if each consecutive character is at the right (on the alphabet) of the previous one.
- Decreasing if each consecutive character is at the left (on the alphabet) of the previous one.
- All the even connection must be down, all the odd connections must be up.
- You can ignore upper/lowercase or consider/convert all to upper case or all to lower case.
- The input words are only characters in the alphabet range of A-Z, no spaces, no punctuation, or symbols.
- If a word has double characters, like "SPOON", you must collapse the doubles to one character: "SPOON"> "SPON" (because if you go from O to O is zero distance).
- The Wavy Words will contain at least 3 distinct characters (even after doubles collapsing).
Here there are some examples:
Task:
Write a full program or function that will take a word from standard input and will output if it is a Wavy Word or not, and in positive case, output if it is raising or decreasing. The output can be True/False/Null, 2/1/0, 1/Null/0, -1/0/1, NO/WR/WD, etc, you decide how to represent it.
Test cases:
WAVY WORDS:
ADEPT, BEGIN, BILL, BOSS, BOOST, CHIMP,
KNOW, SPONGE, SPOON, TROLL, WOLF
ADEPT > YES > RAISING
BEGIN > YES > RAISING
BILL > YES > RAISING
BOSS > YES > RAISING
BOOST > YES > RAISING
CHIMP > YES > RAISING
KNOW > YES > RAISING
SPONGE > YES > DECREASING
SPOON > YES > DECREASING
TROLL > YES > DECREASING
WOLF > YES > DECREASING
NOT WAVY WORDS:
WATCH, EARTH, NINON, FOO, BAR, WAVE, SELECTION,
YES, NO, DEFINITION, WATER, WINE, CODE, AAAHHHH, I, MM, ABCA
Rules:
- Shortest code wins.
Optional Task:
Find, as a list, as many Wavy Words as you can in an English dictionary, and the longest as well. You can take for example as reference the complete list of English words here.
19 Answers 19
05AB1E, (削除) 11 (削除ここまで) 9 bytes (Thanks to Adnan)
Dg2›iÇü‹Ù
Wavy Cases:
0 - Decreasing Wavy
1 - Increasing Wavy
Not Wavy Cases:
[0,1] - Not wavy, initially decreasing, but then has an increase/equality that broke the pattern.
[1,0] - Not wavy, initially increasing, but then has a decrease/equality that broke the pattern
Input String - Not possible to be wavy in the first place due to length.
Explanation:
Dg2›iÇü‹Ù # Full program
D # Push 2 copies of input.
g2›i # If length is greater than 2.
Ç # Push ASCII values for all characters in the string.
ü # Push pairwise array.
‹ # Vectorize 1 if negative difference, 0 if positive difference.
Ù # Uniquify using right most unique values first.
# Else just print the string back, letting them know it's not valid input.
-
1\$\begingroup\$ @JonathanAllan Dangit... I just saw the comments and changes... I took
The input words will contain at least 3 distinct charactersto mean that I didn't have to handle less than 3 char words. Working on changes, may take awhile; this is my first answer I was able to do in 05AB1E. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2016年10月28日 19:12:01 +00:00Commented Oct 28, 2016 at 19:12 -
1\$\begingroup\$ @JonathanAllan Fixed :)! But now you're beating me ;). \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2016年10月28日 19:30:49 +00:00Commented Oct 28, 2016 at 19:30
-
1\$\begingroup\$ Very nice! One tip,
ü‹is the same asü-0‹:) \$\endgroup\$Adnan– Adnan2016年10月29日 14:11:19 +00:00Commented Oct 29, 2016 at 14:11 -
\$\begingroup\$ Hehehe... Man, I may just have to learn python and start helping to expand 05AB1E. This language is impressive. Thanks for the tip! \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2016年10月30日 03:40:51 +00:00Commented Oct 30, 2016 at 3:40
Jelly, 10 bytes
OIṠḟ0μL’aQ
TryItOnline! or run all test cases
Returns:
[1] for wavy increasing
[-1] for wavy decreasing
something else otherwise ([], [0], [-1,1], or [1,-1])
(Declared as unnecessary: For a single value for each OIṠḟ0μL’aQS (11 bytes) will return 1, -1, and 0 respectively.)
How?
OIṠḟ0μL’aQ - Main link: s
O - cast to ordinals
I - incremental differences
Ṡ - sign (-1 for decreasing, 0 for no change, 1 for increasing)
ḟ0 - filter out zeros
μ - monadic chain separation
L - length
’ - decremented
a - and
Q - unique items
-
\$\begingroup\$ Are you allowed to have 3 different possible outputs for the neither case? \$\endgroup\$xnor– xnor2016年10月28日 19:36:38 +00:00Commented Oct 28, 2016 at 19:36
-
\$\begingroup\$ I took "you decide how to represent it" to mean yes, so long as they are different. However your question about rule #5 could invalidate this (and probably every other entry). \$\endgroup\$Jonathan Allan– Jonathan Allan2016年10月28日 19:55:55 +00:00Commented Oct 28, 2016 at 19:55
-
\$\begingroup\$ Added an solution to that if need be. \$\endgroup\$Jonathan Allan– Jonathan Allan2016年10月28日 20:08:00 +00:00Commented Oct 28, 2016 at 20:08
-
\$\begingroup\$ Can you not just sum the list? \$\endgroup\$xnor– xnor2016年10月28日 20:13:54 +00:00Commented Oct 28, 2016 at 20:13
JavaScript (ES6), (削除) 84 (削除ここまで) 81 bytes
s=>(new Set(t=[...s]).size>2)*(!t.some((c,i)=>c>s[i+1])-!t.some((c,i)=>c<s[i+1]))
Assumes the input is all in the same case. Returns 1 for raising wavy, -1 for decreasing wavy, 0 or -0 (both are falsy) for not wavy. Edit: Saved 3 bytes thanks to @RobertHickman.
-
\$\begingroup\$ I'm not an expert on the newer features, but can you remove
new? \$\endgroup\$Cyoce– Cyoce2016年10月29日 17:28:49 +00:00Commented Oct 29, 2016 at 17:28 -
\$\begingroup\$ @Cyoce Annoyingly the newer features require you to use
new. \$\endgroup\$Neil– Neil2016年10月29日 18:05:55 +00:00Commented Oct 29, 2016 at 18:05 -
\$\begingroup\$ @Neil, I believe, You can save a byte by initializing another variable inside of the Set() function
t=[...s]and using t instead of [...s] in those two spots you have it. \$\endgroup\$Robert Hickman– Robert Hickman2016年11月01日 19:36:37 +00:00Commented Nov 1, 2016 at 19:36
Python 2, 54 bytes
lambda s:[2<len(set(s))<s[::b]==sorted(s)for b in-1,1]
Takes input as a list of characters. Outputs:
[False, True] for ascending
[True, False] for descending
[False, False] for neither
Checks if the sorted input string equals its original or reverse. Does so by slicing with step sizes of 1 and -1. At the same time, we check whether the word has at least 2 distinct letters.
If "exit with error" can be used an output for the neither case, we can go down to 51 bytes:
lambda s:[s,s[::-(len(set(s))>2)]].index(sorted(s))
-
\$\begingroup\$ Pretty sure you can take a list of characters since it isn't specified as a string: meta.codegolf.stackexchange.com/a/2216/8478 \$\endgroup\$Jonathan Allan– Jonathan Allan2016年10月28日 20:51:58 +00:00Commented Oct 28, 2016 at 20:51
Python 3, (削除) 77 (削除ここまで) 75 bytes
lambda x:(len(set(x))>2)*(list(x)==sorted(x)or(list(x)==sorted(x)[::-1])*2)
Assumes all letters are of the same case.
Returns:
0if not wavy1if forwards wavy2if backwards wavy
Removed unnecessary spaces thanks @ETHproductions
-
2\$\begingroup\$ Welcome to PPCG, and nice first answer! However, you also need to make sure that there are at least three distinct chars in the string; if not, it's not a wavy word no matter what. \$\endgroup\$ETHproductions– ETHproductions2016年10月28日 19:22:14 +00:00Commented Oct 28, 2016 at 19:22
-
\$\begingroup\$ Ah, right. Should've looked closer at the definition of a wavy word. Fixed. \$\endgroup\$C. Smith– C. Smith2016年10月28日 20:16:57 +00:00Commented Oct 28, 2016 at 20:16
-
\$\begingroup\$ Nice! I'm not a Python expert, but I think you can remove the space on either side of the
or. \$\endgroup\$ETHproductions– ETHproductions2016年10月28日 20:36:40 +00:00Commented Oct 28, 2016 at 20:36 -
\$\begingroup\$ Yep, you're right. Forgot to remove them after surrounding the expressions with parentheses. Thanks for the catch! \$\endgroup\$C. Smith– C. Smith2016年10月28日 21:38:59 +00:00Commented Oct 28, 2016 at 21:38
R, (削除) 96 (削除ここまで) 95 bytes
function(x,d=diff(rle(utf8ToInt(x))$v))if(any(d>0)&any(d<0)|sum(1|d)<2)3 else`if`(all(d<1),2,1)
Returns:
1for wavy and raising2for wavy and decreasing3for non-wavy
Explained
d=diff(rle(utf8ToInt(x))$v): Generates a variabledby first converting the string into it'sASCIIvalues usingutf8ToIntwhich conveniently returns a vector. Subsequently perform run length encoding usingrle.rle(...)$vreturns the non-repeating values of the sequence (i.e. collapsing all runs). Finally take the difference.if(any(d>0)&any(d<0)|sum(1|d)<2)3: If at least one of the differences are positive and at least one negative, or if the difference sequence has less than2elements (equivalent to the original word having less than 3 characters), the word is non-wavy and return3else``if``(all(d<1),2,1): Else if all differences are negative, return2for wavy and decreasing, else return1for wavy and raising.
Try all the test cases at R-fiddle (note that it's named such that it can be vectorized for the test cases).
Javascript (ES6), (削除) 84 (削除ここまで) (削除) 80 (削除ここまで) 78 bytes
i=>new Set(s=[...i]).size>2?[i,s.reverse().join``].indexOf(s.sort().join``):-1
Where wavy increasing is 0, decreasing is 1, and -1 is not wavy.
Thanks to @Neil for helping me save 2 bytes.
-
1\$\begingroup\$
new Set(s=[...i])saves you 2 bytes. (It works by iteratingi, turning it into an array, iterating the array, and turning that into a set. Convoluted but you don't worry about that sort of thing when you're golfing.) \$\endgroup\$Neil– Neil2016年11月01日 22:05:37 +00:00Commented Nov 1, 2016 at 22:05
Python 2, (削除) 53 (削除ここまで) (削除) 52 (削除ここまで) 50 bytes
Expects input enclosed in quotes, e.g. "watch"
As unnamed lambda:
lambda s:(sum(map(cmp,s[1:],s))+1)/min(len(s)-1,3)
Sums the sign of difference between each letters and integer-divides by len-1. If all were 1 (increasing) the sum is len-1 it displays 1, similar for decreasing -1 and for mixed 1,-1 the sum is smaller than len-1 so it displays 0.
-1 byte for changing cmp,s[1:],s[:-1]) to cmp,s[1:],s)+1
-
\$\begingroup\$ Will return
1for"NO"\$\endgroup\$Jonathan Allan– Jonathan Allan2016年10月28日 20:57:00 +00:00Commented Oct 28, 2016 at 20:57 -
\$\begingroup\$ @JonathanAllan
LMNOPso O is after N which means increasing which means 1 \$\endgroup\$Karl Napf– Karl Napf2016年10月28日 21:05:03 +00:00Commented Oct 28, 2016 at 21:05 -
\$\begingroup\$ Yep, but any word of less than 3 characters (after removing any duplicate letters) was defined as not wavy ("NO" is in the not wavy test cases). \$\endgroup\$Jonathan Allan– Jonathan Allan2016年10月28日 21:06:30 +00:00Commented Oct 28, 2016 at 21:06
-
\$\begingroup\$ @JonathanAllan fixed the
lenissue, but i the repeating chars are still a problem \$\endgroup\$Karl Napf– Karl Napf2016年10月28日 22:10:59 +00:00Commented Oct 28, 2016 at 22:10
Ruby, 54 bytes
->w{c=w.chars.uniq;c==(s=c.sort)?2:(c==s.reverse)?1:0}
Returns 0 if the word is not wavy, 1 if backwards wavy, and 2 if forwards wavy.
Groovy - 56 bytes
{d=it[0];c=[0]*3;it.each{a->c[(a<=>d)]=1;d=a};c[1..-1]}
Outputs [1,0] for raising wavy, [0,1] for decreasing wavy, [0,0] for single character input or [1,1] for non-wavy.
NOTE: Assumes input is either a String or a char[] and all letters are of the same case.
PHP, 96 Bytes
for(;($t=$argv[1])[++$i];)$s+=$r[]=$t[$i-1]<=>$t[$i];echo(max($r)-min($r)<2)*(0<=>$s)*(1<$s*$s);
or 98 Bytes
$s=str_split($t=$argv[1]);sort($s);echo(-($t==strrev($j=join($s)))|$t==$j)*!!count_chars($t,3)[2];
0 not wavy 1 raising -1 decreasing
-
\$\begingroup\$
-instead of2*(-1 for decreasing: -1 byte).*(!!...)needs no parentheses. (-2) \$\endgroup\$Titus– Titus2016年10月29日 14:37:16 +00:00Commented Oct 29, 2016 at 14:37 -
\$\begingroup\$
$s*$s>1instead ofabs($s)>1(-2) \$\endgroup\$Titus– Titus2016年10月30日 08:34:27 +00:00Commented Oct 30, 2016 at 8:34 -
\$\begingroup\$ @Titus Done Thank You \$\endgroup\$Jörg Hülsermann– Jörg Hülsermann2016年10月30日 09:27:37 +00:00Commented Oct 30, 2016 at 9:27
PHP, 100 bytes
$n=$m=$l=str_split($argv[1]);sort($n);rsort($m);echo(($n==$l)-($m==$l))*(count(array_unique($l))>2);
Returns:
-1for wavy, decreasing.0for not wavy.1for wavy, raising.
-
\$\begingroup\$
!!array_unique($s)[2]instead ofcount(array_unique($l))>2\$\endgroup\$Jörg Hülsermann– Jörg Hülsermann2016年10月29日 13:14:44 +00:00Commented Oct 29, 2016 at 13:14 -
\$\begingroup\$ Actually, the problem with that is that array_unique will preverse keys. Thus an input like aaabc will falsely output 0 when using array_unique. \$\endgroup\$chocochaos– chocochaos2016年10月30日 11:36:45 +00:00Commented Oct 30, 2016 at 11:36
Java 7, (削除) 254 (削除ここまで) 240 bytes
import java.util.*;int c(String s){char[]a=s.toCharArray(),x=a.clone();Arrays.sort(x);return s.replaceAll("(.)\1円{1,}","1ドル").length()<3?0:Arrays.equals(a,x)|Arrays.equals(x,(new StringBuffer(s).reverse()+"").toCharArray())?a[0]>a[1]?1:2:0;}
Outputs 0 if the input string isn't wavy, 1 if it's a raising wave, and 2 if it's a decreasing wave.
Ungolfed & test code:
import java.util.*;
class M{
static int c(String s){
char[] a = s.toCharArray(),
x = a.clone();
Arrays.sort(x);
return s.replaceAll("(.)\1円{1,}", "1ドル").length() < 3
? 0
: Arrays.equals(a, x) | Arrays.equals(x, (new StringBuffer(s).reverse()+"").toCharArray())
? a[0] > a[1]
? 1
: 2
: 0;
}
public static void main(String[] a){
System.out.print(c("ADEPT") + ", ");
System.out.print(c("BEGIN") + ", ");
System.out.print(c("BILL") + ", ");
System.out.print(c("BOSS") + ", ");
System.out.print(c("BOOST") + ", ");
System.out.print(c("CHIMP") + ", ");
System.out.println(c("KNOW"));
System.out.print(c("SPONGE") + ", ");
System.out.print(c("SPOON") + ", ");
System.out.print(c("TROLL") + ", ");
System.out.println(c("WOLF"));
System.out.print(c("WATCH") + ", ");
System.out.print(c("EARTH") + ", ");
System.out.print(c("NINON") + ", ");
System.out.print(c("FOO") + ", ");
System.out.print(c("BAR") + ", ");
System.out.print(c("WAVE") + ", ");
System.out.print(c("SELECTION") + ", ");
System.out.print(c("YES") + ", ");
System.out.print(c("NO") + ", ");
System.out.print(c("DEFINITION") + ", ");
System.out.print(c("WATER") + ", ");
System.out.print(c("WINE") + ", ");
System.out.print(c("CODE") + ", ");
System.out.print(c("AAAHHHH") + ", ");
System.out.print(c("I") + ", ");
System.out.print(c("MM") + ", ");
System.out.println(c("ABCA"));
}
}
Output:
2, 2, 2, 2, 2, 2, 2
1, 1, 1, 1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-
\$\begingroup\$
int c(char[]s){int t=s[0],f=s.length,a=1,b=1,i;for(i=1;i<f;){if(s[i]-s[i-1]>=0)++a;if(s[i]-s[i++-1]<1)++b;}return a==f?1:b==f?-1:0;}(132 bytes) \$\endgroup\$Numberknot– Numberknot2016年10月31日 12:55:13 +00:00Commented Oct 31, 2016 at 12:55 -
\$\begingroup\$ Output 1 if wavy raising,output -1 if wavy decreasing,0 if not wavy \$\endgroup\$Numberknot– Numberknot2016年10月31日 12:56:32 +00:00Commented Oct 31, 2016 at 12:56
C, 164 bytes
main(){char s[99];scanf("%s",s);char *c=&s;int p=*c;while(*c^0){if(p>*c){if(c-&s[0]>1)return 0;while(*c^0){if(p<*c)return 0;p=*c;c++;}return 2;}p=*c;c++;}return 1;}
Returns 0 if not wawy, 1 if wawy and raising, 2 if decreasing.
Racket 321 bytes
(let*((ld(λ(sl)(for/list((i(sub1(length sl))))(-(list-ref sl(add1 i))(list-ref sl i)))))(l(ld(remove-duplicates(map
(λ(x)(char->integer x))(string->list s)))))(am andmap)(N"Not WAVY")(d displayln))(cond[(<(length l)2)(d N)][(am(λ(x)(>= x 0))l)
(d"YES; RAISING")][(am(λ(x)(<= x 0))l)(d"YES; DECREASING")][else(d N)])))
Ungolfed:
(define (f s)
(let* ((ld (lambda(sl) ; sub-fn to get differences in list elements
(for/list ((i (sub1(length sl))))
(- (list-ref sl (add1 i))
(list-ref sl i) ) )))
(l (ld
(remove-duplicates
(map
(lambda(x)
(char->integer x))
(string->list s)))))
(am andmap)
(N "Not WAVY")
(d displayln))
(cond
[(< (length l) 2)(d N)]
[(am (lambda(x) (>= x 0)) l) (d "YES; RAISING")]
[(am (lambda(x) (<= x 0)) l) (d "YES; DECREASING")]
[else (d N)]
)))
Testing:
(f "ADEPT"); > YES > RAISING
(f "BEGIN"); > YES > RAISING
(f "BILL"); > YES > RAISING
(f "BOSS"); > YES > RAISING
(f "BOOST"); > YES > RAISING
(f "CHIMP"); > YES > RAISING
(f "KNOW"); > YES > RAISING
(f "SPONGE"); > YES > DECREASING
(f "SPOON"); > YES > DECREASING
(f "TROLL"); > YES > DECREASING
(f "WOLF"); > YES > DECREASING
(f "WATCH")
(f "EARTH")
(f "NINON")
(f "FOO")
(f "BAR")
(f "WAVE")
(f "SELECTION")
Output:
YES; RAISING
YES; RAISING
YES; RAISING
YES; RAISING
YES; RAISING
YES; RAISING
YES; RAISING
YES; DECREASING
YES; DECREASING
YES; DECREASING
YES; DECREASING
Not WAVY
Not WAVY
Not WAVY
Not WAVY
Not WAVY
Not WAVY
Not WAVY
C (clang), (削除) 82 (削除ここまで) 78 bytes
d;f(*s,*r,n){for(*r=n>3?strcmp(s,++s):0;*s;*r*=!d|d<1^*r>0)d=strcmp(s-1,s++);}
-4 bytes thanks to @ceilingcat!
Returns:
- < 0 for Increasing Wavy
- > 0 for Decreasing Wavy
- 0 for not Wavy
Perl 5 -p, 68 bytes
$_=(s/(.)1円*/1ドル.*?/g>2)*(($a=join'',A..Z)=~/$_/<=>(reverse$a)=~/$_/)
Outputs -1/0/1 for decreasing wavy/not wavy/increasing wavy.
Haskell, 81 bytes
import Data.List
f s=[b&&t==s,b&&(reverse t)==s]where t=sort s;b=(length$nub t)>2
NOT WAVY WORDSsection though, which is correct.. \$\endgroup\$