title: Count Like a Babylonian

text:
# Question
Title: Count Like a Babylonian
## Challenge

Given an ASCII representation of a Babylonian number as input, output the number in Western Arabic numerals.

## Babylonian Numeral System

How did the Babylonians count? Interestingly, they used a Base 60 system with an element of a Base 10 system. Let's first consider the unit column of the system:

The Babylonians had only three symbols: `T` (or, if you can render it: ) which represented 1, and `<` (or, if you can render it: ) which represented 10, and `\` (or, if you render it: ) which represented zero.

**Note:** Technically, `\` (or ) isn't zero (because the Babylonians did not have a notion of 'zero'). 'Zero' was invented later, so `\` was a placeholder symbol added later to prevent ambiguity. However, for the purposes of this challenge, it's enough to consider `\` as zero

So, in each column you just add up the value of the symbols, e.g.:

```
<<< = 30
<<<<TTTTTT = 46
TTTTTTTTT = 9
\ = 0

```

There will never be more than five `<` or more than nine `T` in each column. `\` will always appear alone in the column.

Now, we need to extend this to adding more columns. This works exactly the same as any other base sixty, where you multiply the value of the rightmost column by \\$60^0\\$, the one to the left by \\$60^1\\$, the one to the left by \\$60^2\\$ and so on. You then add up the value of each to get the value of the number.

Columns will be separated by spaces to prevent ambiguity.

Some examples:

```
<< <TT = 20*60 + 12*1 = 1212
<<<TT \ TTTT = 32*60^2 + 0*60 + 4*1 = 115204

```

## Rules

* You are free to accept either ASCII input (`T<\`) or Unicode input ()
* The inputted number will always be under \\$10^7\\$
* The `<`s will always be to the left of the `T`s in each column
* `\` will always appear alone in a column

## Winning

Shortest code in bytes wins.

# Answer
# JavaScript (ES6), 44 bytes

Takes input as an array of ASCII characters.

```
a=>a.map(c=>k+=c<1?k*59:c<'?'?10:c<{},k=0)|k

```

Try it online!

### How?

The Babylonian Numeral System can be seen as a 4-instruction language working with a single register -- let's call it the accumulator.

Starting with \\$k=0\\$, each character \\$c\\$ in the input array \\$a\\$ modifies the accumulator \\$k\\$ as follows:

* `space`: multiply \\$k\\$ by \\$60\\$ (implemented as: add \\$59k\\$ to \\$k\\$)
* `<`: add \\$10\\$ to \\$k\\$
* `T`: increment \\$k\\$
* `\`: do nothing; this is the `NOP` instruction of this language (implemented as: add \\$0\\$ to \\$k\\$)
> 39 votes

# Answer
# C (gcc), ~~140~~ ~~138~~ 136 bytes

```
B,a,b,y;l(char*o){y=B=0,a=1;for(char*n=o;*n;n++,B++[o]=b,a*=60)for(b=0;*n&&*n-32;n++)b+=*n-84?*n-60?:10:1;for(B=a;B/=60;y+=*o++*B);B=y;}

```

Try it online!
> 12 votes

# Answer
# Perl 6, 39 bytes

*-3 bytes thanks to nwellnhof*

```
{:60[.words>>.&{sum .ords X%151 X%27}]}

```

Try it online!

Uses the cuneiform characters.

### Explanation:

```
{                                     }   # Anonymous code block
     .words  # Split input on spaces
           >>.&{                    }  # Convert each value to
                sum   # The sum of:
                    .ords # The codepoints
                          X%151 X%27   # Converted to 0,1 and 10 through modulo
 :60[                                ]  # Convert the list of values to base 60

```
> 11 votes

# Answer
# Jelly,  ~~13~~  12 bytes

```
ḲO%7C%13§ḅ60

```

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

**Try it online!**

### How?

```
ḲO%7C%13§ḅ60 - Link: list of characters   e.g. "<<<TT \ TTTT"
Ḳ            - split at spaces                 ["<<<TT", "\", "TTTT"]
 O           - cast to ordinals                [[60,60,60,84,84],[92],[84,84,84,84]]
  %7         - modulo by seven (vectorises)    [[4,4,4,0,0],[1],[0,0,0,0]]
    C        - compliment (1-X)                [[-3,-3,-3,1,1],[0],[1,1,1,1]]
     %13     - modulo by thirteen              [[10,10,10,1,1],[0],[1,1,1,1]]
        §    - sum each                        [32,0,4]
         ḅ60 - convert from base sixty         115204

```

---

Another 12: `ḲO⁽¡€%:5§ḅ60` (`⁽¡€` is `1013`, so this modulos `1013` by the `O`rdinal values getting `53`, `5`, and `1` for `<`, `T`, `\` respectively then performs integer division, `:` by `5` to get `10`, `1` and `0`)
> 11 votes

# Answer
# Python 2, ~~96~~ ~~93~~ ~~87~~ 85 bytes

```
lambda s:sum(60**i*sum(8740%ord(c)/4for c in v)for i,v in enumerate(s.split()[::-1]))

```

Try it online!

---

Saved:

* -1 byte, thanks to Mr. Xcoder
* -4 bytes, thanks to Poon Levi
* -2 bytes, thanks to Matthew Jensen
> 6 votes

# Answer
# 05AB1E, 13 bytes

```
8740|Ç%4/O60β

```

Try it online!

To make up for how lazy I've been with my Jelly answer, here is a submission in 05AB1E xD.
> 6 votes

# Answer
# Excel VBA, 121 bytes

Restricted to 32-Bit Office as `^` serves as the `LongLong` type literal in 64-Bit versions

Takes input from cell `A1` and outputs to the vbe immediate window.

```
a=Split([A1]):u=UBound(a):For i=0 To u:v=a(i):j=InStrRev(v,"<"):s=s+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))*60^(u-i):Next:?s

```

### Ungolfed and Commented

```
a=Split([A1])       '' Split input into array
u=UBound(a)         '' Get length of array
For i=0 To u        '' Iter from 0 to length
v=a(i)              '' Get i'th column of input
j=InStrRev(v,"<")   '' Get count of <'s in input
                    '' Multiply count of <'s by 10; check for any T's, if present
                    ''   add count of T's
t=t+(j*10-(InStr(1,v,"T")>0)*(Len(v)-j))
    *60^(u-i)       '' Multiply by base
Next                '' Loop
?s                  '' Output to the VBE immediate window

```
> 4 votes

# Answer
# Dyalog APL, ~~33~~ 30 bytes

```
{+/(⌊10*⍵-3)×60*+\2=⍵}'\ T<'⍳⌽

```

Try it online!

**Edit:** -3 bytes thanks to ngn

`'\ T<'⍳` replaces the characters with numbers (their position in the string constant), and  reverses the input so most significant 'digits' are last. This allows `+\2=` to keep a running count of the desired power of 60 (applied by `60*`) by counting the number of times a space (index 2 in the string constant) is encountered.

`⌊10*⍵-3` gives the desired power of ten for each character. The order of characters in the string constant and the -3 offset cause '\\' and space to go to negative numbers, resulting in fractions when those characters are raised to the power of 10, allowing them to be eliminated by .

All we have to do now is multiply the powers-of-10 digits by the powers-of-60 place values and sum the lot up with `+/`.
> 4 votes

# Answer
# Canvas, ~~20~~ ~~17~~ 16 bytes

```
Ｓ｛｛<≡Ａ×²T≡］∑］<ｃ┴

```

Try it here!

Explanation:

```
E{          ]     map over input split on spaces
  {       ]         map over the characters
   <≡A×               (x=="<") * 10
       ²T≡            x=="T"
           ∑        sum all of the results
             <c┴  and encode from base (codepoint of "<") to 10

```
> 3 votes

# Answer
# Python 2, 62 bytes

```
lambda s:reduce(lambda x,y:x+[10,0,59*x,1]["<\ ".find(y)],s,0)

```

Try it online!

This uses the technique from Arnauld's answer.
> 3 votes

# Answer
# APL(NARS ⎕io←0), 28 chars, 56 bytes

```
{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

```

some test with type check:

```
  q←{60⊥{+/⍵⍳⍨10⍴'\T'}¨⍵⊂⍨⍵≠' '}

  o←⎕fmt
  o q '<< <TT'
1212
~~~~
  o q '<<<TT \ TTTT'
115204
~~~~~~

```

Each type result is number.
> 3 votes

# Answer
# JavaScript (Node.js), ~~122~~ ~~114~~ ~~107~~ ~~106~~ 83 bytes

```
a=>a.split` `.map(b=>[...b].map(c=>x+=c<'T'?10:c<'U',x=0)&&x).reduce((a,b)=>a*60+b)

```

Try it online!

I'm a little obsessed with "functional-style" array operations, uses ASCII input, as far as I can tell, JS isn't very good at getting charcodes golfily

I'm keeping this for posterity's sake, but this is a naive/dumb solution, I suggest you check out Arnauld's answer which is far more interesting an implementation of the challenge
> 2 votes

# Answer
# Dyalog APL, ~~35~~ 32 bytes

```
f←{⍵+('<T\ '⍳⍺)⌷10,1,0,59×⍵}/∘⌽0∘,

```

Try it online!

31 in dzaima/APL
> 2 votes

# Answer
# Retina, ~~29~~ ~~26~~ 23 bytes

```
<
10*T
+`^(.*)¶
60*$1
T

```

Try it online! Uses newline separation, but link includes header to use spaces instead for convenience. Edit: Saved 3 bytes with help from @KevinCruijssen. Saved a further 3 bytes thanks to @FryAmTheEggman. Explanation:

```
<
10*T

```

Replace each `<` with 10 `T`s.

```
+`^(.*)¶
60*$1

```

Take the first line, multiply it by 60, and add the next line. Then repeat until there is only one line left.

```
T

```

Count the `T`s.

Faster 51-byte version:

```
%`^(<*)(T*).*
$.(10*$1$2
+`^(.+)¶(.+)
$.($1*60*_$2*

```

Try it online! Uses newline separation, but link includes header to use spaces instead for convenience. Explanation:

```
%`^(<*)(T*).*
$.(10*$1$2

```

Match each line individually, and count the number of `T`s and 10 times the number of `<`s. This converts each line into its base-60 "digit" value.

```
+`^(.+)¶(.+)
$.($1*60*_$2*

```

Base 60 conversion, running a line at a time. The computation is done in decimal for speed.
> 2 votes

# Answer
# Bash (with sed and dc), 50 bytes

```
sed 's/</A+/g
s/T/1+/g
s/ /60*/g
s/\\//g'|dc -ez?p

```

Takes space-delimited input from `stdin`, outputs to `stdout`

Try it online!

# Explanation

Uses sed to transform the input with a bunch of regular expression matches until, for example, the input `<<<TT \ TTTT` has been transformed to `A+A+A+1+1+60*60*1+1+1+1+`. Then this input is fed to dc with the explicit input execution command `?`, preceded by `z` (pushes the stack length (0) to the stack so that we have somewhere to ground the addition) and followed by `p` (print).
> 2 votes

# Answer
# , 34 30 bytes

```
60#.1#.^:2(10 1*'<T'=/])&>@cut

```

Try it online!
> 2 votes

# Answer
# Java 8, ~~64~~ 60 bytes

```
a->{int r=0;for(int c:a)r+=c<33?r*59:c<63?10:84/c;return r;}

```

-4 bytes thanks to *@ceilingcat*.

Try it online. **Explanation:**

```
a->{            // Method with character-array parameter and integer return-type
  int r=0;      //  Result-integer, starting at 0
  for(int c:a)  //  Loop over each character `c` of the input-array
    r+=         //   Increase the result by:
       c<33?    //    Is the current character `c` a space:
        r*59    //     Increase it by 59 times itself
       :c<63?   //    Else-if it's a '<':
        10      //     Increase it by 10
       :c<85?   //    Else (it's a 'T' or '\'):
        84/c;   //     Increase it by 84 integer-divided by `c`,
                //     (which is 1 for 'T' and 0 for '\')
  return r;}    //  Return the result

```
> 1 votes

# Answer
# Ruby, ~~50~~ 46 bytes

```
->a{x=0;a.bytes{|c|x+=[59*x,10,0,1][c%9%5]};x}

```

Try it online!

A basic port of Arnauld's answer improved by G B for -4 bytes.
> 1 votes

# Answer
# Noether, 55 bytes

```
I~sL(si/~c{"<"=}{k10+~k}c{"T"=}{!k}c{" "=}{k60*~k}!i)kP

```

Try it online!

Same approach as @Arnauld.
> 1 votes

# Answer
# Charcoal, 26 bytes

```
≔⁰θＦＳ«≡ι ≦×⁶⁰θ<≦⁺χθT≦⊕θ»Ｉθ

```

Try it online! Link is to verbose version of code. Explanation:

```
≔⁰θ

```

Clear the result.

```
ＦＳ«...»

```

Loop over the input characters. The  command is wrapped in a block to prevent it from finding a "default" block.

```
≡ι

```

Switch over the current character...

```
 ≦×⁶⁰θ

```

if it's a space then multiply the result by 60...

```
<≦⁺χθ

```

if it's a `<` then add 10 to the result...

```
T≦⊕θ

```

if it's a `T` then increment the result.

```
Ｉθ

```

Print the result.
> 1 votes

# Answer
# , ~~98~~ 81 bytes

```
(u=sapply(scan(,""),function(x,y=utf8ToInt(x))y%%3%*%(y%%6)))%*%60^(sum(u|1):1-1)

```

Try it online!

~~Ridiculously long due to string parsing.~~ Thanks Giusppe for shaving off 16 unnecessary bytes.

Define `y` the bytecode value of unicode input and `R = y("T<\") = y("")`

Observe that `R%%3 = 1,2,0` and `R%%6 = 1,5,0`... so `R%%3 * R%%6 = 1,10,0` !

The rest is easy: sum per column, then dot-product with decreasing powers of 60.
> 1 votes

# Answer
# C (gcc), 65 64 63 bytes

```
f(s,o)char*s;{for(o=0;*s;s++)o+=*s>32?(93^*s)/9:o*59;return o;}

```

Try it online!
> 1 votes

# Answer
# APL (Dyalog Extended), 18 bytesSBCS

Anonymous tacit prefix function.

```
60⊥10⊥¨≠'<T'∘⍧¨⍤⊆⊢

```

Try it online!

```
                  ⊢  the argument; "<<<TT \ TTTT"
       ≠             mask where different from space; [1,1,1,1,1,0,1,0,1,1,1,1]
                ⊆    enclose runs of 1; ["<<<TT","\","TTTT"]
               ⍤     on that
              ¨      for each one
             ⍧       Count the occurrences In it of the elements
            ∘        of the entire list
        '<T'         ["<","T"]; [[3,2],[0,0],[0,4]]
      ¨              for each one
   10⊥               evaluate as base-10 digits
60⊥                  evaluate as base-60 digits

```
> 1 votes

# Answer
# Perl -F// -E, 39 bytes

```
$w+=/</?10:/T/?1:/ /?59*$w:0for@F;say$w

```

This reads the to be converted number from STDIN.

This is essential the same solution as given by @Arnauld using JavaScript.
> 0 votes

# Answer
## F#, 128 bytes

```
let s(v:string)=Seq.mapFoldBack(fun r i->i*Seq.sumBy(fun c->match c with|'<'->10|'T'->1|_->0)r,i*60)(v.Split ' ')1|>fst|>Seq.sum

```

Try it online!

Ungolfed it would look like this:

```
let s (v:string) =
    Seq.mapFoldBack(fun r i ->
        i * Seq.sumBy(fun c ->
            match c with
                | '<' -> 10
                | 'T' ->1
                | _ -> 0
        ) r,
        i * 60) (v.Split ' ') 1
    |> fst
    |> Seq.sum

```

`Seq.mapFoldBack` combines `Seq.map` and `Seq.foldBack`. `Seq.mapFoldBack` iterates through the sequence backwards, and threads an accumulator value through the sequence (in this case, `i`).

For each element in the sequence, the Babylonian number is computed (by `Seq.sumBy`, which maps each character to a number and totals the result) and then multiplied by `i`. `i` is then multiplied by 60, and this value is then passed to the next item in the sequence. The initial state for the accumulator is 1.

For example, the order of calls and results in `Seq.mapFoldBack` for input `<<<TT \ TTTT` would be:

```
(TTTT, 1)     -> (4, 60)
(\, 60)       -> (0, 3600)
(<<<TT, 3600) -> (115200, 216000)

```

The function will return a tuple of `seq<int>, int`. The `fst` function returns the first item in that tuple, and `Seq.sum` does the actual summing.

### Why not use `Seq.mapi` or similar?

`Seq.mapi` maps each element in the sequence, and provides the index to the mapping function. From there you could do `60 ** index` (where `**` is the power operator in F#).

But `**` requires `floats`, not `ints`, which means that you need to either initialise or cast all the values in the function as `float`. The entire function will return a `float`, which (in my opinion) is a little messy.

Using `Seq.mapi` it can be done like this for **139 bytes**:

```
let f(v:string)=v.Split ' '|>Seq.rev|>Seq.mapi(fun i r->Seq.sumBy(fun c->match c with|'<'->10.0|'T'->1.0|_->0.0)r*(60.0**float i))|>Seq.sum

```
> 0 votes

# Answer
# Tcl, 134 bytes

```
proc B l {regsub {\\} $l 0 l
lmap c [lreverse $l] {incr s [expr 60**([incr i]-1)*([regexp -all < $c]*10+[regexp -all T $c])]}
expr $s}

```

Try it online!

In the reversed list, I loop incrementing the result in counting `<` and `T` (with `-all` regexp option) and incrementing a natural as power of 60.

Correct version (see comment)
> 0 votes

# Answer
# 05AB1E (legacy), 10 bytes

```
#Ç9%5BO60β

```

Try it online!

```
#               # split input on spaces
 Ç              # convert each character to its codepoint
  9%            # modulo 9 (maps  to 5,  to 1,  to 0)
    5B          # convert each to base 5 (5 becomes 10, 0 and 1 unchanged)
      O         # sum each column
       60β      # convert from base 60

```

---

## 05AB1E, 11 bytes

```
#Ç9%5B€O60β

```

Try it online!

Same algorithm, but in modern 05AB1E `O` doesn't work on lists of mixed ints and lists, so we need `€O` instead.
> 0 votes

---
Tags: code-golf, number, conversion
---


title: Sort with a neural network

text:
# Question
Title: Sort with a neural network
The previous neural net golfing challenges (this and that) inspired me to pose a new challenge:

## The challenge

Find the smallest feedforward neural network such that, given any 4-dimensional input vector \\$(a,b,c,d)\\$ with integer entries in \\$\[-10,10\]\\$, the network outputs \\$\textrm{sort}(a,b,c,d)\\$ with a coordinate-wise error strictly smaller than \\$0.5\\$.

## Admissibility

For this challenge, a feedforward neural network is defined as a composition of **layers**. A layer is a function \\$L\colon\mathbf{R}^n\to\mathbf{R}^m\\$ that is specified by a matrix \\$A\in\mathbf{R}^{m\times n}\\$ of **weights**, a vector \\$b\in\mathbf{R}^m\\$ of **biases**, and an **activation function** \\$f\colon\mathbf{R}\to\mathbf{R}\\$ that is applied coordinate-wise:

$$ L(x) := f(Ax+b), \qquad x\in\mathbf{R}^n. $$

Since activation functions can be tuned for any given task, we need to restrict the class of activation functions to keep this challenge interesting. The following activation functions are permitted:

* **Identity.** \\$f(t)=t\\$
* **ReLU.** \\$f(t)=\operatorname{max}(t,0)\\$
* **Softplus.** \\$f(t)=\ln(e^t+1)\\$
* **Hyperbolic tangent.** \\$f(t)=\tanh(t)\\$
* **Sigmoid.** \\$f(t)=\frac{e^t}{e^t+1}\\$

Overall, an admissible neural net takes the form \\$L\_k\circ L\_{k-1}\circ\cdots \circ L\_2\circ L\_1\\$ for some \\$k\\$, where each layer \\$L\_i\\$ is specified by weights \\$A\_i\\$, biases \\$b\_i\\$, and an activation function \\$f\_i\\$ from the above list. For example, the following neural net is admissible (while it doesn't satisfy the performance goal of this challenge, it may be a useful gadget):

$$\left\[\begin{array}{c}\min(a,b)\\\max(a,b)\end{array}\right\]=\left\[\begin{array}{rrrr}1&-1&-\frac{1}{2}&-\frac{1}{2}\\1&-1&\frac{1}{2}&\frac{1}{2}\end{array}\right\]\mathrm{ReLU}\left\[\begin{array}{rr}\frac{1}{2}&\frac{1}{2}\\\-\frac{1}{2}&-\frac{1}{2}\\1&-1\\\-1&1\end{array}\right\]\left\[\begin{array}{c}a\\b\end{array}\right\]$$

This example exhibits two layers. Both layers have zero bias. The first layer uses ReLU activation, while the second uses identity activation.

## Scoring

Your score is the total number of *nonzero* weights and biases.

(E.g., the above example has a score of 16 since the bias vectors are zero.)

# Answer
> 14 votes
# Octave, ~~96 88 87 84 76 54~~ 50 weights & biases

This 6-layer neural net is essentially a 3-step sorting network built from a very simple `min`/`max` network as a component. It is basically the example network from wikipedia as shown below, with a small modification: The first two comparisons are done in parallel. To bypass negative numbers though the ReLU, we just add 100 first, and then subtract 100 again at the end.

So this should just be considered as a baseline as it is a naive implementation. It does however sort all possible numbers that do not have a too large magnitude perfectly. (We can adjust the range by replacing 100 with another number.)

Try it online!

### max/min-component

There is a (~~considerably less elegant~~ way more elegant now, thanks @xnor!) way to find the minimum and maximum of two numbers using less parameters:

$$\begin{align} \min &= a - ReLU(a-b) \\ \max &= b + ReLU(a-b) \end{align}$$

This means we have to use a lot less weights and biases.

Thanks @Joel for pointing out that it is sufficient to make all numbers positive in the first step and reversing it in the last one, which makes -8 weights. Thanks @xnor for pointing out an even shorter max/min method which makes -22 weights! Thanks @DustinG.Mixon for the tip of combining certain matrices which result in another -4 weights!

```
function z = net(u)
a1 = [100;100;0;100;100;0];
A1 = [1 0 0 0;0 0 1 0;1 0 -1 0;0 1 0 0;0 0 0 1;0 1 0 -1];
B1 = [1 0 -1 0 0 0;0 0 0 1 0 -1;0 1 1 0 0 0;0 0 0 0 1 1];
A2 = [1 0 0 0;0 1 0 0;1 -1 0 0;0 0 1 0;0 0 0 1;0 0 1 -1];
A3 = [1 0 -1 0 0 0;0 1 1 0 0 0;0 0 0 1 0 -1;0 1 1 -1 0 1;0 0 0 0 1 1];
B3 = [1 0 0 0 0;0 1 0 -1 0;0 0 1 1 0;0 0 0 0 1];
b3 = -[100;100;100;100];
relu = @(x)x .* (x>0);
id = @(x)x;
v = relu(A1 * u + a1);
w = id(B1 * v) ;
x = relu(A2 * w);
y = relu(A3 * x);
z = id(B3 * y + b3);
% disp(nnz(a1)+nnz(A1)+nnz(B1)+nnz(A2)+nnz(A3)+nnz(B3)+nnz(b3)); %uncomment to count the total number of weights
end

```

Try it online!

---
Tags: code-challenge, optimization, neural-networks
---


title: Replace by most recent nonzero

text:
# Question
Title: Replace by most recent nonzero
Given a non-empty list of decimal digits (`0`, `1`, ..., `9`), replace each zero by the most recent nonzero, if possible.

**Example 1**: given

```
1 4 3 0 0 7 5 5 0 3

```

the output should be

```
1 4 3 3 3 7 5 5 5 3

```

Note how the first two zeros are replaced by `3`, which is the most recent (i.e. rightmost) nonzero. Similarly, the last zero is replaced by `5`.

**Example 2**: given

```
0 0 4 0 0 5 0

```

the output should be

```
0 0 4 4 4 5 5

```

Note how it is not possible to replace the first two zeros, because there isn't a nonzero number to the left ot them.

### Additional rules

### Test cases

Input, then output

```
1 4 3 0 0 7 5 5 0 3
1 4 3 3 3 7 5 5 5 3

0 0 4 0 0 5 0
0 0 4 4 4 5 5

0 0 0
0 0 0

0
0

0 1
0 1

4 2 1 0
4 2 1 1

8 0 0 0 6
8 8 8 8 6

```

# Answer
> 4 votes
# JavaScript (ES6),  ~~22~~  21 bytes

```
A=>A.map(x=>A=x||~~A)

```

Try it online!

### Commented

```
A =>          // A[] = input array
  A.map(x =>  // for each value x in A[]:
    A =       //   update A to:
      x ||    //     either x, if it's not equal to 0
      ~~A     //     or A coerced to an integer otherwise
  )           // end of map()

```

Because we're re-using the input array \\$A\[\\:\]\\$ to store the last non-zero value, two special cases arise if the 2nd part of the condition is executed on the 1st iteration:

* if \\$A\[\\:\]\\$ is a singleton array containing \\$0\\$, `~~A` is equal to `~~0`
* if \\$A\[\\:\]\\$ is an array of several elements (starting with \\$0\\$), `~~A` is equal to `~~NaN`

which gives the expected \\$0\\$ in both cases.

# Answer
> 3 votes
## Mathematica, ~~19~~ 17 bytes

```
f@x_:=f@0=x;Map@f

```

Try it online!

Inspired by kglr's answer to a question on Mathematica Stack Exchange, which I assume was the inspiration for this challenge. :)

In the body of `f`, the value of `f[0]` is redefined to be the input, which is also returned. That way, whenever `f` is called with `0` after the first time it's called, it will always yield the "remembered" result, which is updated when `f` is called again with a nonzero argument.

Thanks to @attinat for 2 bytes.

mikado's answer yields a 20 byte solution:

```
FoldList[#2/. 0->#&]

```

# Answer
> 2 votes
# Perl 5 `-p`, 21 bytes

```
s/([^0])0/$1$1/&&redo

```

Try it online!

# Answer
> 1 votes
# Jelly, 3 bytes

```
ȯ@\

```

Try it online!

-2 bytes thanks to FryAmTheEggMan (it's close to being an entirely new solution because 5 -\> 3 bytes is a 40% deduction and that's like half the code lol)

# Explanation

```
ȯ@\  Main Program
  \  Cumulative Reduce
ȯ@   Logical OR (inverted; basically "right OR left")

```

# Answer
> 1 votes
# K (ngn/k), 11 bytes

```
{$[y;y;x]}\

```

Try it online!

`{` `}\` scan - starting with the first element, apply the function in `{` `}` between the current result and the next element. collect intermediate results in a list.

`$[y;y;x]` cond - if the right argument `y` is truthy (not 0), return it, otherwise return the left argument `x`

# Answer
> 1 votes
# 05AB1E, 5 bytes

```
ηε0†θ

```

Try it online!

For each prefix of the input, filter 0s to the front, then get its last digit. Yes, filter-to-the-front is somehow a single-byte built-in (). I didn't think I'd ever need it, but here we are.

# Answer
> 1 votes
# Java 10, 65 bytes

```
s->{while(!s.equals(s=s.replaceAll("(.) 0","$1 $1")));return s;};

```

A Function that repeatedly replaces "N 0" with "N N" until such time as the String stops changing, then returns it.

---
Tags: code-golf, string, number, array
---


title: Weight of the Least Weighted RoD Path

text:
# Question
Title: Weight of the Least Weighted RoD Path
Let `A` be an `m` by `n` rectangular matrix of **positive** integers, where `m` and `n` are also **positive** integers.

We are interested in RoD ('Right-or-Down') paths from the upper-left cell of `A` to the lower right cell; in an RoD path, each successive cell of the path is either one cell to the Right of or one cell Down from the previous cell.

Given any such RoD path, we can take the sum of the cells in `A` in that path.

For example, consider the 4 by 3 matrix:

```
[ [1, 2, 3, 4],
  [5, 1, 6, 7],
  [8, 2, 1, 1] ]

```

Then we can consider the RoD path:

```
1 > 2   3   4
    v
5   1   6   7
    v
8   2 > 1 > 1

```

which has a sum of `1+2+1+2+1+1=8`. It's worth noting that this path has the smallest sum of all possible RoD paths from upper left to lower right in that matrix.

So, the proposed challenge is to provide the shortest function/program in your language of choice that outputs the minimum sum an RoD path from upper left to lower right can have in a given matrix `A`.

The usual forbidden loopholes are in effect. Your input can be in any reasonable format; your output must be an integer.

This is code-golf; answers are scored by number of bytes.

## Test Cases

```
[ [5] ] -> 5

[ [5, 2] ] -> 7

[ [5],
  [2] ] -> 7

[ [ 9 , 1 , 12, 3 ],
  [ 12, 11, 6 , 11],
  [ 12, 9 , 2 , 11] ] -> 40

[ [ 6 , 8 , 11, 2 ],
  [ 3 , 6 , 7 , 6 ],
  [ 6 , 2 , 8 , 12] ] -> 37

[ [ 4 , 5 , 8 , 4 ],
  [ 6 , 5 , 9 , 4 ],
  [ 2 , 5 , 6 , 8 ] ] -> 31

[ [ 4 , 5 , 15, 18, 30],
  [ 26, 26, 3 , 4 , 5 ],
  [ 7 , 9 , 29, 25, 14],
  [ 16, 1 , 27, 13, 27],
  [ 23, 11, 25, 24, 12],
  [ 17, 23, 7 , 14, 5 ] ] -> 94

[ [ 10, 15, 7 , 2 , 9 ],
  [ 24, 5 , 2 , 1 , 25],
  [ 2 , 12, 14, 30, 18],
  [ 28, 4 , 12, 22, 14],
  [ 15, 21, 21, 11, 4 ],
  [ 21, 15, 21, 29, 9 ] ] -> 103

```

# Answer
# , 42 bytes

```
v(+}.<.}:)&.>/@{.[:</.(2#v=._1+1#.$){.!._]

```

Try it online!

### How it works

```
v(+}.<.}:)&.>/@{.[:</.(2#v=._1+1#.$){.!._]
                         v=._1+1#.$         Sum of two dimensions - 1; assign to v
                                            (v is a verb)
                      (2#          ){.!._]  Extend the given array in both dimensions
                 [:</.  Extract the antidiagonals as boxed arrays
v             @{.  Take the first `v` antidiagonals
 (       )&.>/     Reduce over unboxed items:
   }.<.}:            Given the right item R, take the minimum of R[1:] and R[:-1]
  +                  Add to the left item

```

### Illustration

```
1 2 3 4  Input array, dimensions = 3,4
5 1 6 7
8 2 1 1

1 2 3 4 _ _  Extended to 6,6 with filler _ (infinity)
5 1 6 7 _ _
8 2 1 1 _ _
_ _ _ _ _ _
_ _ _ _ _ _
_ _ _ _ _ _

1            Diagonalize and take first 6 rows
5 2
8 1 3
_ 2 6 4
_ _ 1 7 _
_ _ _ 1 _ _

Reduction: left+min(right[1:], right[:-1])
1                                          1  => 8
5 2                               5  2  => 10 7
8 1 3                   8 1 3  => 12 5 11
_ 2 6 4      _ 2 6 4 => _ 4 8 12
_ _ 1 7 _ => _ _ 2 8 _
_ _ _ 1 _ _

```
> 15 votes

# Answer
# JavaScript (ES6), ~~78~~ ~~77~~ 76 bytes

```
m=>(M=g=s=>(v=(m[y]||0)[x])?g(s+=v,y++)|g(s,x++,y--)*x--|M<s?M:M=s:0)(x=y=0)

```

Try it online!

### Commented

```
m => (                      // m[] = input matrix
  M =                       // initialize the minimum M to a non-numeric value
  g = s =>                  // g = recursive function taking the current sum s
    (v = (m[y] || 0)[x]) ?  //   if the current cell v is defined:
      g(s += v, y++) |      //     do a recursive call at (x, y + 1)
      g(s, x++, y--) * x--  //     do a recursive call at (x + 1, y)
      |                     //     if at least one call did not return 0 (which means
                            //     that we haven't reached the bottom-right corner)
      M < s ?               //     or M is less than s (false if M is still non-numeric):
        M                   //       return M unchanged
      :                     //     else:
        M = s               //       update M to s, and return this new value
    :                       //   else (we're outside the bounds of the matrix):
      0                     //     return 0
)(x = y = 0)                // initial call to g with s = x = y = 0

```
> 7 votes

# Answer
## Haskell, ~~63~~ 57 bytes

```
f x@((a:_:_):c:d)=a+min(f$c:d)(f$tail<$>x)
f x=sum$id=<<x

```

Try it online!

```
f x@((a:_:_):c:d)=           -- if it's at least a 2x2 matrix
   a+min                     -- add the top left element to the minimum of the
                             -- path costs of
        f$c:d                --   the matrix with the first row dropped and
        f$tail<$>x           --   the matrix with the first column dropped
f x=                         -- else, i.e. a 1xm or nx1 matrix, i.e. a vector
    sum$id=<<x               -- return the sum of this vector

```
> 5 votes

# Answer
# MATL, ~~38~~ ~~36~~ ~~30~~ 29 bytes

*Thanks to @Giuseppe for pointing out a mistake, now corrected.*

```
lyZyqsG&nghZ^Yc!tsGz=Z)Ys)sX<

```

Try it online! Or verify all test cases.

### Explanation

```
l        % Push 1
y        % Input, implicit. Duplicate from below. Pushes the input below
         % the current 1, and a copy of the input on top
Zy       % Size of input. Gives [m, n]
qs       % Subtract 1 element-wise, sum. Gives m+n-2
G        % Push input again
&n       % Push size as two separate numbers. Gives m, n
gh       % Transform n into 1 and concatenate horizontally. Gives [m, 1]
Z^       % Cartesian power of [m, 1] raised to m+n-2. This produces the
         % Cartesian tuples as row of a matrix. A typical tuple may be
         % [1, m, 1, m, m]. This will define a path along the matrix in
         % linear, column-wise indexing (down, then across). So 1 means
         % move 1 step down, and m means move m steps "down", which is
         % actually 1 step to the right
Yc       % Concatenate strcat-like. This prepends the 1 that is at the
         % bottom of the stack to each row
!        % Transpose. Each tuple (extended with initial 1) is now a column
!ts      % Duplicate, sum of each column
Gz       % Number of nonzeros of input. Gives m*n-1
=Z)      % Keep only columns that sum m*n. That means that, starting from
Ys       % Cumulative sum of each column. This defines the path
)        % Index: pick entries specified by the path
s        % Sum of each column
X<       % Minimum
         % Display, implicit

```
> 4 votes

# Answer
# Röda, ~~100~~ 89 bytes

```
f A{g={|x,y|{g(x-1,y)if[x>0];g(x,y-1)if[y>0];[0]if[x+y=0]}|min|[A[x][y]+_]}g#A-1,#A[0]-1}

```

Try it online!

*-9 bytes thanks to Cows quack*
> 3 votes

# Answer
# , 90 bytes

```
function(m){l=sum(m|1)
if(l>1)for(i in 2:l)m[i]=m[i]+min(m[i-1],m[max(0,i-nrow(m))])
m[l]}

```

Try it online!

The naive solution: iterate through the array (down the columns), replacing each entry by the sum of itself and the minimum of its above and to-the-left neighbors, if they exist, then return the last entry.
> 3 votes

# Answer
# Perl 6, ~~57~~ 54 bytes

```
my&f={|.flat&&.[0;0]+min (f(.[1..*]),f $_>>[1..*])||0}

```

Try it online!

### Explanation

```
my&f={                                               }  # Function f
      |.flat&&  # Return empty slip if matrix is empty
              .[0;0]+  # Value at (0,0) plus
                     min  # Minimum of
                          f(.[1..*])   # Rows 1..*
                                     f $_>>[1..*]  # Columns 1..*
                         (          ,            )||0  # Or 0 if empty

```
> 3 votes

# Answer
# Python 3, 108 bytes

```
def f(A,m,n,i=0,j=0):r=i+1<m and f(A,m,n,i+1,j);d=j+1<n and f(A,m,n,i,j+1);return A[i][j]+min(r or d,d or r)

```

Try it online!

## Ungolfed

```
def f(A, m, n, i=0, j=0):
    right = i + 1 < m and f(A, m, n, i + 1, j)
    down  = j + 1 < n and f(A, m, n, i, j + 1)
    return A[i][j] + min(right or down, down or right)

```
> 2 votes

# Answer
# Jelly, 21 bytes

```
ZI_.ỊȦ
ŒJŒPÇƇLÐṀœị⁸§Ṃ

```

**Try it online!**

### How?

```
ZI_.ỊȦ - Link 1: isDownRight?: List of 2d indices (limited to having no repetitions)
Z      - transpose
 I     - deltas (vectorises)
  _.   - subtract 1/2 (vectorises)
    Ị  - insignificant? (effectively _.Ị here is like "v in {0,1}? 1 : 0")
     Ȧ - any & all (0 if a 0 is present when flattened, else 1)

ŒJŒPÇƇLÐṀœị⁸§Ṃ - Main Link: list of lists of integers, A
ŒJ             - multi-dimensional indices of A
  ŒP           - power-set
     Ƈ         - filter keep only those truthy by:
    Ç          -   last link as a monad
       ÐṀ      - filter keep only those maximal by:
      L        -   length
           ⁸   - chain's left argument, A
         œị    - multi-dimensional index into (vectorises)
            §  - sum each
             Ṃ - minimum

```
> 2 votes

# Answer
# APL (Dyalog Classic), ~~37~~ 32 bytes

```
{⊃⌽,9e9(⊢⌊⍵+(2⊣⌿⍪)⌊2⊣/,)⍣≡+⍀+\⍵}

```

Try it online!

`+⍀+\` partial sums horizontally and vertically - this provides an initial overestimate for the paths to each square

`9e9(`...`)⍣≡` apply "..." until convergence, at each step passing some very large number (9×109) as left argument

`,` add `9e9`-s to the left of the current estimate

`2⊣/` take the first from each pair of consecutive cells, effectively dropping the last column

`2⊣⌿⍪` same thing vertically - put `9e9` on top and drop last row

`(2⊣⌿⍪) ⌊ 2⊣/,` minima

`⍵+` add the original matrix

`⊢⌊` try to improve the current estimates with that

`⊃⌽,` bottom-right cell
> 2 votes

# Answer
# Charcoal, 46 bytes

```
≔Ｅ§θ⁰∧κΣ§θ⁰ηＦθ«≔§η⁰ζＦＬι«≔⁺⌊⟦§ηκζ⟧§ικζ§≔ηκζ»»Ｉζ

```

Try it online! Link is to verbose version of code. Explanation: This would probably be shorter if there was a three-argument `reduce` in Charcoal.

```
≔Ｅ§θ⁰∧κΣ§θ⁰η

```

Prefill the working array with large values except for the first which is zero.

```
Ｆθ«

```

Loop over the rows of the input.

```
≔§η⁰ζ

```

Initialise the current total with the first element of the working array.

```
ＦＬι«

```

Loop over the columns of the input.

```
≔⁺⌊⟦§ηκζ⟧§ικζ

```

Take the minimum of the current total and the current element of the working array and add the current element of the input to give the new current total.

```
§≔ηκζ

```

And store that back in the working array ready for the next row.

```
»»Ｉζ

```

Print the total once the input has been completely processed.
> 1 votes

# Answer
# Jelly, 17 bytes

```
XL,1ẋLḊŒ!1;ⱮÄịẎ§Ṃ

```

Try it online!
> 1 votes

# Answer
# Java 8, ~~197~~ ~~193~~ ~~190~~ 188 bytes

```
m->{int r=m.length-1,c=m[0].length-1,i=r;for(;i-->0;)m[i][c]+=m[i+1][c];for(i=c;i-->0;)m[r][i]+=m[r][i+1];for(i=r*c;i-->0;)m[i/c][r=i%c]+=Math.min(m[i/c+1][r],m[i/c][r+1]);return m[0][0];}

```

-9 bytes thanks to *@ceilingcat*.

Try it online.

**General explanation:**

I actually already did this challenge about a year ago with Project Euler #81, except that was limited to a square-matrix instead of an `N` by `M` matrix. So I slightly modified my code from back then to account for that.

I first sum the bottom row and rightmost column from the very last cell backwards. So let's use the example matrix of the challenge:

```
1, 2, 3, 4
5, 1, 6, 7
8, 2, 1, 1

```

The last cell remains the same. The second last cell of the bottom row becomes the sum: `1+1 = 2`, and the same for the second last cell of the rightmost column: `1+7 = 8`. We continue doing this, so now the matrix looks like this:

```
 1,  2,  3, 12
 5,  1,  6,  8
12,  4,  2,  1

```

After doing that, we look at all the remaining rows one by one from bottom to top and right to left (except for the last column/row), and we look for each cell at both the cell below it and right of it to see which one is smaller.

So the cell containing the number `6` becomes `8`, because the `2` below it is smaller than the `8` right of it. Then we look at the `1` next of it (to the left), and do the same. That `1` becomes `5`, because the `4` below it is smaller than the `8` right of it.

So after we're done with the second to last row, the matrix looks like this:

```
 1,  2,  3, 12
10,  5,  8,  8
12,  4,  2,  1

```

And we continue doing this for the entire matrix:

```
 8,  7, 11, 12
10,  5,  8,  8
12,  4,  2,  1

```

Now the very first cell will contain our result, which is `8` in this case.

**Code explanation:**

```
m->{                    // Method with integer-matrix input and integer return-type
  int r=m.length-1,     //  Amount of rows minus 1
      c=m[0].length-1,  //  Amount of columns minus 1
      i=r;              //  Index integer
  for(;i-->0;)m[i][c]+=m[i+1][c];
                        //  Calculate the suffix-sums for the rightmost column
  for(i=c;i-->0;)m[r][i]+=m[r][i+1];
                        //  Calculate the suffix-sums for the bottom row
  for(i=r*c;i-->0;)     //  Loop over the cells in reversed order:
    m[i/c][r=i%c]+=     //   Add to the value of the current cell:
      Math.min(         //    The minimum of:
        m[i/c+1][r],    //     The value in the cell below it
        m[i/c][r+1]);   //     And the value in the cell left of it
  return m[0][0];}      //  Return the value in the cell at index {0,0} as result

```
> 1 votes

# Answer
# Brachylog, ~~26~~ 25 bytes

```
∧≜.&{~g~g|hhX&{b|bᵐ}↰+↙X}

```

Try it online!

-1 byte because the cut isn't necessary--you can't take the head of an empty list

There's probably a lot of room to golf this but I need sleep.

The approach boils down to trying every value for the output, smallest first, (`∧≜.`) until a path can be found (`b|bᵐ`) to the bottom right corner (`~g~g`) which produces that sum (`hhX&...↰+↙X`).
> 1 votes

# Answer
# Java (JDK), 223 bytes

Takes input as a 2D List of ints.

Additional 19 bytes for `import java.util.*;` included.

```
import java.util.*;m->{var l=m.get(0);int s=m.size(),c=l.size(),x=-1>>>1,a=l.get(0);return s*c<2?a:Math.min(s>1?n.n(new Vector(m.subList(1,s))):x,c>1?n.n(new Vector<>(m){{replaceAll(l->new Vector(l.subList(1,c)));}}):x)+a;}

```

Try it online!

---

**How it works**

```
import java.util.*;                                     // Import needed for Vector class
m->{                                                    // Lambda that takes a 2D list of integers
    var r=m.get(0);                                     // Store first row in variable
    int h=m.size(),                                     // Store number of rows
        w=r.size(),                                     // Store number of columns
        x=-1>>>1,                                       // Store int max
        a=r.get(0);                                     // Store the current cell value
    return h*w<2?a:                                     // If matrix is single cell return value
        Math.min(                                       // Otherwise return the minimum of...

            h>1?                                        // If height is more than 1
                n.n(                                    // Recursively call this function with
                    new Vector(m.subList(1,h))):        // a new matrix, without the top row
                x,                                      // Otherwise use int max as there is no row below this

            w>1?                                        // If width is more than 1
                n.n(new Vector<>(m){{                   // Recursively call this function with a new matrix
                    replaceAll(                         // where all columns have been replaced with
                        l->new Vector(l.subList(1,w))   // cloned lists without the leftmost column
                    );
                }}):                                    // Otherwise use int max as there is
                x                                       // no column to the right of this
        )+a;                                            // Add the current cell value to the result before returning
}

```
> 0 votes

# Answer
# Python 2, 86 bytes

```
f=lambda A:len(A)>1<len(A[0])and A[0][0]+min(f(zip(*A)[1:]),f(A[1:]))or sum(sum(A,()))

```

Try it online!

If `B` is the transpose of `A`, then the problem definition implies that `f(A)==f(B)`.

`A[1:]` is the array `A` missing its top row. `zip(*A[1:])` is the array `A` missing its leftmost column and transposed. `sum(sum(A,()))` is the sum of all elements in `A`.

If `A` has only a single column or single row, there is only one path, so `f` returns the sum of all elements in `A`; otherwise we recurse and return the sum of `A[0][0]` \+ the smaller of `f` of `A` missing the top row and `f` of `A` missing the leftmost column.
> 0 votes

---
Tags: code-golf, path-finding
---


title: Is this a valid Tichu play?

text:
# Question
Title: Is this a valid Tichu play?
Tichu is a card game in which players take turn playing sets of cards from a deck consisting of a standard 52-card deck, plus 4 additional cards:

* the **dragon**, which has a greater value than any other card
* the **phoenix**, which can act as a wildcard
* the **dog**, which passes the turn to your partner
* the **Mah Jong**, which has value 1 (and the person holding it plays first)

The first player (who is said to have "lead") can choose to play one of the following types of card combinations:

* a **single** (e.g. `6`)
* a **pair** (`JJ`)
* a **triple** (`555`)
* a **full house** (`QQQ33`) - a triple and a pair
* a **straight** (`56789`) - 5 or more consecutive cards
* a **tractor** (`223344`) - any consecutive sequence of pairs

Subsequent players are then only allowed to play a set of cards of the same type, but strictly higher. For example, `QQ` can be played on top of `JJ`, but `QQKK` cannot (it is a tractor, not a pair). Full houses are ordered by the triple (e.g. `77722` \> `44499`), and straights and tractors must be the same length (`456789` cannot be played on top of `23456`). Aces are high.

There is one exception: any 4 of the same card is a **bomb**, and can be played on top of anything except a higher bomb.1

The dragon can be played by itself on top of any single or with lead (but nowhere else). The phoenix, aside from being a wildcard, can also be played on top of any single except the dragon.2 The dog can only be played by itself with lead and immediately ends the turn.3

---

Your challenge is to determine whether a given Tichu play is valid, given the previous play.

You may accept both plays in any order as either lists of integers or strings -- in either case, you may choose any mapping of cards to integers/characters. If there was a previous play, it will always be valid, and if not (i.e. the player has lead), the first input will be the empty array/string (matching the type of the other input). The cards are not guaranteed to be given in any particular order.

Your output must be selected from a set of exactly two distinct values, one of which indicates the play is legal and one that indicates it is not.

There is no need to test for whether the set of cards actually exists in the deck (e.g. `77766` followed by `88877` is impossible because there are only four 7's) -- such cases will never be given.

In the following test cases, `234567890JQKA` represent 2 through ace, and `RPD1` represent the dragon, phoenix, dog, and Mah Jong respectively. The empty string is shown here as `-`. These plays are legal:

```
6 J
JJ QQ
555 KKK
44499 77722
23456 56789
223344 QQKKAA
49494 72727
A R
A P
P R
66 7P
P6 77
58304967 6P0594J7
5P304967 680594J7
57446765 788657P5
- D
- 1
- 12345
3344556677889900 JJJJ
5555 7777

```

And these are not:

```
9 3
66 55
888 444
44 888
77722 44499
44499 777
44499 777JJJ
45678 34567
34567 456789
556677 334455
5566 778899
72727 49494
A A
R A
R P
77 RP
77 6P
P7 66
680594J7 5P304967
6P0594J7 58304967
57446765 3645P536
1 D
2 D
2 1
- 1234
7777 5555
- 223355

```

---

1: actually, a straight flush is also a bomb, but since this is the only place in the game that the suit of the cards matter, I have chosen to leave it out for simplicity's sake

2: the value of the phoenix played on top of a card with value *n* is actually *n+0.5* (a phoenix on a 9 is a 9 and a half); since this requires knowledge of additional history to adjudicate, no test cases involve a single played on top of a single phoenix

3: so the first input will never be dog

# Answer
> 5 votes
# JavaScript (ES6),  ~~274~~  273 bytes

Takes input as `(a)(b)`, where \\$a\\$ and \\$b\\$ are arrays of integers with:

* \\$1\\$ = dog
* \\$3\\$ = Mah Jong
* \\$4..16\\$ = 2 ... Ace
* \\$18\\$ = dragon
* \\$19\\$ = phoenix

Returns *false* for valid or *true* for invalid.

```
a=>b=>!(L='length',[A,B]=(g=a=>(h=n=>--n?[i=1,2,3,'(20*)3|30*2','1{5,}','22+',4].some(p=>m=o.join``.match(`9(0*)(${p})0*$`,i++),a.map(x=>o[x-19?x:x=n]=-~o[x],o=[...9e16+'']))?[i,m[1][L]+(m[3]||[])[L]]:h(n):[])(18))(a),[C,D]=g(b),a+a?A-C?C>7|+b>a:a[L]==b[L]&D>B|A<3&b==18:C)

```

Try it online!

### How?

To evaluate a hand, we build an array `o[]` made of a leading \\$9\\$, initially followed by 16 zeros:

```
//       D  -  1  2  3  4  5  6  7  8  9  T  J  Q  K  A
o = [ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];

```

For each card rank in the hand, the corresponding slot in `o[]` is incremented. Once joined back to a string, we can apply the following regular expressions to detect each type of hand:

```
 hand        | pattern     | full regex              | example
-------------+-------------+-------------------------+-------------------
 single      | 1           | /9(0*)(1)0*$/           | 90000100000000000
 pair        | 2           | /9(0*)(2)0*$/           | 90000002000000000
 3-of-a-kind | 3           | /9(0*)(3)0*$/           | 90003000000000000
 full house  | (20*)3|30*2 | /9(0*)((20*)3|30*2)0*$/ | 90020000030000000
 straight 5+ | 1{5,}       | /9(0*)(1{5,})0*$/       | 90000111110000000
 tractor     | 22+         | /9(0*)(22+)0*$/         | 90000000000022200
 bomb        | 4           | /9(0*)(4)0*$/           | 90000000000000004

```

If the hand does not trigger any of these regular expressions, it's invalid.

The value of the hand is given by the number of zeros just after the leading \\$9\\$ (the higher, the better). A special case is a full house where the rank of the triple is higher than that of the pair, in which case we need to add the length of the `(20*)` pattern.

The phoenix (i.e. the wildcard) is simply replaced with each possible card rank, starting with the highest one, until a match is detected.

# Answer
> 0 votes
# Python 3, ~~466~~ ~~455~~ ~~403~~ ~~401~~ 399 bytes

```
R=lambda H,n=3:n==len(H)*(len({*H})<2)and[15]!=H[1:]
s=lambda H:[H[2:],H[:1]][R(H[:3])]
def n(J,K):j,k=[[16in H,R(H,4),len(H)>4and all(15!=t>T-2for t,T in zip(H,H[1:])),[R(H[2:])*R(H[:2],2),R(H[3:],2)][R(H[:3])],R(H),R(H,2),R(H,1),1].index(1)for H in[J,K]];return k!=7and[17]==J or[j==k*[J<K,s(J)<s(K)][2<j<5],J<K][k==1]
f=lambda P:any(n(*[sorted([L,i][i>0]for i in H)for H in P])for L in range(16))

```

Try it online! Input is list of hands where hand is list of integers1 with the following value mapping:

* 0: Phoenix
* 1: Mah Jong
* 2-13: 2 to Ace
* 14: Dragon
* 15: Dog
* 16: Empty string

---

1: Although in the linked TIO tests are expressed with list of strings due to convenience which are translated according to value mapping before calling `f`

---
Tags: code-golf, decision-problem, card-games
---


# Question
Title: Decode a UTF-8 string to character byte counts
Given a UTF-8 string, give a string that represents byte counts of each characters.

**Rules:**

1. As long as the input string is encoded in UTF-8 **(without BOM)**, its type doesn't matter. In C++, it can be `char[]` or `std::string`. In Haskell, it can be `[Int8]` or `[CChar]`.
2. The output must be (in usual case) a string of ASCII digit characters. Its encoding doesn't matter.
3. When given an invalid UTF-8 sequence (including representation of surrogates), **every bytes** of the sequence are to be represented as the replacement character �.
4. Reserved characters and noncharacters are still considered as valid UTF-8 sequences, and thus must have corresponding output digit.
5. As this is a code-golf, the shortest code in bytes wins.

**Example:**

When given the following byte sequence:

```
00 80 C0 80 EB 80 80

```

The output must be:

```
1���3

```

# Answer
> 2 votes
# Python 3, 135 bytes

```
def f(b):
	B=b.decode(errors="ignore")[:1].encode();l=len(B)
	if B and b[:l]!=B:return"�"+f(b[1:])
	return str(l)+f(b[l:])if b else''

```

Try it online!

Explanation:

```
def f(b):
	B=b.decode(errors="ignore")[:1].encode();l=len(B)
	 # B is the UTF-8-encoded version of the first Unicode character in the given bytes
	 # (Or the Nth, if the first N-1 bytes were invalid Unicode bytes)
	if B and b[:l]!=B:return"�"+f(b[1:])
	 # If the two encoded byte-strings don't match,
	 # then the first byte in b is invalid,
	 # so append "�" to the returned string, and recurse
	return str(l)+f(b[l:])if b else''
	 # If the byte-string is not empty,
	 #  append the length of the first character and recurse.
	 # Else (the input is empty) return the empty string (recursion base case)

```

---
Tags: code-golf, string, unicode
---


title: Bytes/Character

text:
# Question
Title: Bytes/Character
### Task

Given a UTF-8 string (by any means) answer (by any means) an equivalent list where every element is the number of bytes used to encode the corresponding input character.

### Examples

`!``1`

`Ciao``1 1 1 1`

`tʃaʊ``1 2 1 2`

`Adám``1 1 2 1`

`ĉaŭ``2 1 2` (single characters)

`ĉaŭ``1 2 1 1 2` (uses combining overlays)

`チャオ``3 3 3`

(empty input) →  (empty output)

`!±≡``1 2 3 4`

� (a null byte) → `1`

### Null bytes

If the only way to keep reading input beyond null bytes is by knowing the total byte count, you may get the byte count by any means (even user input).

If your language cannot handle null bytes at all, you may assume the input does not contain nulls.

# Answer
> 10 votes
# Pyth, ~~9~~ 7 bytes

Thanks to @Maltysen for saving 2 bytes!

```
mlc.Bd8

```

Test suite

Converts every character of the input to it's binary representation and then splits this into chunks of length 8. The number of those chunks is then the amount of bytes needed to encode that character.

# Answer
> 21 votes
## Python 3, ~~42~~ 36 bytes

```
lambda x:[len(i.encode())for i in x]

```

# Answer
> 11 votes
## APL, 15 chars

```
≢¨'UTF-8'∘⎕ucs¨

```

In English: convert each character to UTF-8 (meaning: vector of bytes representation) and get its tally.

# Answer
> 11 votes
# C, ~~68~~ 65 bytes

```
b;main(c){for(;~c;b=c/64^2?b?putchar(b+48)/48:1:b+1)c=getchar();}

```

*Thanks to @FryAmTheEggman for golfing off 3 bytes!*

Test it on Ideone.

# Answer
> 7 votes
# GolfScript, 16 bytes

```
{64/2=}%1,/{,)}*

```

Try it online!

### Background

GolfScript doesn't have a clue what Unicode is; all strings (input, output, internal) are composed of bytes. While that can be pretty annoying, it's perfect for this challenge.

UTF-8 encodes ASCII and non-ASCII characters differently:

* All code points below 128 are encoded as `0xxxxxxx`.
* All other code points are encoded as `11xxxxxx 10xxxxxx ... 10xxxxxx`.

This means that the encoding of each Unicode character contains either a single `0xxxxxxx` byte or a single `11xxxxxx` byte and 1 to 5 `10xxxxxx` bytes.

By dividing all bytes of the input by **64**, we turn `0xxxxxxx` into **0** or **1**, `11xxxxxx` into **3**, and `10xxxxxx` into **2**.

If we compare the quotient with **2** – pushing **1** for **2**; and **0** for **0**, **1**, and **3** – each character will be turned into a **0**, followed by 1 to 5 **1**'s.

All that's left is to split the resulting string at occurrences of **0**, count the number of **1**'s between those zeroes and add one to the amount.

### How it works

```
{     }%          Map the following over all bytes in the input.
 64/                Divide the byte by 64.
    2=              Compare the quotient with 2, pushing 1 or 0.
        1,        Push range(1), i.e., [0].
          /       Split the array of Booleans around zeroes.
           {  }*  Fold; for each run of ones but the first:
            ,       Push its length.
             )      Increment.

```

# Answer
> 6 votes
## JavaScript (ES6), ~~54~~ ~~45~~ 43 bytes

```
s=>[...s].map(c=>encodeURI(c).length/3-8&7)

```

Edit: Saved 2 bytes with help from @l4m2.

# Answer
> 6 votes
## PowerShell v4, 58 bytes

```
[char[]]$args[0]|%{[Text.Encoding]::UTF8.GetByteCount($_)}

```

---

### NB

OK, this should work, and does in almost all of the test cases except for  which is somehow counted as `3,3` on my machine. That character even shows as 7 bytes on my computer. I suspect this is due to some sort of bug in the Windows or .NET version that I'm running locally, as @Mego doesn't have that issue. (*Edit: @cat points out this is due to BOM. Thanks for solving that mystery, @cat!*)

However, that still doesn't account for all of the problem. I think I know where *some* of the problems are coming from, though. Inside .NET, all strings are composed of UTF-16 code units (which is the System.Char type). With the very loose typecasting that PowerShell uses, there's a *lot* of implicit casting and conversion between types in the background. *Likely* this is a contributing factor to the behavior we're seeing -- for example, `[system.text.encoding]::utf8.getchars([System.Text.UTF8Encoding]::UTF8.GetBytes(''))` returns two unprintables, rather than a single character.

---

### Explanation

Very straightforward code. Takes the input `$args[0]` and explicitly casts it as a char-array so we can loop through each component of the string `|%{...}`. Each iteration, we use the .NET call `[System.Text.Encoding]::UTF8.GetByteCount()` (the `System.` is implied) to get the byte count of the current character `$_`. That's placed on the pipeline for later output. Since it's a collection of `[int]`s that are returned, casting to an array is implicit.

### Test Runs

```
PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'tʃaʊ'
1
2
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'Adám'
1
1
2
1

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'ĉaŭ'
2
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'ĉaŭ'
1
2
1
1
2

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 'チャオ'
3
3
3

PS C:\Tools\Scripts\golfing> .\bytes-per-character.ps1 '!±≡'
1
2
3
3
3

```

*Edited to add* This does properly account for the null-bytes requirement that was added to the challenge after I originally posted, provided you pull the data from a text file and pipe it as follows:

```
PS C:\Tools\Scripts\golfing> gc .\z.txt -Encoding UTF8|%{.\bytes-per-character.ps1 $_}
2
1
1
1

```

# Answer
> 5 votes
# Java 10, ~~100~~ ~~96~~ ~~95~~ ~~67~~ 61 bytes

```
a->{for(var c:a)System.out.print(c.getBytes("utf8").length);}

```

-4 bytes removing spaces because this is allowed in the comments
-1 byte changing `UTF-8` to `utf8`
-28 bytes going from Java 7 to 8 (`a->{...}` instead of `void c(char[]i)throws Exception{...}`)
-3 bytes taking the input as String-array instead of character-array, and
-3 bytes going from Java 8 to 10 (`var` instead of `String`)

**Explanation:**

Try it online.

```
a->{                      // Method with String-array parameter and no return-type
  for(var c:a)            //  Loop over the input-array
    System.out.print(     //   Print:
      c.getBytes("utf8")  //    The bytes as array in UTF-8 of the current item,
       .length);}         //    and print the amount of bytes in this array

```

# Answer
> 5 votes
# Perl 6,  ~~77 69~~  63 bytes

~~```
put +$0 if $_».base(2).fmt("%8d")~~/^(1)**2..*|^(" ")/ while $_=$*IN.read: 1

```

```
put +$0 if $_».fmt("%8b")~~/^(1)**2..*|^(" ")/ while $_=$*IN.read: 1

```~~
```
put 1+$0 if $_».fmt("%8b")~~/^1(1)+|^" "/while $_=$*IN.read: 1

```

```
put 1+$0 if $_».fmt("%0.8b")~~/^1(1)+|^0/while $_=$*IN.read: 1

```

Since Perl 6 uses NFG strings I have to pull in the bytes directly, which sidesteps the feature.
(NFG is like NFC except it also creates synthetic composed codepoints)

The output is separated by newlines.

### Test:

```
for text in '!' 'Ciao' 'tʃaʊ' 'Adám' 'ĉaŭ' 'ĉaŭ' 'チャオ' '' '!±≡' '\0';
do
  echo -en $text |
  perl6 -e 'put 1+$0 if $_».fmt("%8b")~~/^1(1)+|^" "/while $_=$*IN.read: 1' |

  # combine all of the lines into a single one for display purposes
  env text=$text perl6 -e 'put qq["%*ENV<text>"], "\t\t", lines.gist'
done

```

```
"!"     (1)
"tʃaʊ"      (1 2 1 2)
"Adám"      (1 1 2 1)
"ĉaŭ"       (2 1 2)
"ĉaŭ"     (1 2 1 1 2)
"チャオ"       (3 3 3)
""      ()
"!±≡"     (1 2 3 4)
"\0"        (4 1 4)

```

### Explanation:

```
# turns the list in ｢$0｣ into a count, and adds one
# ｢put｣ prints that with a trailing newline
put 1+$0

   # if the following is true
   if

       # format the input byte to base 2 and pad it out to 8 characters
       $_».fmt("%8b")

       ~~ # smart match against

       # check to see if it starts with more than one 1s, or a space
       # ( also sets ｢$0｣ to a list that is 1 shorter
       # than the number of bytes in this codepoint )
       / ^1 (1)+ | ^" " /

           # for every byte in STDIN
           while
               $_ = $*IN.read: 1

```

This works because the first byte in a multi-byte codepoint has the number of bytes encoded inside of it, and the other bytes in the codepoint have the highest bit set, but not the next highest. While the single byte codepoints don't have the highest bit set.

# Answer
> 5 votes
# Ruby, 33 bytes

Barely edges out Python, yay! Try it online.

```
->s{s.chars.map{|c|c.bytes.size}}

```

# Answer
> 5 votes
# Python 3, 82 bytes

```
import math
lambda x:[ord(i)<128and 1or int((math.log2(ord(i))-1)//5+1)for i in x]

```

This is much longer than the other Python answer, and the majority of the other answers, but uses an approach involving logarithms that I haven't yet seen.

An anonymous function that takes input, via argument, as a string and returns a list.

Try it on Ideone

**How it works**

This method relies on the way in which UTF-8 encodes the code-point of a character. If the code-point is less than 128, the character is encoded as in ASCII:

```
0xxxxxxx

```

where `x` represents the bits of the code point. However, for code-points greater than or equal to 128, the first byte is padded with the same number of `1` s as the total number of bytes, and subsequent bytes begin `10`. The bits of the code-point are then entered to give the shortest possible multibyte sequence, and any remaining bits become `0`.

```
No. of bytes  Format
1             0xxxxxxx
2             110xxxxx 10xxxxxx
3             1110xxxx 10xxxxxx 10xxxxxx
4             11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
...           ...

```

and so forth.

It can now be noticed that for each number of bytes `n`, the upper limit for the number of code-point bits is given by `(-n+7)+6(n-1) = 5n+1`. Hence, the upper limit code-point `c` for each `n` is given, in decimal, by  `c= 2^(5n+1)`. Rearranging this gives `n = (log2(c)-1)/5`. So for any code-point, the number of bytes can be found by evaluating the above expression, and then taking the ceiling.

However, this does not work for code points in the range `64 <= c <= 127`, since the lack of a padding `1` due to the ASCII-like encoding for 1 byte characters means that the wrong upper limit is predicted, and `log2` is undefined for `c = 0`, which happens if a null byte is present in the input. Therefore, if `c <= 127`, a value of `1` is returned for n.

This is exactly what the code is doing; for each character `i` in the string `x`, the code-point is found using the `ord` function, and the ceiling of the expression is found by using integer rather than float division by `5` and then adding `1`. Since Python's float type always represents integers as `x.0`, even after integer division, the result is passed to the `int` function to remove the trailing zero. If `ord(i) <= 127`, logical short-circuiting means that `1` is instead returned. The number of bytes for each character is stored as an element in a list, and this list is returned.

# Answer
> 3 votes
# Julia, 34 bytes

```
s->s>""?map(sizeof,split(s,"")):[]

```

This is an anonymous function that accepts a string and returns an integer array. To call it, assign it to a variable.

The approach is quite straightforward: If the input is empty, the output is empty. Otherwise we map the `sizeof` function, which counts the number of bytes in a string, to each one-character substring.

Try it online! (includes all test cases)

# Answer
> 3 votes
# JavaScript (Node), 27 bytes

```
s=>s.map(Buffer.byteLength)

```

This takes input as an array of individual characters, and returns an array of byte counts.

`Buffer` is a method of representing raw binary data. Buffer.byteLength(string) gives the number of bytes in the string. UTF-8 is the default encoding. Note that only Node.js has buffers, not browser JS. The rough browser equivalent is called Blob, which comes in at 31 bytes:

```
s=>s.map(e=>new Blob([e]).size)

```

## Test

Save this file and run it through node, or try it online.

```
var f =
  s=>s.map(Buffer.byteLength)

var tests = [
  ["!"],
  ["C","i","a","o"],
  ["t","ʃ","a","ʊ"],
  ["A","d","á","m"],
  ["ĉ","a","ŭ"],
  ["c","̂","a","u","̆"],
  ["チ","ャ","オ"],
  [],
  ["!","±","≡",""]
];

tests.forEach(test => {
  console.log(test, f(test));
});

```

This should be the result:

```
$ node bytes.js
[ '!' ] [ 1 ]
[ 'C', 'i', 'a', 'o' ] [ 1, 1, 1, 1 ]
[ 't', 'ʃ', 'a', 'ʊ' ] [ 1, 2, 1, 2 ]
[ 'A', 'd', 'á', 'm' ] [ 1, 1, 2, 1 ]
[ 'ĉ', 'a', 'ŭ' ] [ 2, 1, 2 ]
[ 'c', '̂', 'a', 'u', '̆' ] [ 1, 2, 1, 1, 2 ]
[ 'チ', 'ャ', 'オ' ] [ 3, 3, 3 ]
[] []
[ '!', '±', '≡', '�' ] [ 1, 2, 3, 4 ]

```

# Answer
> 3 votes
# PHP, ~~92~~ 57 bytes

On second thought you can do this with much less faffing around:

```
<?php for(;$a=strlen(mb_substr($argv[1],$i++,1));)echo$a;

```

Try it online note that this is slightly longer as it uses stdin rather than a program argument.
This version requires you to ignore notices sent to stderr but that's fine.

old version:
Uses a rather different approach to the other php answer. Relies on the lack of native support for multi-byte strings in php.

```
<?php for($l=strlen($a=$argv[1]);$a=mb_substr($a,1);$l=$v)echo$l-($v=strlen($a));echo$l?:'';

```

# Answer
> 3 votes
# Emacs Lisp, ~~55~~ 49 bytes

```
(lambda(s)(mapcar'string-bytes(mapcar'string s)))

```

First dissects the string into a list of characters with `(mapcar 'string s)`. The `string` function in Emacs Lisp takes a list of characters and builds a string out of them. Due to the way Emacs splits strings with `mapcar` (i.e. into a list of integers, not characters or strings), this explicit conversion is needed. Then maps the `string-bytes` function onto that list of strings.

Example:

```
(mapcar 'string "abc") ; => ("a" "b" "c")
(mapcar 'string-bytes '("a" "b" "c")) ; => (1 1 1)

```

Testcases:

```
(mapcar
 (lambda(s)(mapcar'string-bytes(mapcar'string s)))
 '("!""Ciao""tʃaʊ""Adám""ĉaŭ""ĉaŭ""チャオ""""!±≡""\0"))
;; ((1) (1 1 1 1) (1 2 1 2) (1 1 2 1) (2 1 2) (1 2 1 1 2) (3 3 3) nil (1 2 3 4) (1))

```

~~Old answer:~~

~~```
(lambda(s)(mapcar(lambda(s)(string-bytes(string s)))s))

```
Ungolfed:
```
 (lambda (s)
   (mapcar
    ;; we can't use string-bytes directly,
    ;; since Emacs mapcar yields a list of ints instead of characters
    ;; therefore we need a wrapper function here.
    (lambda (s)
      (string-bytes (string s)))
    s))

```
Testcases:
```
(mapcar
 (lambda(s)(mapcar(lambda(s)(string-bytes(string s)))s))
 '("!""Ciao""tʃaʊ""Adám""ĉaŭ""ĉaŭ""チャオ""""!±≡""\0"))
;; ((1) (1 1 1 1) (1 2 1 2) (1 1 2 1) (2 1 2) (1 2 1 1 2) (3 3 3) nil (1 2 3 4) (1))

```~~

# Answer
> 3 votes
# Bash, 74 bytes

**Golfed**

```
xxd -p|fold -2|cut -c1|tr -d '89ab'|echo `tr -t '01234567cbef' '[1*]2234'`

```

**Algorithm**

hexdump input string, fold 2 chars per line, cut the first char only

```
echo -ne '!±≡' | xxd -p|fold -2|cut -c1

2
c
b
e
8
a
f
a
b
b

```

(4 high order bits of an each input byte as a hex char, one per line)

Remove "continuation bytes" 0x80..0xBF

```
tr -d '89ab'

2
c

e

f

```

(what is left, is 4 bits of the first byte of an each unicode char)

map the first bits into the char length, collapse the output and print

```
echo `tr -t '01234567cbef' '[1*]2234'`

1 2 3 4

```

**Test**

```
 U() { xxd -p|fold -2|cut -c1|tr -d '89ab'|echo `tr -t '01234567cbef' '[1*]2234'`;}

 echo -ne '!' | U
 1

 echo -ne 'Ciao' | U
 1 1 1 1

 echo -ne 'tʃaʊ' | U
 1 2 1 2

 echo -ne 'Adám' | U
 1 1 2 1

 echo -ne 'ĉaŭ' | U
 2 1 2

 echo -ne 'ĉaŭ' | U
 1 2 1 1 2

 echo -ne 'チャオ' | U
 3 3 3
 echo -ne '!±≡' | U
 1 2 3 4

 echo -ne "\x0" | U
 1

 echo -ne '' | U

```

# Answer
> 2 votes
# PHP, 126 bytes

```
<?php $s=fgets(STDIN);echo $s!=''?implode(' ',array_map(function($x){return strlen($x);},preg_split('/(?<!^)(?!$)/u',$s))):'';

```

Try it online!

# Answer
> 2 votes
# C#, ~~89~~ 82 bytes

```
I=>{var J="";foreach(char c in I){J+=Encoding.UTF8.GetByteCount(c+"");}return J;};

```

A simple C# lambda that iterates through the string and returns the space separated list.

**Edit:** saved 6 bytes thanks to some very nice comments.

# Answer
> 2 votes
# Haskell, 85 bytes

```
import Data.ByteString as B
import Data.ByteString.UTF8
(B.length.fromString.pure<$>)

```

# Answer
> 1 votes
# Pyth, 17 bytes

```
mhxS+11+16,7lCdlC

```

Try it online!

Use the code-point of the characters with some arithmetics.

# Answer
> 1 votes
# Factor, ~~57~~ ~~87~~ ~~82~~ 80 bytes

```
[ [ dup zero? [ drop "1"] [ >bin length 4 /i 10 >base ] if ] { } map-as ""join ]

```

Explained:

```
USING: kernel math math.parser sequences ;
IN: byte-counts

: string>byte-counts ( str -- counts )
  [                  ! new quotation: takes a char as a fixnum
    dup zero?        ! true if this is a NUL byte
    [ drop "1" ]     ! NUL bytes have length 1
    [ >bin           ! else, convert to binary string
      length         ! length of binary string
      4              ! the constant 4
      /i             ! integer division
      number>string  ! 4 -> "4"
    ] if             ! conditionally execute one of the previous quotations
  ]                  ! end
  { } map-as         ! map and clone-like an { } array
  "" join ;          ! join array of 1strings on empty string

```

Unit tests:

```
USING: tools.test byte-counts ;
IN: byte-counts.tests

{ "1" } [ "!" string>byte-counts ] unit-test
{ "1111" } [ "Ciao" string>byte-counts ] unit-test
{ "1212"} [ "tʃaʊ" string>byte-counts ] unit-test
{ "1121" } [ "Adám" string>byte-counts ] unit-test
{ "212" } [ "ĉaŭ" string>byte-counts ] unit-test
{ "12112" } [ "ĉaŭ" string>byte-counts ] unit-test
{ "333" } [ "チャオ" string>byte-counts ] unit-test
{ "" } [ "" string>byte-counts ] unit-test
{ "1234" } [ "!±≡" string>byte-counts ] unit-test
{ "1" } [ "\0" string>byte-counts ] unit-test

```

They all pass, now. c:

# Answer
> 1 votes
# C, 85 bytes.

```
l(unsigned char* c){while(*c){int d=(*c>>4)-11;
d=d<0?1:d+(d==1);putchar(48+d);c+=d;}}

```

Examines the high 4 bits of each byte to determine the encoding and the number of subsequent bytes to skip;

# Answer
> 1 votes
# F#, ~~59~~ ~~54~~ 66 bytes

```
(s)=seq{for c in s->System.Text.Encoding.UTF8.GetByteCount([|c|])}

```

Technically, s is a char sequence, but it turns out there's an implicit conversion that allows a string to be passed in.

When testing this in the console with `!±≡`, it splits the kanji into two characters, each 3 bytes long. All the other test cases work fine.

**Edit:** It turns out common namespace imports are not implicit. Up another 12 chars.

# Answer
> 1 votes
# Swift 2.2, ~~67~~ ~~52~~ 50 bytes

```
for c in i.characters{print(String(c).utf8.count)}

```

Horribly ugly. There's no way to get the UTF-8 length of a Character in Swift, so I need to iterate through the string by character, convert the `Character` to a `String`, and find the `count` of that single-character `String` (hey, at least there's a built-in method to do that). Looking for optimizations, possibly using a scanner.

Revision 1: Saved 15 bytes by using `count` instead of `underestimateCount()`.

Revisions 2: Saved another 2 character by using a for-in loop instead of a for each closure.

# Answer
> 1 votes
## Rust, 53 bytes

```
|s:&str|for c in s.chars(){print!("{}",c.len_utf8())}

```

Rust has utf-8 char primitives, iterators, and lambdas, so this was straightforward. Test code:

```
fn main() {
    let s = "Löwe 老虎 Léopard";
    let f =|s:&str|for c in s.chars(){print!("{}",c.len_utf8())};
    f(s);
}

```

Outputs

```
1211133112111114444

```

# Answer
> 1 votes
# jq, 26 characters

(23 characters code + 3 characters command line option)

```
(./"")[]|utf8bytelength

```

Hopefully competing. Although `utf8bytelength` was added 9++ months before this question, it is still not included in released version.

Sample run:

```
bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'tʃaʊ'
1
2
1
2

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'ĉaŭ '
1
2
1
1
2
1

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< 'チャオ'
3
3
3

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< ''

bash-4.3$ ./jq -R '(./"")[]|utf8bytelength' <<< '!±≡'
1
2
3
4

```

# Answer
> 1 votes
# C (gcc), 53 bytes

```
k=49;f(char*s){*++s/64-2?k=puts(&k)+47:++k;*s&&f(s);}

```

Try it online!

# Answer
> 1 votes
# SmileBASIC, 69 bytes

```
DEF C B
WHILE I<LEN(B)Q=INSTR(BIN$(B[I],8),"0")I=I+Q+!Q?Q+!Q
WEND
END

```

Input is an array of bytes.

The number of bytes in a UTF-8 character is equal to the number of leading `1` bits in the first byte (unless there are no `1`s, in which case the character is 1 byte). To find the number of leading 1s, the program finds the first `0` in the binary representation, then adds 1 if this was 0.

```
0xxxxxxx - no leading ones, 1 byte
110xxxxx 10xxxxxx - 2 leading ones, 2 bytes
1110xxxx 10xxxxxx 10xxxxxx - 3 leading ones, 3 bytes
etc.

```

# Answer
> 1 votes
# 05AB1E, 15 bytes

```
ÇεDžy‹i1ë.²<5÷>

```

**Try it online.**
Header `ε` is used to for-each over all the test cases;
Footer `ï]J]»` to pretty-print the output character-lists (`ï`: decimals and characters to integers; `]`: close if-else and for-each; `J`: Join digits together; `}`: close header foreach; `»`: Join by new-lines).

**Explanation:**

```
Ç                   # Convert each character to its unicode value
 εD                 # Foreach over this list
      i             #  If the current item
     ‹              #  is smaller than
   žy               #  128
       1            #   Use 1
        ë           #  Else
         .²         #   Use log_2
           <        #   minus 1
            5÷      #   integer-divided by 5
              >     #   plus 1

```

Since 05AB1E doesn't have any builtins to convert characters to amount of bytes used, I use `Ç` to convert the characters to their unicode values, and in a for-each do the following in pseudo-code:

```
if(unicodeValue < 128)
  return 1
else
  return log_2(unicodeValue-1)//5+1    # (where // is integer-division)

```

Inspired by *@TheBikingViking*'s Python 3 answer.

# Answer
> 0 votes
# Zsh, 41 bytes

```
for c (${(s::)1})set +o multibyte&&<<<$#c

```

Try it online!

Zsh is UTF-8 aware, so we split the string on characters, then disable multibyte and print each character's length.

---
Tags: code-golf, unicode
---


# Question
Title: Checking a file contains only null bytes
Your goal is to write a program or function that takes in as input a string representing the path to a file, and outputs a truthy value if that file is not empty and contains no non-null bytes -- i.e., all bits are 0 -- and a falsey value otherwise.

I realize it is a very simple problem and I guess I could hack something, but I suspect there must be some short and elegant way of doing it, and that gave me the idea to make a challenge out of it.

This is , so shortest code in bytes wins. (My own preference would go to the fastest solution, but that is too implementation dependent...)

**Related questions**: Pad a file with zeros

**Motivation** : *This is only to tell where the problem comes from, in case you are interested. You do not need to read it.*

ISO images of CDs and DVDs, copied with "dd" or other means, often terminate with a sequence of useless blocks containing only null bytes. Standard techniques to remove these blocks are known and simple (see https://unix.stackexchange.com/questions/74827/ ) but they may sometimes remove non null useful data because the medium can lie about its own size. So I want to check that the removed blocks contain only null bytes. Removing these blocks is important for defining a normalised version of ISO-images.

# Answer
> 5 votes
# Pyth, ~~6~~ 5 bytes

```
!sCM'

```

Try it online!

Takes a filename from STDIN, opens and reads the file, converts it to a list of `int`s (think Python `ord`) `sum`s the list (will return `0` iff file is all null bytes), and `not`s the result, printing it.

---

Hey,

This looks a lot like a general programming question. These belong on Stack Overflow. However, from the comments under the main post, I can see that this was not your intent. That said, I feel that the discussion has been unnecessarily hostile on both sides, so I've decided to pick up the slack and give you the proper PPCG welcome!

Generally, we ask that any challenges are first posted to our sandbox for proper feedback. You can take a look at the current submissions in there to see what format we prefer for challenges. Please give it a try next time!

Just in case we've all misunderstood you and you *are* looking for a general solution, here's a solution in Python 3:

```
def main(string):
    with open(string) as file:
        return not any(map(ord,file.read()))

```

# Answer
> 2 votes
# GNU sed -zn, 5 bytes

The input file is passed to sed as a command-line parameter. Output as a standard shell return code - i.e. 0 is TRUE, 1 is FALSE.

```
/./q1

```

Normally `sed` works on newline-delimited input records (AKA "lines"). `-z` changes this to nul-delimited input records. If any input records match the `.` regex, then `q`uit with exit code 1.

Try it online!

# Answer
> 2 votes
## DOS, 37 bytes

```

100:BE 80 00 MOV SI, 0080
103:AD       LODSW ;get command-line length
104:98       CBW ;only a byte
105:93       XCHG BX,AX
106:88 40 FF MOV [BX+SI-01], AL ;zero end of name
109:B4 3D    MOV AH, 3D
10B:89 F2    MOV DX, SI
10D:CD 21    INT 21 ;open file
10F:93       XCHG BX, AX ;handle into BX
110:AF       SCASW ;DI=0
111:B4 3F    MOV AH, 3F
113:B1 01    MOV CH, 01
115:CD 21    INT 21 ;read 1 byte
117:91       XCHG CX, AX
118:E3 06    JCXZ 0120 ;quit on EOF
11A:97       XCHG DI, AX ;set true for later
11B:38 2C    CMP [SI], CH
11D:74 F2    JZ 0111 ;loop while zero
11F:4F       DEC DI ;set false
120:97       XCHG DI, AX
121:B4 4C    MOV AH, 4C ;return
123:CD 21    INT 21
```

It opens the file named on the command-line, returns 0 if empty or contains non-zero, otherwise returns 1.

# Answer
> 1 votes
# Attache, 24 bytes

```
Zero@Max&0@Ords@FileRead

```

Try it online!

## Explanation

This is a composition of 4 functions, executed one after the other:

* `FileRead` \- takes a file name as input, returns the contents of that file
* `Ords` \- returns the ASCII code points of each character in a list
* `Max&0` \- this is equivalent to, for argument `x`, `Max[x, 0]`; this in turn computes the maximum of all entries in `x` and `0` (yielding `0` for the empty list)
* `Zero` \- this is a predicate that checks if this number is in fact 0, and returns that boolean.

# Answer
> 1 votes
# (32bit platform), 65 bytes

```
main(x,v)int*v;{for(v=fopen(v[1],"r");!(x=fgetc(v)););return++x;}

```

Assumes sizes of pointers are all the same, which is almost always true. Returns with a `0` exit code on success (file contains only `NUL` characters), some other value otherwise.

Behavior is undefined if command line argument isn't a path to a readable file.

# Answer
> 0 votes
# Bash \+ GNU utilities, 26 bytes

```
od -An $1|grep -qv [^0\ *]

```

Input filename is given as a command-line parameter. Output as a standard shell return code - i.e. 0 is TRUE, 1 is FALSE.

Try it online!

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

```
BinaryReadList@#~MatchQ~{0..}&

```

Try it online!

## Explanation

```
                             & (* Function which returns whether *)
BinaryReadList                 (* the list of bytes *)
              @                (* of *)
               #               (* the input *)
                ~MatchQ~       (* matches *)
                        {0..}  (* a list of a one or more zeros *)

```

# Alternate solution, 22 bytes

If empty files are supposed to pass, then this can be shortened to:

```
Tr@BinaryReadList@#<1&

```

Try it online!

# Answer
> 0 votes
# Java, 149 bytes

```
boolean b(String f)throws Exception{java.io.InputStream s=new java.io.FileInputStream(f);int i=Math.abs(s.read());while(i==0)i+=s.read();return i<0;}

```

# Answer
> 0 votes
# Perl 5, 20 bytes

`$\=0;exit<>=~/^\0+$/`

Takes a file name in command line args and returns the response in the exit code of the program

# Answer
> 0 votes
# Haskell, 49 bytes

```
import Data.ByteString
f=(all(<1)<$>).getContents

```

Obviously if the import is not included, then it is 26 bytes.

# Answer
> 0 votes
# Python 3, 59 bytes

```
f=lambda s:any(open(s,'rb').read())+not len(open(s).read())

```

Returns 0 for success (all bytes zero).

Returns 1 for failure (at least one nonzero byte, or zero length file).

# Answer
> 0 votes
# APL (Dyalog Unicode), 14 bytes

Full program. Prompts for filename from stdin.

```
0=⌈/11 ¯1⎕MAP⍞

```

Try it online!

prompt for filename

`11 ¯1⎕MAP` map that file to a packed bit array

`⌈/` maximum (reduction); smallest float if empty, otherwise 0 or 1

`0=` is zero equal to that?

# Answer
> 0 votes
# JavaScript (ES8), 52 bytes

Takes a url as an argument and returns a promise that resolves to `true` if the file isn't empty and contains no null bytes.

```
async p=>!/\0|^$/.test(await(await fetch(p)).text())

```

# Answer
> 0 votes
# Zsh, 35 bytes

```
! for c (${(s::)"$(<$1)"})((i|=#c))

```

Try it online! Outputs via exit code.

Read in, split on characters, and bitwise-or each codepoint together.

If the file is empty, the body of the loop is never run and so the loop returns truthy. If the truthy-falsy values can be swapped, the leading `!` can be removed for a 2-byte save.

---
Tags: code-golf, file-system
---


# Question
Title: Create a uniquely solvable crossword ... without clues
Can you imagine solving the New York Times crossword puzzle without any clues? Maybe not with all of the creativity and new words and phrases appearing in modern crosswords, but with a fixed word list there's some hope. In this challenge, you create a crossword puzzle grid in which this is theoretically possible.

# The challenge

Maximize the number of white squares in a white- and black-shaded 15x15 crossword puzzle grid, such that the white squares can be *uniquely* filled with letters so that every across and down word appears in the international Scrabble word list.

# Grid construction clarifications

In US newspapers, crossword grids are usually constructed so that every letter is "checked", meaning it is part of both an "across" word and a "down" word. In the UK and elsewhere (especially in cryptic crosswords), this is not necessarily the case: if an "across" or "down" word would only be one letter, it need not be an actual word (like "A" or "I"). For this challenge, follow the more relaxed rules: single-letter words need not appear in the word list.

There are various other traditions (in the US and elsewhere), none of which need to be followed in this challenge. For example, words can be only two letters long, words are allowed to repeat, and the grid need not have (rotational) symmetry.

# Is this even possible?

Yes! One can write a short script to verify that the unique solution to the following blank grid on the left is the filled grid on the right:

One can display the filled grid in a computer-readable format as follows:

```
###CH##########
###YE##########
###AM##########
CYANOCOBALAMINE
HEMOCHROMATOSES
###CH##########
###OR##########
###BO##########
###AM##########
###LA##########
###AT##########
###MO##########
###IS##########
###NE##########
###ES##########

```

# Your solution

The grid above has 56 white squares out of the 225 squares total in the 15x15 grid. This serves as a baseline for this challenge. Grids with fewer white squares may also be interesting for reasons other than their score, for example if they satisfy some of the aesthetic traditions mentioned above.

Please submit your solution in the same format as the computer-readable baseline above. Please include code that verifies that there is a unique solution to your grid.

Interesting code snippets (eg for searching the space of possibilities) and discussion of how you found your grid are appreciated.

# The word list

The international Scrabble word list was previously known as SOWPODS and is now called Collins Scrabble Words (CSW). It is used in most countries (except notably the US). We prefer to use this list because it includes British spellings and generally has significantly many words than the American word list. There are multiple editions of this list which differ slightly. You can find different versions of this list linked from Wikipedia, on Github, in Peter Norvig's Natural Language Corpus and elsewhere, often still called "SOWPODS".

This challenge is highly sensitive to the broad nature of the choice of word list, but less so to smaller details. For example, the baseline example above works with any edition of CSW, but `CH` is not a word in the American Scrabble word list. In the event of a discrepancy, we prefer to use CSW19, the most recent edition of CSW. (If we use this list, which was released this year, we can expect answers to this challenge to remain valid longer). You may query this list interactively on the official Scrabble word finder site or download it (as well as the previous edition, CSW15) from the Board & Card Games Stack Exchange or Reddit's r/scrabble.

*Tldr*: the authoritative word list for this challenge is available as a plain text file (279,496 words, one per line) over on the Board & Card Games Stack Exchange.

# Further discussion

One issue raised in an early answer and comment is why existing crosswords (eg, in the NYT) don't answer this question. Specifically, the record for fewest number of black squares (and thus largest number of white squares) for a published NYT crossword is already the most famous record in crosswords. Why can't we use the record grid? There are a few issues:

* Many of the answers in NYT crosswords do not appear on our word list. For example, the record grid includes `PEPCID` (a brand name), `APASSAGETOINDIA` (a four-word proper name for a film and novel, written without spaces), and `STE` (an abbreviation for "Sainte"). It appears that the record grid is not solvable with Scrabble words.
* Merely expanding the word list to include more words does not necessarily help with this challenge: even if all of the words in the record grid appeared on our word list, the solution would not be *unique* without the clues. It is often possible to alter some letters at the ends of answers while keeping everything a word. (For example, the bottom-right-most letter can be changed from a `D` to an `R`.) Indeed, this is part of the (human) construction process when writing a crossword, trying to obtain "better" words.

The reason ordinary crosswords (usually) have a unique solution is that the *clues* help narrow down the correct answers. If you simply try to fill the grid with words *without* using clues, it's likely that there will either be no possibilities or *many* possibilities. Here's an example of three different fills (using the word list for this challenge!) for the same grid (one that's relatively frequently used in the NYT):

* Another issue raised in the comments is some amount of disbelief that this question is a *coding challenge*. Perhaps it is not immediately clear, but **it is hard to even find a single valid answer to this challenge**. Finding the baseline above involved multiple, specially-crafted search programs that were not guaranteed to find an answer. I do not personally even know of a *general* way to solve an arbitrary grid, if you want the answer in reasonable time. Existing crossword construction programs can help, but I assume (perhaps incorrectly) that they do not actually do a full search of the possibilities. (I used such a program for the three side-by-side grids above; this worked because that particular grid allows for many solutions.)

# Answer
> 11 votes
# 180 white squares

My strategy was simply to find a smaller rectangle with no black squares, such that it can be filled in uniquely. All `2×k` rectangles have multiple solutions. For `3×k` rectangles, there are multiple solutions for `k` between 3 and 14, but there is a exactly one solution for `k=15`.

I then fit 4 such rectangles in the grid. This means that each word appears 4 times in the solution, which is usually frowned upon in crossword construction, but OK for this challenge. On the other hand, this solution has both left/right and top/down symmetry!

Computer-readable grid:

```
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES
###############
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES
###############
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES
###############
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES

```

Here is the R code I used to find all solutions for a given grid size. Looping over all triples of 15-letter words is too slow. Instead, I try to fill in rectangles by

* setting the first two columns (two 3-letter words)
* then looping through all 15-letter words starting with the first two letters which are now settled.
* for each possible choice of the 15-letter words, I then verify whether all 3-letter words generated are in the dictionary.

For example, for the eventual solution, the code first put in `HOP` and `EVO`, then completed into `HETERNORMATIVE`, `OVEROPINIONATED` and `POSSESSEDNESSES`, and finally verified all the 3-letter words (`HOP`, `EVO`, `TES`, `ERS`, `ROE`, `OPS`, `NIS`, `ONE`, `RID`, `MON`, `ANE`, `TAS`, `ITS`, `VEE`, `EDS`).

## R code

```
library(fastmatch)
f = "scrabble-wordlist.txt"
d = read.table(f, skip=2, as.is=T, na.strings=NULL)

d$l = apply(d, 2, nchar)
d3 = d[d$l==3, 1]

sp = function(s) strsplit(s, "")[[1]]
cm = function(v) paste0(v, collapse="")
d3s = sapply(d3, sp)

f3 = function(l){
  m = matrix("", 3, l)

  md = sapply(d[d$l == l, 1], sp)
  nf = 0

  a1 = seq(1, 3*l, by=3); a2 = a1 + 1; a3 = a1 + 2

  for(i in 1:ncol(d3s)){
    m[, 1] = d3s[, i]

    id1 = as.matrix(md[, md[1, ] == m[1, 1]])
    id2 = as.matrix(md[, md[1, ] == m[2, 1]])
    id3 = as.matrix(md[, md[1, ] == m[3, 1]])

    if(any(ncol(id1) == 0, ncol(id2) == 0, ncol(id3) == 0)) next

    for(j in 1:ncol(d3s)){
      m[, 2] = d3s[, j]

      jd1 = as.matrix(id1[, id1[2, ] == m[1, 2]])
      jd2 = as.matrix(id2[, id2[2, ] == m[2, 2]])
      jd3 = as.matrix(id3[, id3[2, ] == m[3, 2]])

      if(any(ncol(jd1) == 0, ncol(jd2) == 0, ncol(jd3) == 0)) next

      for(k1 in 1:ncol(jd1)){
        m[1, ] = jd1[, k1]

        for(k2 in 1:ncol(jd2)){
          m[2, ] = jd2[, k2]

          for(k3 in 1:ncol(jd3)){
            m[3, ] = jd3[, k3]

            w = paste0(m[a1], m[a2], m[a3])
            if(all(w %fin% d3)){
              nf = nf + 1
              print(m)
            }
            if(nf >= 2){
              print(c(l, nf))
              return()
            }
          }
        }
      }
    }
  }

  return(nf)
}

```

Called as `f3(15)`. Took a few hours on my personal computer.

# Answer
> 3 votes
# 182 white squares

Inspired by Robin Ryder's answer, I tried to squeeze in a couple more white squares. I believe this solution is unique, and I will soon post verification code accordingly.

Computer-readable grid:

```
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES
B##############
INCOMMUNICATIVE
NEUROANATOMICAL
DETERMINATENESS
###############
HETERONORMATIVE
OVEROPINIONATED
POSSESSEDNESSES
B##############
INCOMMUNICATIVE
NEUROANATOMICAL
DETERMINATENESS

```

---
Tags: code-challenge, optimization, crossword
---


title: Split string using rules

text:
# Question
Title: Split string using rules
## Introduction

Some time ago, I need to write function which split string in some specific way. At the first look, task looks trivial, but it was not so easy - especially when I want to decrease code size.

## Challenge

As example we have following input string (it can be arbitrary)

> Lorem ipsum dolor sit amet consectetur adipiscing elit sed doeiusmod tempor incididunt ut Duis aute irure dolor in reprehenderit in esse cillum dolor eu fugia ...

We need to splitting it into elements ( groups of adjacent words) using following rules (A-E)

```
 "Lorem ipsum dolor",  // A: take Three words if each has <6 letters
 "sit amet",           // B: take Two words if they have <6 letters and third word >=6 letters
 "consectetur",        // C: take One word >=6 letters if next word >=6 letters
 "adipiscing elit",    // D: take Two words when first >=6, second <6 letters
 "sed doeiusmod",      // E: Two words when first<6, second >=6 letters
 "tempor"              // rule C
 "incididunt ut"       // rule D
 "Duis aute irure"     // rule A
 "dolor in"            // rule B
 "reprehenderit in"    // rule D
 "esse cillum"         // rule E
 "dolor eu fugia"      // rule D
 ...

```

So as you can see input string (only alphanumeric characters) is divided to elements (substrings) - each element can have min one and max three words. You have 5 rules (A-E) to divide your string - if you take words one by one from beginning - only one of this rule applied. When you find rule, then you will know how many words move from input to output (1,2 or 3 words) - after that start again: find next rule for the remaining input words.

Boundary conditions: if last words/word not match any rules then just add them as last element (but two long words cannot be newer in one element)

In the output we should get divided string - each element separated by new line or `|` (you don't need to use double quotes to wrap each element)

## Example Input and Output

Here is example input (only alphanumeric ASCII characters):

```
Lorem ipsum dolor sit amet consectetur adipiscing elit sed doeiusmod tempor incididunt ut Duis aute irure dolor in reprehenderit in esse cillum dolor eu fugia

```

and its output:

```
Lorem ipsum dolor|sit amet|consectetur|adipiscing elit|sed doeiusmod|tempor|incididunt ut|Duis aute irure|dolor in|reprehenderit in|esse cillum|dolor eu fugia

```

# Answer
# Jelly, 23 bytes

```
ḲµẈṁ3<6Ḅ+8:5⁸sḢKṄȧƲẎµ¹¿

```

A full-program printing the result.

**Try it online!**

### How?

Given the lengths of three words (`a`, `b`, and `c`) we can write the following mapping for how many word we should take:

```
a<6?  b<6?  c<6?   words
   1     1     1     3
   1     1     0     2
   1     0     1     2
   1     0     0     2
   0     1     1     2
   0     1     0     2
   0     0     1     1
   0     0     0     1

```

Treating the comparisons as a single number in binary this is:

```
bin([a<6,b<6,c<6]):   7   6   5   4   3   2   1   0
             words:   3   2   2   2   2   2   1   1

```

So we can map like so:

```
bin([a<6,b<6,c<6]):   7   6   5   4   3   2   1   0
         add eight:  15  14  13  12  11  10   9   8
    divide by five:   3   2   2   2   2   2   1   1

```

Note that when less than three words remain we want to take all of them, unless there are two left and they are both of length six or more when case `C` says to take one word. To make this the case we repeat what we have up to length three (with `ṁ3` instead of `ḣ3`) and use that.

```
a<6?  b<6?         moulded  bin  + 8  div 5 (= words)
   1                111     7    15   3  (i.e. all 1)
   0                000     0     8   2  (i.e. all 1)
   1    1           111     7    15   3  (i.e. all 2)
   1    0           101     5    13   2  (i.e. all 2)
   0    1           010     2    10   2  (i.e. all 2)
   0    0 (i.e. C)  000     0     8   1  (i.e. just 1)

```

The code then works as follows.

```
ḲµẈṁ3<6Ḅ+8:5⁸sḢKṄȧƲẎµ¹¿ - Main Link: list of characters
Ḳ                       - split at spaces
                      ¿ - while...
                     ¹  - ...condition: identity (i.e. while there are still words)
 µ                  µ   - ...do: the monadic chain:
  Ẉ                     -   length of each
    3                   -   literal three
   ṁ                    -   mould like ([1,2,3])
      6                 -   literal six
     <                  -   less than? (vectorises)
       Ḅ                -   from binary to integer
         8              -   literal eight
        +               -   add
           5            -   literal five
          :             -   integer divide
            ⁸           -   chain's left argument
             s          -   split into chunks (of that length)
                  Ʋ     -   last four links as a monad (f(x)):
              Ḣ         -     head (alters x too)
               K        -     join with spaces
                Ṅ       -     print & yield
                 ȧ      -     logical AND (with altered x)
                   Ẏ    -   tighten (back to a list of words)

```
> 3 votes

# Answer
# Python 2, ~~92~~ ~~90~~ ~~88~~ ~~87~~ ~~86~~ 85 bytes

```
r=''
n=0
for w in input().split():L=w[:5]<w;x=n+L<3;r+='| '[x]+w;n=n*x-~L
print r[1:]

```

Try it online!

<sub>-1 byte, thanks to Kevin Cruijssen</sub>
> 7 votes

# Answer
# Perl 5, 47 bytes

seems regex can be shorten with this equivalent one

```
s/(\w{1,5} ){3}|\w{6,} (?=\w{6})|\w+ \w+ /$&
/g

```

Try it online!

Previous regex

# Perl 5, 86 bytes

```
s/(\w{1,5} ){3}|((\w{1,5} ){2}|\w{6,} )(?=\w{6})|\w{6,} \w{1,5} |\w{1,5} \w{6,} /$&
/g

```

Try it online!

Not valid:

# Perl 5 (`-M5.01` `-lnF/(?:\S{1,5}\K\s+){3}|\S{6,}\K\s+(?=\S{6})|\S+\s+\S+\K\s+/`), 9 bytes

```
say for@F

```

Try it online!
> 3 votes

# Answer
# AWK, 65 bytes (thanks manatwork!)

```
BEGIN{RS=FS}{printf(x=n+(L=length($1)>5)<3)?FS$1:"|"$1;n=n*x+L+1}

```

Try it online!

I didn't even know AWK had a ternary operator

# AWK, 97 79 72 bytes (thanks manatwork!)

```
BEGIN{a[0]="|";a[1]=RS=FS}{printf a[x=n+(L=length($1)>5)<3]$1;n=n*x+L+1}

```

Try it online!

I shamelessly stole the algorithm from @TFeld's Python2 solution.
> 3 votes

# Answer
# 05AB1E, 28 bytes

```
0U#v„
 yg6@DX+3‹DŠX*+>Uèy}J¦

```

Port of *@TFeld*'s Python answer, so make sure to upvote him!

Try it online.

**Explanation:**

```
0U                       # Set variable `X` to 0 (it's 1 by default)
#                        # Split the (implicit) input-string on spaces
 v                       # Loop over each word `y`:
      yg                 #  Get the length of the word
        6@               #  And check that it's >= 6
          D              #  Duplicate this
           X+            #  Add variable `X` to it
             3‹          #  And check that it's smaller than 3
               DŠ        #  Duplicate this as well, and triple-swap (a,b,c to c,a,b)
                 X*      #  Multiply the <3 check with variable `X`
                   +     #  Add it to the length >=6 check
                    >U   #  Increase it by 1, and set it as the new variable `X`
  „\n                 è  #  Index the <3 check into the string "\n "
                       y #  And push the current word
 }J                      # After the loop: join the entire stack together
   ¦                     # And remove the leading space
                         # (after which the top of the stack is output implicitly as result)

```
> 2 votes

# Answer
# Clean, 206 bytes

```
import StdEnv,Text
$s=join"|"(map(join" "o map fst)(?[(w,size w<6)\\w<-split" "s]))
?l=case l of[a,b,c:t]|all(snd)[a,b,c]=[[a,b,c]: ?t];[a:t=:[b:_]]|not(snd a||snd b)=[[a]: ?t];[]=[];l=[take 2l: ?(drop 2l)]

```

Try it online!
> 2 votes

# Answer
# Jelly, ~~27~~ 23 bytes

```
ḲµẈ<6ḣ3Ḅ+8:5Ṭk⁸KṄṛɗ/µÐL

```

Try it online!

A full program that takes as its argument the input string and prints newline-separated groups of words. Takes advantage of the fact that if the current first three words have their length checked to see if \<6 and this is then treated as a binary number, the number of words needed will be 1,1,2,2,2,2,2,2,3 for numbers from 0 to 7 respectively.

## Explanation

```
Ḳ                       | Split at spaces
 µ                  µÐL | Repeat the following until no new results:
  Ẉ                     | - Lengths of lists (i.e. words)
   <6                   | - Less than 6
     ḣ3                 | - First three
       Ḅ                | - Comvert from binary to integer
        +8              | - Add 8
          :5            | - Integer divide by 5
            Ṭ           | - Convert from index to boolean list
             k⁸         | - Split input to this loop iteration at that point
                  ɗ/    | - Reduce using following as a dyad:
               K        |   - Join with spaces
                Ṅ       |   - Output with trailing newline
                 ṛ      |   - Right argument (i.e. rest of list)

```
> 2 votes

# Answer
# Jelly, 24 bytes

```
Ḳµḣ3Ẉ5<+2/Ṁ3_⁸sḢKṄṛƲẎµ¹¿

```

Try it online!

-1 thanks to Jonathan Allan.
> 2 votes

# Answer
# Charcoal, 49 bytes

```
≔⮌⪪Ｓ θＷθ«≔⌊⟦Ｌθ⊕ΣＥ²›⁶Ｌ§θ⁻κ²⟧ι⪫Ｅ⁻ι∧⁼ι³‹⁵Ｌ§θ±³⊟θ ¿θ|

```

Try it online! Link is to verbose version of code. Explanation:

```
≔⮌⪪Ｓ θ

```

Split the input into words and reverse it so that we can use `Pop` to remove words in order.

```
Ｗθ«

```

Repeat while there are still words left.

```
≔⌊⟦Ｌθ⊕ΣＥ²›⁶Ｌ§θ⁻κ²⟧ι

```

Estimate the number of words needed as equal to one more than the number of the first two words that are less than 6 letters, but no more than the number of words left.

```
⪫Ｅ⁻ι∧⁼ι³‹⁵Ｌ§θ±³⊟θ

```

Adjust the number of words if there are three and the third word is not less than 6 letters, then remove that many words and print them separated with spaces.

```
¿θ|

```

Output a separator if there are still more words left.
> 1 votes

# Answer
# , ~~55~~ 53 bytes

```
</.~[:+/\@}:[:(}:@],[((3<]),,{~4>])_1{+)/0|.@,1+5<#&>

```

Try it online!
> 1 votes

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