| Bytes | Lang | Time | Link |
|---|---|---|---|
| 043 | JavaScript V8 | 250519T123831Z | Steve Be |
| 018 | Japt | 250519T081359Z | Shaggy |
| 051 | Swift 6 | 240317T005927Z | macOSist |
| 012 | Vyxal | 241204T225436Z | lyxal |
| 041 | AWK | 241204T211832Z | xrs |
| 045 | Scala 3 | 240317T022326Z | 138 Aspe |
| 102 | C gcc | 171121T220846Z | gastropn |
| 063 | Python 3 | 171125T153020Z | Jonathan |
| 077 | Ruby | 180622T160740Z | Alex All |
| 045 | Z80 Assembly | 171123T022509Z | introspe |
| 025 | APL Dyalog Unicode | 180409T124247Z | Erik the |
| 181 | Excel | 180409T112036Z | Wernisch |
| 141 | C 168 | 171120T230621Z | PrincePo |
| 099 | C | 171122T105042Z | Toby Spe |
| 102 | C gcc | 171120T200731Z | Michael |
| 432 | Matlab | 171126T210535Z | Jeremiah |
| 069 | C gcc | 171122T103100Z | jxh |
| 021 | Jelly | 171125T131143Z | Jonathan |
| 022 | Deorst | 171123T203643Z | caird co |
| 085 | Python 3 no regex | 171123T184111Z | Alex |
| 081 | Haskell | 171123T155815Z | Laikoni |
| 020 | QuadS | 171122T225959Z | Uriel |
| 039 | Jelly | 171120T215331Z | Adalynn |
| 023 | Retina | 171120T171653Z | Neil |
| 026 | Perl5 | 171122T174208Z | Kjetil S |
| 033 | Ruby | 171122T153140Z | G B |
| 035 | GNU sed | 171122T122424Z | Toby Spe |
| 076 | Befunge | 171120T214200Z | James Ho |
| 043 | Java OpenJDK 8 | 171121T101707Z | Luca H |
| nan | 171121T210534Z | djhurio | |
| 035 | J | 171120T235347Z | FrownyFr |
| 041 | JavaScript | 171120T235527Z | Forty3 |
| 051 | q/kdb+ | 171121T090058Z | mkst |
| nan | 171120T232234Z | Brad Gil | |
| 125 | Mathematica | 171120T220110Z | ZaMoC |
| 036 | Jelly | 171120T205851Z | lynn |
| 027 | Pip | 171120T202005Z | DLosc |
| 044 | Jelly | 171120T175051Z | Erik the |
| 023 | Pyth | 171120T171733Z | Mr. Xcod |
| 020 | Retina | 171120T172106Z | Uriel |
| 050 | Python 2 | 171120T170512Z | Erik the |
| 028 | Retina | 171120T171253Z | ovs |
JavaScript (V8), 43 bytes
s=>s.replace(/(one|th|tw|f|s|.i|z)/g,',$1')
JavaScript (V8), 46 bytes
s=>s.replace(/(one|tw|th|f|s|ei|ni|z)/g,',$1')
JavaScript (V8), 51 bytes
s=>s.replace(/(ne|wo|ee|ur|ive|x|en|ht|ro)/g,'$1,')
Swift 6, 76 69 51 bytes
{($0+"").replacing(/one|t[wh]|.i|[fsz]/){" "+$0.0}}
The output includes an extra leading space.
Vyxal, 12 bytes
øṖ'ƛ9ʀ∆ċ$c;A
The joys of having a number to words built-in. Where we're going we don't need regex
Explained
øṖ'ƛ9ʀ∆ċ$c;A
øṖ' # Keep partitions of the input where:
ƛ ;A # All strings in the partition:
$c # Are cornained within
∆ċ # Number to wordification of
9ʀ # The range [0, 9]
💎
Created with the help of Luminespire.
Scala 3, 45 bytes
Use Regular Expression (scala.util.matching.Regex)
Golfed version. Attempt This Online!
"""..[eox]|[tse]?....""".r.findAllIn(_).toSeq
Ungolfed version. Attempt This Online!
import scala.util.matching.Regex
object Main {
def main(args: Array[String]): Unit = {
val pattern: Regex = """..[eox]|[tse]?....""".r
val input = "threesevensevensixninenineninefiveeighttwofiveeightsixthreeeight"
val matches = pattern.findAllIn(input).toList
println(matches.mkString(", "))
}
}
C (gcc), 106 bytes 104 102 bytes
-2 bytes thanks to @jxh -2 bytes thanks to ceilingcat
c;f(char*s){for(char*t=" $&=B*,29/?";*s;)for(c=4+(index(t,(*s^s[1])+35)-t)/4;c--;)putchar(c?*s++:32);}
XOR is truly our greatest ally.
Python 3, no regex, 83 68 65 63 bytes
-15 thanks to Lynn (refactor into a single function)
-3 more thanks to Lynn (avoid indexing into a list with more arithmetic)
...leading to another save of 2 bytes (avoiding parenthesis with negative modulos) :)
def f(s):h=ord(s[0])*ord(s[1])%83%-7%-3+5;print(s[:h]);f(s[h:])
A function which prints the words separated by newlines and then raises an IndexError.
Try it online! (suppresses the exceptions to allow multiple runs within the test-suite)
Ruby, 77 bytes
puts gets.gsub(/(one|two|three|four|five|six|seven|eight|nine)/,' \1 ').strip
Z80 Assembly, 46 45 bytes
; HL is the address of a zero-terminated input string
; DE is the address of the output buffer
Match5: ldi ; copy remaining characters
Match4: ldi
Match3: ld a,32 : ld (de),a : inc de ; and add space after a matched word.
Uncollapse:
ld a,(hl) : ldi : or a : ret z ; copy first byte (finish if it was zero)
ex af,af' ; and save its value for later.
ldi : ld a,(hl) : ldi ; copy second and third bytes
cp 'e' : jr z,Match3 ; is the third letter 'e' or 'o' or 'x'?
cp 'o' : jr z,Match3
cp 'x' : jr z,Match3
ex af,af' ; now look at the first letter
cp 'e' : jr z,Match5 ; is it 't' or 's' or 'e'?
sub 's' : jr z,Match5
dec a : jr z,Match5
jr Match4
(It was fun to adapt the Uriel's cool regex to a regex-unfriendly environment).
Excel, 181 bytes
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"z"," z"),"on"," on"),"tw"," tw"),"th"," th"),"f"," f"),"s"," s"),"ei"," ei"),"ni"," ni")
Places a space in front of: z, on, tw, th, f, s, ei, ni
C 168 ,145,144,141 bytes
EDIT: Tried init 'i' to 1 like so
a,b;main(i)
To get rid of leading whitespace,
but it breaks on input starting with three, seven or eight
141
#define s|a%1000==
a,i;main(b){for(;~scanf("%c",&b);printf(" %c"+!!i,b),a|=b%32<<5*i++)if(i>4|a%100==83 s 138 s 116 s 814 s 662 s 478)a=i=0;}
144
a,i;main(b){for(;~(b=getchar());printf(" %c"+!!i,b),a=a*21+b-100,++i)if(i>4|a==204488|a==5062|a==7466|a==23744|a==21106|a==6740|a==95026)a=i=0;}
168
i,a;main(b){for(;~scanf("%c",&b);printf(" %c"+!!i,b),a|=b<<8*i++)if(i>4|a==1869768058|a==6647407|a==7305076|a==1920298854|a==1702259046|a==7891315|a==1701734766)a=i=0;}
Ungolfed
i,a;main(b){
for(;~scanf("%c",&b); // for every char of input
printf(" %c"+!!i,b), // print whitespace if i==0 , + char
a|=b<<8*i++ // add char to a for test
)
if(
i>4| // three seven eight
a==1869768058| // zero
a==6647407| // one
a==7305076| // two
a==1920298854| //four
a==1702259046| //five
a==7891315| //six
a==1701734766 //nine
) a=i=0; //reset i and a
}
int constants gets unnecessary large by shifting a<<8
but in case you can compare to strings somehow it should be the most natural
146 Using string comparison
#define s|a==*(int*)
a,b;main(i){for(;~(b=getchar());printf(" %c"+!!i,b),a|=b<<8*i++)if(i>4 s"zero"s"one"s"two"s"four"s"five"s"six"s"nine")a=i=0;}
Obfuscated
#define F(x)if(scanf(#x+B,&A)>0){printf(#x,&A);continue;}
B;A;main(i){for(;i;){B=1;F(\40e%4s)F(\40th%3s)F(\40se%3s)F(\40o%2s)B=2;F(\40tw%1s)F(\40si%1s)B=1;F(\40%4s)i=0;}}
C, 103 99 bytes
char*r="f.tzuonresn.xgv";f(char*s){*s&&f(s+printf("%.*s ",(strrchr(r,s[2])-strchr(r,*s))%10,s)-1);}
This works for any character encoding (including awkward ones like EBCDIC), because it doesn't use the numeric value of the input characters. Instead, it locates the first and third letters in a magic string. The distance between these indicates how many letters to advance with each print.
Test program
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
f(argv[i]);
puts("");
}
}
C (gcc), 179 159 146 139 137 116 107 103 102 bytes
Edit 1: (Added suggestions from Mr. Xcoder - thanks! - My macro version was same size as yours, but I like yours better.)
Edit 2:
Changed char individual compares to calls to strchr()
Edit 3: K&R's the var declarations (Eww!)
Edit 4: When 1 macro is not enough...
Edit 5: Redone with new algorithm suggested above. Thanks to James Holderness for this great idea!
Edit 6: Removed 0 set as it seems to go there automatically - Master level code golf techniques used (commas, printf trick, etc.) - thanks gastropner!
Edit 7: Use memchr and fixed a bug pointed out by James Holderness.
Edit 7:
Use && on final check to replace ? - thanks jxh.
c,h;f(char*s){while(c=*s++)putchar(c),h=h%10816*104+c%27,memchr("&;@X\\ru{",h%3817,9)&&putchar(h=32);}
Non-golfed (Which is still very golfy honestly...)
int c;
int h;
void f(char*s)
{
while(c=*s++)
putchar(c),
h=h%10816*104+c%27,
memchr("&;@X\\ru{",h%3817,9)?putchar(h=32):1;
}
Old, straight forward grep-esqe solution:
#define p putchar
#define q c=*s++
c,x;f(char*s){while(q){p(c);x=strchr("tse",c);p(q);p(q);if(!strchr("eox",c)){p(q);if(x)p(q);}p(' ');}}
Old, cleaner version.
// Above code makes a macro of putchar() call.
void f(char *s)
{
char c;
while(c = *s++)
{
putchar(c);
int x = strchr("tse", c);
putchar(*s++);
putchar(c=*s++);
if(!strchr("eox", c))
{
putchar(*s++);
if(x)
{
putchar(*s++);
}
}
putchar(' ');
}
}
Matlab, 432 bytes
A long attempt.
s=char(input('','s'));o=[];while length(s)>0;switch s(1:2);case'ze';o=[o,' ',s(1:4)];s(1:4)=[];case'on';o=[o,' ',s(1:3)];s(1:3)=[];case'tw';o=[o,' ',s(1:3)];s(1:3)=[];case 'th';o=[o,' ',s(1:5)];s(1:5)=[];case'fo';o=[o,' ',s(1:4)];s(1:4)=[];case'fi';o=[o,' ',s(1:4)];s(1:4)=[];case 'si';o=[o,' ',s(1:3)];s(1:3)=[];case'se';o=[o,' ',s(1:5)];s(1:5)=[];case 'ei';o=[o,' ',s(1:5)];s(1:5)=[];otherwise;o=[o,' ',s(1:4)];s(1:4)=[];end;end;o
ungolfed:
s=char(input('','s'))
o=[]
while length(s)>0
switch s(1:2)
case 'ze'
o=[o,' ',s(1:4)]
s(1:4)=[]
case 'on'
o=[o,' ',s(1:3)]
s(1:3)=[]
case 'tw'
o=[o,' ',s(1:3)]
s(1:3)=[]
case 'th'
o=[o,' ',s(1:5)]
s(1:5)=[]
case 'fo'
o=[o,' ',s(1:4)]
s(1:4)=[]
case 'fi'
o=[o,' ',s(1:4)]
s(1:4)=[]
case 'si'
o=[o,' ',s(1:3)]
s(1:3)=[]
case 'se'
o=[o,' ',s(1:5)]
s(1:5)=[]
case 'ei'
o=[o,' ',s(1:5)]
s(1:5)=[]
otherwise
o=[o,' ',s(1:4)]
s(1:4)=[]
end
end
o
C (gcc), 89 80 76 75 72 71 70 69 bytes
f(char*s){*s&&f(s+printf(" %.*s",""[(*s^s[2])%12],s)-1);}
(89) Credit to gastropner for the XOR hash.
(76) Credit to Toby Speight for the idea of using 1st and 3rd.
(75) Credit to Michael Dorgan for '0' → 48.
(72) Credit to Michael Dorgan and Lynn for literals with control characters.
(69) Credit to Lynn for x?y:0 → x&&y
f (char *s) { /* K&R style implicit return type. s is the input. */
*s&&f( /* Recurse while there is input. */
s+printf( /* printf returns the number of characters emitted. */
" %.*s", /* Prefix each digit string with a space. Limit
* how many bytes from the string to print out. */
""
/* Magic hash table, where the value represents
* the length of the digit string. The string
* is logically equivalent to
* "\04\01\05\03\04\05\05\04\04\01\03\03" */
[(*s^s[2])%12],
/* The XOR hash (mod 12) */
s) /* The current digit. */
-1);} /* Subtract 1 for the space. */
Jelly, 23 21 bytes
ḣ3OP%953%7%3+3ɓḣṄȧṫḊÇ
A full program printing line-feed separated output. Note: once it's done it repeatedly prints empty lines "forever" (until a huge recursion limit or a seg-fault)
Try it online! (TIO output is accumulated, a local implementation will print line by line)
How?
Starting with a list of characters, the program repeatedly:
- finds the length of the first word of the list of characters using some ordinal mathematics;
- prints the word plus a linefeed; and
- removes the word from the head of the list of characters
The length of the first word is decided by inspecting the first three characters of the current list of characters (necessarily part of the first word). The program converts these to ordinals, multiplies them together, modulos the result by 953, modulos that by seven, modulos that by three and adds three:
word head3 ordinals product %953 %7 %3 +3 (=len(word))
zero zer [122,101,114] 1404708 939 1 1 4
two two [111,110,101] 1233210 28 0 0 3
one one [116,119,111] 1532244 773 3 0 3
three thr [116,104,114] 1375296 117 5 2 5
four fou [102,111,117] 1324674 4 4 1 4
five fiv [102,105,118] 1263780 102 4 1 4
six six [115,105,120] 1449000 440 6 0 3
seven sev [115,101,118] 1370570 156 2 2 5
eight eig [101,105,103] 1092315 177 2 2 5
nine nin [110,105,110] 1270500 151 4 1 4
ḣ3OP%953%7%3+3ɓḣṄȧṫḊÇ - Main link, list of characters e.g. "fiveeight..."
ḣ3 - head to index three "fiv"
O - ordinals [102,105,118]
P - product 1263780
%953 - modulo by 953 102
%7 - modulo by seven 4
%3 - modulo by three 1
+3 - add three 4
ɓ - dyadic chain separation swapping arguments...
... ḣṄȧṫḊÇ ...
ḣ - head to index "five"
Ṅ - print the result plus a line-feed and yield the result
ṫ - tail from index "eeight..."
ȧ - and (non-vectorising) "eeight..."
Ḋ - dequeue "eight..."
Ç - call the last link (Main*) as a monad with this as input
- * since it's the only link and link indexing is modular.
Deorst, 22 bytes
'..[eox]|[tse]?....'gf
Of course, this uses the regex found by Uriel. Although, it’s great when Deorst beats Pyth and Jelly :P
Python 3 (no regex), 85 bytes
i=3
while i<len(s):
if s[i-3:i]in'ineiveroneghtwoureesixven':s=s[:i]+' '+s[i:]
i+=1
Haskell, 81 bytes
f[c]=[c]
f(h:t)=[' '|s<-words"z one tw th f s ei ni",and$zipWith(==)s$h:t]++h:f t
Explanation:
f(h:t)= h:f t -- recurse over input string
[' '|s<- ]++ -- and add a space for each string s
words"z one tw th f s ei ni" -- from the list ["z","one","tw","th","f","s","ei","ni"]
,and$zipWith(==)s$h:t -- which is a prefix of the current string
Jelly, 40 39 bytes
“¢¤Ƙƒ⁺6j¹;Ċ-ḶṃżṃgɼṘƑUẏ{»Ḳe€€@ŒṖẠ€TḢịŒṖK
How it works
“¢¤Ƙƒ⁺6j¹;Ċ-ḶṃżṃgɼṘƑUẏ{»Ḳe€€@ŒṖẠ€TḢịŒṖK
“¢¤Ƙƒ⁺6j¹;Ċ-ḶṃżṃgɼṘƑUẏ{» = the compressed string of the digit names
Ḳ = split at spaces
e€€@ŒṖ = check whether each member of each partition of the argument is a digit.
Ạ€ = A function that checks whether all values of an array are true, applied to each element.
T = Finds the index of each truthy element
Ḣ = Grab the first element, since we have a singleton array
ịŒṖ = The previous command gives us the index, partition that splits the input into digits. This undoes it and gives us the partition.
K = Join the array of digits with spaces
Retina, 24 23 bytes
!`..[eox]|[fnz]...|.{5}
Try it online! Edit: Saved 1 byte thanks to @FrownyFrog.
Perl5, 26 bytes
echo zeronineoneoneeighttwoseventhreesixfourtwofive \
| perl -ple 's/..[eox]|[tse]?..../$& /g'
Or just the program:
s/..[eox]|[tse]?..../$& /g
GNU sed, 35 bytes
(including +1 for the -r flag)
s/([ots]|[zfn].|(se|th|ei).)../ &/g
Just a simple regexp replacement.
Befunge, 87 85 81 76 bytes
<*"h"%*:"h"$_02g-v1$,*<v%*93,:_@#`0:~
"@{&ruX;\"00^ !: _>_48^>+:"yp!"*+%02p0
Befunge doesn't have any string manipulation instructions, so what we do is create a kind of hash of the last three characters encountered, as we're processing them.
This hash is essentially a three digit, base-104 number. Every time a new character is read, we mod the hash with 1042 to get rid of the oldest character, multiply it by 104 to make space for the new character, then add the ASCII value of the new character mod 27 (to make sure it doesn't overflow).
For comparison purposes, we take this value mod 3817, write it into memory (thus truncating it to 8 bits), which results in smaller numbers that are easier for Befunge to handle. The hashes we then have to compare against are 0, 38, 59, 64, 88, 92, 114, 117, and 123. If it matches any of those, we know we've encountered a character sequence that marks the end of a number, so we output an additional space and reset the hash to zero.
If you're wondering why base 104, or why mod 3817, those values were carefully chosen so that the hash list we needed to compare against could be represented in as few bytes as possible.
Java (OpenJDK 8), 55 46 43 bytes
Saving 9 bytes thanks to Forty3/FrownyFrog
Saving 3 bytes thanks to Titus
s->s.replaceAll("one|tw|th|f|z|s|.i"," $0")
edit: Thank you for the welcome and explanation of lambdas!
Quite long one. You are welcome to golf it down.
R, 109 bytes
function(x)for(i in utf8ToInt(x)){F=F+i;cat(intToUtf8(i),if(F%in%c(322,340,346,426,444,448,529,536,545))F=0)}
JavaScript, 66 57 52 44 41 bytes
s=>s.replace(/one|t[wh]|.i|[fsz]/g," $&")
Pretty naive, but it works.
Nice catch by FrownyFrog to use 2 chars .. except for "one" which a pure 2 char check might mess up zeronine. Edit: the single f and s were good catches by FrownyFrog that I overlooked my first two golfs.
Thanks, Neil, for the suggestion of an unnamed lambda and being able to use a single char for z gets down to 52.
Titus comes up with a smaller RegEx. I feel we are heading toward Uriel's regex eventually.
q/kdb+, 59 51 bytes
Solution:
{asc[raze x ss/:string`z`one`tw`th`f`s`ei`ni]cut x}
Example:
q){asc[raze x ss/:string`z`one`tw`th`f`s`ei`ni]cut x}"threesevensevensixninenineninefiveeighttwofiveeightsixthreeeight"
"three"
"seven"
"seven"
"six"
"nine"
"nine"
"nine"
"five"
"eight"
"two"
"five"
"eight"
"six"
"three"
"eight"
Explanation:
Quick solution, probably better and more golfable approaches.
{asc[raze x ss/:string`z`one`tw`th`f`s`ei`ni]cut x} / ungolfed solution
{ } / lambda with implicit x as input
cut x / cut x at indices given by left
asc[ ] / sort ascending
string`z`one`tw`th`f`s`ei`ni / string list ("z","one",...)
x ss/: / string-search left with each right
raze / reduce down list
Notes:
46 bytes with some simple golfing, replacing q calls with k ones, but still a hefty solution.
asc[(,/)x ss/:($)`z`one`tw`th`f`s`ei`ni]cut x:
Perl 6, 42 30 bytes
*.comb(/<{(0..9).Str.uninames.lc.words}>/)
{m:g/..<[eox]>||<[tse]>?..../}
Test it
(Translated from other answers)
Mathematica, 125 bytes
(s=#;While[StringLength@s>2,t=1;a="";While[FreeQ[IntegerName/@0~Range~9,a],a=s~StringTake~t++];Print@a;s=StringDrop[s,t-1]])&
TIO outputs an error message about "CountryData"(???)
I don't know why this happens, but eveything works fine on Mathematica
Jelly, 36 bytes
œṣj⁶;$}
W;“€ɗİẒmṫṃ¦¦ạỊɦ⁼Fḷeṭḷa»s2¤ç/
Algorithm:
for x in ['ze', 'ni', 'on', 'tw', 'th', ...]:
replace x in input by space+x
I bet we can do even better.
Pip, 27 bytes
aR`[zfs]|one|[ent][iwh]`s._
Takes input as a command-line argument. Try it online!
Simple regex replacement, inserts a space before each match of [zfs]|one|[ent][iwh].
Jumping on the bandwagon of stealing borrowing Uriel's regex gives 23 bytes (with -s flag):
a@`..[eox]|[tse]?....`
Python 2, 50 bytes
import re
re.compile('..[eox]|[tse]?....').findall