| Bytes | Lang | Time | Link |
|---|---|---|---|
| 108 | AWK | 250820T140819Z | xrs |
| 084 | Retina | 240627T210102Z | mbomb007 |
| 074 | Perl 5 + pl060F | 240627T123532Z | Dom Hast |
| 040 | Japt | 240626T195155Z | Shaggy |
| 085 | Zsh | 240626T214608Z | GammaFun |
| 099 | R | 240626T162046Z | Glory2Uk |
| 123 | Python | 220909T225423Z | 97.100.9 |
| 057 | Brachylog | 220909T213551Z | DLosc |
| 150 | Java JDK | 170519T090203Z | Olivier |
| 008 | Vyxal | 220909T012121Z | lyxal |
| 120 | Retina | 170518T222030Z | eush77 |
| 155 | Python 2 | 170523T080941Z | Gáb |
| 198 | C | 170521T083250Z | Khaled.K |
| 254 | Java | 170521T071832Z | Khaled.K |
| 099 | Javascript ES6 | 170519T010312Z | nderscor |
| 060 | Ruby + to_words | 170518T231106Z | Value In |
| 028 | Jelly | 170518T220705Z | Jonathan |
| 163 | Bash | 170519T130143Z | marcosm |
| 087 | PHP>=7.0 | 170518T224838Z | Jör |
| 041 | Pyth | 170519T095604Z | KarlKast |
| 052 | Japt | 170519T093609Z | Luke |
| 148 | Python | 170518T230646Z | Jonathan |
| 083 | Mathematica | 170518T220651Z | Greg Mar |
| 121 | Javascript | 170519T041136Z | Steve Be |
| 128 | PHP | 170518T232348Z | Titus |
| 121 | JavaScript ES6 | 170519T000738Z | Neil |
| 111 | Haskell | 170518T230916Z | nimi |
| 026 | 05AB1E | 170518T220749Z | Adnan |
| 150 | Python 3 | 170518T213824Z | 0WJYxW9F |
AWK, 108 bytes
{a="ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE"
gsub(/[A-Z]/,"&.*",a)
for(;i++<split(a,b);)$1~b[i]&&$0=i}1
Prints your digit, or it prints the word back to you for falsey. You could add a ,$0+=0 to the end to get a zero instead.
Retina, 84 bytes
K`ONE1TWO2THREE3FOUR4FIVE5SIX6SEVEN7EIGHT8NINE9
[A-Z]
.$*$0.$*
\d
¶$0¶
"$+"~`¶$
¶\D¶
Explanation
This discards the input and generates the program to use
K`ONE1TWO2THREE3FOUR4FIVE5SIX6SEVEN7EIGHT8NINE9 # K (constant): discard input, use the string
[A-Z] # Replace each letter
.$*$0.$* # With ".*" before and after the match
\d # Replace each digit
¶$0¶ # With a newline before and after the match
¶$ # Replace the final newline/end
¶\D¶ # With "¶\D¶"
Generates this:
.*O.*.*N.*.*E.*
1
.*T.*.*W.*.*O.*
2
.*T.*.*H.*.*R.*.*E.*.*E.*
3
.*F.*.*O.*.*U.*.*R.*
4
.*F.*.*I.*.*V.*.*E.*
5
.*S.*.*I.*.*X.*
6
.*S.*.*E.*.*V.*.*E.*.*N.*
7
.*E.*.*I.*.*G.*.*H.*.*T.*
8
.*N.*.*I.*.*N.*.*E.*
9
\D
Then this configuration on the last Eval ~ stage evaluates that program using the initial input, gotten with "$+".
"$+"~`
Perl 5 + -pl060F, 74 bytes
$"="*";$\||=/^@F*$/*++$-for ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE}{
Japt, 40 bytes
Ò`ÆRtwodÈ(‚fÆfivÀ£xç P ightdÍÂ`qd a!øUà
Ò`...`qd a!øUà :Implicit input of lowercase string U
Ò :Negate the bitwise NOT of
`...` : Compressed string of lowercase digit names, delimited with "d"
qd : Split on "d"
a : 0-based index of first element (or -1 if no element)
!ø : Contained in
Uà : Combinations of U
Zsh, 85 bytes
for d (ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE);((++i,${#1:#${~d///*}*}))||bye i
The magic happens at ${~d///*}*, which turns ONE into *O*N*E*, etc. The :# operator removes the whole string if it matches, so if it's length is zero, (( )) is falsy and we exit with $i as the retcode.
If there's no matches, it will exit with 0, since the last command run was a truthy (( )).
Zsh, 96 bytes
local -A A
for d (ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE);A[${d///*}*]=$[++i]
<<<$A[(k)$1]
A much cooler variant imo, using the k subscript flag. It's unfortunate that associative arrays have to be declared with local -A, unlike normal arrays.
k: If used in a subscript on an associative array, this flag causes the keys to be interpreted as patterns, and returns the value for the first key found where exp is matched by the key. Note this could be any such key as no ordering of associative arrays is defined. This flag does not work on the left side of an assignment to an associative array element. If used on another type of parameter, this behaves liker.
R, 103 102 99 bytes
\(s)grep("^[MI]*$",attr(adist(scan(,s,t="ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE"),s,,T),"t"))
- -1 byte thanks to Dominic van Essen
- -3 bytes thanks to pajonk
Once again, a solution that relies upon the Levenshtein distances. Here as the output from the adist function the trafos patterns are used. These patterns are strings with the lengthes corresponding either to the input or to the output string, with 4 possible code letters: M- if the character has not been changed, I - a new character inserted, D - deleted, S - substituted. We only need to filter the trafos having neither substitutions nor deletions.
Conveniently, grep gives the position of the matched digit. If no digit was matched, the output is integer(0).
Python, 125 123 bytes
f=lambda b,x=9,i=0:x and f(b,x-1)+x*all(i:=b.find(c,i)+1for c in"NINE EIGHT SEVEN SIX FIVE FOUR THREE TWO ONE".split()[-x])
-2 bytes from @xnor, also fixing a misalignment with the spec
Brachylog, 57 bytes
∧"ONE
TWO
THREE
FOUR
FIVE
SIX
SEVEN
EIGHT
NINE"ṇi₁Ph⊆?∧Pt
Explanation
I think this could be shorter if i were reversible, but it doesn't appear to be.
∧"..."ṇi₁Ph⊆?∧Pt
∧ Break unification with input
"..." String containing words ONE through NINE, newline-separated
ṇ Split on newlines
i₁ [item, index] pair for some item in that list (1-based index)
P Call that pair P
h Its first element (the word)
⊆ is a non-contiguous substring of
? the input
∧ And
Pt P's last element (the index) is the output
Java (JDK), 150 bytes
s->{for(var i=0;i<9;)if(s.matches("."+"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")[i++].replaceAll(".","*$0.")+"*"))return i;return"NO";}
Saves
- 167 -> 153: various optimization thanks to @KevinCruijssen
Vyxal, 9 8 bytes
9'∆ċ?ṗṠc
-1 thanks to EmanresuA
9 bytes but faster:
9'∆ċ:?Þ∩=
The joys of having number to word built-ins!
Explained
9'∆ċ:?Þ∩=
9' # From the range [1, 9], keep only items n where:
∆ċ # n as a word
?Þ∩ # under multiset intersection with the input
: = # is the same.
Retina, 160 126 120 bytes
O.*N.*E
1
T.*W.*O
2
T.*H.*R.*E.*E
3
F.*O.*U.*R
4
F.*I.*V.*E
5
S.*I.*X
6
S.*E.*V.*E.*N
7
E.*I.*G.*H.*T
8
N.*I.*N.*E
9
\D
Returns an empty string if the input does not contain a digit.
-6 bytes thanks to @CalculatorFeline.
Python 2, 155 bytes
import re;lambda k:next((i for i,j in enumerate([re.search('.*'.join(list(s)),k)for s in'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()])if j),-1)+1
An anonymous function searching for regex group. Not the best solution here in Python but an alternative way.
C, 198 bytes
char*T[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};
g(char*a,char*b){while(*a&*b)a+=(*b++==*a);return!*a;}
i;char*f(char*b){for(i=0;i<9;i++)if(g(T[i],b))return T[i];return"NO";}
Java, 254 bytes
int g(String a,String b){int i=0,p=0;for(char c:a.toCharArray()){p=i;i=b.indexOf(c);if(i<=p)return 0;}return 1;}
String f(String a){String[]T={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};for(String t:T)if(g(t,a)>0)return t;return"NO";}
boolean g(String a,String b)
{
int i = 0, p = 0;
for(char c:a.toCharArray())
{
p = i;
i = b.indexOf(c);
if(i <= p) return false;
}
return true;
}
String f(String a)
{
String[]T={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};
for(String t:T)if(g(t,a))return t;
return"NO";
}
Javascript (ES6), 101 99 bytes
f=
s=>-~'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split` `.findIndex(x=>s.match([...x].join`.*`))
<!-- snippet demo: -->
<input list=l oninput=console.log(f(this.value))>
<datalist id=l><option value=BOUNCE>
<option value=ENCODE>
<option value=EIGHT>
<option value=BLACKJACK>
<option value=FABULOUS>
<option value=EXERCISE>
<option value=DRIFTWOOD>
<option value=SERVICEMAN>
<option value=INSIGNIFICANCE>
<option value=THROWDOWN>
<option value=ZERO>
<option value=OZNERO>
Ruby + to_words: 49 48+12 = 61 60 bytes
Uses the flags -rto_words -n. Takes lowercase words. Returns nil if no "digit" found.
-1 byte now that lowercase input is allowed, allowing for the removal of the i flag on the regex.
p (1..9).find{|i|$_=~/#{i.to_words.chars*".*"}/}
For a more pure Ruby answer without external gems, 91+1 = 92 bytes:
p (1..9).find{|i|$_=~/#{%w"0 ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE"[i].chars*".*"}/}
Jelly, 31 28 bytes
-2 bytes now that lowercase input is acceptable
“¡¦ẇṆb~ṇjṚØ%ĖġṘḥḞṾṇJḌ»Ḳe€ŒPT
A full program that expects lowercase input and prints the result, using 0 for the falsey case.
As a monadic link taking a list of characters it actually returns a list of integers which contains a single 0 in the falsey case, a single integer between 1 and 9 inclusive in the expected use cases and multiple such entries in cases where more than one number exists in the word.
How?
“¡¦ẇṆb~ṇjṚØ%ĖġṘḥḞṾṇJḌ»Ḳe€ŒPT - Main link: list of characters, s
“¡¦ẇṆb~ṇjṚØ%ĖġṘḥḞṾṇJḌ» - dictionary lookup of "one two three four five six seven eight nine"
Ḳ - split on spaces
ŒP - partitions of s
e€ - exists in? for €ach
T - truthy indexes
Bash, 163 bytes
a=NO;case $1 in *O*N*E*)a=1;;*T*W*O*)a=2;;*T*H*R*E*E*)a=3;;*F*O*U*R*)a=4;;*F*I*V*E*)a=5;;*S*I*X*)a=6;;*S*E*V*E*N*)a=7;;*E*I*G*H*T*)a=8;;*N*I*N*E*)a=9;;esac;echo $a
a=NO;
case $1 in
*O*N*E*)a=1;;
*T*W*O*)a=2;;
*T*H*R*E*E*)a=3;;
*F*O*U*R*)a=4;;
*F*I*V*E*)a=5;;
*S*I*X*)a=6;;
*S*E*V*E*N*)a=7;;
*E*I*G*H*T*)a=8;;
*N*I*N*E*)a=9;;
esac;
echo $a
Don't know RETINA but seems a straight port of that answer.
PHP>=7.0, 87 Bytes
<?for(;$i++<9;)levenshtein(IntlChar::charName("$i"),"DIGIT $argn",0,1,1)?:die("$i")?>NO
If only insertions of chars from one digit as word to the input is done exit the program with the digit.
Or change the order to levenshtein("DIGIT $argn",IntlChar::charName("$i"),1,1,0) to count not the deletions of chars
PHP>=7.0, 112 Bytes
for(;$i<9;)$r+=++$i*preg_match("#".chunk_split(substr(IntlChar::charName("$i"),6),1,".*")."#",$argn);echo$r?:NO;
PHP, 128 Bytes
foreach([ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE]as$v)$r+=++$k*preg_match("#".chunk_split($v,1,".*")."#",$argn);echo$r?:NO;
143 Bytes for more then 1 digit
foreach([ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE]as$v)$r.=++$k*preg_match("#".chunk_split($v,1,".*")."#",$argn);echo+$r?strtr($r,[""]):NO;
Pyth, -44- 41 bytes
+1xm}dyQc."EX%~)Û#lº,îQÓCe¯4Aô4"\P1
Takes a quoted string, outputs 0 for NO.
explanation
+1xm}dyQc."EX%~)Û#lº,îQÓCe¯4Aô4"\P1
."EX%~)Û#lº,îQÓCe¯4Aô4" # Compressed string: "ONEPTWOPTHREEPFOURPFIVEPSIXPSEVENPEIGHTPNINE" (P is close to the other letters, makes the compression better)
c \P # split on P: ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
m # map over this list (variable: d)
}dyQ # is d a (ordered) subset of the input (Q)? (= element of the powerset)
x 1 # get the index of the first true
+1 # add one, because the list was indexed at 0 and conveniently -1 (not found) becomes 0
Python, 148 bytes
from itertools import*
lambda s:[tuple(w)in combinations(s,len(w))for w in("x ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE "+s).split()].index(1)%10
An unnamed function taking an uppercase only word and returning the integer (1 to 9), or 0 for NO.
How?
For an input string s the function traverses through a list of the strings: "x", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT" , "NINE", and s itself looking for any matches.*
The comparison used is whether this string, w, is one that may be formed from a combination of letters in order from the input. The function combinations gets these for us (and only the ones of the required length using len(w)), but they are in the form of tuples, so the strings are cast to tuples for the comparison.
Of the eleven results the one for "x" will always be False, while the one for s itself will always be True. The "x" is there to ensure the index of a match with ONE through NINE are the values required (since Python lists are 0-indexed), the s is there to ensure
the call to index(1) (synonymous with index(True)) wont fail when no digit word was found, whereupon the resulting 10 is converted to a 0 with a modulo of ten using %10.
* If s contains spaces for some reason, the list of ws will be longer, but the process will still work since the digit word matches will work the same way, and if none match the first space-split substring from s will match, once again giving 10 and returning 0.
If multiple digit words exist the function will return the minimal one.
Mathematica, 83 bytes (WindowsANSI encoding)
±w_:=Rest@Position[Subsets@w~Cases~#&/@Characters@*IntegerName~Array~9,Except@{},1]
Defines a unary function ± that takes a list of lowercase characters as input and returns either a digit, in a form like {{7}}, or else an empty list {}. I don't feel like I did a ton of golfy things here, except that Characters@*IntegerName~Array~9 generates the number-name matches to look for without hard-coding them.
Example usage:
±{"i", "n", "s", "i", "g", "n", "i", "f", "i", "c", "a", "n", "c", "e"}
yields {{9}}.
Javascript, 121 bytes
(s,a=0)=>'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split``.map((p,i)=>RegExp(p.split``.join`.*`).exec(s)?a=i+1:0)&&a
or 116
(s,a=0)=>' ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split` `.map((p,i)=>a|=~s.search(p.split``.join`.*`)&&i)&&a
But just recycling material at this point.
PHP, 134 132 128 bytes
<?=preg_match(strtr(chunk_split("#(ONE0TWO0THREE0FOUR0FIVE0SIX0SEVEN0EIGHT0NINE",1,".*"),[")|("]).")#",$argn,$m)?count($m)-1:NO;
run as pipe with -nF or try it online.
Creates a regex with the words in parentheses; i.e. each word N is in the Nth sub-expression.
If a word is found, the matched string will be in $m[0] and in the the Nth element, with the elements between them empty and no empty string behind; i.e. $m has N+1 elements.
JavaScript (ES6), 121 bytes
f=
s=>[...s].map(c=>a=a.map(s=>s.slice(s[0]==c)),a=`ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE`.split` `)&&1+a.indexOf(``)
<input oninput=o.textContent=f(this.value)><pre id=o>0
Returns the lowest detected digit or 0 if no digit was detected (+6 if NO is required).
Haskell, 113 111 bytes
import Data.List
last.((`elemIndices`([]:words"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE"))=<<).subsequences
Returns 0 if no digit is found.
Find all subsequences of the input word in the list of digits. Prepend an empty string [] at index 0 which is part of every subsequence. elemIndices returns a list of indices and =<< flattens them into a single list. Pick the last index.
05AB1E, 26 bytes
The falsy value here is 0.
æ‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#å1k>
Explanation:
æ # Compute the powerset of the input
‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘ # Push "ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE"
# # Break on spaces
å # Check each for membership
1k # Get the index of 1 in the array (-1 if not found)
> # Increment by one
Uses the 05AB1E encoding. Try it online! or Verify all test cases!
Python 3, 150 bytes
from itertools import*;lambda x:([i for i in range(10)if(*' OTTFFSSENNWHOIIEIIEORUVXVGN ERE EHE E NT '[i::9],)in[*combinations(x+' ',5)]]+[0])[0]
combinations returns all the combinations of things in order. It would be simpler to have a set number for the second parameter of combinations, so spaces are added onto the end of the original string that is a parameter of my lambda. That's a simple description of how my entry works. Ask if you would like any more clarification.