# Question
Title: Calculate to how many cubes one cube can be cut
Imagine some cube which we can cut into smaller cubes without remaining pieces.

Find to how many cubes a cube can be cut.

For example, a cube can be cut into 8, 27 (obviously 3rd powers of integers) and 20 (19 small cubes plus one eight times the size of the others, see image).
See here some help: http://mathworld.wolfram.com/CubeDissection.html

Program should take as input integer `n` (`0 <= n <= 1 000`) and print all numbers less or equal to `n` so that a cube can be cut into that number of cubes. Suppose that cube can be cut into 1 cube and cannot into 0 cubes.

You can use only integral data-types (no arrays, objects etc) of size no greater than 64-bits. Shortest code wins.

# Answer
> 1 votes
# Golfscript, 55 (or ~~43~~ 42)

```
{.:^}{.47>20{.^>^@- 7%|!|}:/~1/38/39/{}{;}if^(}while;]`

```

Can be tested here (just change the number on line 2) and only uses the array (last two chars of code) for clean printing, not for any collection or problem solving. If you leave it off, all results will be concatenated.

**Method:** Iterate down from given n: If current number is greater than 47 or of the form 1+7x, 20+7x, 38+7x, or 39+7x where x = any non-negative integer, then keep it on the stack, otherwise drop it.

**Short answer (43 bytes):**

~~{:/6+,{7\*/+}%|}:&;):a,48,^1&20&38&39&{a\<},\`~~

```
):a,48,^1{:/6+,{7*/+}%|}:&~20&38&39&{a<},`

```

**Method:** Similar, but with a few set theory ops. This uses arrays so it's technically not an acceptable answer. Can be tested here. Btw: nobody ever said they had to be in any particular order ;)

# Answer
> 1 votes
**Mathematica, 62 bytes (or 52)**

It's hardcoded answer, nothing interesting.

> `If[EvenQ@BitShiftRight[164015534735101,n],Print@n]~Do~{n,1000}`

This one is 52 bytes long but violates my rules - it uses large integers (powers of 2) and lists (Range).

> `Select[Range@1000,EvenQ@Floor[164015534735101/2^#]&]`

# Answer
> 0 votes
# C, 72

```
i;main(){for(scanf("%d",&i);i;i--)0x952BD7AF7EFC>>i&1||printf("%d ",i);}

```

Another hardcoded answer. This counts downwards (there's nothing in the rules about the order the numbers have to be output in.) In theory it should work. The constant has a bit set to 1 for all the numbers into which a cube can NOT be cut, and a 0 for the numbers which can. In theory, the constant when right shifted by a very large number should be zero, so the large number should always be printed.

What's interesting is that in practice this does not work. The code above compiles and runs fine on GCC up to 65. But above that number there is a bug (or "feature") in the compiler. it interprets `0x952BD7AF7EFC>>i` as `0x952BD7AF7EFC>>i%64`. So it skips (for example) the numbers 66 through 71 (64+2 through 64+7).

To run in Visual Studio, a bit more boilerplate is needed (it doesn't let you get away with things like implied integers and `#include`s.) Once the program's up and running, it's fine up to 257... Then it skips 258 through 263 (256+2 through 256+7.) So it's taking `i%256.`

I may fix it later (if I can be bothered.) Moral: compiler manuals don't normally tell you the upper limit on bitshifts. There's a reason for that!

# Answer
> 0 votes
# Ruby, 44 bytes

```
->n{1.upto(n){|i|i/7<777159>>i%7*3&7||p(i)}}

```

Try it online!

Takes advantage of the fact that solutions occur modulo 7 (as a result of the fact that a cube can be dissected into 8 cubes, adding 7.)

Below are all solutions below 49 (there is a solution for all numbers over 49.) The magic number `777159` decimal = `2755707` octal encodes the lowest value of `i/7` for which a solution exists for each possible value of `i%7`.

```
n%7=0                         not possible where i/7<7
n%7=1    1,8,15,22,29,36,43                      i/7<0
n%7=2                                            i/7<7
n%7=3                 38,45                      i/7<5
n%7=4                 39,46                      i/7<5
n%7=5                                            i/7<7
n%7=6        20,27,34,41,48                      i/7<2

```

---
Tags: code-golf, math
---


title: Find the J twin

text:
# Question
Title: Find the J twin
For a 2 dimensional array we will define the elements in either the first row or the last column to be the largest "J-Bracket" of the array. For example in the following array elements in the J-bracket are highlighted:

\\$ \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} & \color{red}{\underline 8} \\ 9 & 3 & 6 & \color{red}{\underline 7} \\ 3 & 3 & 2 & \color{red}{\underline 9} \end{bmatrix} \\$

The J-bracket is given in order starting from the first element of the first row and going clockwise. The element that is in both the row and the column is not repeated. So for the above that is:

\\$ \left\[1, 2, 4, 8, 7, 9\right\] \\$

To get the next largest J-bracket is just remove the largest J-bracket from the array and take the largest J-bracket of the remainder:

\\$ \begin{bmatrix} \color{lightgrey}{1} & \color{lightgrey}{2} & \color{lightgrey}{4} & \color{lightgrey}{8} \\ \color{red}{\underline 9} & \color{red}{\underline 3} & \color{red}{\underline 6} & \color{lightgrey}{7} \\ 3 & 3 & \color{red}{\underline 2} & \color{lightgrey}{9} \end{bmatrix} \\$

and so on until every element is in exactly 1 J-bracket.

The set of J-brackets from an array is not necessarily unique. In fact if the matrix is non-square every matrix has a twin with the same J-bracket set.

\\$ \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} & \color{red}{\underline 8} \\ \color{green}9 & \color{green}3 & \color{green}6 & \color{red}{\underline 7} \\ \color{blue}{\overline 3} & \color{blue}{\overline 3} & \color{green}2 & \color{red}{\underline 9} \end{bmatrix} \cong \begin{bmatrix} \color{red}{\underline 1} & \color{red}{\underline 2} & \color{red}{\underline 4} \\ \color{green}{9} & \color{green}3 & \color{red}{\underline 8} \\ \color{blue}{\overline 3} & \color{green}6 & \color{red}{\underline 7} \\ \color{blue}{\overline 3} & \color{green}2 & \color{red}{\underline 9} \end{bmatrix} \\$

This twin has the opposite dimensions and in the case of a square matrix it is its own twin.

Your task is to take a 2D array of positive integers and output its J-twin. You may take input and output in any standard format but the input format should be the same as the output.

This is so answers will be scored in bytes with fewer bytes being the goal.

# Test cases

```
[[2]] -> [[2]]
[[1,2,3]] -> [[1],[2],[3]]
[[1,2,4,8],[9,3,6,7],[3,3,2,9]] -> [[1,2,4],[9,3,8],[3,6,7],[3,2,9]]
[[1,2,4],[9,3,8],[3,6,7],[3,2,9]] -> [[1,2,4,8],[9,3,6,7],[3,3,2,9]]

```

# Answer
# Jelly, 10 bytes

```
ZL_Lṙ@ŒdŒḍ

```

A monadic Link that accepts a rectangular list of lists and yields its J-bracket-twin as a list of lists.

**Try it online!** Or see the test-suite.

### How?

```
ZL_Lṙ@ŒdŒḍ - Link: list of lists, A
Z          - transpose A
 L         - length of that -> columnCount(A)
   L       - length of A -> rowCount(A)
  _        - columnCount(A) subtract rowCount(A) = N
      Œd   - anti-diagonals of A
    ṙ@     - rotate this list of anti-diagonals left by N
        Œḍ - create a matrix with these anti-diagonals

```
> 7 votes

# Answer
# K (ngn/k), 154 74 72 bytes

```
{$[1=&/#'1*:\x;:+x;[r:,/(*x),1_-1#'x;(,(#x)#r),+(+o(1_-1_'x)),,(#x)_r]]}

```

Try it online!
> 5 votes

# Answer
# , 76 bytes

```
\(m)array(unsplit(split(m,i),rev(t(i<-pmin(row(m),rev(col(m)))))),dim(t(i)))
```

Attempt This Online!

As in the other challenge, `split`s the array to find the J-brackets. Then `unsplit`s and adds `array` structure to get to the J-twin as a matrix.

Longer explanation to follow.
> 4 votes

# Answer
# Python 3, 111 bytes

```
def f(x):
 r,*a=x;k=len(a)
 if k*r[1:]:r+=map(list.pop,a);x=*zip(r[:k],*f(a)),r[k:]
 return[*map(list,zip(*x))]

```

Try it online!
> 4 votes

# Answer
# PARI/GP, 59 bytes

```
m->matrix(#m,#m~,i,j,m[i-d=min(l=i+j-1,#m)-min(l,#m~),j+d])
```

Attempt This Online!

Shift the \\$n\\$-th anti-diagonal to lower left by \\$\min(n,w)-\min(n,h)\\$, where \\$w\\$ and \\$h\\$ are the number of columns and rows of the matrix respectively.
> 3 votes

# Answer
# , ~~62~~ 60 bytes

Quite messy. The logic is very similar to my Python answer. Porting the Jelly answer might be shorter.

```
[:|:*@#@,(({.,{:"1@}.)((}.~#),~({.~#),.])|:@$:@:(}:"1)@}.^:)

```

Try it online!
> 3 votes

# Answer
# Charcoal, ~~52~~ ~~43~~ 39 bytes

```
Ｆ⁺θ§θ⁰⊞υ⟦⟧ＵＭθＥι⊞Ｏ§υ⁺κμλ≦⮌υＩＥ§θ⁰Ｅθ⊟§υ⁺κμ

```

Try it online! Link is to verbose version of code. Outputs in Charcoal's default one-element-per-line format. Explanation:

```
Ｆ⁺θ§θ⁰⊞υ⟦⟧

```

Create a list of empty lists that will eventually hold the antidiagonals.

```
ＵＭθＥι⊞Ｏ§υ⁺κμλ

```

Extract the antidiagonals from the input. (This replaces each element in the array with the antidiagonal to which it belongs, but unfortunately I can't make use of this fact.)

```
≦⮌υ

```

Reverse the antidiagonals so that we can extract the elements in the original order using `Pop()`.

```
ＩＥ§θ⁰Ｅθ⊟§υ⁺κμ`

```

Transpose the array, but read the elements back from the antidiagonals. (If Charcoal had an equivalent of JavaScript's `unshift()` then I would be able to unshift directly from the transposed array's antidiagonals to recover the elements.)
> 2 votes

# Answer
# Python \+ NumPy, 80 bytes

```
def f(a):b=0*a.T;b[1:,:-1]=a.any()and f(a[1:,:-1]);b[b<1]=a[a>0];a[:]=0;return b
```

Attempt This Online!

Accepts and destroys (overwrites with zeros) a NumPy array. Relies on elements being positive as promised in OP.
> 2 votes

# Answer
# Haskell, ~~132~~ 121 bytes

*-11 thanks to Wheat Wizard*

```
t[h]=pure<$>h
t s@([x]:r)=[s>>=id]
t(h:r)|n<-t$init<$>r,(a,b)<-splitAt(length r)$h++(last<$>r)=zipWith(\i->(++[i]))b(a:n)

```

Try it online!

If the input list has only one row, or only one column, transpose it. Otherwise, recurse on the "nub" that results from removing the J-bracket; then split the J-bracket into two parts, put one part atop the nub, and append the other part itemwise to the right side of the nub.

It's still pretty long, so I'm guessing there's a better way to do this...
> 2 votes

# Answer
# Haskell, 100 bytes

-3 bytes thanks to Wheat Wizard.

```
t m=[[m!!(i-1-x+y)!!(j+x-y)|j<-[0..l m-1],let[x,y]=min(i+j)<$>[l$m!!0,l m]]|i<-[1..l$m!!0]]
l=length

```

Try it online!

An ugly port of my PARI/GP answer.

---

# Curry (PAKCS), 101 bytes

-4 bytes thanks to Wheat Wizard.

```
t m=[[m!!(i-1-x+y)!!(j+x-y)|j<-[0..l m-1],let[x,y]=map(min$i+j)[l$m!!0,l m]]|i<-[1..l$m!!0]]
l=length

```

Try it online!
> 1 votes

# Answer
# Python3, 234 bytes:

```
E=enumerate
s=lambda m,d:(k for i,j in E(m)for x,k in E(j)if(i==d and x<(len(m[0])-d))or(i>d and x==(len(m[0])-1-d)))
r=lambda d,m:[[next(d[min(x,len(m)-1-y)])for y,_ in E(m)]for x,_ in E(m[0])]
lambda m:r({i:s(m,i)for i,_ in E(m)},m)

```

Try it online!
> 0 votes

---
Tags: code-golf, array
---


title: AoCG2021 Day 2: Naughty or nice?

text:
# Question
Title: AoCG2021 Day 2: Naughty or nice?
Part of **Advent of Code Golf 2021** event. See the linked meta post for details.

The story continues from AoC2015 Day 5, Part 2.

---

Santa needs help figuring out which strings in his text file are naughty or nice. He has already tried two sets of rules, but they're totally ad-hoc, cumbersome, and janky, so he comes up with a single rule that will rule them all:

* A string is nice if it contains a pattern `n..i..c..e` where the letters `n`, `i`, `c`, and `e` are equally far apart from each other.

In other words, a string is nice if, for some non-negative integer `x`, it matches the regex `n.{x}i.{x}c.{x}e`.

**Input:** A nonempty string of lowercase English letters (you can choose to take uppercase instead).

**Output:** Truthy or falsy indicating whether the input string is nice or not. You can choose to

* output truthy/falsy using your language's convention (swapping is allowed), or
* use two distinct, fixed values to represent true (affirmative) or false (negative) respectively.

Standard rules apply. The shortest code in bytes wins.

## Test cases

Truthy:

```
nice
noizcue
aaaaanicezzzz
nnicceee

```

Falsy:

```
x
abc
ince
nnicce
nniccexe
precinct

```

# Answer
> 11 votes
# , 35 bytes

```
1 e.[:,'nice'E."1]#~#$"1&><@=\@i.@#

```

Try it online!

Consider `f 'noizcue'`:

* `<@=\@i.@#` Create a bunch of identity matrixes, up to the input length:

```
┌─┬───┬─────┬───────┬─────────┬───────────┬─────────────┐
│1│1 0│1 0 0│1 0 0 0│1 0 0 0 0│1 0 0 0 0 0│1 0 0 0 0 0 0│
│ │0 1│0 1 0│0 1 0 0│0 1 0 0 0│0 1 0 0 0 0│0 1 0 0 0 0 0│
│ │   │0 0 1│0 0 1 0│0 0 1 0 0│0 0 1 0 0 0│0 0 1 0 0 0 0│
│ │   │     │0 0 0 1│0 0 0 1 0│0 0 0 1 0 0│0 0 0 1 0 0 0│
│ │   │     │       │0 0 0 0 1│0 0 0 0 1 0│0 0 0 0 1 0 0│
│ │   │     │       │         │0 0 0 0 0 1│0 0 0 0 0 1 0│
│ │   │     │       │         │           │0 0 0 0 0 0 1│
└─┴───┴─────┴───────┴─────────┴───────────┴─────────────┘

```
* `#$"1&>` Extend each row to the input length, filling extra rows with zeroes:

```
1 1 1 1 1 1 1
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

1 0 1 0 1 0 1
0 1 0 1 0 1 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

1 0 0 1 0 0 1
0 1 0 0 1 0 0
0 0 1 0 0 1 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

1 0 0 0 1 0 0
0 1 0 0 0 1 0
0 0 1 0 0 0 1
0 0 0 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

1 0 0 0 0 1 0
0 1 0 0 0 0 1
0 0 1 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

1 0 0 0 0 0 1
0 1 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 1 0
0 0 0 0 0 0 0

1 0 0 0 0 0 0
0 1 0 0 0 0 0
0 0 1 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 1 0
0 0 0 0 0 0 1

```
* `#$"1&>` Use those as masks to filter the input (rows of all zeroes elided to save space):

```
noizcue
nice
ozu
nze
oc
iu
nc
ou
ie
z
nu
oe
i
z
c
ne
o
i
z
c
u
n
o
i
z
c
u
e

```
* `1 e.[:,'nice'` Is "nice" in any resulting rows?

# Answer
> 9 votes
# 05AB1E, 8 bytes

```
ā€ι»'ŒÁå

```

Try it online! or Try all cases!

```
ā         -- range from 1 to the length of the input s
 €ι       -- for each value k in this range, push [s[0::k], ..., s[k-1::k]]
   »      -- join each inner list by spaces and the resulting strings by newlines
    'ŒÁ   -- dictionary compressed word "nice"
       å  -- is this a substring?

```

Or look at the output of just `ā€ι»`

# Answer
> 7 votes
# Retina 0.8.2, ~~42~~ 41 bytes

```
n(.)*i(?<2-1>.)*(?(1)^)c(?<-2>.)*(?(2)^)e

```

Try it online! Link includes test cases. Edit: Saved 1 byte by porting @ZaelinGoodman's regex. Explanation:

```
n(.)*i

```

Match `n`, followed by `x` characters, capturing `x` in capture group `1`, followed by `i`.

```
(?<2-1>.)*(?(1)^)c

```

Match `x` characters by popping from capture group `1`, simultaneously capturing into capture group `2`, followed by `c`.

```
(?<-2>.)*(?(2)^)e

```

Match `x` characters by popping from capture group `2`, followed by `e`.

# Answer
> 7 votes
# Jelly, ~~17~~ ~~12~~ 11 bytes

```
ẆmþJẎ“£uƇ»e

```

Try it online!

-5 bytes by adapting emanresu A's approach
-1 byte thanks to ovs!

## How it works

```
ẆmþJẎ“£uƇ»e - Main link. Takes a word W on the left
Ẇ           - Contiguous substrings S of W
   J        - Yield the range 1 ≤ i ≤ len(W)
  þ         - For each pair (S, i):
 m          -   Take the ith elements of s
    Ẏ       - Tighten into a list of strings
     “£uƇ»  - Compressed string; "nice"
          e - Is this in the list of strings?

```

# Answer
> 7 votes
# JavaScript (ES6), 59 bytes

```
s=>[...s].some((_,i)=>s.match(`n.{${i}}i.{${i}}c.{${i}}e`))

```

Try it online!

# Answer
> 6 votes
# Python, 66, 64, 62, 61 (@dingledooper), 60 bytes (@Kevin Cruijssen)

```
f=lambda s,i=1:s>s[:i]and('nice'in s[::i])|f(s,i+1)|f(s[i:])

```

Try it online!

Old version

Old version

Old version

Old version

# Answer
> 6 votes
# Vyxal, 10 bytes

```
ǎ?żvef‛ß¦c

```

Try it Online!

```
ǎ          # Substrings
   v       # Each...
    e      # Get every nth character for each of...
 ?ż        # 1...input length
     f     # flattened
         c # Includes
      ‛ß¦  # Compressed string 'nice'

```

# Answer
> 5 votes
# Python 3.8 (pre-release), 72 bytes

```
lambda s:'nice'in[L:=range(len(s))]+[s[i::j+1][:4]for j in L for i in L]

```

Try it online!

Same code pattern as yesterday?

# Answer
> 5 votes
# Excel, 78 bytes

```
=MAX(LET(q,REPT("?",SEQUENCE(LEN(A1))-1),COUNTIF(A1,"*n"&q&"i"&q&"c"&q&"e*")))

```

Input is in the cell `A1`. Returns `1` for truthy and `0` for falsey.

* `REPT("?",SEQUENCE(LEN(a))-1)` creates an array of strings, all made entirely of `?` and varying in length from 1 to the length of the input minus 1. If the input is `nice` then this returns `['','?','??','???']`.
* `LET(q,REPT(~)` defines the results of the previous step to be `q` so we can reference it multiple times later using just the variable name and save bytes.
* `COUNTIF(A1,"*n"&q&"i"&q&"c"&q&"e*")` does the actual checking. `COUNTIF()` accepts wild cards where `*` is any number of characters (including zero) and `?` is exactly one character. Here, we search for something like `*n?i?c?e*` except the number of question marks varies with the results of the `REPT()` function. For a four letter word, we will search for all of these combinations: `*nice*`, `*n?i?c?e*`, `*n??i??c??e*`, and `*n???i???c???e*`.
* `MAX(LET(~,COUNTIF(~)))` returns the max value of all those `COUNTIF()` checks. Since we only ever check one cell in any one of those, the max value will be `1` even if it appears multiple times such as in `nicenice` or `nicenoiocoe`.

# Answer
> 4 votes
# TypeScript Types, 313 bytes

```
//@ts-ignore
type a<S,T>=T extends[infer C,...infer T]?S extends`${0 extends C?string:C}${infer S}`?a<S,T>:0:1;type b<S,T>=a<S,T>|(S extends`${string}${infer S}`?b<S,T>:never);type c<S,T=S,N=[],>=b<S,["n",...N,"i",...N,"c",...N,"e"]>|(T extends`${string}${infer T}`?c<S,T,[...N,0]>:0);type M<S>=1 extends c<S>?1:0

```

Try it online!

# Answer
> 4 votes
# Python 3, 79 bytes:

```
import re
lambda s:any(re.findall(('.'*i).join('nice'),s)for i in range(len(s)))

```

Try it online!

# Answer
> 4 votes
# Charcoal, ~~25~~ 16 bytes

```
⊙θ⊙θ№✂θκＬθ⊕μnice

```

Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. `-` if nice, nothing if not. Explanation:

```
 θ                  Input string
⊙                   Any index satisfies
   θ                Input string
  ⊙                 Any index satisfies
      θ             Input string
     ✂              Sliced in steps of
           μ        Inner index
          ⊕         Incremented
       κ            From outer index
        Ｌθ          To the end of the string
    №               Count i.e. contains substring
            nice    Literal string `nice`

```

# Answer
> 4 votes
# Rust (1.53+), 118 111 bytes

```
|mut s:&str|loop{(1..s.len()).any(|j|s.bytes().step_by(j).take(4).eq(*b"nice"))|(s=="")&&break ""!=s;s=&s[1..]}

```

Try it online!

This only works on Rust 1.53 and newer as older Rust versions did not implement `IntoIterator` for arrays, but only for array references, so the `eq` comparison would end up trying to compare `u8` with `&u8` which would not work without doing something like `b"nice".iter().copied()`, a good 15 extra characters.

* -7 bytes by replacing the outer range with `loop` (thanks @AnttiP)

# Answer
> 4 votes
# PowerShell, 57 bytes

Developed on my own, then discovered as I checked the other solutions before posting that Neil beat me to this method with their excellent Retina Answer; so credit where credit is due.

Outputs False for Nice, and True for Naughty.

```
!($args-match'n(.)*i(?<2-1>.)*(?(1)$)c(?<-2>.)*(?(2)$)e')

```

Try it online!

# Answer
> 3 votes
# Pari/GP, 71 bytes

```
s->sum(i=1,#s,sum(j=1,(#s-i)\3,[Vec(s)[i+j*k]|k<-[0..3]]==Vec("nice")))

```

Try it online!

Outputs the number of "nice" patterns, truthy when this number is nonzero.

# Answer
> 3 votes
# Java 8, 94 bytes

```
s->{int i=s.length();for(;!s.matches(".*n.{"+i+"}i.{"+i+"}c.{"+i+"}e.*")&&i-->0;);return i<0;}

```

Outputs `false` for truthy results and `true` for falsey results.

Try it online.

**Explanation:**

```
s->{                // Method with String parameter and boolean return-type
  int i=s.length(); //  Start `i` at the length of the input-String
  for(;             //  Continue looping as long as:
      !s.matches(".*n.{"+i+"}i.{"+i+"}c.{"+i+"}e.*")
                    //   We haven't found "nice" yet (with `i` delimited chars)
      &&i-->0;);    //   And `i` hasn't reached 0 yet
                    //   (Decreasing `i` by 1 after every check with `i--`)
  return i<0;}      //  After the loop: return whether `i` is -1

```

Java's String#matches checks the entire String with implicit leading `^` and trailing `$`, hence the need for the leading/trailing `.*` in the regex-check.

# Answer
> 3 votes
# Zsh, 37 bytes

```
repeat $#1 {<*~*n$2i$2c$2e*;2+=?;}>$1
```

Attempt This Online!

Outputs via exit code: `0` for naughty, `1` for nice. Requires options `extendedglob errexit globsubst`.

Explanation:

* `>$1`: create a file named {input}
* `repeat $#1`: do {length of input} times:

+ `<*~`: search for a file *not* matching:
        - `*n$2i$2c$2e*`: construct a pattern using the variable `$2`
            * over the course of the loop, this makes `*nice*` `*n?i?c?e*` `*n??i??c??e*` etc.
            * `*` matches anything; `?` matches any single character. These patterns match all possible "nice" strings
    + `errexit`: if there was no non-matching file (i.e., `*n$2i$2c$2e*` *did* match), then exit the program with code `1`
    + append `?` to the variable `$2` (which starts out empty) to construct the new level of pattern
* I used a numbered variable `$2` rather than a named variable because it can be placed directly adjacent to a letter (like `$2i`)
* `globsubst` is needed so that `$2` can be treated as a pattern, not a literal string
* `extendedglob` is needed to enable the `~` pattern negation syntax

Combining `errexit` with pattern negation basically does a De Morgan's Law transformation on the whole program, matching *any* of the constructed patterns.

# Answer
> 3 votes
# Ruby, ~~56 ...~~ 51 bytes

```
->s{(0..s.sum).any?{|x|s[/#{%w(n i c e)*(?.*x)}/]}}

```

Try it online!

# Answer
> 2 votes
# Factor \+ `math.unicode`, <sup>~~75~~</sup> 74 bytes

```
[ all-subseqs [ dup length 4 / ⌈ group flip first "nice">array = ] ∃ ]

```

Try it online!

```
all-subseqs [ ... ] ∃      ! Is there any subsequence in the input that...
dup length 4 / ⌈ group     ! ...when divided into quarters, with last quarter cut off...
flip first "nice">array =  ! ...the first column of these parts is equal to "nice"?

```

# Answer
> 2 votes
# PHP, 80 bytes

```
for($i=-1;$argn[++$i];)preg_match("~n.{{$i}}i.{{$i}}c.{{$i}}e~",$argn)?die(A):0;

```

Try it online!

Port of Arnauld's answer, terminates with a truthy `A` if nice, or a falsy empty string if naughty.

Note: one of the input lines has to be a falsy one if you want to see the test cases, as the program terminates if truthy (for the same reason the `die` in the test cases is changed to a `print`)

# Answer
> 1 votes
# , 78 bytes

Or **\>=4.1, 71 bytes** by replacing the word `function` with `\`.

```
function(s){for(i in 0:nchar(s))F=F|grepl(gsub("x",i,"n.{x}i.{x}c.{x}e"),s);F}

```

Try it online!

# Answer
> 1 votes
# ayr, 29 bytes

Thanks to this great answer for the method! I've never been very good at algorithms, so this was a great help.

```
v./'nice'E.&:,]#\:#$@1"i:&~&#

```

Try it!

Glad I saw this challenge, I have only just implemented `E.`, nice to see it's already coming in handy!

# Explained

`i:&~&#` List of identity matrices of increasing size, up to the length of the string

`#$@1"` For each of these matrices, extend it to match the size of the string

`]#\:` Then filter the string using each row of the identity matrices as a boolean mask.

`'nice'E.&:,` Flatten this to a single string, find matches of the string `nice`

`v./` Or reduce. Is there a match?

# Answer
> 1 votes
# PowerShell, 53 bytes

```
!(($t=$args)|?{$i++;"$t"-match"n.{$i}i.{$i}c.{$i}e"})

```

Try it online!

---

and 57 bytes alternatives:

```
!(($t=$args)|?{"$t"-match('nice'-replace'\B',($s+='.'))})

```

Try it online!

```
!(($t=$args)|?{"$t"-match((echo n i c e)-join($s+='.'))})

```

Try it online!

see also Zaelin Goodman's answer.

# Answer
> 1 votes
# Julia 1.0, 65 bytes

```
!x=any(i->x>replace(x,Regex(join("nice",".{$i}"))=>1),keys(x).-1)

```

Try it online!

# Answer
> 1 votes
# SnakeEx, 30 bytes

```
m:n{s<>}i{s<>}c{s<>}e
s{P0}:.*

```

Matches (at least once) for truthy; doesn't match for falsey.

Try it here! No permalinks, so you'll need to enter the input and code yourself. (FYI: Newlines in the text boxes display correctly in Chrome but not in Firefox.) You can run all of the test cases at the same time; the program will find one match for each truthy case.

### Explanation

```
s{P0}:.*
s    :    Define snake s as
      .*  Match any run of 0 or more characters
 {  }     With these parameters:
  P        After matching, move the location pointer to the end of the match
   0       All matches of s are in group 0, meaning they must have the same length

m:n{s<>}i{s<>}c{s<>}e
m:                     Define main snake m as
                       Start out moving rightward (implicit)
  n                    Match "n"
   {s  }               Match snake s
     <>                in the same direction (rightward)
        i{s<>}         Match "i" followed by snake s again
              c{s<>}   Match "c" followed by snake s again
                    e  Match "e"

```

# Answer
> 0 votes
# BQN, 44 bytes

```
{∨´("nice"≡/⟜)¨∾{(↕l)⌽¨<l↑∾4⥊<↑1}¨1+↕l←≠}

```

Try it!

Not sure if J can be ported here, but I'm sure there's much scope for golfing.

# Answer
> 0 votes
# Wolfram Language (Mathematica), 68 bytes

```
Array[c=Characters@#;""<>c[[Span@##]]==="nice"&,0{,,}+Tr[1^c],1,Or]&

```

Try it online!

# Answer
> 0 votes
# Haskell + hgl, 44 bytes

```
ay(Uc mp<bm(lt2<l<nb<δ)(eq"nice")<uz)<ss<eu

```

### Explanation

Here we are looking for the subsequence "nice" where all the elements are evenly spaced. So the first things we do to the input are, pair it with it's indexes and get all possible subsequences.

```
ss<eu

```

Now that we have these we want to check if any meet the criteria. So we use `ay` for any.

```
ay ... <ss<eu

```

Now we want to check two separate things here. One is that the values are equal to `nice` and the second is that the indexes are evenly spaced. So it would be nice to unzip the two parts e.g. `[(0,'n'),(3,'i'),(4,'c'),(9,'e')] -> ([0,3,4,5],"nice")`.

```
ay(...<uz)<ss<eu

```

Now lets formulate our two tests. One is very easy:

```
eq"nice"

```

So now we want to determine if the indices are evenly spaced. We use `δ` to determine the distances, then to check if the list only contains one value we do `lt2<l<nb`, that is we nub the list and check the length is less than 2.

```
lt2<l<nb<δ

```

Now we use `bm` to map the two functions across our tuple:

```
ay(...<bm(lt2<l<nb<δ)(eq"nice")<uz)<ss<eu

```

Lastly we convert this tuples booleans to a single boolean with `Uc mp`, which is and (`mp`) uncurried (`Uc`).

```
ay(Uc mp<bm(lt2<l<nb<δ)(eq"nice")<uz)<ss<eu

```

## Reflection

With that I'd like to reflect a bit on ways we might improve hgl in light of this. It doesn't score very well here, 44 bytes is pretty long. There are a couple of things that could be improved.

* `lt2<l<nb` is really long to determine if a list is unique. This should probably be 1 function.
* Although it wouldn't help with the size here there probably should be some way to get subsequences of a particular size. We almost had to get all the subsequences and then filter by size. It also would make this much faster.

# Haskell + hgl, 47 bytes

*Here's it solved with the parsing library*

```
pP$lF bn_(h'*>ʃn*>l<h')$is(rM hd)$p<ʃ<p<"ice"

```

This is a good deal faster than the previous solution since it doesn't calculate every single subsequence.

## Explanation

Let's start with the string we are looking for:

```
"nice"

```

Now we want to parse these letters with things in between them. It would be nice to use an `is` which intersperses elements in a list. So lets turn these into parsers:

```
χ<"nice"

```

This creates a list of parsers each which parses a single letter. Now we want to intersperse it with something that parsers that all parse the same amount of characters. `hd` parses a single character so `rM hd` takes a number and parses exactly that many of the character.

However this is a function, not a parser so we can't intersperse it with our parsers. We could try to supply the argument first and then intersperse but it's easier to just make our char parsers into functions. They take a single argument, a number, and just ignore it. To do this we just map `p`, (short for `const`) across the list.

```
p<χ<"nice"

```

However we can't intersperse yet. Unfortunately the parsers for `rM hd` return a string while our other parsers return a character. Even though we don't care about the results we can't put them in a list together. So we have to change one of them. It's fairly easy to just make our char parsers into string parsers:

```
p<ʃ<p<"nice"

```

`p` turns the char into a string, `ʃ` turns the string into a parser `p` turns the parser into a parser function. Now we can intersperse:

```
is(rM hd)$p<ʃ<p<"nice"

```

At this point we have a list of functions to parsers. We would like to supply all these parsers with the same argument since the gaps need to be the same sizes.

There are a couple of ways to do this. The first way that springs to mind is to use a traverse. `sQ` will pull all the arguments outside and it's super cheap. But it gets a little messy instead we can use a fold.

`bn_` is a sort of chaining operator like `>>=`.

```
bn_ :: Monad m => m a -> (a -> m b) -> m a

```

We can use a fold across the list to then chain everything together.

```
lF bn_ :: (Foldable t, Monad m) => m a -> t (a -> m b) -> m a

```

So if we apply this to what we have:

```
ghci> :t F(lF bn_)$is(rM hd)$p<ʃ<p<"nice"
F(lF bn_)$is(rM hd)$p<ʃ<p<"nice"
  :: (Integral i, Ord i) =>
     Parser (List Prelude.Char) i -> Parser (List Prelude.Char) i

```

This takes a parser which produces the initial integer and gives us back the parser we want.

Now the question is "How do we figure out which integer?" We could try and have it do something like, guess every size less than the list to see, but the best way seems to be to break the `n` off of nice and get the number just as the size of the first gap after the `n`.

To parse an `n` we can do:

```
ʃn

```

Then after it we want a known number of characters. `h'` will parse any number of characters. And `l<` will convert that into a length.

```
ʃn*>l<h'

```

And we also have to allow for arbitrary characters before the first `n`:

```
h'*>ʃn*>l<h'

```

So now we slot that in:

```
lF bn_(h'*>ʃn*>l<h')$is(rM hd)$p<ʃ<p<"ice"

```

And we have a full parser. To turn that parser into a function we use `pP`, which returns true whenever there is a parse even if it doesn't consume the entire string.

## Reflection

The parsers are very powerful but disappointingly parser based answers are usually a bit shy of the non-parser answer. Here it's 3 bytes, which is the cost to invoke a parser.

* It's probably going to be eventually necessary to add a regex processor. Sometimes we will beat regex, but it would really open up a lot of opportunities.
* I should probably make a parser evaluator that matches the parser anywhere in the input. Would save a `h'*>` here and probably in a few other places.
* `lMy` could have been useful here but `l<h'` was shorter than `lMy hd`. Not sure if this is actionable, even shortening `lMy` to one character would leave them tied. But it's of interest to note.

# Answer
> 0 votes
# Curry (PAKCS), 63 bytes

```
f(_++'n':x++'i':y++'c':z++'e':_)=g$map length[x,y,z]
g[x,x,x]=1

```

Try it online!

This returns `1` if the input string is nice, and nothing otherwise.

---
Tags: code-golf, string, decision-problem, subsequence
---


title: Mode length of a sentence

text:
# Question
Title: Mode length of a sentence
The task is simple. You are given a string with **alphabetical words** (say `"Hello world, this are tests"`). You have to return the **mode** of the lengths of words in the string. In this case, output is `5`, as it's the *most often length* of words in the string.

Definition of an alphabetical word (for this challenge): a string that consists of `a-zA-Z` only.

### Sample I/O:

**Constraints:** Input has *atleast* one word, and a *unique* mode. Max. length is provided in last test case. Also, the string would be a single line, no newline chars.

(`In = Out` format)

```
"Hello world, this are tests"                     =  5
"Hello    world, this... are tests"               =  5
"I"                                               =  1
"Let's box (ง︡'-'︠)ง"                               =  3
"Writing some ✍(◔◡◔) program"                   =  7
"the-the-the-then"                                =  3
"Gooooooooogle is an app"                         =  2
"()<>a+/sentence$#@(@with::many---_symbols{}|~~"  =  4
"anot_her test actually"                          =  4

```

The unicode tests are *optional*.

1000 words string = 5 (Password: `PXuCdMj5u65vwst`)

This is a , so fewest bytes will win!

# Answer
> 6 votes
# 05AB1E, ~~10~~ ~~9~~ 7 bytes

-1 byte inspired by Jonathan Allans Jelly answer.
-2 bytes thanks to Kevin Cruijssen!

Input is a list of characters.

```
aγO0K.M

```

Try it online!

### Commented:

```
aγO0K.M     implicit input       ["a","b"," ","c","d"," ","e","."]

a           is_alpha (vectorizes)[1, 1, 0, 0, 1, 1, 0, 1, 0]
 γ          split into chunks of equal elements
              [[1, 1], [0, 0], [1, 1], [0], [1], [0]]
  O         sum the lists        [2, 0, 2, 0, 1, 0]
   0K       remove 0's
     .M     mode                 2

            implicit output      2

```

`a` is implemented as `Regex.match?(~r/^[a-zA-Z]+$/, to_string(x))`, which should be equivalent to the challenge specification.

~~I feel like there has to be a shorter way to remove `0`s from a list than `ʒĀ}`.~~

# Answer
> 5 votes
# Ruby, 70 ~~68~~ 58 bytes

```
->s{(s=s.scan(/[a-z]+/i).map &:size).max_by{|y|s.count y}}

```

Try it online!

-20 bytes from Dingus.

-2 bytes from Rahul Verma.

-10 bytes from Dingus(again) by removing a variable.

# Ruby, 90 bytes

```
->a{a.split(/\W+/).map(&:size).inject(Hash.new(0)){|h,v|h[v]+=1;h}.sort_by{|k,v|v}[-1][0]}

```

Try it online!

# Answer
> 5 votes
# APL (Dyalog Unicode), 30 bytes

```
{⍵[⊃⍒+/∘.=⍨⍵]}≢¨⊆⍨⎕A∊⍨1(819⌶)⎕

```

Try it online!

```
{⍵[⊃⍒+/∘.=⍨⍵]}≢¨⊆⍨⎕A∊⍨1(819⌶)⎕ ⍝ Full program
1(819⌶)⎕ ⍝ Uppercase the input
⎕A∊⍨     ⍝ Test if each character is a capital letter
⊆⍨       ⍝ Group the letters together
≢¨       ⍝ Length of each word
{⍵[⊃⍒+/∘.=⍨⍵]} ⍝ Mode

```

The mode dfn is by ngn. My approach was similar but one byte longer: `{⊃⍵[⍒+/¨⍵⍷¨⊂⍵]}`.

# Answer
> 4 votes
# , ~~79~~ 67 bytes

*Edit: -9 and then -3 more bytes thanks to Giuseppe*

```
names(sort(-table(nchar(el(strsplit(scan(,''),"[^a-zA-Z]+"))))))[1]

```

Try it online!

Commented:

```
names(              # Get the names (=values) of...
  sort(-            # the descending (-) frequencies of...
    table(          # the table of values of...
     (w=nchar(      # the number of characters of...
       strsplit(scan(,''),
                    # the input, grouped by splitting on...
       "[^a-zA-Z0-9]")[[1]]))
                    # non-alphanumeric characters...
     [w>0]          # ignoring zero-length groups.
    )
  )
)[1]                # Output the first name, which is
                    # the most-frequent number of characters
                    # per group.

```

# Answer
> 3 votes
# JavaScript (ES6), 66 bytes

```
s=>s.replace(o=/[a-z]+/gi,w=>o[s]>(o[n=w.length]=-~o[n])?0:s=n)&&s

```

Try it online!

# Answer
> 3 votes
# Jelly, 11 bytes

```
e€ØẠŒg§ḟ0Æṃ

```

A monadic Link accepting a list of characters which yields an integer.

**Try it online!** Or see the test-suite.

### How?

```
e€ØẠŒg§ḟ0Æṃ - Link: S
  ØẠ        - alphabetic characters
 €          - for each (c in S)
e           -   (c) exists in (S)?
    Œg      - group runs of equal elements (1s or 0s)
      §     - sums
        0   - zero
       ḟ    - filter discard
         Æṃ - mode

```

# Answer
> 3 votes
# Retina 0.8.2, 43 bytes

```
M!i`[a-z]+
%M`.
O#`
O#^$`(.+)(¶\1)*
$#2
1G`

```

Try it online! Link includes test cases. Explanation:

```
M!i`[a-z]+

```

List only the words.

```
%M`.

```

Take the length of each word.

```
O#`

```

Sort the lengths numerically.

```
O#^$`(.+)(¶\1)*
$#2

```

Sort in reverse order of frequency.

```
1G`

```

Take the mode.

# Answer
> 3 votes
# Perl 5 `-pF'[^A-Za-z]+'`, 51 bytes

```
map$k{y///c}++,@F;$_=(sort{$k{$b}-$k{$a}}keys%k)[0]

```

Try it online!

# Answer
> 3 votes
# MATL, 8 bytes

```
3Y4XXzXM

```

Supports ASCII characters only. Try it online! Or verify all ASCII test cases.

### How it works

```
3Y4   % Push predefined literal '[A-Za-z]+'
XX    % Implicit input. Regexp. Gives cell array of matched substrings
z     % Number of nonzero chars of each substring
XM    % Mode. Implicit display

```

# Answer
> 2 votes
# Python 3, ~~148~~ ~~143~~ ~~140~~ ~~132~~ ~~100~~ 99 bytes

```
n,*c=0,
for x in input()+'1':
 if'`'<x.lower()<'{':n+=1
 elif n:c+=n,;n=0
print(max(c,key=c.count))

```

Try it online!

Uses regex to check if character is a letter of the English alphabet and adds the count of all consecutive alphabets to a list and finds the mode of that list.

*-3 bytes thanks to Rahul Verma*

*-32 bytes thanks to ovs*

*-1 byte thanks to DLosc*

# Answer
> 2 votes
# Pip, 18 bytes

```
aMR:+XA#_(_NaSKav)

```

Try it online!

### Explanation

```
aMR:+XA#_(_NaSKav)
                    a is 1st cmdline arg; v is -1 (implicit)
aMR:                Map a function to each regex match in a and assign the result back to a
    +XA              Regex: a letter (XA) repeated one or more times (+)
       #_            The function: length of the match
                    Now we just need to get the mode:
             SKa    Sort a using this key function:
          _Na        Count of each element in the full list a
         (      v)  Since it's now sorted from least common to most, get the last element

```

If Pip had a two-byte builtin for getting the mode of a list, I could do this in 10 bytes: `MO#*Ya@+XA` (with `MO` being the mode builtin). Ah well.

# Answer
> 2 votes
# Husk, ~~12~~ 8 bytes

```
►=mLmf√w

```

Try it online!

Previous answer was badly optimized.(-4 bytes)

From Zgarb:

> ► has a second mode. If you give it a binary function f, it returns an element x that maximizes the number of elements y for which fxy holds.

> So ►= is a 2-byte max by frequency.

## Explanation

```
►=fImLmf√ġK√
         ġK√ group string on non alphabet-characters.
       f√    filter out non-alphabet characters
      m      map that to each word ↑
    mL       Length of each word
  fI         filter out zeroes (empty string length)
►=           max by frequency

```

# Answer
> 1 votes
# Scala, 66 bytes

```
"[a-zA-Z]+".r.findAllIn(_).toSeq.groupBy(_.size)maxBy(_._2.size)_1

```

Try it in Scastie

Unfortunately, finding the mode in Scala is a bit clumsy

# Answer
> 1 votes
# Io, 141 bytes

A really awful solution... just 2 bytes shorter than the Python one. 3

```
method(x,x asUppercase asList map(i,if(if(i at(0),i at(0),0)isLetter,1,0))join split("0")map(size)remove(0)uniqueCount map(reverse)max at(1))

```

Try it online!

# Answer
> 1 votes
# Java (JDK), 129 bytes

*Saved 10 bytes thanks to @ceilingcat!*

```
s->{int m=0,z=s.length()+1,a[]=new int[z];for(var x:s.split("[^a-zA-Z]+"))a[x.length()]++;for(;z-->0;m=a[z]>a[m]?z:m);return m;};

```

Try it online!

---

Explanation:

```
s -> {
  int m=0,             //m is the index of the max element in a
      z=s.length()+1,  //z is to avoid using a.length twice
      a[]=new int[z];  //Each index corresponds to a length, and the element at that index its frequency
  for(var x : s.split("[^a-zA-Z]+")) //Fill up the pigeonholes
    a[x.length()]++;
  for(;                 //Find the index of the max element/highest frequency/mode
      z-->0;            //For every index from a.length to 0,
      m=a[z]>a[m]?z:m); //If the current element is greater than the current max frequency, change the mode length
  return m;             //Return the length with the highest frequency
};

```

# Answer
> 1 votes
# Japt v2.0a0, 13 bytes

```
q\L f üÊñÊÌÌÊ

```

Try it

```
q\L f üÊñÊÌÌÊ     :Implicit input of string U    e.g., "()<>a+/sentence$#@(@with::many---_symbols{}|~~"
q                 :Split on
 \L               :  Regex /[^a-z]/i             ["","","","","a","","sentence","","","","","with","","many","","","","symbols","","","","",""]
    f             :Filter (remove empty strings) ["a","sentence","with","many","symbols"]
      ü           :Group & sort by
       Ê          :  Length                      [["a"],["with","many"],["symbols"],["sentence"]]
        ñ         :Sort by
         Ê        :  Length                      [["a"],["symbols"],["sentence"],["with","many"]]
          Ì       :Last element                  ["with","many"]
           Ì      :Last element                  "many"
            Ê     :Length                        4

```

# Answer
> 1 votes
# C (gcc), ~~115~~ ~~113~~ 112 bytes

-1 byte ceilingcat

```
m;n;w;c;l;i;f(char*s){for(m=n=l=0;s[l++];m=c>n?n=c,l:m)for(i=w=c=0;w=isalpha(s[i])?1+w:w-l?0:!++c,s[i++];);n=m;}

```

Try it online!

# Answer
> 1 votes
# Java (JDK), 113 bytes

```
s->{int m=0,l=s.length(),t,L=0;for(;l>0;L=t>m?(m=t)-m+l:L)t=s.split("\\b[a-zA-Z]{"+l--+"}\\b").length;return-~L;}

```

Try it online!

## Explanation

This basically splits the String on ascii words of all possible lengths to count them, and returns the max value of the count.

```
s->{
 int m=0,                                 // The maximum number of
     l=s.length(),                        // The length of ASCII letters, going from high to low
     t,                                   // Declare a temp variable.
     L=0;                                 // Initialize the most present length to 0.
 for(                                     // Loop
      ;
      l>0;                                // On each length, going down
      L=t>m?(m=t)-m+l:L                   // If a count is higher than the max count, the new count becomes the max count and the most present length becomes the current length
     )
  t=
      s.split("\\b[a-zA-Z]{"+l--+"}\\b")  // Count the number of parts between or around words of length l
                                          // Also, decrement l
       .length;                           // Store the count into t
 return-~L;                               // Return L + 1
}

```

# Answer
> 0 votes
# Python 3.8, ~~81~~ 75 bytes

*Thanks to Mukundan314 for 5 bytes and ovs for another 1 byte*

```
lambda S:max(L:=[*map(len,re.findall("[a-z]+",S,2))],key=L.count)
import re

```

Try it online!

Anonymous function: Finds all runs of letters using regex, collects a list of the lengths of those runs, and prints the item with the maximum frequency in the list.

# Answer
> 0 votes
# Wolfram Language (Mathematica), 48 bytes

```
Commonest@*StringLength@*StringCases[__?LetterQ]

```

Try it online! Function. Takes a string as input and returns a list of most common lengths as output. The list should only have a single number if the mode length is unique. It gives incorrect output on one of the Unicode examples, presumably due to  counting as a letter.

# Answer
> 0 votes
# PHP, 101 bytes

```
$a=array_count_values(array_map(strlen,preg_split('/[^A-Za-z]/',$argn,0,1)));arsort($a);echo key($a);

```

Try it online!

Drat PHP and it's super long function names again...

# Answer
> 0 votes
# Factor \+ `math.unicode`, 57 bytes

```
[ [ Letter? ¬ ] split-when harvest [ length ] map mode ]

```

Try it online!

Split on non-letters, harvest (remove) any vestigial empty strings, get the length of each word, and take the mode.

---
Tags: code-golf, string, statistics
---