title: It's Just Simple Math!

text:
# Question
Title: It's Just Simple Math!
# Task

Your boss is on another crusade for 'efficiency.' He wants to encourage the use of numbers with fewer syllables, so that they're easier to *discuss* in meetings. If you want to take some time off work, you're boss would prefer you take `9` days instead of `7`. You're boss would prefer a credit card expense of `$99,502` over `$77,601`

## Input

You can chose your input format for the numbers, if you want to take in `7/9` or `seven/nine` it's completely up to you

## Output

Output whichever number has the least syllables. ***CATCH!*** You must output the answer in the same format you chose for the input. So if your program takes in `7/9` as input, it must output `9`. And if your program takes in binary numbers as the input, such as `0000111/0001001`, then it must output the answer as `0001001`

## Examples

I used howmanysyllables.com to find the amount of syllables in each number:

| `Input` | `Syllables` | `Output` |
| --- | --- | --- |
| `7\9` | `2 vs 1` | `9` |
| `ninety nine\one hundred and five` | `3 vs 5` | `ninety nine` |
| `0111101\1100011` | `3 vs 3` | `0111101 1100011` |
| `seventy seven thousand six hundred and one\ninety one thousand five hundred and two` | `12 vs 10` | `ninety one thousand five hundred and two` |
| `10011111111011\10111111111111` | `10 vs 11` | `10011111111011` |
| `13\15` | `2 vs 2` | `13 15` |

## Additional rules

1. Numbers must include `and` where appropriate. For example, `105` should be calculated as `one hundred and five` instead of `one hundred five`. I know some people might include `and` more than others when pronouncing numbers, so this is open to change in future depending on feedback!
2. If both numbers have the same number of syllables, output both numbers in the format you took them in
3. The input will only ever be a positive integer

## Numbers/Syllables

> 1,2,3,4,5,6,8,9,10,12 = 1 syllables

> 7,13,14,15,16,18,19,20 = 2 syllables

> 11,17,21,22,23,24,25,26 = 3 syllables

> 27 = 4 syllables

This is , so **the shortest program wins!**

# Answer
# sed `-E`, 120 bytes

```
h;s/n//g;s/[ls]e/##/g;s/ve/-/g;s/[aeiou]+/#/g;s/y/#/g;s/[^#,]//g;G;s/^(#*)#+,\1\n.*,//;s/^(#*),\1#+.(.*),.*/\2/;s/.*\n//

```

Try it online!
> 1 votes

---
Tags: code-golf, number, natural-language
---


title: Piecing Paired Primes

text:
# Question
Title: Piecing Paired Primes
## Problem

You've stumbled upon a paradoxical mathematical phenomenon related to prime numbers. Consider the following scenario:

You have an infinite list of prime numbers: $$2, 3, 5, 7, 11, 13, 17, 19, ...$$

Now, you decide to pair up these prime numbers in a way that each prime is paired with its consecutive prime number and generate fractions by dividing the smaller number of each pair by the larger number. And you start adding them... $$\frac{2}{3}+\frac{3}{5}+\frac{5}{7}+\frac{7}{11}+\frac{11}{13}+\frac{13}{17}...$$ **they seem to be converging!!!???** Your task is to calculate the sum of all fractions in this sequence.

Write a program or function that calculates the **sum of these fractions** up to a specified number of pairs (`n`).

## Input:

* An **integer** `n` representing the number of prime pairs to consider (1 ≤ `n` ≤ 1000).

## Output

* A floating-point number or The accurate fraction representing the sum of the fractions.

## Examples

$$n = 3$$ $$\frac{2}{3}+\frac{3}{5}+\frac{5}{7}=1.980952$$

**Smallest code wins** (bytes)

#### Some test cases

```
  3 =   1.980952  (208/105)
  7 =   5.122912  (24845332/4849845)
  9 =   6.742102  (21809669044/3234846615)
185 = 179.189745
564 = 556.886274
849 = 841.414962
999 = 991.228537

```

# Answer
> 3 votes
# 05AB1E, ~~6~~ 5 bytes

```
ÝØü/O

```

Try it online or verify all test cases.

**Explanation:**

```
Ý      # Push a list in the range [0, (implicit) input]
 Ø     # Convert each to their 0-based n'th prime
  ü    # For each overlapping pair of values:
   /   #  Divide them
    O  # Them sum all these decimal values together
       # (which is output implicitly as result)

```

# Answer
> 9 votes
# Python 3, 66 bytes

```
f=lambda n,p=3,P=4,d=2:n and P%p*d/p+f(n-P%p,p+1,P*p*p,[d,p][P%p])

```

Try it online!

The Wilson's Theorem generator strikes again. Similar to the template for the first n primes here, but also stores the previous prime as `d` and keeps the running sum of the ratios.

# Answer
> 7 votes
# Desmos, 69 bytes

```
L=[2...7920]
P=L[∏_{d=3}^Lmod(L,d-1)>0]
f(k)=∑_{n=1}^kP[n]/P[n+1]

```

Try It On Desmos!

Try It On Desmos! - Prettified

Probably golfable but this is the best I could think of for now.

# Answer
> 6 votes
# Pari/GP, ~~48~~ 38 bytes

Saved 10 bytes thanks to the comment of @alephalpha

---

```
f(n)=sum(k=1,n,prime(k)/prime(k+1))*1.

```

Try it online!

# Answer
> 5 votes
# Husk, ~~8~~ 7 bytes

```
Σ↑Ẋ`/İp

```

Try it online!

```
Σ↑Ẋ`/İp
  Ẋ      # map over adjacent pairs of values
   `/    #   flipped division: x ÷ y
     İp  # apply this to the infinite list of primes
 ↑       # then take the first arg1 values
Σ        # and sum them

```

# Answer
> 4 votes
# Factor \+ `math.primes math.unicode`, 35 bytes

```
[ 1 + nprimes 2 clump unzip v/ Σ ]

```

Try it online!

```
         ! 3
1        ! 3 1
+        ! 4
nprimes  ! { 2 3 5 7 }
2        ! { 2 3 5 7 } 2
clump    ! { { 2 3 } { 3 5 } { 5 7 } }
unzip    ! { 2 3 5 } { 3 5 7 }
v/       ! { 2/3 3/5 5/7 }
Σ        ! 1+103/105

```

# Answer
> 4 votes
# Ruby -rprime, 42+6 = 48 bytes

```
->n{k=0;Prime.take(n+1).sum{|x|k*1.0/k=x}}

```

Try it online!

# Answer
> 3 votes
# Vyxal `s`, 35 bitsv2, 4.375 bytes

```
ʀǎ¨p/

```

Try it Online!

Works for any n \>= 1 (even bigger than 1000). The flag is for display purposes.

## Explained

```
ʀǎ¨p/
ʀǎ     # First n prime numbers
  ¨p/  # With every overlapping pair reduced by divison
# Automatically sum

```

Created with the help of Luminespire.

# Answer
> 3 votes
# Python, 71 bytes

```
lambda n:sum(p(k+1)/p(k+2)for k in range(n))
from sympy import*
p=prime

```

Attempt This Online!

## Explanation

`prime` computes the n-th prime

# Python, 105 bytes

longer but faster

```
lambda n:sum(a/b for(a,b)in i.pairwise(i.islice(sympy.primerange(4**n),n+1)))
import sympy,itertools as i

```

Attempt This Online!

## Explanation

Uses the fact that the n+1-st prime is less than 4n+1 to obtain a list of the first n+1 primes from the list of the primes less than n (`sympy.primerange`).

`pairwise` groups the elements in adjacent pairs

# Answer
> 3 votes
# Python 3, ~~131~~ 112 bytes

*-19 thanks to bsoelch*

```
lambda n:sum(x[k]/x[k+1]for k in range(n))
x=[i for i in range(2,7920)if not[i%j for j in range(2,i)if not i%j]]

```

Try it online!

Old explanation:

```
lambda n:                                # lambda with an argument
x:=[i for i in range(2,7920)if not[i%j for j in range(2,i)if not i%j]][:n+1]
# prime getter till 1000. 7919 is 1000th prime, slice until n+1
sum(x[k]/x[k+1]for k in range(len(x)-1)) # sum it up
[1]                                      # and return the latter

```

# Answer
> 3 votes
# Thunno 2 `+`, 7 bytes

```
ÆpDḣỊØ.

```

Try it online!

*2 flags -\> 1 flag thanks to Neil*

#### Explanation

```
ÆpDḣỊØ.  # Implicit input
Æp       # First (input + 1) primes
  Dḣ     # Push a copy without the first item
    Ị    # Reciprocal of each
     Ø.  # Dot product of the two lists
         # Implicit output

```

# Answer
> 3 votes
# Raku, 41 bytes

```
[\+] {.(2)Z/.(3)}({grep &is-prime,$_..*})

```

Try it online!

This is an expression for the infinite sequence of partial sums.

* `{ grep &is-prime, $_ .. * }` is an anonymous function that returns a sequence of primes starting from the number given as its argument.
* `{ .(2) Z/ .(3) }` is another anonymous function that is given the previous anonymous function as its argument in the variable `$_`, and evaluated immediately. `.(2)` calls the first function with the number 2, generating the primes starting from 2, and likewise with `.(3)`. `Z/` zips those sequences together with division, producing the sequence of fractions.
* `[\+]` produces the infinite sequence of partial sums.

# Answer
> 3 votes
# sclin, 20 bytes

```
$P"1dp"Q / rev tk +/

```

Try it here!

For testing purposes:

```
999 ; 20N>d
$P"1dp"Q / rev tk +/

```

NOTE: the default representation is a rational number, but `20N>d` converts the representation to decimal for convenience.

## Explanation

Prettified code:

```
$P 1.dp Q / rev tk +/

```

Assuming input *n*:

* `$P` infinite list of primes
* `1.dp Q` duplicate and drop first item
* `/` element-wise divide
* `rev tk +/` take *n* elements and sum

# Answer
> 2 votes
# Excel, 127 bytes

```
=LET(
    a,ROW(1:7327),
    b,FILTER(a,MMULT(N(MOD(a,TOROW(a))=0),a^0)=2),
    SUM(EXP(MMULT(LN(INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1}),{1;1})))
)

```

Input in cell `A1`. Fails for `A1>932`.

**Explanation**

```
ROW(1:7327)
# Vertical array of integers 1 to 7327

TOROW(a)
# Transpose the above

MOD(a,TOROW(a))
# 2D array of all those integers modulo all those integers

MOD(a,TOROW(a))=0)
# Which of these is equal to 0

N(MOD(a,TOROW(a))=0)
# Convert Booleans to ones and zeroes

a^0
# Vertical array of size 7327, each entry unity

MMULT(N(MOD(a,TOROW(a))=0),a^0)
# Matrix multiplication of the above arrays

MMULT(N(MOD(a,TOROW(a))=0),a^0)=2
# Which of these is equal to 2, i.e. only divisors are unity and itself

FILTER(a,MMULT(N(MOD(a,TOROW(a))=0),a^0)=2)
# Filter array of integers accordingly, i.e. list of primes <=7327

SEQUENCE(A1)
# Vertical array from 1 to value in cell A1

SEQUENCE(A1)+{0,1}
# Additional column added to above with values offset by 1

INDEX(b,SEQUENCE(A1)+{0,1})
# Index list of primes with these indices

INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1}
# Reciprocate the last entry in each pair with unity

LN(INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1})
# Take the natural logarithm

MMULT(LN(INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1}),{1;1})
# Matrix multiplication for pairwise summation

EXP(MMULT(LN(INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1}),{1;1}))
# Take the natural exponentiation

SUM(EXP(MMULT(LN(INDEX(b,SEQUENCE(A1)+{0,1})^{1,-1}),{1;1})))
# Sum all entries

```

# Answer
> 2 votes
# Wolfram Language (Mathematica), ~~43~~ 32 bytes

Saved 11 bytes thanks to the comment of @Roman

---

```
N@Sum[Prime@i/Prime[i+1],{i,#}]&

```

Try it online!

# Answer
> 2 votes
# Charcoal, 32 bytes

```
Ｎθ→→Ｗ¬›Ｌυθ¿⬤υ﹪ⅈκ⊞υⅈＭ→ＩΣＥΦυκ∕§υκι

```

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

```
Ｎθ→→Ｗ¬›Ｌυθ¿⬤υ﹪ⅈκ⊞υⅈＭ→

```

Input `n` and generate the first `n+1` primes using the same method as for my answer to Number of bits needed to represent the product of the first primes.

```
ＩΣＥΦυκ∕§υκι

```

Divide each prime by its successor and output the sum.

30 bytes using the newer version of Charcoal on ATO:

```
Ｎθ→→Ｗ¬›Ｌυθ¿⬤υ﹪ⅈκ⊞υⅈＭ→ＩΣ×υ∕¹Φυκ

```

Attempt This Online! Link is to verbose version of code. Explanation: Takes the dot product of the primes with the reciprocals of the odd primes.

# Answer
> 2 votes
# JavaScript (ES6), 56 bytes

```
n=>(g=(p,d=k++)=>k%d--?g(p,d):d?g(p):n--&&p/k+g(k))(k=2)

```

Try it online!

# Answer
> 2 votes
# GAWK, 49 47 bytes

```
func f(n){t=0;for(i=1;i<=n;)t+=$i/$++i;print t}

```

Try it online!

This one implies that the input file is an infinite list of prime number. The function is still taking an integer `n` as argument.

As mentionned by @Olivier Dulac, this script need to run using `gawk` or other `awk` variant that support having multiple digits fields.

He also suggested a variant that could work with Unix Shell, that would be **61 bytes**, and would take as input file an infinite list of prime number, with one number per record :

```
# HEADER
BEGIN{OFMT = "%.6f"} # Get precision set up
#HEADER

{a[NR]=$0}func f(n){t=0;for(i=1;i<=n;)t+=a[i]/a[++i];print t}

# FOOTER
END{
    f(3)
    f(185)
    f(564)
    f(849)
    f(999)
}
# FOOTER

```

---

# AWK, 120 111 109 bytes

```
{for(a[n=1]=2;t=j=n<1e3;a[++n]=m)for(m=a[n]+(i=1);++i<m;)i=m%i<1?2+0*m++:i;for(;j<$0;)t+=a[++j]/a[1+j];$1=t}1

```

Try it online!

* -9 bytes, thanks to @ceilingcat
* -2 bytes, replaced `print t` with `$1=t`, then `1` as precision is not necessary

This one work with just n as input. It only supplies `999` pair of prime number, but if you change `1e3` with `1e4` it will supplies `9999`, it will just get 10 time longer for each lines.

# Answer
> 1 votes
# Japt v2.0a0 `-x`, 9 bytes

```
_j}jUÄ ä÷

```

Try it

---
Tags: code-golf, sequence, primes
---


title: Golf GitHub's Pager Logic

text:
# Question
Title: Golf GitHub's Pager Logic
## Background

When searches return many pages of results, GitHub avoids cluttering their UI by eliding page links. Instead, their UI lets you select:

1. Pages at the beginning of the results.
2. Pages near the current page.
3. Pages at the end of the results.

In this way, no more than 11 page links are ever displayed at one time. Before describing the precise logic underlying the pager, a few screenshots will help demonstrate it:

## The logic

Assuming a total of `n` results, and a current page of `p`, the pager will always show:

1. The current page.
2. The 4 pages closest in absolute distance to the current page.
    * That is, it will show a "window" of length 5, centered on the current page, but shifting as needed if the current page is too close to one of the boundaries (the first or last page).
3. The first 2 pages.
4. The last 2 pages.
5. All other contiguous pages besides these will be elided with a single `...`, with one exception:
    * If only 1 page would be elided, simply show that page rather than the `...`, because it's going to take up the same amount of space anyway.

As an aside unrelated to the challenge, it's interesting that Stack Overflow does not follow the exception to rule 5.

## Task

**Input:** A total number of pages `n` and a current page `p`.

**Output:** A list containing all the pages, in order, to be shown by the GitHub pager, with logic as described above. You may use any value that is not a possible page value to represent the ellipses. For example, -1, infinity or 0 (but 0 is only valid if you are using 1-based indexing).

* You can use 0-based or 1-based indexing.
* You can take input and output in any reasonable format (e.g. output can be an array, 1 number per line, etc.)

This is code golf with standard site rules.

## Test Cases

Format will be `[n, p] => <output list>`, using -1 to represent ellipsis. Test cases use 1-based indexing.

```
[1, 1] => [1]
[2, 1] => [1, 2]
[2, 2] => [1, 2]
[5, 1] => [1, 2, 3, 4, 5]
[5, 5] => [1, 2, 3, 4, 5]
[11, 6] => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[11, 5] => [1, 2, 3, 4, 5, 6, 7, -1, 10, 11]
[12, 6] => [1, 2, 3, 4, 5, 6, 7, 8, -1, 11, 12]
[12, 7] => [1, 2, -1, 5, 6, 7, 8, 9, 10, 11, 12]
[13, 7] => [1, 2, -1, 5, 6, 7, 8, 9, -1, 12, 13]
[100, 1] => [1, 2, 3, 4, 5, -1, 99, 100]
[100, 100] => [1, 2, -1, 96, 97, 98, 99, 100]
[100, 99] => [1, 2, -1, 96, 97, 98, 99, 100]
[100, 98] => [1, 2, -1, 96, 97, 98, 99, 100]
[100, 95] => [1, 2, -1, 93, 94, 95, 96, 97, 98, 99, 100]
[100, 94] => [1, 2, -1, 92, 93, 94, 95, 96, -1, 99, 100]

```

# Answer
# Jelly, 22 bytes

```
_2«Ɠ»3,‘ŻạⱮ«4§<11×RŒg§

```

Try it online!

Takes page count as a command-line argument and page number from standard input. 1-based, using 0 for elided pages.

## Algorithm

In order to handle the special case of showing five pages at one end if the active page happens to be there, the page number \\$p\\$ is clamped into the range \\$\[3, n-2\]\\$ (this is impossible if there are 4 or fewer pages, but in that case, the algorithm gives the correct result regardless of the page number because the first two and last two pages cover the whole range). The idea is that instead of having a special case, we can just use the "natural" behaviour of showing pages within two spaces of the current page in order to show the five pages at an end.

For each page, its page number is then compared to \\$0\\$, the clamped value of \\$p\\$, and \\$n+1\\$, looking for the absolute distance. If the page is within two pages of any of these anchors, then we want to display its page number. We also want to display a page if it's within three pages of two of the anchors (if the anchors are on the same side of the page, it'll necessarily be within two pages of one of them because no two anchors can be in the same place; if the anchors are on opposite sides, then they're forming a one-page gap which needs to be displayed rather than elided). To accomplish this check, any absolute distance that's 4 or greater is clamped to 4, and then the three absolute distances are added together. If we're within two pages of any anchor, the sum will be at most \\$4+4+2=10\\$ (but could be lower). If we're within three pages of two anchors, the sum will be at most \\$4+3+3=10\\$ (again, it could be lower). If neither of these conditions hold, the sum will be at least \\$4+4+3=11\\$. So we can check whether a page should be displayed by seeing whether the sum is in the range \\$\[0,10\]\\$ or not.

Once the list of pages to include has been determined, they're converted into a list of page numbers of the appropriate format (by pointwise-multiplying the "should be included" boolean by the page number, and then collapsing runs of consecutive zeroes). The runs of consecutive zeroes can be detected by looking for runs of consecutive equal elements, because all the included page numbers will be different from each other.

## Explanation

```
_2«Ɠ»3,‘ŻạⱮ«4§<11×RŒg§
   Ɠ                     Read and parse standard input
  «                      Clamp to at most
_2                         {the argument} minus 2
    »3                   Clamp to at least 3
      ,                  Form a 2-element list with
       ‘                   {the argument} plus 1
        Ż                Prepend 0
          Ɱ              For each number from 1 to {the argument}
         ạ                 take its absolute difference with {each list element}
           «4            Clamp to at most 4
             §           For each {page}, sum the three clamped differences
              <11        1 for sums below 11, 0 for sums at least 11
                 ×       Multiply
                  R        {pointwise} by a list from 1 to {the argument}
                   Œg    Group consecutive equal elements
                     §   Replace each {group} with its sum

```
> 4 votes

# Answer
# Python 3.8, 103 bytes

```
lambda n,m:[S&{i+1}and i for i in range(n)if{i}&(S:={0,1,2,*range(min(n-5,m-2),max(6,m+4)),n-2,n-1,n})]

```

Try it online!

0-indexed. Use `set()` for ellipsis. And it can be 97 bytes if we can output each page numbers as a set.
> 5 votes

# Answer
# Python, 98 bytes (@xnor)

```
lambda n,k:[1,2,3*(k<7),*range(max(6,min(k,m:=n-2))-2,min(max(6,m),k+3+2//k)),m*(k+6>n),n-1,n][:n]
```

Attempt This Online!

### Old Python, 101 bytes

```
lambda n,k:[1,2,3*(k<7),*range(max(4,min(k-2,n-4)),min(max(6,n-2),k+3+2//k)),(n-2)*(k+6>n),n-1,n][:n]
```

Attempt This Online!

### Old Python, 110 bytes (@tsh)

```
lambda n,k:range(1,-~n*(n<9))or[1,2,3*(k<7),*range(max(4,min(k-2,n-4)),min(n-2,k+3+2//k)),(n-2)*(k+6>n),n-1,n]
```

Attempt This Online!

### Old Python, 112 bytes

```
lambda n,k:range(1,-~n*(n<9))or[1,2,3*(k<7),*range(max(4,k-2--2//(k+~n)),min(n-2,k+3+2//k)),(n-2)*(k+6>n),n-1,n]
```

Attempt This Online!

Thanks to @tsh for spotting typo.

1-based, 0 for ellipsis. Outputs a range object instead of a list if n\<9. If that is not acceptable we can add 3 bytes or switch to python 2.
> 4 votes

# Answer
# Python3, 194 bytes:

```
lambda n,p:F([[-1,i][i<3 or p+4-2*(p-2>0)>=i>=p-2-2*(n-p<2)+(n-p==1)or i>n-2]for i in range(1,n+1)])
F=lambda j,l=0:j if[]==j else[[[-1,l+1][l+2 in j],j[0]][j[0]!=-1]]*(j[0]+l!=-2)+F(j[1:],j[0])

```

Try it online!
> 2 votes

# Answer
# 05AB1E, ~~45~~  ~~44~~  38 bytes

<sub>*Crossed out  44  is no longer 44 :)*</sub>

```
4ÝÍ+¤I-F<}¬(ƒ>}3LìI2Ý-«ILÃïêD¥Θ2ä1.ý˜*

```

Inputs in the order \\$p,n\\$. Outputs with 0 for the ellipsis.

Try it online or verify all test cases.

**Explanation:**

Step 1: Create list `[1,2,3,p-2,p-1,p,p+1,p+2,n-2,n-1,n]`, while keeping \\$p-2\\$ and \\$p+2\\$ in bounds, and remove any overlapping duplicated values:

```
4Ý          # Push list [0,1,2,3,4]
  Í         # Decrease each by 2 to [-2,-1,0,1,2]
   +        # Add each to the first (implicit) input p: [p-2,p-1,p,p+1,p+2]
    ¤       # Push the last value / maximum (without popping the list): p+2
     I-     # Decrease it by the second input n
       F }  # (If it's positive) loop that many times:
        <   #  Decrease the values in the list by 1 each iteration
    ¬       # Push the first value / minimum (without popping the list): p-2
     (      # Negate it
      ƒ }   # (If it's now non-negative) loop that + 1 amount of times:
       >    #  Increase the values in the list by 1 each iteration
3Lì         # Prepend-merge list [1,2,3]
 2Ý         # Push list [0,1,2]
I  -        # Subtract each from the second input n: [n,n-1,n-2]
    «       # Merge that list
IL          # Push a list in the range [1,n]
  Ã         # Only keep those values from the list, removing out of bounds values
   ï        # `Ã` converts the values to strings, so convert them back to integers
ê           # Sorted-uniquify the list

```

Step 2: Insert the `0`s where necessary, and output the result:

```
D           # Duplicate this list
 ¥          # Pop the copy, and push its forward differences
  Θ         # Check for each whether it's equal to 1 (1 if 1; 0 otherwise)
   2ä1.ý˜   # Insert a 1 in the middle of the list:
   2ä       #  Split it into two equal-sized parts
     1.ý    #  Intersperse with 1
        ˜   #  Flatten it back to a single list
         *  # Multiply the values at the same positions
            # (after which the result is output implicitly)

```
> 2 votes

# Answer
# Python, 151 bytes

```
lambda l,k:re.sub('  +',' . ',' '.join(str(i)if(i<2 or i>l-3or k-3<i<k+3or(i<5and k<6)or(i>l-6and k>l-7))else''for i in range(l))).split(' ')
import re
```

Attempt This Online!

Returns a list of strings. Abuses regex to remove duplicate spaces. Elipsed pages are replaced with a `.`
> 2 votes

# Answer
# Jelly, ~~34~~ ~~32~~ ~~30~~ ~~29~~ 28 bytes

```
R©ạÞḣ5;⁸’¤;2ḣ⁸Ṭµ+3\ỊŻ¬o×®Œg§

```

Try it online!

Thanks to Unrelated String for -2 byte.

### Explanation (outdated)

```
R©                       Range and copy to register.
   Þ                     Sort by...
  ạ                        Absolute difference with p.
    ḣ5                   First 5 elements.
      ;⁸’¤;2             Append n-1 and 2.
            ®œ&          Intersection with register, for the special case that n=1.
               Ṭ         Untruth (boolean array from truthy indices).
µ                        Chain separator.
ṡ3                       All slices with length 3.
  §                      Sum each slice.
   2=                    True if equals to 2.
     1;                  Prepend 1.
       |                 Vectorized OR with the result of the previous chain.
        ×®               Vectorized multiplication by the register.
          Œg             Group nearby equal elements. Only possible for the zeros.
            §            Sum each group.

```
> 2 votes

# Answer
# JavaScript (ES6), 106 bytes

Expects `(n)(p)`. The output is 1-indexed, with `0` for ellipsis.

```
n=>g=(p,b=k=i=[])=>++k>n?b:g(p,k<(p<3?6:3)|k>n-(p+3>n?5:2)|(p-=k)*p<9?[...b,...k>++i?[k+~i?0:i]:[],i=k]:b)

```

Try it online!
> 1 votes

# Answer
# Retina 0.8.2, 158 bytes

```
.+
$*
\G1
$`1
¶

O`1+
\b(1+) \1\b
<$1>
(?=(1+ ){0,2}<)((1+ |<1+> ){5}).+ 1+( 1+ 1+)
$2...$4
(1+ 1+ )1+ .+(( 1+| <1+>){5})(?<=>( 1+){0,2})
$1...$2
<|>

1+
$.&

```

Try it online! Takes newline-separated values but link is to test suite that splits on spaces for convenience. Explanation:

```
.+
$*

```

Convert to unary.

```
\G1
$`1

```

Generate all of the page numbers.

Concatenate the current page.

```
O`1+

```

Sort it into position, so it's now a duplicate.

```
\b(1+) \1\b
<$1>

```

Change the duplicate into a marking.

```
(?=(1+ ){0,2}<)((1+ |<1+> ){5}).+ 1+( 1+ 1+)
$2...$4

```

Elide at least two page links starting from three pages after the current page to two pages before the last page, but also not starting before page 6.

```
(1+ 1+ )1+ .+(( 1+| <1+>){5})(?<=>( 1+){0,2})
$1...$2

```

Elide page links before the current page, using the same rules but mirrored.

```
<|>

```

Remove the marking for the current page.

```
1+
$.&

```

Convert to decimal.
> 1 votes

# Answer
# Scala 3, 160 bytes

Port of @tsh's Python answer in Scala.

---

```
n=>m=>{val S=Set(0,1,2)++(Math.min(n-5,m-2)to Math.max(6,m+4)-1)++Set(n-2,n-1,n);(0 to n-1).toSeq.filter(i=>S.contains(i)).map(i=>if(S.contains(i+1))i else -1)}

```

Attempt This Online!
> 1 votes

# Answer
# Uiua, ~~54~~ ~~52~~ 49 bytes (SBCS)

~~Previous versions:~~

```
↘1⊜(⊂⊙'⊂¯1)[]>0+=2∩'/+⍉⊃=<3≐'⌵-,⊂⊂0↥3↧⊙(⊃'-2'+1⧻.)∶+1⇡
↘1⊜(⊂⊙'⊂¯1)[]>0+=2∩/+⊃=<3∺'⌵-,⊂⊂0↥3↧⊙(⊃'-2'+1⧻.)∶+1⇡

```

Current version:

```
↘1⊜(⊂⊙'⊂¯1)[]>0+=2∩/+⊃=<3⊂⊟⇌.,⌵-,↥3↧⊙(⊃'-2(+1⇡))∶

```

Note: An extra byte can be saved by reversing the input values (i.e. \[p, n\] rather than \[n, p\].

Try it online! (contains all three versions)

**Explanation:**

```
                                                     ∶
# Reverse the top two items on the stack
                                        ⊙(         )
# Temporarily pop the top item and:
                                           ⊃
# Perform the following two functions on the same values:
                                               (+1⇡)
# Create an array of numbers from 1 to n
                                            '-2
# Get n - 2
                                      ↧
# Get the minimum of p and n - 2
# (This pushes p away from the end, if needed)
                                    ↥3
# Get the maximum of 3 and the result
# (This pushes p away from the beginning, if needed)
                                  ⌵-,
# Copy the 1 to n array and for each item:
# Get the absolute difference between it and the calculated value
# (Creates a n-length array)
                           ⊂⊟⇌.,
# Join the result, the 1 to n array, and its reverse together
# (Creats a 3-by-n matrix)
                       ⊃=<3
# Check if each matrix entry is equal to or less than 3
# (Creates 2 3-by-n matrices)
                    ∩/+
# For both matrices, add each column up
# (Results in 2 n-length arrays)
                  =2
# Convert the counts of =3 to 0s and 1s (1 if there are exactly 2 3s)
                 +
# Add the result to the counts of <3
               >0
# Convert the result to 0s and 1s (1 if the count is >0)
↘1⊜(⊂⊙'⊂¯1)[]
# Use the result to remove the page numbers we shouldn't see and replace them with a -1

```

**Example:**

```
Input: 12 7       Stack (top on left):
                  # 12 7
:                 # 7 12
⊙(               # 12
   ⊃
     (
      ⇡           # [0 1 2 3 4 5 6 7 8 9 10 11]
      +1          # [1 2 3 4 5 6 7 8 9 10 11 12]
     )
     '-2          # 10 [1 2 3 4 5 6 7 8 9 10 11 12]
)                 # 7 10 [1 2 3 4 5 6 7 8 9 10 11 12]
↧                 # 7 [1 2 3 4 5 6 7 8 9 10 11 12]
↥3                # 7 [1 2 3 4 5 6 7 8 9 10 11 12]
⌵-,               # [6 5 4 3 2 1 0 1 2 3 4 5] [1 2 3 4 5 6 7 8 9 10 11 12]
⊂⊟⇌.,            # [[12 11 10 9 8 7 6 5 4 3 2 1][1 2 3 4 5 6 7 8 9 10 11 12][6 5 4 3 2 1 0 1 2 3 4 5]] [1 2 3 4 5 6 7 8 9 10 11 12]
⊃=<3              # [[0 0 0 0 0 0 0 0 0 1 0 0][0 0 1 0 0 0 0 0 0 0 0 0][0 0 0 1 0 0 0 0 0 1 0 0]] [[0 0 0 0 0 0 0 0 0 0 0 1 1][1 1 0 0 0 0 0 0 0 0 0 0 0][0 0 0 0 1 1 1 1 1 1 0 0 0]] [1 2 3 4 5 6 7 8 9 10 11 12]
∩/+               # [0 0 1 1 0 0 0 0 0 2 0 0] [1 1 0 0 1 1 1 1 1 1 0 1 1] [1 2 3 4 5 6 7 8 9 10 11 12]
=2                # [0 0 0 0 0 0 0 0 0 1 0 0] [1 1 0 0 1 1 1 1 1 1 0 1 1] [1 2 3 4 5 6 7 8 9 10 11 12]
+                 # [1 1 0 0 1 1 1 1 1 1 1 1] [1 2 3 4 5 6 7 8 9 10 11 12]
>0                # [1 1 0 0 1 1 1 1 1 1 1 1] [1 2 3 4 5 6 7 8 9 10 11 12]
↘1⊜(⊂⊙'⊂¯1)[]   # [1 2 -1 5 6 7 8 9 10 11 12]

```
> 1 votes

# Answer
# JavaScript (Node.js), 113 bytes

```
n=>p=>[L=0,1,2,p>6?{}:3,p=p>n-2?n-4:p>2?p-2:1,p+1,p+2,p+3,p+4,p<n-7?{}:n-2,n-1,n].filter(v=>v>L&v<=n?(L=v):v>={})

```

Try it online!

Hardcode
> 0 votes

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


title: Tips for golfing in Bash

text:
# Question
Title: Tips for golfing in Bash
What general tips do you have for golfing in Bash? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Bash (e.g. "remove comments" is not an answer). Please post one tip per answer.

# Answer
***Undocumented***, but works in every version I've run into for legacy `sh` backwards compatibility:

`for` loops allow you to use `{` `}` instead of `do` `done`. E.g. replace:

```
for i in {1..10};do echo $i; done

```

with:

```
for i in {1..10};{ echo $i;}

```
> 52 votes

# Answer
For arithmetic expansion use `$[…]` instead of `$((…))`:

```
bash-4.1$ echo $((1+2*3))
7

bash-4.1$ echo $[1+2*3]
7

```

In arithmetic expansions don't use `$`:

```
bash-4.1$ a=1 b=2 c=3

bash-4.1$ echo $[$a+$b*$c]
7

bash-4.1$ echo $[a+b*c]
7

```

Arithmetic expansion is performed on indexed array subscripts, so don't use `$` neither there:

```
bash-4.1$ a=(1 2 3) b=2 c=3

bash-4.1$ echo ${a[$c-$b]}
2

bash-4.1$ echo ${a[c-b]}
2

```

In arithmetic expansions don't use `${…}`:

```
bash-4.1$ a=(1 2 3)

bash-4.1$ echo $[${a[0]}+${a[1]}*${a[2]}]
7

bash-4.1$ echo $[a[0]+a[1]*a[2]]
7

```
> 38 votes

# Answer
The normal, lengthy and boring way to define a function is

```
f(){ CODE;}

```

As this guy found out, you absolutely need the space before `CODE` and the semicolon after it.

This is a little trick I've learned from @DigitalTrauma:

```
f()(CODE)

```

That is two characters shorter and it works just as well, provided that you don't need to carry over any changes in variables' values after the function returns (the parentheses run the body in a subshell).

As @jimmy23013 points out in the comments, even the parentheses may be unnecessary.

The Bash Reference Manual shows that functions can be defined as follows:

> ```
> name () compound-command [ redirections ]
>
> ```
>
> or
>
> ```
> function name [()] compound-command [ redirections ]
>
> ```

A compound command can be:

* a Looping Construct: `until`, `while` or `for`
* a Conditional Construct: `if`, `case`, `((...))` or `[[...]]`
* Grouped Commands: `(...)` or `{...}`

That means all of the following are valid:

```
$ f()if $1;then $2;fi
$ f()($1&&$2)
$ f()(($1))                # This one lets you assign integer values

```

And I've been using curly brackets like a sucker...
> 22 votes

# Answer
`:` is a command that does nothing, its exit status always succeeds, so it can be used instead of `true`.
> 20 votes

# Answer
More tips

1. Abuse the ternary operator, `((test)) && cmd1 || cmd2` or `[ test ] && cmd1 || cmd2`, as much as possible.

Examples (length counts always exclude the top line):

```
    t="$something"
    if [ $t == "hi" ];then
    cmd1
    cmd2
    elif [ $t == "bye" ];then
    cmd3
    cmd4
    else
    cmd5
    if [ $t == "sup" ];then
    cmd6
    fi
    fi

```

By using ternary operators only, this can easily be shortened to:

```
    t="$something"
    [ $t == "hi" ]&&{
    cmd1;cmd2
    }||[ $t == "bye" ]&&{
    cmd3;cmd4
    }||{
    cmd5
    [ $t == "sup" ]&&cmd6
    }

```

As nyuszika7h pointed out in the comments, this specific example could be shortened even further using `case`:

```
    t="$something"
    case $t in "hi")cmd1;cmd2;;"bye")cmd3;cmd4;;*)cmd5;[ $t == "sup" ]&&cmd6;esac

```
1. Also, prefer parentheses to braces as much as possible. Since parentheses are a metacharacter, and not a word, they never require spaces in any context. This also means run as many commands in a subshell as possible, because curly braces (i.e. `{` and `}`) are reserved words, not meta-characters, and thus have to have whitespace on both sides to parse correctly, but meta-characters don't. I assume that you know by now that subshells don't affect the parent environment, so assuming that all the example commands can safely be run in a subshell (which isn't typical in any case), you can shorten the above code to this:

```
 t=$something
 [ $t == "hi" ]&&(cmd1;cmd2)||[ $t == "bye" ]&&(cmd3;cmd4)||(cmd5;[ $t == "sup" ]&&cmd6)

```

Also, if you can't, using parentheses can still minify it some. One thing to keep in mind is that it only works for integers, which renders it useless for the purposes of this example (but it is much better than using `-eq` for integers).

1. One more thing, avoid quotes where possible. Using that above advice, you can further minify it. Example:

```
 t=$something
 [ $t == hi ]&&(cmd1;cmd2)||[ $t == bye ]&&(cmd3;cmd4)||(cmd5;[ $t == sup ]&&cmd6)

```
2. In testing conditions, prefer single brackets to double brackets as much as possible with a few exceptions. It drops two characters for free, but it isn't as robust in some cases (it's a Bash extension - see below for an example). Also, use the single equals argument rather than the double. It is a free character to drop.

```
 [[ $f == b ]]&&: # ... <-- Bad
 [ $f == b ]&&: # ... <-- Better
 [ $f = b ]&&: # ... <-- Best.  word splits and pathname-expands the contents of $f.  Esp. bad if it starts with -

```

Note this caveat, especially in checking for null output or an undefined variable:

```
    [[ $f ]]&&:    # double quotes aren't needed inside [[, which can save chars
    [ "$f" = '' ]&&: <-- This is significantly longer
    [ -n "$f" ]&&:

```

In all technicality, this specific example would be best with `case` ... `in`:

```
    t=$something
    case $t in hi)cmd1;cmd2;;bye)cmd3;cmd4;;*)cmd5;[ $t == sup ]&&cmd6;esac

```

So, the moral of this post is this:

1. Abuse the boolean operators as much as possible, and **always** use them instead of `if`/`if-else`/etc. constructs.
2. Use parentheses as much as possible and run as many segments as possible in subshells because parentheses are meta-characters and not reserved words.
3. Avoid quotes as much as physically possible.
4. Check out `case` ... `in`, since it may save quite a few bytes, particularly in string matching.

P.S.: Here's a list of meta-characters recognized in Bash regardless of context (and can separate words):

```
< > ( ) ; & | <space> <tab>

```

---

EDIT: As manatwork pointed out, the double parenthesis test only works for integers. Also, indirectly, I found that you need to have whitespace surrounding the `==` operator. Corrected my post above.

I also was too lazy to recalculate the length of each segment, so I simply removed them. It should be easy enough to find a string length calculator online if necessary.
> 19 votes

# Answer
Avoid `$( ...command... )`, there is an alternative which saves one char and does the same thing:

```
` ...command... `

```
> 11 votes

# Answer
If you need to pass the content of a variable to STDIN of the next process in a pipeline, it is common to echo the variable into a pipeline. But you can achieve the same thing with a `<<<` bash here string:

```
$ s="code golf"
$ echo "$s"|cut -b4-6
e g
$ cut -b4-6<<<"$s"
e g
$

```
> 10 votes

# Answer
# One-line `for` loops

An arithmetic expression concatenated with a range expansion will be evaluated for each item in the range. For example the following:

```
: $[expression]{0..9}

```

will evaluate `expression` 10 times.

This is often significantly shorter than the equivalent `for` loop:

```
for((;10>n++;expression with n)){ :;}
: $[expression with ++n]{0..9}

```

If you don't mind command not found errors, you can remove the inital `:`. For iterations larger than 10, you can also use character ranges, for example `{A..z}` will iterate 58 times.

As a practical example, the following both produce the first 50 triangular numbers, each on their own line:

```
for((;50>d++;)){ echo $[n+=d];} # 31 bytes
printf %d\\n $[n+=++d]{A..r}    # 28 bytes

```
> 10 votes

# Answer
Instead of `grep -E`, `grep -F`, `grep -r`, use `egrep`, `fgrep`, `rgrep`, saving two chars. The shorter ones are deprecated but work fine.

(You did ask for one tip per answer!)
> 8 votes

# Answer
A shorter syntax for infinite loops (which can be escaped with `break` or `exit` statements) is

```
for((;;)){ code;}

```

This is shorter than `while true;` and `while :;`.

If you don't need `break` (with `exit` as the only way to escape), you can use a recursive function instead.

```
f(){ code;f;};f

```

If you do need break, but you don't need exit and you don't need to carry over any variable modification outside the loop, you can use a recursive function with parentheses around the body, which run the function body in a subshell.

```
f()(code;f);f

```
> 7 votes

# Answer
Element 0 of an array may be accessed with the variable name only, a five byte saving over explicitly specifying an index of 0:

```
$ a=(code golf)
$ echo ${a[0]}
code
$ echo $a
code
$

```
> 7 votes

# Answer
### Use arithmetic `(( ... ))` for conditions

You could replace:

```
if [ $i -gt 5 ] ; then
    echo Do something with i greater than 5
fi

```

by

```
if((i>5));then
    echo Do something with i greater than 5
fi

```

(Note: There is no space after `if`)

or even

```
((i>5))&&{
    echo Do something with i greater than 5
}

```

... or if only one command

```
((i>5))&&echo Echo or do something with i greater than 5

```

### Further: Hide variable setting in arithmetic construct:

```
((i>5?c=1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

```

or same

```
((c=i>5?c=0,1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

```

... where *if i \> 5, then c = 1* (not 0;)
> 7 votes

# Answer
# Loop over arguments

As noted in Bash “for” loop without a “in foo bar…” part, the `in "$@;"` in `for x in "$@;"` is redundant.

From `help for`:

```
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

    Exit Status:
    Returns the status of the last command executed.

```

For example, if we want to square all numbers given positional arguments to a Bash script or a function, we can do this.

```
for n;{ echo $[n*n];}

```

Try it online!
> 7 votes

# Answer
# Use `if` to group commands

Compared to this tip which removes the `if` at all, this should only work better in some very rare cases, such as when you need the return values from the `if`.

If you have a command group which ends with a `if`, like these:

```
a&&{ b;if c;then d;else e;fi;}
a&&(b;if c;then d;else e;fi)

```

You can wrap the commands before `if` in the condition instead:

```
a&&if b;c;then d;else e;fi

```

Or if your function ends with a `if`:

```
f(){ a;if b;then c;else d;fi;}

```

You can remove the braces:

```
f()if a;b;then c;else d;fi

```
> 6 votes

# Answer
# Use `[` instead of `[[` and `test` when possible

**Example:**

```
[ -n $x ]

```

# Use `=` instead of `==` for comparison

**Example:**

```
[ $x = y ]

```

Note that you **must** have spaces around the equals sign or else it won't work. Same applies to `==` based on my tests.
> 5 votes

# Answer
## `tr -cd` is shorter than `grep -o`

For example, if you need to count spaces, `grep -o <char>` (print only the matched) gives 10 bytes while `tr -cd <char>` (delete complement of `<char>`) gives 9.

```
# 16 bytes
grep -o \ |wc -l
# 15 bytes
tr -cd \ |wc -c

```

(source)

Note that they both give slightly different outputs. `grep -o` returns line separated results while `tr -cd` gives them all on the same line, so `tr` might not always be favourable.
> 5 votes

# Answer
# Shorten file names

In a recent challenge I was trying to read the file `/sys/class/power_supply/BAT1/capacity`, however this can be shortened to `/*/*/*/*/capac*y` as no other file exists with that format.

For example, if you had a directory `foo/` containing the files `foo, bar, foobar, barfoo` and you wanted to reference the file `foo/barfoo`, you can use `foo/barf*` to save a byte.

The `*` represents "anything", and is equivalent to the regex `.*`.
> 5 votes

# Answer
# Alternative to cat

Say you are trying to read a file and use it in something else. What you might do is:

```
echo foo `cat bar`

```

If the contents of `bar` was `foobar`, this would print `foo foobar`.

However, there is an alternative if you are using this method, which saves 3 bytes:

```
echo foo `<bar`

```
> 5 votes

# Answer
Sometimes it is shorter to use the `expr` builtin for displaying the result of a simple arithmetic expression instead of the usual `echo $[ ]`. For example:

```
expr $1 % 2

```

is one byte shorter than:

```
echo $[$1%2]

```
> 5 votes

# Answer
Use tail recursion to make loops shorter:

These are equivalent in behavior (though probably not in memory/PID usage):

```
while :;do body; done
f()(body;f);f
body;exec $0
body;$0

```

And these are roughly equivalent:

```
while condition; do body; done
f()(body;condition&&f);f
body;condition&&exec $0
body;condition&&$0

```

(technically the last three will always execute the body at least once)

Using `$0` requires your script to be in a file, not pasted into the bash prompt.

Eventually your stack might overflow, but you save some bytes.
> 4 votes

# Answer
# Alternatives to `head`

`line` is three bytes shorter than `head -1`, but is being deprecated.

`sed q` is two bytes shorter than `head -1`.

`sed 9q` is one byte shorter than `head -9`.
> 4 votes

# Answer
Use a pipe to the `:` command instead of `/dev/null`. The `:` built-in will eat all its input.
> 3 votes

# Answer
`split` has another (deprecated, but nobody cares) syntax for splitting input into sections of `N` lines each: instead of `split -lN` you can use `split -N` e.g. `split -9`.
> 3 votes

# Answer
### Expand away the tests

Essentially, the shell is a kind of macro language, or at least a hybrid or some kind. Every command-line can be basically broken into two parts: the parsing/input part and the expansion/output part.

The first part is what most people focus on because it's the most simple: you see what you get. The second part is what many avoid ever even trying to understand very well and is why people say things like *`eval` is evil* and *always quote your expansions* \- people want the result of the first part to equal the first. That's ok - but it leads to unnecessarily long code branches and tons of extraneous testing.

Expansions are *self-testing*. The *`${param[[:]#%+-=?]word}`* forms are more than enough to validate the contents of a parameter, are nestable, and are all based around evaluating for *NUL* \- which is what most people expect of tests anyway. `+` can be especially handy in loops:

```
r()while IFS= read -r r&&"${r:+set}" -- "$@" "${r:=$*}";do :;done 2>&-

IFS=x
printf %s\\n some lines\ of input here '' some more|{ r;echo "$r"; }

```

---

```
somexlines ofxinputxhere

```

...while `read` pulls in not blank lines `"${r:+set}"` expands to `"set"` and the positionals get `$r` appended. But when a blank line is `read`, `$r` is empty and `"${r:+set}"` expands to `""` \- which is an invalid command. But because the command-line is expanded *before* the `""` null command is searched, `"${r:=$*}"` takes the values of all of the positionals concatenated on the first byte in `$IFS` as well. `r()` could be called again in `|{` compound command `;}` w/ a different value for `$IFS` to get the next input paragraph as well, since it is illegal for a shell's `read` to buffer beyond the next `\n`ewline in input.
> 3 votes

# Answer
# Use `pwd` instead of `echo` to generate a line of output

Need to put a line on stdout but don't care about the contents, and want to restrict your answer to shell builtins? `pwd` is a byte shorter than `echo`.
> 3 votes

# Answer
Quotes can be omitted when printing strings.

```
echo "example"
echo example

```

Output in SM-T335 LTE, Android 5.1.1:

```
u0_a177@milletlte:/ $ echo "example"
example
u0_a177@milletlte:/ $ echo example
example

```
> 3 votes

# Answer
# Abuse function definitions to check for equality

If you want to check if two strings are equal to each other, the obvious way is to use the `[[`/`test`/`[` builtins:

```
[[ $a == b ]]
[[ $a = b ]]
[ $a = b ]

```

But in fact often a shorter way is to define a do-nothing function under the name of `b` and then try to call it with `$a`.

```
b()(:);$a
# zsh only:
b():;$a

```

Depending on the possible values `$a` can take, you might need to add some characters to ensure that it never coincides with the name of a real command:

```
,b()(:);,$a
# zsh only:
,b();,$a

```

If you're testing and immediately using `&&`, then you can put generally put the command after the `&&` as the body of the function:

```
[ $a = b ]&&foo
b()(foo);$a
# zsh only:
b()foo;$a

```

Here are a few answers I've abused this in (Zsh not Bash, but the same idea applies):
> 3 votes

# Answer
#### Output a string based on a test string or numeric test with `expr`

From my question: For any form of test `expr` supports (numerical or string equality, inequality, less than, greater than, regex pattern match, with support for math), there are often ways to use it to improve on the naive approach to echoing a particular string based on a given test. For example, the most straightforward approach to performing an "is a program argument a substring of a fixed string?" test, echoing the string `true` or `false` based on the result, assuming the substring contains no regex special characters, is:

```
[[ FIXEDSTRING =~ $1 ]]&&echo true||echo false

```

But with `expr`, we can shave off six characters by careful use of `&` and `|` to select the string that results from the overall test:

```
expr true \& FIXEDSTRING : .*$1 \| false

```

Changing the `*` to `\*` (and costing a character) if there is a possibility that the command will be run in a directory where `.*$1` would match existing files.

The ordering is important here; `\&` evaluates to the *first* argument (not the second like in Python and similar language) when the overall "and" expression is true, so `true \&` must come before the pattern match test `FIXEDSTRING : .*$1`. The `.*` is needed because pattern matching is implicitly anchored at the beginning, as with `^`, so the `.*` lets it match anywhere. And no, sadly, you can't remove any of these spaces; `expr` expects each operand and operator to be a completely separate argument, so it doesn't need to do any tokenizing of its own, which means the spaces must be there so the shell can tokenize it.

For the specific case of a regex match, you can shorten it four more characters with `sed`, :

```
sed "/$1/ctrue
cfalse"<<<FIXEDSTRING

```

Similar uses allow replacing the various forms of numerical test and echo:

```
[ $1 -gt 0 ]&&echo yes||echo no
[[ $1>0 ]]&&echo yes||echo no
(($1>0))&&echo yes||echo no

```

with:

```
expr yes \& $1 \> 0 \| no

```

which, even with the need to escape the `>`, and despite numerical tests with `(())` allowing you to drop all whitespace, is still two characters shorter than the shortest of the naive approaches. If the comparison is more complex, you can mix-and-match:

```
expr yes \& $[$1>0] \| no

```

is the same length as the purely `expr`-based approach, but grows more slowly in more complex cases (as fewer things need escaping, and spaces aren't needed between terms).
> 3 votes

# Answer
When assigning noncontinuous array items, you can still skip the successive indices of continuous chunks:

```
bash-4.4$ a=([1]=1 [2]=2 [3]=3 [21]=1 [22]=2 [23]=3 [31]=1)

bash-4.4$ b=([1]=1 2 3 [21]=1 2 3 [31]=1)

```

The result is the same:

```
bash-4.4$ declare -p a b
declare -a a=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")
declare -a b=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")

```

According to `man bash`:

> Arrays are assigned to using compound assignments of the form *name*=(value*1* ... value*n*), where each *value* is of the form \[*subscript*\]=*string*. Indexed array assignments do not require anything but *string*. When assigning to indexed arrays, if the optional brackets and subscript are supplied, that index is assigned to; otherwise the index of the element assigned is the last index assigned to by the statement plus one.
> 2 votes

# Answer
## Print the first word in a string

If the string is in the variable `a` and doesn't contain escape and format characters (`\` and `%`), use this:

```
printf $a

```

But it would be longer than the following code if it is needed to save the result into a variable instead of printing:

```
x=($a)
$x

```
> 2 votes

# Answer
It is **almost always** better to receive input as arguments to a script or function instead of on stdin. Examples:

*Input: a string*:

```
# == stdin ==
read a;echo $a
echo `<&0`
# == arguments ==
echo "$1"       # if $1 can have globbing characters/newlines/tabs
echo $1         # if $1 does not have any problematic characters

```

*Input: a list of strings*:

```
# == stdin ==
while read s; do echo $s; done          # one-time use, split on newlines
read -a a;for s in ${a[@]};{echo $s;}   # read one line from stdin; splits on spaces
mapfile a;for s in "${a[@]}";{echo $s;} # read to EOF, split on newlines
# == arguments ==
for s;{ echo $s;}

```

The exception: a list of strings **and** other arguments:

```
read i;while read s; do echo ${s[$i]}; done   # both on stdin
i=$1;shift;for s;{ echo ${s[$i]};}            # both as arguments
read i;for s;{ echo ${s[$i]};}                # list as arguments, other as stdin

```

Additionally, `read` will mangle backslashes without `-r`, and will stop on newlines without `-d ''`, making it even more expensive in worst case scenarios.
> 2 votes

# Answer
# In Pure Bash (or any other pure shellscript), use `.` for looping.

For example, if you want to display each value of 1^2, 2^2, 3^2, ..., 999^2, 1000^2,

```
echo $[++x*x]
((x>999))||. x

```

(where filename is `x`) is shorter than

```
for((;x++<1000;));{
echo $[x*x]
}

```

Try it online!
> 2 votes

# Answer
# Use `$_` (the underscore variable)

The special shell variable `$_` always contains the last argument to the most recently executed command. If you have any sort of immediate repetition in your code, it can probably be reduced with this.

```
touch hello;cat hello
touch hello;cat $_

```

More details can be found in this Unix & Linux question.

(I can't believe this hasn't been posted before, and, as far as I can tell, barely ever even been *used* in code golf before!)
> 2 votes

# Answer
# Know `grep` options

See also man 1p grep and manual for GNU Grep.

## `grep -x foo` is equivalent to `grep '^foo$`

This is POSIX-compatible.

> Consider only input lines that use all characters in the line excluding the terminating \<newline\> to match an entire fixed string or regular expression to be matching lines.

For example, the following two are equal:

> ```
> grep -E '^abc$|^def$'
>
> ```

> ```
> grep -F -x 'abc
> def'
>
> ```
> 2 votes

# Answer
## Doing 2 embed loop with 1 `for` instruction:

```
for ((l=i=0;l<=99;i=i>98?l++,0:++i)) ;do
    printf "I: %2d, L: %2d\n" $i $l
done |
    tee >(wc) | (head -n4;echo ...;tail -n 5)
I:  0, L:  0
I:  1, L:  0
I:  2, L:  0
I:  3, L:  0
...
I: 96, L: 99
I: 97, L: 99
I: 98, L: 99
I: 99, L: 99
  10000   40000  130000

```
> 1 votes

# Answer
In a case statement, it is valid to omit the last ';;' - which saves 2 bytes:

```
#!/bin/sh

case $I in
0)cmdA;;
1)cmdB;;
*)cmdC
esac

```
> 1 votes

# Answer
# Assign and Print quoted strings

If you want to assign a quoted string to a variable, and then print the value of that variable, then the usual way to do that would be:

```
a="Programming Puzzles & Code Golf";echo $a

```

If `a` was previously unset, this may be shortened to:

```
echo ${a=Programming Puzzles & Code Golf}

```

If `a` was previously set, then this should be used instead:

```
echo ${a+Programming Puzzles & Code Golf}

```

Note this is only useful if the string requires quotes (e.g. contains whitespace). Without quotes, `a=123;echo $a` is just as short.
> 1 votes

# Answer
# Use `{..}` expansions with `eval`

Occasionally loops can be shortened by using `eval` with a brace expansion. For example, to run a command `foo` with all letters a-z sequentially; instead of:

```
for x in {a..z};{ foo $x;}
# or, zsh only:
for x ({a..z})foo $x

```

```
eval foo\ {a..z}\;
# or, zsh only:
eval ';foo '{a..z}

```

If you need to reuse the loop variable, it tends to be shorter to use a normal for-loop though.

I can't remember exactly the first answer I saw to do this, but  now use it  lot (those examples are all Zsh because it's obviously superior to Bash, but it's a similar general idea).
> 1 votes

# Answer
## Compress long runs of decimal digits using alternate base representation

`bash`'s arithmetic context supports numbers in arbitrary alternate bases more compactly that any other language I know of (e.g. Python's `int(string,base)` has overhead of five characters for the `int`, `(`, `)`, and `,`, if you aren't given the string from elsewhere, two more for the `'` or `"` around the literal, plus 1-2 characters for the base). By contrast, `bash` only needs three characters to impose arithmetic context, `$[]` (if you're not already in it), and just one character to impose alternate base context, and the same 1-2 characters for the base, so `bash` needs 2-6 characters to do what Python (which is relatively good on this score) needs 6-9 characters to do.

Bash also supports higher bases for integer literals than most languages (topping out at base 64, rather than base 36 as is common; if you use a base above 36, it uses a digit "alphabet" of up to `0-9a-zA-Z@_`).

Between these two features, you can shave up to three characters off long strings of decimal digits by replacing them with arithmetic context (using the shorter form of arithmetic expansion) of a base 64 value. The best savings occur when the digits in question require an even multiple of six bits to represent in binary, and no savings are available unless the decimal representation of the integer is at least 15 characters long, but when it works, it's a great way to shorten further. If you're using it as a number in an existing arithmetic context that does other math, you can save up to 6 characters (since the `$[]` is already paid for by the need to do math, so it doesn't count against the cost of the alternate base), and benefits begin to appear at just 8 decimal digits.

For the best case scenario, a program that needs a literal string numerically equivalent to a number between (with `_` for readability) `1_000_000_000_000_000_000` and `1_152_921_504_606_846_975` can represent such a number as either:

```
1000000000000000000
# or shaving three characters
$[64#TwJHeDp000]

```

If you were already in arithmetic context, it saves six instead:

```
$[var%1000000000000000000]
# becomes
$[var%64#TwJHeDp000]

```
> 1 votes

# Answer
# This work under simple shell

```
cd `mktemp -d` &&>'c'a't'
ln -s /proc/loadavg /proc/uptime .

```

Then now

```
procs=$(*)
echo $procs
0.30 0.08 0.03 1/612 31671 322787.60 1259967.99

```

Nota: Of course, `>cat` could be written `>$(echo -e \\0143\\0141t)`

## Care, from there, you could encouter some issues due to Locales!

**Goto last demo using `LC_ALL=C`**

Same way:

```
mv cat grep
mv loadavg Mem
ln -s /proc/meminfo Zdatas
rm uptime

mems=$(*)
echo $mems
MemTotal: 16386788 kB MemFree: 9816320 kB MemAvailable: 12144892 kB

```

or worst...

```
mv grep sed
mv Mem s+\\\(Mem\\\|Swap\\\).\*\:++p\;d

```

then

```
memsw=$(*)
echo $memsw
16386788 kB 9834080 kB 12163596 kB 0 kB 20971516 kB 20971516 kB

```

So simple is this!

```
declare -p procs mems memsw
declare -- procs="0.14 0.12 0.05 1/612 32078
324221.56 1265616.26"
declare -- mems="MemTotal:       16386788 kB
MemFree:         9832212 kB
MemAvailable:   12161688 kB"
declare -- memsw="       16386788 kB
         9834080 kB
   12163596 kB
            0 kB
      20971516 kB
       20971516 kB"

```

## Last test using `LANG=C`

(or not)

```
cd `mktemp -d` &&>'c'a't'
ln -s /proc/meminfo zdatas
cp c* y+-+-+\;s+\\\(Mem\\\|Swap\\\).\*\:\ \*++p\;d
rename 'y/act/esd/' ???
*

```

may render something like

```
378908 kB
31940 kB
217924 kB
0 kB
102396 kB
102396 kB

```

Or

```
cd `mktemp -d`
ln -s +++\;s+\\\(Mem\\\|Swap\\\).\*\:\ \*++p\;d /proc/me*o ed .
rename 's/^/chr(113+(20>length?1.3*length:8))/e' *
*

```
> 0 votes

# Answer
# Changing behaviour of `+=` by setting *integer* flag

Try this many times:

```
unset i
i=1
for a in {1..10} ;do
    i+=1
    ((RANDOM%9)) || declare -i i
  done
echo $i
11117

```

or in one line

```
unset i;i=1;for a in {1..10};do i+=1;((RANDOM%9))||declare -i i;done;echo $i

```

This could answer something between `20` to `11111111111`...
> 0 votes

# Answer
To print a range of characters (shorter than `echo {a..z}|tr -d ' '`):

```
printf "%s" {a..z}

```

Print range in reverse order (shorter than `printf "%s" {a..z}|rev`):

```
printf "%s" {z..a}

```
> 0 votes

# Answer
### ONE-LINE CONDITIONAL SETTER

NOTE: I see now that this first bit is already present on the first page, so I updated to add another tip (*below the phrase '**EDIT-POINT:**'*) which adds to the initial syntax to achieve a different outcome.

Here is a super efficient way to do control statements in bash.

instead of

```
if [ -e "${var}" ]
then
   echo "${var}"
else
   echo "empty"
fi

```

which translates to the one-liner:

```
if [ -e "${var}" ]; then echo "${var}"; else echo "empty"; fi

```

...you can use logical and / or like so:

```
[ -e "${var}" ] && echo "${var}" || echo "empty"

```

The second bit runs only if the first bit returns a `0` exit code. If either of the first two bits fail to exit with 0 (in other words, if false when used with `[] / test` command), the third bit runs. This means that in production / distribution use cases, this form is often a bad idea (if the `if` logic runs but fails fails, the `else` statement runs..), but for code golf, it is ore than sufficient, so long as you test it on the command line first.

It also works with the `if` / `&&` (no `else` / `||`), e.g.

```
[ -e "${var}" ] && echo "${var}"

```

if that is what you need. This version runs exactly as the long form, without the caveat mentioned above.

**EDIT-POINT:**

Another advantage of using this syntax is that you can put the entire command inside a variable. When you need to set a variable to a value that is based on a condition, this saves a lot of space.

For example,

```
if [ -e "${var}" ]
then
   TEXT="${var}"
else
    TEXT="empty"
fi

```

can be dropped to:

```
TEXT=$([ -e "${var}" ] && echo "${var}" || echo "empty")

```

As a code golf tip, this has limited uses, but they do exist. The space gained or lost depends on the size of the variable name. It adds up to the same as setting a four-letter variable (so ends in unity in the example above.)

Since we use single-letter variable names in code golf, this normally doesn't save any space at all. The space saving effect kicks in when we have no control over the name, in cases where we are using an environment variable in a cheeky way, or when a variable name is provided via a constraint in the question.
> -1 votes

---
Tags: code-golf, tips, bash
---


title: Repeated Digit Primes

text:
# Question
Title: Repeated Digit Primes
Another sequence, another challenge.\*

### Definition

A prime `p` is in this sequence, let's call it `A`, iff for every digit `d` in `p`'s decimal expansion, you replace `d` with `d` copies of `d` and the resulting integer is still prime; zeros are not permitted.

For example, `11` is trivially in this sequence (it's the first number, incidentally). Next in the sequence is `31`, because `3331` is also prime; then `53` because `55555333` is also prime, and so on.

### Challenge

Given an input `n`, return `A(n)`, i.e. the `n`th item in this sequence.

### Examples

Here are the first 20 terms to get you started. This is A057628 on OEIS.

```
11, 31, 53, 131, 149, 223, 283, 311, 313, 331, 397, 463, 641, 691, 937, 941, 1439, 1511, 1741, 1871

```

This means `A(0) = 11`, `A(1) = 31`, etc., when using zero indexing.

### Rules

* You can choose zero- or one-based indexing; please specify in your answer which.
* Instead of returning just the `n`th element, you can instead choose to return the first `n` terms.
* You can assume that the input/output will not be larger than your language's native integer format; however, the repeated-digit prime *may* be larger than your language's native format, so that will need to be accounted for.
* For example, `1871`, the last number of the examples, has a corresponding prime of `18888888877777771`, which is quite a bit larger than standard INT32.
* Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
* Output can be to the console, returned from a function, displayed in an alert popup, etc.
* Standard loopholes are forbidden.
* This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

\*To be fair, I had come up with the first few terms of the sequence just playing around with some numbers, and then went to OEIS to get the rest of the sequence.

# Answer
> 6 votes
# Husk, 15 bytes

```
!fo§&öεpd´ṘΠdİp

```

Try it online!

```
!                 Index into
             İp     the list of primes
 f                    for which:
            d            the digits of p
  o§&                      satisfy both:
     öεpd´Ṙ                  repeated "themselves" times, they form a prime.
           Π                 they are all nonzero.

```

Erik the Outgolfer saved a byte. Using  instead of `εp` would save another byte, but that makes the program so slow it times our even for n = 2.

# Answer
> 6 votes
# 05AB1E, ~~14~~ 13 bytes

-1 byte thanks to Emigna!

```
µNSÐPŠ×JpNpPĀ½

```

Try it online!

### Explanation

```
µNSÐPŠ×JpNpPĀ½
µ              # Do until the input is reached...
 N              # Push the iteration counter
  S             # Split it to its digits
   Ð            # And push two copies of it to the stack
    P           # Get the digital product of the counter
     Š          # And place it two places down the stack
      ×J        # Repeat each digit by itself and join it back to a number
        p       # Check for primality on that result
         Np     # And on the original counter as well
           PĀ   # Create the product and truthify the result
                # Implicit: If it is true increment the input number

```

# Answer
> 5 votes
# Jelly, ~~18~~ 14 bytes

```
ÆPaDxDḌÆPaDẠµ#

```

Try it online!

Mr. Xcoder: -1 Byte (logical all)

Erik the Outgolfer: -2 Bytes (one line instead of two)

HyperNeutrino: -1 Byte (return first n elements of sequence)

**Explanation**

```
ÆPaDxDḌÆPaDẠµ#     First Link
ÆP                Is prime?
  a               logical and
   D              convert number to list of digits
    xD            repeat each digit as many times as it's value
      Ḍ           convert to an integer
       ÆP         is prime?
         a        logical and
          D       list of digits
           Ạ      logical all
            µ     the following link as a monad
             #    Do this until n matches are found and return them all

```

Edit: originally submitted an answer that included numbers with 0 in it's decimal representation which is specifically not allowed.

# Answer
> 5 votes
# Wolfram Language (Mathematica), 100 bytes

```
Nest[#+1//.i_/;!PrimeQ@FromDigits[##&@@#~Table~#&/@(l=IntegerDigits@i)]||Min@l<1:>NextPrime@i&,1,#]&

```

Try it online!

Jonathan Frech saved 3 bytes

and -7 bytes from JungHwan Min

-15 bytes from Martin Ender

also thanks to Jenny Mathy

# Answer
> 4 votes
# Python 2, 130 bytes

* Thanks to ArBo for this four byte shorter solution.

```
f=lambda n,c=9:n and f(n-(('0'in`c`)<p(c)*p(int("".join(d*int(d)for d in`c`)))),c+1)or~-c
p=lambda n:all(n%m for m in xrange(2,n))

```

Try it online!

---

# Python 2, ~~195~~ ~~179~~ ~~167~~ ~~140~~ ~~138~~ ~~136~~ ~~135~~ 134 bytes

* Saved 27 bytes thanks to ovs; using `xrange` instead of `range`, thus circumventing a `MemoryError` and compacting the prime function; improving integer index counting.
* Saved two bytes; using binary pipe or operations `|` to save bytes over `or`.
* Saved two bytes; inverting the prime function and doing some further logic manipulation.
* Saved a byte; using `~-` instead of `0**` to invert the existence of a zero in `j`, as `&` followed by a true boolean isolates this value's boolean property.
* Saved a byte thanks to Lynn; golfing `~-A&B&C` (equivalent to `(not A) and B and C`) with `A, B, C` being booleans to `A<B==C`.

```
def f(n,j=9,p=lambda n:all(n%j for j in xrange(2,n))):
 while n:j+=1;n-=("0"in`j`)<p(j)==p(int("".join(d*int(d)for d in`j`)))
 print j

```

Try it online! (1-indexed)

# Explanation

Defines a main function `f` which takes in an integer index, `n`, and a by default set value `j`, the current sequence canditate (intitiated to `9` to improve performance whilst keeping program size) and a prime checking function.
As long as `n` is non-zero, the `n`-th sequence entry is not yet found. Thus `j` is incremented and `n` is decremented by one iff `j` is a number which satisfies the required properties.
When the loop ends, `j` is the `n`-th sequence entry and thus printed.

# Answer
> 4 votes
## Alice, ~~72~~ ~~70~~ ~~66~~ ~~62~~ 56 bytes

*Thanks to Leo for saving 5 bytes.*

```
/.\&wh...tz~F0/*$\W.tzt$W?K/ o
\i/&.,a:.$K;d&\FR/K.!w.a%

```

Try it online!

Uses 1-based input.

### Explanation

The neatest golfing trick here (even though it only saves a couple of bytes) is that I'm using a primality test which gives `0` for composite **n** for `n` for non-composite **n**. That way, we don't have to use the result directly in a conditional, but we can pass it straight on to the next part that checks that the input doesn't contain any zeros.

```
/i\       Read all input in Ordinal mode (the usual way to read decimal input).
&w        Push the current IP position onto the return address stack (RAS)
          n times. This effectively begins our main loop. We will return
          here after each number we've checked, but whenever we come across
          a repeated digit prime (RDP), we will pop one copy of the address
          from the RAS, so that the loops ends once we've found n RDPs.

h.        Increment our main loop iterator X (initially an implicit zero on
          the empty stack) and duplicate it.
.         Make another copy.
.tz       Drop all factors less than X. This gives X for prime X and 1 for
          non-prime X.
~F        Check whether X divides this value. Of course, X divides X so this
          gives X for non-composite X. But X doesn't divide 1 (unless X is 1),
          so we get 0 for composite X. Call this Y.
0         Push a 0.
\         Switch to Ordinal mode.
F         Implicitly convert both to string and check whether Y contains 0.
$/K       If it does, return to the w. Either way, switch back to Cardinal mode.
          Note that the only numbers that get to this point are 1 and prime
          numbers which don't contain 0. It's fine that we let 1 through here,
          because we'll use a proper primality test for the digit-expanded
          version later on.
.!        Store a copy of X on the tape. Let's call the copy that remains on
          the stack Z, which we're now decomposing into digits while expanding
          them.
w         Push the current IP position to the RAS. This marks the beginning
          of an inner loop over the digits of Z.

  .a%       Duplicate Z and retrieve its last digit D by taking Z % 10.
  \./       Duplicate D (in Ordinal mode but that doesn't matter).
  &.        Duplicate D, D times. So we end up with D+1 copies of D.
  ,         Pop the top D and pull up the Dth stack element, which is Z.
  a:        Discard the last digit by taking Z / 10.
  .$K       If Z is zero now, skip the K and end the inner loop, otherwise
            repeat the inner loop.
;         Discard the 0 (what used to be Z).
          We now have D copies of each digit D on the stack, but the digits
          were processed in reverse order, so the last digit is at the bottom.
d&        Repeat the next command once for each stack element.
\*        Concatenate in Ordinal mode. This joins all the digits on the
          stack into a single string.
R         Reverse that string. This is the digit-expanded version of X.
/         Switch back to Cardinal mode.
W         Pop the inner loop's return address from the RAS. We could have done
          this right after the most recent K, but putting it here helps lining
          up the two Ordinal sections in the program layout.
.tzt      Is the digit-expanded number a prime?
$W        If so, we've found an RDP. Pop one copy of the main loop address
          from the RAS.
g         Recover the current value of X from the top left grid cell.
K         Jump back to the w if any copies of the return address are left
          on the RAS. Otherwise, we leave the main loop.
/o        Implicitly convert the result to a string and print it in
          Ordinal mode.
          The IP will then bounce off the top right corner and start
          travelling through the program in reverse. Whatever it does
          on the way back is utter nonsense, but it will eventually get
          back to the division (:). The top of the stack will be zero
          at that point and therefore the division terminates the program.

```

# Answer
> 3 votes
# Pyth, 21 bytes

```
.f&.AKjZT&P_ss*VK`ZP_

```

**Try it here!**

Rather lengthy as Pyth doesn’t have a *Decimal Expansion* built-in.

* Take the first **N** positive integers (`.f`), that:
    + Have all the digits truthy (`.AKjZT`), and (`&`)...
    + The vectorized multiplication of their string representation with their digits (`*VK`Z`), joined together and converted to an integer (`ss`) are prime (`P_`), and (`&`)...
    + That are primes themselves (`P_`).

# Answer
> 2 votes
# Perl 6, 51 bytes

```
{(grep {!/0/&is-prime $_&S:g/./{$/x$/}/},2..*)[$_]}

```

Try it online!

* `grep {...}, 2..*` filters the infinite sequence of natural numbers starting from 2 using the predicate function between the braces. `(...)[$_]` indexes into this filtered list using the function's argument `$_`.
* `!/0/` filters out numbers that contain a zero digit.
* `S:g/./{$/ x $/}/` replicates each digit in the test number's decimal expansion.
* `is-prime $_ & S:g/./{$/ x $/}/` calls the built-in `is-prime` function with an and-junction of `$_`, the test number, and the number resulting from replicating its digits. The function will return true if both members of the and-junction are prime.

# Answer
> 2 votes
# J, 81 bytes

```
f=.[:1&p:(*@(*/)*x:@#~)&.(10&#.inv)
[:{.(4&p:@{.@]([,]+f@[){:@])^:([>{:@])^:_&2 0

```

This is one of those situations for which I haven't yet found a good J solution.

Nevertheless, I post this in hopes of learning something new.

`f` tells us if a given number is a "repeated digit prime". It breaks down as follows:

```
[:1&p:                               is the following a prime?
      (*@                            the signum of...
         (*/)                        the product of the digits
             *                       times...
              x:@                    force extended precision of...
                 #~)                 self-duplicated digits
                    &.               "Under": perform this, then perform its inverse at the end
                      (10&#.inv)     convert to a list of digits

```

And finally the main Do... While verb, with its pesky, seemingly unavoidable boilerplate, which arises from the fact that we need to use a list to store our progress, which requires both "current prime" and "found so far" registers, since our left argument is already taken to store the stopping condition, ie, `n`. This means that we must use many precious bytes for the simple task of specifying args (`[` and `]`) and unpacking our 2 element list (`{.` and `{:`):

```
[:{.                                                take the first element of the final result, of the following Do... While:
    (4&p:@                                          the next prime after...
          {.@                                       the first element of...
             ]                                      the right arg
                       {:@])                        the last (2nd) elm of the arg...
              ([,]+f@[)                             those two now become the left and right args to this verb...
               [,                                   left arg appended to...
                 ]+                                 right arg plus...
                   f@[                              f of the left arg...
                             ^:(      )^:_          keep doing all that while...
                                [>                  the left is bigger than...
                                  {:@]              the last elm of the right arg
                                          &2 0      seed the process with 2 0, ie,
                                                    the first prime, and 0 rdps found so far.

```

Try it online!

# Answer
> 1 votes
# Vyxal, 88 bitsv2, 11 bytes

```
Þp'f:ẋfṅ⌊æ;~AẎ

```

Try it Online!

Bitstring:

```
0010101101000000100111110011100100110010100100011000111001011001000011111011010100010010

```

---
Tags: code-golf, sequence, number-theory, primes
---


title: Write a C++ demangler

text:
# Question
Title: Write a C++ demangler
If you have ever looked at an objdump of a C++ program, you have likely seen something like this:

```
_ZN3foo3bar3bazI6sampleEE3quxvi3foo

```

This is a C++ mangled symbol, which encodes the namespaces, classes, and function/template arguments, using the Itanium ABI.

Specifically, it is for the following function:

```
void foo::bar::baz<sample>::qux(int, foo);

```

Your job is to demangle a C++ symbol in a dramatically simplified version of the Itanium ABI. (That is **incompatible** with `c++filt` or `__cxa_demangle()`, so don't try it).

Everything will be plain identifiers (so no `int`, `void`, or "special" identifiers like `std::`), no const/pointers, no return type encoding, no reuse of template args, etc.

Specifically, these are the syntax rules:

* All mangled symbols start with `_Z`.
* Everything is case sensitive.
* All identifiers are encoded as `<length><name>`, where `<length>` is the positive length of `<name>` in base 10, so `foo` is encoded as `3foo`, `sample` is encoded as `6sample`, etc.
    + Naturally, this means identifiers will never start with a number (but they can contain numbers after the first letter/underscore). For you regex fans, it is `[a-zA-Z_][a-zA-Z0-9_]*`.
* Each symbol is one base identifier, optionally followed by a list of function parameters.
* Each identifier can be prefixed with a namespace, or suffixed with a template.
    + Namespaces are encoded as a sequence of 1 or more identifiers between an `N` and an `E`. Each identifier is printed as the identifier, followed by `::`. So `N3fooE` is `foo::`, and `N3foo3barE` is `foo::bar::`.
        - Namespaces will never have a namespace themselves: you don't have to worry about `NN3fooE3barE`.
    + Templates are encoded similar to namespaces, only using `I..E` instead of `N..E`. They are printed as a comma separated list of identifiers, wrapped in `<angle brackets>`. These come before `::` in a namespace. So `I3fooE` is `<foo>`, and `I3foo3barE` is `<foo,bar>`.
    + **These may be nested.**
* All identifiers *after* the base symbol are to be treated as function parameters, and they are to be printed as a comma separated list wrapped in `(parentheses)`. This does not apply to namespaces or template arguments.

So, let's take a simpler example:

```
_ZN3fooI3barEE3baz3qux
_Z                      Mangle prefix
              3baz      Base: Identifier baz
  N          E           Namespace
   3foo                   Identifier foo
       I    E              Template
        3bar                Identifier bar
                  3qux  Parameters: Identifier qux

```

The result is this:

```
foo<bar>::baz(qux)

```

Your function or program will take a single string containing a mangled symbol, and the output will be the demangled symbol.

You can safely assume each string will only contain numbers, letters, and underscores, and that every identifier will be 99 characters or less.

Assume all symbols are valid, standard input/output format, you know the deal.

You can have any amount of whitespace between identifiers, however, empty parameter/template/namespaces and trailing commas are **not** allowed.

This is , so shortest program in bytes wins.

### Test cases:

```
_Z1x -> x
_Z3foo3bar -> foo(bar)
_ZN3fooE3bar -> foo::bar
_Z3FOOI3barE -> FOO<bar>
_Z3foo3bar3baz -> foo(bar,baz)
_Z3fooI3barE3baz -> foo<bar>(baz)
_Z3fooI3bar3bazE -> foo<bar,baz>
_ZN3fooE3bar3baZ -> foo::bar(baZ)
_ZN3fooI3barEE3baz3qux -> foo<bar>::baz(qux)
_ZN9CPlusPlusI2isEE11soooooooooo5great -> CPlusPlus<is>::soooooooooo(great)
_ZN2soI1II4herdEE1UI4liekEE9templates -> so<I<herd>>::U<liek>::templates
_Z12identifier12 -> identifier12
_Z2_Z -> _Z
_ZN1a1b1c1d1e1f1g1hE1i -> a::b::c::d::e::f::g::h::i
_ZN1a1bI1c1d1eE1fE1gN1hE1iIN1jE1kI1lEEN1m1nE1o -> a::b<c,d,e>::f::g(h::i<j::k<l>>,m::n::o)
_Z14N3redE7herring1x7foo_bar -> N3redE7herring(x,foo_bar)

```

Sandbox

# Answer
# C (gcc), ~~267~~ ... ~~222~~ 221 bytes

*-30 bytes thanks to @EasyasPi*
*-8 more bytes thanks to @EasyasPi and @ceilingcat*
*-1 more byte thanks to @ceilingcat*

```
#define P puts(
char*m;a(){if(*m==73){P"<");for(++m;*m^69;*m-69&&P","))p();m++;P">");}}p(){if(*m==78){for(++m;*m^69;P"::"))p();++m;}a(m+=write(1,m,strtol(m,&m,!a())));}z(char*t){p(m=t+2);for(*m&&P"(");*m;P!*m+L",)"))p();}

```

Try it online! For pretty output, see previous revisions.
> 17 votes

# Answer
# Python 3, ~~460~~ ~~417~~ ~~362~~ 355 bytes

Try it online!

*-43 bytes thanks to @Easyaspi*
*-55 bytes thanks to @ovs*
*-7 bytes thanks to @Arnauld*

```
import re
m=input()[2:]
o=""
def a():
 global m,o
 if"I"==m[:1]:
  m=m[1:];o+="<"
  while"E"!=m[:1]:p();o+=","
  m=m[1:];o=o[:-1];o+=">"
def p():
 global m,o
 if"N"==m[:1]:
  m=m[1:]
  while"E"!=m[:1]:p();o+="::"
  m=m[1:]
 a();j=int(re.match(r'\d+',m)[0]);b=len(str(j));o+=m[b:j+b];m=m[j+b:];a()
p()
if m:
 o+="("
 while m:p();o+=","if m else")"
print(o)

```
> 13 votes

# Answer
# brainfuck, 494 bytes

```
>>+++++[->++++++++<]>>>>>,,,[<+>>+++++++[-<---------->]<+[----[<<[<<[.<]>[>]++++++++[-<----->]<[>>-<<[->+<]]>[-<+>]++++++++[-<+++++>]>[<<++++<++++++[-<+++++++>]<->>>>-]]>>-----[>+++++[-<++++++>],[>++++++[-<-------->]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[<<->>>-[-<+++++++>]<+.[-]]]]]]]]]]]<<[>[->>++++++++++<<]>>[-<<+>>]<,<<-]+>>]<-[-<,.>]<[-]<+>>]<[->>+++++++[->++++++++<]>++[->+>+<<<<+>+>]>>>>>]>]<[+++++[->++++++++++>>+++++++<<<]>.++>>++>>>]>]<[-<[-]<<[[-]<]<[.[-]<]]>,]<<<<[<]<[.<]

```

Try it online!

While working on my JavaScript solution, I noticed that a relatively simple stack machine would be able to solve this task. So, naturally, I wrote a Brainfuck solution. Yes, I was bored, what did you expect? Probably still beats Java.

The TIO interpreter handles identifiers of up to 255 chars. Any length should work with an interpreter that has bigint cells and returns 0 for EOF.

### Annotated (with a chance of undecipherability)

```
cell layout
| 0 | finterm | 0 | finsep | 0 | sepflag | parseflag | char/accum | digit | holding |
                                         | 0         | term       | 0     | sep     | etc

>> make space for terminator
+++++ create 5
[- > ++++++++ <] >>> convert to 0 40 0 = (
> add sepflag cell
> add parseflag cell

,, skip _Z

, start reading #
[ loop over input (char cell)
  <+> set parseflag
  > +++++++ set digit cell to 7
  [- < ---------- >] < + subtract E
  [ not E
    ---- subtract I
    [ not I; must be some kind of identifier start
      <<[ sepflag cell set
        <<[.<] print separator
        >[>] return to right of separator
        ++++++++ create 8
        [- < ----- >] subtract ( from separator
        <[ separator wasn't (
          >> - clear sepflag
          << [- > + <] move separator to right
        ]
        > [- < + >] move separator back
        ++++++++ create 8
        [- < +++++ >] fix separator
        >[ sepflag is set; separator was (
          << ++++ update separator to comma
          < ++++++ create 6
          [- < +++++++ >] < - set terminator to 41 )
          >>>>- clear sepflag
        ]
      ]
      >> back to char cell
      ----- subtract N
      [ not N; must be simple identifier #
        > +++++ create 5
        [- < ++++++ >] add back to ch minus 0
        , read into digit cell
        [
          > ++++++ create 6
          [- < -------- >] subtract 0
          < [ not 0
            ->+< [ not 1
              ->+< [ not 2
                ->+< [ not 3
                  ->+< [ not 4
                    ->+< [ not 5
                      ->+< [ not 6
                        ->+< [ not 7
                          ->+< [ not 8
                            ->+< [ not 9 or any digit #
                              <<- clear parseflag
                              >>> - set digit holding cell to 8
                              [- < +++++++ >] < + return the char to its former glory (add 57)
                              . print as first identifier char
                              [-] clear digit cell
                            ]
                          ]
                        ]
                      ]
                    ]
                  ]
                ]
              ]
            ]
          ]
          <<[ parseflag still set; was some digit #
            > back to accumulator
            [->>++++++++++<<] add 10x accumulator to holding
            >>[-<<+>>] move the value back to accumulator
            <, read new digit cell
            <<- clear parseflag to exit this if
          ]
          + reset parseflag to keep parsing digits
          >> back to digit cell
        ]
        digit cell clear; accumulator is valid number now #
        < go to accumulator
        -[-<,.>] print n minus 1 chars; clears accumulator and overwrites parseflag
        <[-] clear parseflag
        <+ set sepflag
        >> back to char cell
      ]
      <[ parseflag set; was N #
        - clear parseflag
        >> +++++++ create 0 0 7 starting from parseflag
        [- > ++++++++ <] > ++ convert to 0 0 0 (58)
        [- > + > + <<<< + > + >] convert to 0 58 58 0 > 58 > 58 > 0 > 0 > (0)
        we are now at new parseflag
      ]
      > back to char cell
    ]
    <[ parseflag set; was I #
      +++++ set parseflag cell to 6
      [- > ++++++++++ >> +++++++ <<<] convert to 0 > (60) 0 42
      . print 60 = lbracket
      ++ >> ++ > convert to 0 62 0 44 0 > 0 > (0)
      we are now at new parseflag
    ]
    > back to char cell
  ]
  <[ parseflag set; was E #
    - clear parseflag
    <[-] clear sepflag cell
    <<[[-]<] clear separator
    <[.[-]<] print and clear terminator
    we're now in prev parseflag cell which is clear
  ]
  > back to char cell
  , read new char #
]
<<<<[<] skip separator
<[.<] print terminator

```
> 13 votes

# Answer
# JavaScript (Node.js), ~~287~~ 233 bytes

Saved **a ton of bytes** thanks to @A username, @FZs, @Arnauld and @Recursive Co.!
(Hope I didn't miss anyone!)

```
(i,r="",P=2,s=c=>i[P]!=c,e=_=>{if(!s`N`)for(P++;s`E`||!++P;r+="::")e();r+=i.slice(P+=b=`${l=parseInt(i.slice(P))}`.length,P+=l);s`I`||P++&a`<>`&P++},a=([[p,q]])=>{for(r+=p;i[P]&&s`E`;i[P]&&s`E`?r+=",":0)e();r+=q})=>i[e(),P]&&a`()`||r

```

Try it online!
> 7 votes

# Answer
# Haskell, 257 bytes

```
(l:r)%x=l:tail(x>>=(',':))++r
h('I':r)|(x,e:r)<-f r=("<>"%x,r)
h e=("",e)
f('N':r)|(x,e:r)<-f r,(h:t,r)<-f r=(((x>>=(++"::"))++h):t,r)
f r|[(n,r)]<-reads r,(i,u)<-h(drop n r),(x,u)<-f u=((take n r++i):x,u)
f e=([],e)
p[x]=x
p(x:y)=x++"()"%y
z=p.fst.f.drop 2

```

Try it online!
> 7 votes

# Answer
# Pyth, ~~97~~ ~~96~~ ~~95~~ 93 bytes

```
L*bnz=:z+\^bkL?y\Ek++Eb'bDER&z++&y\N'"::"&yJh:z"\D"3y<zsJ&y\IjP'\,"<>"=ttzpEIzjj\,ufTaYE0)"()

```

Try it online!

I really didn't expect to beat Retina, and I still think it might come back. Pyth kinda shows its age, but this is starting to feel pretty nicely optimized. I also got to use some very rarely used Pyth features like the imperative `D`, `R` and `I`.

Passes all tests. Requires the `-M` flag to disable memoization.

### Explanation

The program consists of three functions and main code. At the start, input is read to `z`.

The first function `L&nz=:z+\^bkb` consumes its argument from the input if it matches.

```
L                Define y(b):
L*bnz=:z+\^bk
        +\^b      Compute "^" + b.
      :z    k     Replace this regex in z with k="".
     =            Save this in z.
   nz             See if it is different from the previous value of z.
 *b               If so, return b, otherwise "". (Multiply b by 1 or 0).

```

We'll only be passing `N`, `I`, `E`, numbers and simple identifiers to this, so we can safely use them as regex. There will only ever be 0 or 1 matches thanks to `^`.

The second function `L?y\Ek++Eb'b` recursively demangles a namespace or template, adding its argument after each identifier.

```
L              Define '(b):
  y\E            Match, consume and return E from z.
 ?               If it was present,
     k           return k.
        E        Otherwise, call E() to demangle an identifier,
       + b       add b,
      +   'b     and recursively call '(b) and add that.

```

The third (monster) function `DER&z++&y\N'"::"&yJh:z"\D"3y<zsJ&y\IjP'\,"<>"` recursively demangles identifiers with namespaces and templates.

```
DE                                               Define function E():
   &z                                              If z is "", return it.
     ++                                            Concatenate:
        y\N                                        - Match, consume and return N from z.
       &   '"::"                                     If it matched, '("::").
                                                     Otherwise, "".
                    :z"\D"3                       - Split z by non-digits.
                   h                                Take the first piece.
                  J                                 Save it in J.
                 y                                  Consume and return it from z.
                &                                   Always truthy, continue.
                              sJ                    Convert J to int,
                            <z                      take that many chars from z,
                           y                        consume and return them.
                                 y\I              - Match, consume and return I from z.
                                &     '\,           If it matched, call '(","),
                                     P              remove the last ",",
                                    j    "<>"       and put the rest in <>.
                                                    Otherwise, "".
  R                                               Return that.

```

Finally, the main code.

```
 ttz                      Strip the first 2 chars of z
=                         and store the result back in z.
     E                    Call E()
    p                     and print the result without newline.
      Iz                  If z isn't empty,
            u     0)        For all H=0,1,..., repeat until results stop changing:
                 E            Call E(),
               aY             append that to Y (initially []),
             fT               and remove falsey elements (i.e. "").
         j\,                Join the values (of Y) with ",".
        j           "()     Put the result in () and print.

```
> 6 votes

# Answer
# JavaScript (Node.js), ~~216~~ ~~215~~ ~~213~~ ~~204~~ ~~197~~ 188 bytes

```
(m,o=2,X=A=>m[o]<X?X(n=A+m[o++]):o,M=x=>m[o]==x?o++:"",I=(e="")=>m[o]?M`E`?"":e+(M`N`&&I()+I`::`+"::")+m.slice(X``,o+=+n)+(M`I`&&`<${I()+I`,`}>`)+(e&&I(e<I?(a=")",","):e)):a)=>I(a="")+I`(`

```

Try it online! (comes with test cases)

Turns out keeping a major fork of my approach was useful after all. I ended up dropping half of the functions, switching from arrays to strings, and weirdly enough, this new code has lots of repetition that wasn't in the old one.

I wrote this independently based on my Pyth answer's algorithm, and it's currently shorter than any suggestion on the other JS answer, so I'm posting it separately.

### Previous approach (197 bytes)

```
([,,...m],X=A=>m<X?X(A+M(m[0])):A,M=x=>m[0]==x?m.shift():"",N=e=>M`E`?[]:[I()+e,...N(e)],I=_=>[...M`N`&&N`::`,...m.splice(0,X``),M`I`&&`<${N``}>`].join``,R=s=>m+""&&s+I(a=")")+R`,`)=>I(a="")+R`(`+a

```

### Explained

```
(
  m,       // Input string.
  o = 2,   // Offset into input string.

  X = A =>     // Matches and consumes numbers in input.
    m[o] < X      // Compare input to the stringification of the
                  // function X. Since that begins "A=>", and
                  // valid identifier start chars are all >= "A",
                  // this only matches numbers.
    ? X(          // If we got a number,
      n = A + m[o++] // add it to arg and consume it,
                     // save the result to n,
    )             // then keep parsing.
    : o           // Otherwise, return the current input offset.

  M = x =>     // Matches and consumes input. Used as M`E` or M("E").
    m[o] == x     // Check if first char of input equals (stringified) arg.
    ? o++         // If matched, consume and return something truthy.
    : "",         // Otherwise return "" (falsy and a string).

  I = (e = "") =>  // Recursively demangles identifiers. E-terminated if e!="".
    m[o]              // See if the input is empty.
    ? M`E`            // If input not empty, try to consume "E" from input.
    ? ""              // If successful, return "".
    :                 // Otherwise:
    e                    // Start with the separator.
    + (
      M`N`               // Try to consume "M" from input.
      &&                 // If the match fails, "".
      I()                // If successful, parse an identifier,
      + I`::`            // parse an E-terminated identifier, prefixing
                         // each part with "::",
      + "::"             // and add an additional "::".
    )                    // Append this to the result.

    + m.slice(
      X``,               // Parse a number from input, store it in n and
                         // get the input offset after the number.
      o += +n            // Add n to the input offset.
    )                    // Get the n characters between these indices
                         // and append them to the result.
    + (
      M`I`               // Try to consume "I" from input.
      &&                 // If the match fails, "".
      `<${
        I()              // If successful, parse an identifier,
        + I`,`           // parse an E-terminated identifier, prefixing
                         // each part with ",",
      }>`                // and wrap these in <>.
    )                    // Append this to the result.
    + (
      e &&               // If not parsing an E-terminated identifier, "".
      I(
        e < I ? (        // Otherwise, if the separator is less than the
                         // stringification of I (starting "(e=" which
                         // only matches "("),
          a = ")",       // set the terminator to ")"
          ","            // and use "," as the next separator.
        ) : e            // Otherwise, keep using the same separator.
      )                  // Keep searching with that separator.
    ) : a             // If the input was empty, return the terminator.
) =>
  I(           // Parse an identifier
    a=""       // (and initialize a=""),
  ) + I`(`     // then parse an E-terminated identifier (until EOF).

```
> 6 votes

# Answer
# Retina 0.8.2, 133 bytes

```
1`\d+(?=.*\z)
$*#
}`(#)+((?<-1>.)+)
@$2¶
{`N(@.*)¶@
$1::N@
N(@.*)¶E@
$1::
(¶I@.*)¶@
$1,
}`¶I@(.*)¶E
<$1>¶
^_Z|@|¶$

1>`¶
,
¶(.+)
($1)

```

Try it online! Link includes test cases. Explanation:

```
1`\d+(?=.*\z)
$*#

```

Convert the first integer in the (remainder of the) unconverted string to unary.

```
(#)+((?<-1>.)+)
@$2¶

```

Extract the identifier after the integer, mark it so that it doesn't get confused with `N` or `E` marks, and put it on its own line with the remainder of the unconverted string on the next line.

```
}`

```

Repeat until all of the identifiers have been extracted.

```
{`
}`

```

Repeat until all namespaces and templates have been processed.

```
N(@.*)¶@
$1::N@

```

If a type has more than one namespace then join each one with the next using `::`.

```
N(@.*)¶E@
$1::

```

If this is the last namespace then join it to the type and remove the namespace markers.

```
(¶I@.*)¶@
$1,

```

If a type has more than one template then join it to the next using `,`.

```
¶I@(.*)¶E
<$1>¶

```

If this is the last type in the template then wrap the types in `<>` and remove the template markers.

```
^_Z|@|¶$

```

Remove all the remaining leftovers.

```
1>`¶
,
¶(.+)
($1)

```

If this is a function then separate the parameters with `,` and wrap them in `()`.
> 5 votes

# Answer
# Knight (UB), 142 bytes

```
;=xP;=l';W&x-69Ax;Cp&&x-69AxO","Cn';C=nB=xSxF1"";Cn;C=pB;O;&?78Ax;E;CnSl 22T"::"O"::"GxL=m+0x m;=xSxF+mLm""&?73Ax;O"<";Cn;ElO">"&x;O"(";ElO")"

```

Try it online!

Shameless non-winning self-answer.

It is a pretty good example of recursion and EVAL/BLOCK in Knight.

Abuses this interpreter's acceptance of out of bounds `ASCII` and `GET`. This won't work on the c/ast interpreter as `ASCII("")` is an error and so is reading past the end of a string.

```
# Read line
; = symbol PROMPT
# Template for printing identifier lists
; = parse_iden_list '
    # While symbol is not empty and not E
    ; WHILE & symbol - 69 ASCII(symbol)
        # Recurse into parse()
        ; CALL parse()
        # If symbol is not empty and not E, print sep
        : &(& symbol - 69 ASCII(symbol))
            # dynamically replaced separator
            OUTPUT ","
    # Pop the "E".
    # UB: This actually cuts off an extra char from the string,
    # but since the interpreter uses strchr to replace newlines,
    # there is going to be an extra null byte to save us.
    : CALL pop()
'
; = pop() BLOCK {
    : = symbol SUBSTITUTE(symbol 0 1 "")
}
# Pop the _Z
; CALL pop()
; CALL pop()
; = parse() BLOCK {
    # Check for N
    ; & ? 78 ASCII(symbol)
        ; CALL pop()
        # Parse the identifier list, replacing "," with "::".
        # I cba to update the offset for the ungolfed version
        ; EVAL SUBSTITUTE(parse_iden_list 22 1 "::")
        # print trailing "::"
        : OUTPUT "::"
    # Get the length (done inline in golfed code)
    # by converting the string to a number.
    ; = length + 0 symbol
    # Print length chars after the number
    # LENGTH(number) will convert int to string and take the length.
    ; OUTPUT GET(symbol, LENGTH(length), length)
    # Pop the number and the identifier
    ; = symbol SUBSTITUTE(symbol (+ length LENGTH(length)) 0 "")
    # Check for I
    # UB: Again, this will technically read out of bounds, but
    # this will in practice return the null terminator.
    : & (? 73 ASCII(symbol))
        ; CALL pop()
        ; OUTPUT "<"
        ; EVAL parse_iden_list
        : OUTPUT ">"
}
# Parse base identifier
; CALL parse()
# Check for parameters
: & symbol
    ; OUTPUT "("
    ; EVAL parse_iden_list
    : OUTPUT ")"

```

---

# Knight (no known UB), 146 bytes

```
;=xP;=l';W&x-69Ax;Cp&&x-69AxO","&xCn';C=nB=xSxF1"";Cn;C=pB;O;&?78Ax;E;CnSl 22T"::"O"::"GxL=m+0x m;=xSxF+mLm""&&x?73Ax;O"<";Cn;ElO">"&x;O"(";ElO")"

```

Try it online!

Simply adds some range checks to avoid reading an empty string.
> 4 votes

# Answer
# Raku, ~~221~~ 218 bytes

```
->[\a,*@b]{a~"({join ',',@b})"x?@b}o{my rule s{(\d+){}:my$n=$0;(.**{$n})}
my rule i{(N$<n>=<~~>+E)?<s>(I$<t>=<~~>+E)?}
sub p($/){join('::',$0<n>».&p,'')xx?$0~$<s>[1]~("<{join ',',$1<t>».&p}>" if $1)}
m/<i>+/<i>».&p}

```

Try it online!

Leverages the considerable power of Raku's regexes.
> 2 votes

# Answer
# Red, 236 bytes

```
func[s][d: charset[#"0"-#"9"]i:[copy x[1 2 d](x: do x)keep x skip]n:["N"any[b keep("::")]"E"]t:["I"keep("<")any[b["E"keep(">")break | keep(",")]]]b:[any[n]i opt t]parse s[collect["_Z"b[end | keep("(")any[b[end keep(")")| keep(",")]]]]]]

```

Try it online!

Output is block that gets printed with a lot of extraneous whitespace, which is allowed, but prepending it with a simple `rejoin` will produce precisely the same results as in the examples.

Overall, this looks like a perfect task for learning Red's Parse dialect, so here's my attempt at it:

```
func[s][
 ; Digits rule:
 d: charset[#"0"-#"9"]
 ; Identifiers rule:
 i: [copy x[1 2 d](x: do x)keep x skip]
  ; Match 1-2 digits, copy to x, eval x as number, skip and save next x characters
 ; Namespaces rule:
 n: ["N"any[b keep("::")]"E"]
  ; "N", any number of Base components (b) appended with "::" ,"E"
 ; Templates rule:
 t: ["I"keep("<")any[b["E"keep(">")break | keep(",")]]]
  ; "I" (change to "<"), any number of b appended with "," or with ">" if followed by "E"
 ; Base component rule:
 b: [any[n]i opt t]
  ; Any number of namespaces, main identifier and optional template
 ; Actual parse operation:
 parse s [collect ; 'collect' all entries after 'keep'
   ; Final rule:
   ["_Z" b [end | keep("(") any [ b [end keep(")") | keep(",")]]]]]
   ; "_Z", base component, "(" if the input hasn't ended yet,
   ; any number of subsequent b's as parameters, separated by "," and ")" in the end
]

```
> 2 votes

# Answer
# Befunge-98, 151 bytes

```
~~1345x
>]')\j,@
 ~
^>:'E-  v  >'>,
^  v-I':_$2w'::,,3
^v\_$'<,03>
 j
v>',,0
v>'(,0
v>'::,,2
\
>>:'N-v
v<  \0_$23^
'~>$68x
0+w~ v
-*0
:a:
a\-
w^^1,<+0'

```

Try it online! | Run all test cases.

Something something, stack machines. Getting dangerously close to the golf languages.

(I got a notification from my Brainfuck answer and decided this had to be done :D)
> 0 votes

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