title: Backronymiser

text:
# Question
Title: Backronymiser
## *Back*ground

A **backronym** is an acronym that was formed from an existing word. For example, *spam* is actually named after the canned meat product as used in the Monty Python sketch, but can be interpreted as "stupid pointless annoying mail".

## Challenge

Given a string `a`, and a word `t`, capitalise the correct letters of the words in `a` such that they spell out `t`. You should always move left-to-right through `a`, and capitalise the first occurrence of each letter.

For example, if `a` is `all the worlds a stage`, and `t` is `LAG`, then we walk along the letters of `all the worlds a stage`:

* we look for the first `l` and capitalise it: `aLl the worlds a stage`
* now we look for the next `a`, but it must be after the previously found `l`: `aLl the worlds A stage`
* now we look for a `g`: `aLl the worlds A staGe`.

You may assume `a` will only contain lowercase ASCII letters and spaces.

You may assume `t` will only contain ASCII letters. You should choose whether `t` will be input in uppercase or lowercase.

You do not need to handle empty inputs or inputs that have no possible backronymisation.

## Test cases

```
a                            t        output
================================================================
never gonna give you up      VIP      neVer gonna gIve you uP
all the worlds a stage       LAG      aLl the worlds A staGe
why                          WHY      WHY
baacbbccba                   ABC      bAacBbCcba
x                            X        X
xxxx                         X        Xxxx
yellow submarine time        YEET     YEllow submarinE Time

```

## Rules

# Answer
> 22 votes
# C (gcc), 49 bytes

```
f(char*a,char*t){for(;*a;)*a++^=*a-*t?0:32+!++t;}

```

Try it online!

Modifies `a` in place. Input `t` lowercase.

# Answer
> 10 votes
# Python 3.10, ~~76~~ ~~73~~ ~~47~~ ~~57~~ ~~51~~ 49 bytes

```
def f(a,t,i=0):
 for c in t:a[i:=a.find(c,i)]-=32

```

Attempt This Online

Takes in `a` and `t` as byte arrays with UTF-8 encodings with `t` lowercase, modifies `a` in place.

---

-3 bytes from @pxeger for replacing the double spaces with single spaces (I blame my IDE for auto-converting my tabs)
-26 bytes from @Cong Chen because the rules allow you to take in a list of characters and modify it in place (I should have read the rules more carefully)
+10 bytes from @Cong Chen because all of the previous methods just didn't work properly (not sure how to notate this)
-6 bytes by using code points instead of characters
-2 bytes from @loopy walt by using byte arrays & walrus operator

# Answer
> 8 votes
# , 49 bytes

```
toupper@[`(0{"1[:(|.~"#:0,2>:/\{."1)^:_[:I.=/)`]}

```

Try it online!

This challenge resisted all my attempts to find a short array paradigm solution.

I tried more than 5 approaches, and my best result is still rather long.

It's interesting to contrast how simple it is to solve procedurally -- you need only a single loop and a single register.

## my best idea

The interesting part of the solution is calculating the indices of the uppercase letters.

Consider `'abc' f 'xbacbcb'`.

* First we construct an equality table:

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

```
* And then convert each row to the indices of its ones, with zero fill:

```
2 0 0
1 4 6
3 5 0

```
* Finally, we start rotating any "out of order" rows to the left. A row is out of order if first element is not greater than the first element of the row above. We continue rotating until a fixed point is reached: the entire first column is increasing.

```
Focus on first column
|
v
2 0 0
1 4 6  <-- 1 less than 2, so rotate
3 5 0

2 0 0
4 6 1
3 5 0  <-- 3 less than 4, so rotate

2 0 0
4 6 1
5 0 3  <-- now 2, 4, 5 increasing, so done

```
* We now have our answer: `2 4 5` are the indices we need to capitalize.

# Answer
> 7 votes
# Curry (KiCS2) \+ `:set +first`, 61 bytes

```
import Data.Char
(f s)#(g s)=s
f=map toLower
g=filter isUpper

```

Attempt This Online!

`a # t` finds a string `s` such that converting `s` to lowercase gives `a`, and picking out the uppercase characters in `s` gives `t`.

Curry is a functional logic programming language. It searches for solutions using backtracking. Without `:set +first` it would return all possible solutions. With `:set +first` it only gives the first one.

This works on KICS2 3.0.0. It seems that it does not work on PAKCS or older versions of KICS2.

# Answer
> 7 votes
# Prolog (SWI), 55 bytes

```
[H|T]+Z+[X|P]:-[H|B]=Z,X is H-32,T+B+P;X=H,(T+Z+P;P=T).

```

Try it online!

-33 bytes thanks to Jo King

Recursive.

# Haskell, 44 bytes

```
x#[]=x
(h:t)#a@(x:b)|h==x=h-32:t#b|1>0=h:t#a

```

Try it online!

I/O as codepoints. -2 bytes thanks to alephalpha

# Answer
> 6 votes
# Vyxal, 12 bytes

```
v=vTΠ~Þ⇧h⁽⇧V

```

Try it Online! I/O as char lists.

I feel like there's gotta be a smarter/faster way to do `Π~Þ⇧h`.

```
v=           # Create an equality table
  vT         # Get all indices of each letter in the string
    Π        # Take the cartesian product, getting all combinations
     ~Þ⇧     # Filter by those which are strictly ascending
        h    # Get the first, which will be the first occurences
           V # To those indices in the original string...
         ⁽⇧  # Uppercase them

```

# Answer
> 6 votes
# x86-64 machine code, 11 bytes

```
AC AE 75 FD 80 67 FF DF 75 F6 C3

```

Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes the addresses of `a` and `t`, as null-terminated byte strings, in RDI and RSI, respectively, with `t` lowercase, and modifies `a` in place.

In assembly:

```
f:  lodsb       # Load a character from t into AL, advancing the pointer.
rc: scasb       # Compare AL with a character from a, advancing the pointer.
    jne rc      # Jump back to repeat if they are not equal.
    and BYTE PTR [rdi-1], 0xDF  # Set bit 5 of the matching character to 0, capitalizing it.
    jnz f       # Jump to the start if the result is not 0.
    ret         # Return (once the null terminator is reached).

```

# Answer
> 5 votes
# Retina, 27 bytes

```
i+`(.)(.+)/(\1)
$3¶$2/
¶|/

```

Takes input separated by `/`.

Try it online!

# Answer
> 5 votes
# , ~~55~~ 54 bytes

```
\(s,t)sapply(s,\(c){if(F<-t[1]%in%c)t<<-t[-1];c-32*F})
```

Attempt This Online!

Input is vector of codepoints.

---

# , 61 bytes

```
\(s,t)for(c in s){if(t[1]%in%c){c=toupper(c);t=t[-1]};cat(c)}
```

Attempt This Online!

Function with null return value that prints output to console. Input is vector of characters.

# Answer
> 5 votes
# Vyxal, 9 bytes

```
£ƛ¥h=[&Ḣ⇧

```

Try it Online!

Literally is different by one character from this, and also very similar to this.

Input as strings, output as char list. (`s` flag in link smashes)

```
£ƛ¥h=[&Ḣ⇧
£         # Put the first input in the register
 ƛ        # Map over the second input:
  ¥h=[    #  Is the current character equal to the first character of the register?
      &Ḣ⇧ #  If so, remove the first character of the register and uppercase the current character
          #  (implicit) else, return the current character unchanged

```

# Answer
> 5 votes
# Java (JDK), 40 bytes

```
a->t->a.map(c->t.peek()!=c?c:t.pop()^32)

```

Try it online!

With `a` is an `Stream<Integer>` (stream of codepoints) and `t` is a `Deque<Integer>`. Both inputs are lowercase.

There's a lot going on with automatic null tests, autoboxing and friends, so this answer might seem trivial, but it's actually not at all.

# Answer
> 5 votes
# K (ngn/k), 24 bytes

-1 byte from @ngn's improvement

```
{`c$x-32*y{y_x,y~:*x}/x}

```

Try it online!

Adapted from my answer on the Speed of Lobsters code golf.

* `y{...}/x` set up a reduction seeded with y (the characters to search for), run over the characters in x (the full string). confusingly, within the function itself, x and y are flipped. this ends up returning a boolean array with 1s in the positions containing the desired matches and 0s everywhere else
    + `y~:*x` compare the first character to search for (`*x`) to the current character being iterated over (`y`), updating y with the result of 0 or 1. note that as soon as we have matched all the search characters, no more matches will be identified (since a character will never ~ (match) a 0 or 1)
    + `x,` append this result to the list of characters to search for (essentially overloading the reduction to end up returning the desired output)
    + `y_` if there was a match, drop the first character (if there wasn't a match, this is a no-op). this allows us to search for the next search character in the next iteration of the reduction
* ``c$x-32*` multiply this bitmask by 32, representing the offset necessary to capitalize characters at truthy indices, subtract it from the original text, and convert that result "back" to a string/text

# Answer
> 4 votes
# JavaScript (Node.js), 62 bytes

```
f=(a,[h,...l])=>a.replace(eval(`/${h}(.*)/i`),(s,t)=>h+f(t,l))

```

Try it online!

Input uppercase `t`.

# Answer
> 4 votes
# 05AB1E, 11 bytes

```
v¬yQićuëy}?

```

Based on my 05AB1E answer of the related challenge.

Inputs as lowercase strings in the order \\$a,t\\$.

Try it online or verify all test cases.

**Explanation:**

```
v        # Loop over the characters `y` of the first (implicit) input-string `a`
 ¬       #  Push the first character of string `t`
         #  (which will be the implicit second input-string `t` in the first iteration)
  yQi    #  If it's equal to character `y`:
     ć   #   Extract the first character from string `t`
      u  #   And uppercase it
    ë    #  Else:
     y   #   Push character `y` as is
    }    #  After the if-else statement:
     ?   #  Pop this character, and print it

```

# Answer
> 4 votes
# Perl 5 `-plF` , ~~36~~ 35 bytes

*saved a byte by taking the first input in upper case*

```
$_=<>;s/./uc$&eq$F[0]?shift@F:$&/ge

```

Try it online!

Takes `t` on the first input line in upper case, then `a` on the second line.

# Answer
> 4 votes
# Brachylog (v2), 10 bytes

```
↔{|ụ}ᵐ↔w₆⊇

```

Try it online!

Function submission, using both its arguments (input string on the left, uppercase acronym on the right) and outputting to standard output. Very inefficient (O(2*n*) performance).

## Explanation

```
↔{|ụ}ᵐ↔w₆⊇
     ᵐ      Iterate over {the left argument}
↔     ↔       in reverse order
 {|           either doing nothing (try this option first)
  |ụ}         or uppercasing {the character being iterated over}
         ⊇  such that {the right argument} is a subsequence of {the result}
       w₆   and when we find it, output {the result of the iteration}

```

Uppercase some of the characters so that we can find the acronym in the uppercased string. The inefficiency comes from the fact that the iteration order will try uppercasing the first character, then the second, then the first two, then the third, then the first and third, then the second and third, then the first three, then the fourth, etc. – the interpreter doesn't realise that the first solution it finds will uppercase a number of characters exactly equal to the length of the right-hand argument (because any solution which uppercases too many characters will be found later, and any solution that doesn't uppercase enough won't match), so it just tries all possibilities within a given prefix before going onto the next character.

Iterating in reverse is required for the uppercasing of prefixes to be the first thing the interpreter requires (with the normal iteration method, it would try uppercasing the last character first, etc.).

`w₆` (which outputs the current value, without discarding it, and where the output is used only if all the constraints in the rest of the program end up matching) is by far the most useful of Brachylog's nine write instructions, so could probably do with a 1-byte representation (I would likely make this the default behaviour for a write if I were designing a Brachylog-alike from scratch).

# Answer
> 3 votes
# Rust, ~~149~~ 148 bytes

```
|m:&str,v:&str|{m.chars().fold(v.chars().peekable(),|mut a,c|{print!("{}",if a.peek()==Some(&((c as u8+32)as char)){a.next().unwrap()}else{c});a});}
```

Attempt This Online!

# Answer
> 3 votes
# Charcoal, 22 bytes

```
Ｆη«≔⌕θ↧ιζ…θζι≔Φθ›λζθ»θ

```

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

```
Ｆη«

```

Loop over the uppercase letters.

```
≔⌕θ↧ιζ

```

Find the index of the next matching lowercase letter.

```
…θζ

```

Output its prefix.

```
ι

```

Output the uppercase letter.

```
≔Φθ›λζθ

```

Remove the prefix and the lowercase letter from the string.

```
»θ

```

Output any remaining lowercase letters.

# Answer
> 3 votes
# Pyth, 15 bytes

```
?Lqrd4h+Q0.(Q0E

```

Try it online! -- Try with formatted I/O -- Try all test cases

Accepts `t` then `a` on separate lines as lists of characters and returns a list of characters.

# Answer
> 3 votes
# Factor, 55 bytes

```
[ [ over index cut capitalize swap write ] each print ]

```

Try it online!

Takes the string and the lowercase word in that order. Assuming the input is `"all the worlds a stage" "lag"`

* `[ ... ] each` For each letter in the word...

```
        <<iteration 1 of each>>
            ! "all the worlds a stage" 108
over        ! "all the worlds a stage" 108 "all the worlds a stage"
index       ! "all the worlds a stage" 1
cut         ! "a" "ll the worlds a stage"
capitalize  ! "a" "Ll the worlds a stage"
swap        ! "Ll the worlds a stage" "a"
write       ! "Ll the worlds a stage"    (write to stdout without newline)
       <<iteration 2 of each>>
            ! "Ll the worlds a stage" 97
over        ! "Ll the worlds a stage" 97 "Ll the worlds a stage"
index       ! "Ll the worlds a stage" 14
cut         ! "Ll the worlds " "a stage"
capitalize  ! "Ll the worlds " "A stage"
swap        ! "A stage" "Ll the worlds "
write       ! "A stage"    (write to stdout without a newline)
     <<and so forth..>>
            ! "Ge"
print       ! (write to stdout with a newline)

```

# Answer
> 3 votes
# Go, 70 bytes

```
func s(a,b[]byte){i:=0;for _,c:=range b{for a[i]-32!=c{i++};a[i]-=32}}

```

Try it online!

# Answer
> 3 votes
# K (ngn/k), 36 bytes

Takes the string as first argument, then the acronym in lowercase.

```
{@[x;(#x)-1+#'x{y/1_y\x}\y;`c$-;32]}

```

Try it online!

# Answer
> 3 votes
# Jelly, 16 bytes

```
ẹⱮŒpI>0PƊƇḢ
Œuç¦

```

Try it online!

```
ẹⱮŒpI>0PƊƇḢ - Helper link g(s, w) - takes string on the left and word on the right.
ẹⱮ          -  For each character in w, get all indices of it in s.
  Œp        -  Take the cartesian product over this list.
         Ƈ  -  Filter keep for:
        Ɗ   -  Last three links as a monad:
    I       -   Increments (deltas / consecutive differences)
     >0     -   Are they greater than zero? (positive)
       P    -   Take the product of is to check that all are truthy
          Ḣ -  Get the first item (that satisfies that condition)

Œuç¦   - Main link f(s, w) - takes string on the left and word on the right.
  ç    - Run the helper link (as a dyad, given s and w)
   ¦   - At those indices in w...
Œu     - Uppercase them

```

# Answer
> 3 votes
# Regex (.NET), 69 bytes

```
s/.(?=(.*$)(?<=(?=(?>.*?(.)(?=.*
((?>\3?)(\2))))+\1$)^.*))|
.*/$4/img

```

Try it online! \- all test cases
Try it on regex101! \- try it on your own

This is a single regex substitution, to be applied once. This is the only kind of substitution that can be efficiently used on regex101.

Input is taken in the form of the two strings delimited by a newline.

The primary challenge here is that each match+substitution must be done as a separate event, with no communication between them (other than that each subsequent match is done following the end of the previous one). No captures can survive from one match to the next, so each one must reconstruct its state from scratch, relying only on the position of the match to let it do that.

Also note that the actual replacement is only done after all matches are found, so that can't be used to communicate state.

In this explanation, a raw newline is shown as :

```
s/                                     # Match the following:
      .                                # Match a character in string A
      (?=                              # Lookahead (keep this out of what will
                                       # be replaced)
          (.*$)                        # \1 = capture the rest of string A, to
                                       #      our position
          (?<=                         # Lookbehind - evaluated from right to
                                       # left, so read from the bottom up
              (?=                      # Lookahead - go back to evaluating from
                                       # left to right.
                  (?>                  # Atomic group - after each iteration,
                                       # lock in its match and prevent
                                       # backtracking.
                      .*?              # Skip as few characters as possible,
                                       # minimum zero, to match the following:
                      (.)              # \2 = a character in string A
                      (?=              # Lookahead
                          .*¶          # Skip to the beginning of string T
                          (            # \3 = concatenation of the following:
                              (?>\3?)  # Previous value of \3, if set
                              (\2)     # $4 = the next character in string T
                                       #      (which is capitalized)
                          )
                      )
                  )+                   # Loop the above as many times as
                                       # possible, minimum one, to make the
                                       # following match:
                  \1$                  # Stop at the point we snapshotted,
                                       # making sure that the string ends after
                                       # it, to prevent matching an earlier
                                       # duplicate.
              )
              ^.*                      # First step in the lookbehind - skip
                                       # back to the beginning of the string.
          )
      )
  |                                    # or...
      ¶.*                              # Match the newline and string T, in
                                       # order to erase it.
/                                      # Substitution - replace with this:
$4                                     # The capital letter we captured in $4,
                                       # which will be empty if it was the
                                       # second alternative that matched.
/                                      # Flags:
i                                      # Case Insensitive (so that letters in
                                       # string T will match those captured in
                                       # string A)
m                                      # Multiline - "$" matches the end of any
                                       # line instead of just the end of string.
g                                      # Global - replace all matches instead of
                                       # only the first.

```

# Regex (Python`regex` / .NET), 74 bytes

```
s/.(?=(.*$)(?<=(?=(?>.*?(.)(?=.*
(?=(\4?))(\3+(\2))))+\1$)^.*))|
.*/\5/img

```

**Attempt This Online! \- Python `import regex`**
Try it online! \- .NET

Since mrab-regex supports variable-length lookbehind, the only adaptation necessary in this port was to eliminate the use of nested backreferences. Groups `\4` and `\5` are copied to each other.

# Regex (Perl / PCRE), 86 bytes

```
s/.(?=(.*)
(.)+((?<=(?=^(?>.*?(.)(?=.*
(\5?+(\4))))+\1
.*(?=\2)\4|(?3)).)))|
.*/$2/sig

```

Try it online! \- Perl - all test cases
Try it online! \- PCRE1 - all test cases
Try it online! \- PCRE2 v10.33 / Attempt This Online! \- PCRE2 v10.40+ - all test cases
Try it on regex101! \- PCRE1/PCRE2 - try it on your own

This is a port of the .NET regex, emulating variable-length lookbehind using recursion with fixed-length lookbehind, but there's an additional challenge. The .NET regex makes a capture inside the lookbehind which is used as the substitution replacement. That is impossible in Perl/PCRE, since all captures made inside a subroutine (recursive or not) are erased upon exiting it.

So to communicate back from the emulated lookbehind, this regex makes a guess (`\3`, captured by `(.)+`) as to what the capital letter in string `t` will be, and then compares that with the capital letter actually matched inside the lookbehind (`(?=\3)\5`). If it's not a match, the regex will backtrack to before the emulated lookbehind, and try capturing a different capital letter from string `t`.

# Answer
> 3 votes
# Regex (GNU ERE or better), 30 bytes

```
s/(.)(.*(
))(\1)|
/$4$3$3$2/ig

```

Try it online! \- ECMAScript
Try it online! \- Perl
Try it online! \- PCRE1
Try it online! \- PCRE2
Try it online! \- Boost
Try it online! \- Python
Try it online! \- Python `import regex`
Try it online! \- Ruby
Try it online! \- .NET

This is a single regex substitution to be repeatedly applied until it has nothing to match (or until there is no change, in engines whose API doesn't supply the information as to whether anything was matched – i.e. ECMAScript, Boost, and Python).

Input is taken as string `a` and word `t` concatenated with a newline delimiter between them.

This is similar to Leaky Nun's **27 byte** Retina solution, but that one does two regex substitutions (looping the first until there is no change, then applying the second one once, then done) and uses two different types of delimiters at once (newline and slash), while this solution does just one looping regex substitution, and only uses newlines as a delimiter.

The intermediate states as this one progresses are different than those in the 27 byte Retina solution. In it, as the first stage progresses, it inserts a newline after each capitalized letter in string `a` and deletes the corresponding letter from the beginning of word `t`. It's only in its second stage that the newlines in string `a` are deleted.

As this 30 byte regex substitution progresses, it inserts two newlines after each capitalized letter in string `a` and deletes the corresponding letter from the beginning of word `t` – but as it progresses, the previous double newline gets deleted; at any given step (other than before it starts), only the letter last changed to uppercase has two newlines after it. Then when no letters are left to capitalize, it deletes all the newlines.

```
s/            # Match the following:
    (.)       # \1 = $1 = one character from string A (which is in lowercase)
    (         # $2 = concatenation of the following:
        .*    # Match as many non-newline characters as possible, minimum zero
        (¶)   # $3 = one newline
    )
    (\1)      # $4 = the first character in word T (which is in uppercase)
|         # or
    ¶         # One newline
/             # Replace with the following:
$4            # The uppercase letter from word T, replacing $1
$3$3          # Two newlines inserted
$2            # $2, preserved unchanged from string A
              # No $4 – it is deleted from the beginning of word T
              # Note that all of the above will be empty if the second
              # alternative, one newline, was what matched, thus deleting
              # the newline.
/             # Flags:
i             # Case Insensitive
g             # Global - replace all matches instead of only the first. After
              # the first match is made, each additional match attempt begins
              # after the end of the last full match (i.e. they don't overlap).
              # The replacement pass is only done after all matches are found.

```

## \\$\large\textit{Anonymous functions}\\$

# Ruby, 52 bytes

```
->s{0while s.gsub! /(.)(.*(
))(\1)|
/i,'\4\3\3\2';s}

```

Try it online!

## \\$\large\textit{Full programs}\\$

# Retina, 28 bytes

```
i+`(.)(.*(¶))(\1)|¶
$4$3$3$2

```

Try it online!

# Perl `-p0`, 37 bytes

```
1while s/(.)(.*(
))(\1)|
/$4$3$3$2/ig

```

Try it online!

# GNU sed `-z`, 39 bytes

```
:a
s/(.)(.*(\n))(\1)|\n/\4\3\3\2/Mig
ta

```

Try it online!

The `M` flag tells `.` to match everything except newline, whereas normally in sed, `.` matches any character including newline.

# Answer
> 2 votes
# Lua, 71 bytes

```
a,b=...;j=1;for i=1,#a do x=a[i]-32;if x==b[j]then a[i]=x j=j+1 end end

```

Try it online!

Chunk which modifies `a` in place. Mostly equivalent to the Go solution.

# Answer
> 2 votes
# PHP, 90 bytes

```
function($a,$t,$i=0){foreach(str_split($a)as$c)echo($z=$c^' ')==@$t[$i]?[$z,++$i][0]:$c;};

```

Simply loops through the characters in the string, and outputs the capitalized one when necessary.

This is an anonymous function, so, it has to be given to a variable to be called.

You can try it on here: https://onlinephp.io/c/61a1c
(Contains all test cases in the question.)

---

## How it works?

It uses the fact that XORing an ASCII character with a space, will toggle the 3rd bit, which will change the letter case.
With this knowledge, I avoid running `strtoupper($c)`, saving me a bunch of bytes.

---

This is useful for checking against the backronym letters, which are in upper case, and to display the upper case letter.
These are accomplished in `($z=$c^' ')==@$t[$i]`.
The `@` is there to suppress warnings, which will happen when we exhaust all characters in `$t`.

---

To make the code shorter, I've used `[$z,++$i][0]`, which displays the upper case character and increments `$i`, without the need to make an `if`.
The (much longer) alternative is the following:

```
if(($z=$c^' ')==@$t[$i]){++$i;echo$z;}else echo$c;

```

---

One edge-case that people may see as an issue, is with spaces.
However, if you XOR a space with a space, it gives a null character (`\0`).
**Luckily**, a null character is a truthy value.

Another possible edge-case, with spaces, comes from the fact that, after the `$t` string is exhausted, the value will be `null`.
Since the null character is a truthy value, and `null` is a falsy value, this will never be `true`, which means that I can use `==` instead of `===`, and saves 1 byte.

# Answer
> 2 votes
# knight, 68 60 bytes

```
;;=aP=bP;=j=i 0W<iLa;O I-32-A=cGa i 1A=dGb j 1c;=j+1j d=i+1i

```

Try it online!

*-8 bytes thanks to Adam for some nice spacing rearrangements*

In my J answer, which required a lot of machinery, I noted:

> It's interesting to contrast how simple it is to solve procedurally -- you need only a single loop and a single register.

Since knight is a very simple procedural language, I thought it would make an interesting juxtaposition.

## how

```
;=j=i 0                     # initialize indices for the two input strings
;
;=aP=bP                     # read the inputs into variables a and b
W<iLa                       # while (i < a.length)...
;O I-32-A=cGa i 1A=dGb j 1  # Take the ascii difference between the chars
                            # a[i] (store it in c) and b[i] (store in d),
                            # and subtract that from 32
c                           # if the difference is not 0, return c (the lowercase)
;=j+1j d                    # if it is 0, return d (the uppercase) and
                            # increment j
=i+1i                       # increment i in either case

```

# Answer
> 2 votes
# \>\<\>, 26 bytes

```
ri\  >~&o!
&:<&o^?=-*48@:$

```

Try it online!

# Answer
> 2 votes
# Thunno `J`, \\$ 13 \log\_{256}(96) \approx \\$ 10.70 bytes

```
XeDxAJ=?xZTXu

```

Attempt This Online!

Port of Steffan's Vyxal answer.

#### Explanation

```
XeDxAJ=?xZTXu  # Implicit input
X              # Store the first input in x
 e             # Map over the second input:
  D            #  Duplicate the character
   xAJ         #  Push the first character of x
      =?       #  If they are equal:
        xZT    #   Push x without its first character
           X   #   And store it back in x
            u  #   Push the character, uppercased
               #  (Otherwise: the character remains on top)
               # The J flag joins it into a string
               # Implicit output

```

# Answer
> 1 votes
# Retina 0.8.2, 45 bytes

```
+r`^((?i:\3))(.*)([a-z])([^A-Z]*)$
$2$1$4
^

```

Try it online! Link includes test cases. Takes the word and string separated by spaces. Explanation:

```
+r`^((?i:\3))(.*)([a-z])([^A-Z]*)$
$2$1$4

```

Repeatedly match the earliest lowercase letter in the string which doesn't precede an uppercase letter that case insensitively matches the first letter of the word and move that (uppercase) letter into its place. The match is performed in right-to-left order as this makes the test simpler.

```
^

```

Remove the space that separated the word and the string.

# Answer
> 1 votes
# C# (Visual C# Compiler), 103 bytes

```
(a,t)=>{for(int i=-1,j=-1;++i<t.Length;)for(;;)if(a[++j]==t[i]){a[j]=(char)(t[i]-32);break;}return a;};

```

Try it online!

# Answer
> 1 votes
# Thunno 2 `c`, 9 bytes

```
Xıxh=?ẋḣR

```

Try it online!

Port of Steffan's Vyxal answer.

#### Explanation

```
Xıxh=?ẋḣR  # implicit input
X          # x = first input
 ı         # map over second input:
  xh=      #   character == x[0]
     ?     #   if true:
      ẋḣ   #     x = x[1:]
        R  #     uppercase the character
           #   otherwise, leave the
           #   character unchanged
           # implicit output

```

# Answer
> 0 votes
# Uiua SBCS, 17 bytes

```
&p∧(⍜⊢¯&pf⊃↙↘⊗⊙.)

```

Try it!

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


title: Is this word in standard order?

text:
# Question
Title: Is this word in standard order?
Let \\$ A \\$ represent the alphabet, such that \\$ A\_1 = \\$ `a` and \\$ A\_{26} = \\$ `z`.

Let's define that a word \\$ W = w\_1 w\_2 ... w\_n \\$ (where \\$ w\_c \in A\\$) is in **standard order** if and only if:

* \\$ w\_1 = A\_1 \\$, and
* for \\$ 2 \le i \le n \\$, if \\$ w\_i = A\_x \\$ then \\$ w\_j = A\_{x-1} \\$ for some \\$ j \< i \\$ and some \\$x\\$.

In other words, the word must start with `a` and each other letter can only appear in a word if the preceding letter in the alphabet has already appeared. Equivalently, if we take only the first appearance of each unique letter in the word, the resulting word is a prefix of the alphabet.

For example, `ac` is not in standard order, because there is no `b` before the `c`.

The following relationships exist between the property of standard order and some others (this list is mainly here for searchability):

## Task

Given a string of letters, determine if it is in standard order according to the Latin alphabet.

## Test cases

Truthy:

```
a
aaa
abab
aabcc
abacabadabacaba
abcdefghijklmnopqrstuvwxyzh

```

Falsey:

```
b
ac
bac
abbdc
bcdefghijklmnopqrstuvwxyza
abracadabra

```

## Rules

* You should represent true and false outputs using any two distinct values of your choice
* You may assume the input is non-empty and only contains lowercase ASCII letters
* Alternatively, you may accept input as a list of integers representing alphabet indices (in either \\$ \[0, 25\] \\$ or \\$ \[1, 26\] \\$, at your option)
* You may use any standard I/O method
* Standard loopholes are forbidden
* This is , so the shortest code in bytes wins

# Answer
> 6 votes
# JavaScript (Node.js), 27 bytes

```
a=>a.every(n=>a[-n]=a[1-n])

```

Try it online!

Input as an array of 1~26 integers.

# Answer
> 5 votes
# Python 3, ~~39~~ 32 bytes

*Thanks @xnor for saving 2 bytes by proposing this approach (going from right to lefft)*
*Thanks @loopy walt for golfing a further 3 bytes*

```
def f(L):len({*L})>L.pop()!=f(L)

```

Try it online!

Takes in a list of integers from 0 to 25. Throws exception if the numbers are in standard order, otherwise terminates without exception (aka returns through exit code).

Check if the last element is less than the number of unique elements in the list:

* If true, recurs on the remaining list (after the last element has been removed). If the list is in order, then we'll eventually run out of elements after some recursions, throwing an exception on `L.pop()`.
* If false, then that last element must not be in order, in which case the comparison short circuited and the function terminates.

# Answer
> 4 votes
# Jelly, 3 bytes

```
QJƑ

```

Try It Online!

Takes input as one-indexed alphabet indices.

```
QJƑ    Main Link
Q      Uniquify
 JƑ    Is it equal to [1, 2, 3, ..., len]?

```

# Answer
> 4 votes
# x86 32-bit machine code, 13 bytes

```
b0 61 38 02 7f 05 1c ff 42 e2 f7 d6 c3

```

Try it online!

Following the `fastcall` calling convention, this takes the length of the string in ECX and the address of the string in EDX, and returns in AL, -1 for standard order and 0 for not standard order.

Assembly:

```
f:  mov al, 0x61    # 'a' -- AL will hold the highest acceptable letter.
r:  cmp [edx], al   # Compare -- Letting c be the current letter, calculate c - AL.
    jg b            # If c > AL, the word is not in standard order; jump out.
    sbb al, 0xFF    # Here, the carry flag CF is 1 if c < AL and 0 if c = AL.
                    # Subtract 255+CF from AL. This leaves AL unchanged if c < AL
                    #  while increasing it by 1 if c = AL.
    inc edx         # Advance the pointer.
    loop r          # Loop, counting down from the length in ECX.
b:  .byte 0xD6      # Undocumented SALC instruction -- sets AL to -CF.
                    #  If the word is not in standard order, CF = 0 from the CMP.
                    #  If it is in standard order, CF = 1 from the SBB,
                    #   as INC and LOOP leave CF unchanged.
    ret             # Return.

```

# Answer
> 4 votes
# Vyxal, 4 bytes

```
U:ż⁼

```

Try it Online!

Takes a list of nonnegative integers.

```
U    # Uniquify
   ⁼ # Is equal to
 :ż  # 1...length?

```

# Answer
> 3 votes
# JavaScript (V8), 35 bytes

```
a=>[...new Set(a)].some((x,i)=>x^i)

```

Try it online!

takes input as an array with integers representing 0-indexed alphabet indices. returns false for valid words, and true for invalid words

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

Expects a list of 0-based indices. Returns *false* for valid or *true* for invalid.

```
a=>a.some(c=>c*!a[a[-c-2]=~c])

```

Try it online!

### Commented

```
a =>            // a[] = input array, re-used as an object to keep track of
                //       characters that have already appeared in the list
a.some(c =>     // for each code c in a[]:
  c *           //   return true if c is not equal to 0
  !a[           //   and the following entry is defined:
    a[-c - 2] = //     set a[-c - 2] to a non-zero value
    ~c          //     use -c - 1 as the lookup value
  ]             //   end of test
)               // end of some()

```

# Answer
> 3 votes
# Wolfram Language (Mathematica), 26 bytes

```
(l=#)&@@@Tally@#==Range@l&

```

Try it online!

Input a list of alphabet indices, 1-indexed.

```
   # &@@@Tally@#            deduplicate
(l= )           ==Range@l   equal to (1...(last unique value))?

```

# Answer
> 3 votes
# 05AB1E, 3 bytes

```
ÙāQ

```

Input as a 1-based integer-list.

Try it online or verify all test cases.

If we take the actual lowercase letters as input, it would have been 5 bytes instead:

```
AIÙÅ?

```

Try it online or verify all test cases.

**Explanation:**

```
Ù     # Uniquify the (implicit) input-list
 ā    # Push a list in the range [1,length] (without popping)
  Q   # Check if both lists are equal
      # (after which the result is output implicitly)

A     # Push the lowercase alphabet
 I    # Push the input-string
  Ù   # Uniquify this input-string
   Å? # Check if the lowercase alphabet starts with this uniquified input
      # (after which the result is output implicitly)

```

# Answer
> 3 votes
# BQN, 3 bytesSBCS

Takes input as a list in \\$\[0, 25\]\\$.

```
≡⟜⊐

```

Run online!

BQN's primitive *Classify*  basically converts a sequence to "standard order" in non-negative integers. As the input uses the same domain we can simply check if the result of that matches the input.

# Answer
> 2 votes
# Factor, ~~31~~ 30 bytes

```
[ members 26 iota swap head? ]

```

Try it online!

## Explanation

Get the unique elements of the input, preserving order, and check whether that is a prefix of the alphabet(ic indices).

```
          ! { 0 1 0 1 }
members   ! { 0 1 }
26 iota   ! { 0 1 } { 0 1 2 ... 25 }
swap      ! { 0 1 2 ... 25 } { 0 1 }
head?     ! t

```

# Answer
> 2 votes
# Haskell + hgl, 9 bytes

```
fsw β<nb

```

## Explanation

`nb` takes the string and removes all but the first occurrence of every character. `fsw` takes two lists and determines if the first one starts with the second. `β` is the lowercase alphabet. So all in all this asks if the first occurrence of every character forms a prefix of the alphabet.

You can replace `β` with `nn` for numbers 0 through 25 and `nN` for numbers 1 through 26.

## Reflections

This does well. For once there's not too much to say here.

* An "is this sorted" builtin might be nice but because the string must start with `a` it would require that as a second check and it wouldn't save anything on this challenge.
* I also noticed there is no upper case alphabet builtin, which there should probably be. It doesn't make a difference to this answer though.

# Answer
> 2 votes
# Nibbles, 5 bytes (9 nibbles)

```
==;`$_,,@

```

## Verbose

```
==   # Equals?
  ; `$ _   #   Uniq of input, save it
  , , @   # Range from 1 to length of saved value

```

## Variant with alphabet (8 bytes / 15 nibbles)

```
==.;`$@-$'`',,@

```

### Verbose

```
==   # Equals?
  .   # Map
    ; `$ @   #   Uniq of input, save it
    - $ '`'   #   Subtract '`'
  , , @   # Range from 1 to length of saved value

```

# Answer
> 2 votes
# , 35 bytes

```
function(W)any(seq(u<-unique(W))-u)

```

Try it online!

Takes input as a vector of integers from `1` to `26`. Outputs `FALSE` for truthy and `TRUE` for falsey.

# Answer
> 2 votes
# Brachylog, 3 bytes

```
d~⟦

```

Try it online!

Takes 0-indices into the alphabet.

```
d      The nub of the input
 ~⟦    is the range from 0 to something.

```

# Brachylog, 5 bytes

```
d~a₀Ạ

```

Try it online!

Takes a string of lowercase letters.

```
d        The nub of the input
 ~a₀     is a prefix of
    Ạ    the lowercase alphabet.

```

# Answer
> 2 votes
# Shue, 67 65 bytes

Shue confirmed less verbose than Java ????

Takes input as a list of unary numbers (1-26) separated by ",", with a trailing ",". Returns "LR" for yes, and "FR" for no.

```
=L
=R
L1,=L>,
L,=L
>1=1>
>,1=,>
,,=,
>,R=,R
LR
L11=F
F1=F
F,=F
FR

```

Try it online!

# Explanation

```
=L      - Left edge
=R      - Right edge
L1,=L>, - Decrement the first element, which is 1, create triangle
L,=L    - Remove a 0 without creating a triangle
>1=1>   - Triangle passes trough ones
>,1=,>  - Triangle decrements the next element
,,=,    - Remove zeros since they don't affect the result
>,R=,R  - Delete triangle when it reaches the end
LR      - Success
L11=F   - Failure, the first element is 2 or greater
F1=F    - Propagate failure
F,=F    - Propagate failure
FR      - Failure

```

# Rough pseudocode

```
def is_valid(array):
    if array == []:
        return True
    if array[0] == 0:
        return is_valid(array[1:])
    elif array[0] == 1:
        return is_valid(array[1:]-1)
    else:
        return False

```

# Answer
> 1 votes
# , 9 bytes

```
(-:#\)@~.

```

Try it online!

Input is 1-based indices of the alphabet letters.

* `@~.` Take the unique (preserves order) and...
* `(-:#\)` Check if it equals `1 2 3 ... <length of uniq>`.

# Answer
> 1 votes
# Python 3 \- 47 bytes

Thanks to @pxeger and @m90

```
lambda a:[*range(len(u:={}.fromkeys(a)))]==[*u]

```

Input is a list of integers from `[0,25]`. All it does is remove duplicates and makes sure that each integer is equal to its position. Output is inverted, which is allowed.

Attempt it online!

## Python 3.8 \- 50 bytes

Thanks to @pxeger for -12 bytes here.

```
lambda a,i=0:any(k^(i:=i+1)for k in{}.fromkeys(a))

```

Input is a list of integers from `[1,26]`. All it does is remove duplicates and makes sure that each integer is equal to its position. Output is inverted, which is allowed.

Try it online! (Function output is inverted, but I inverted it back in the footer of the interpreter)

## Python 3 \- 58 bytes

Thanks to @m90.

```
lambda a:0in map(int.__eq__,{}.fromkeys(a),range(len(a)))

```

Input is a list of integers from `[0,25]`. All it does is remove duplicates and makes sure that each integer is equal to its position. Outputs are inverted, which is allowed.

Try it online!

# Answer
> 1 votes
# SNOBOL4 (CSNOBOL4), 90 bytes

```
	I =INPUT
N	I LEN(1) . X	:F(O)
	O =O X
	&LCASE O	:F(END)
R	I X =	:S(R)F(N)
O	OUTPUT =1
END

```

Try it online!

Same "check if unique characters are a prefix of the alphabet" algorithm others have posted.

# Answer
> 1 votes
# Retina 0.8.2, 30 bytes

```
D`.
^
$'¶
T`l`@l`^.+
^@(.*)¶\1

```

Try it online! Link includes test cases. Explanation:

```
D`.

```

Remove duplicate letters.

```
^
$'¶

```

Duplicate the remaining letters.

```
T`l`@l`^.+

```

Shift the letters in the first copy back by 1, e.g. `abcd` becomes `@abc`.

```
^@(.*)¶\1

```

Check that the second copy starts with the tail of the first copy, which is only possible if this is a prefix of the alphabet.

# Answer
> 1 votes
# Charcoal, 10 bytes

```
¬⌕βΦθ⁼κ⌕θι

```

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

```
 ⌕          Index of
    θ       Input string
   Φ        Filtered where
      κ     Current index
     ⁼      Equals
       ⌕    First index of
         ι  Current letter
        θ   In input string
  β         In predefined variable lowercase alphabet
¬           Equals zero
            Implicitly print

```

# Answer
> 1 votes
# C (gcc), ~~66~~ ~~63~~ 62 bytes

```
r;m;f(char*s){for(r=0,m=96;*s;++s)r|=*s-m==1?m=*s,0:*s>m;m=r;}

```

Try it online!

Inputs a word as a string.
Returns \\$0\\$ if the word is in standard order or \\$1\\$ otherwise.

# Answer
> 1 votes
# Java, 68 bytes

```
l->{int[]x={0};return l.stream().distinct().allMatch(i->i==x[0]++);}

```

Takes input as a `List` of alphabet indices.

Try it online!

# Answer
> 1 votes
# Dyalog APL, 7 bytes

```
⍳∘≢∘∪≡∪

```

Takes input as integers from 1 to 26.

Try it online!

# Answer
> 0 votes
# Uiua SBCS, 3 bytes

```
≍⊛.

```

Try it!

Port of ovs' BQN answer.

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


# Question
Title: Convert an Expression to Panfix Notation
I was browsing esolangs, and chanced upon this language: https://github.com/catseye/Quylthulg.

One interesting thing about this language, is that it doesn't use prefix, postfix, or infix, it uses *all three of them*, calling it "panfix" notation.

Here is an example. To represent normal infix `1+2` in panfix, it becomes: `+1+2+`. Notice how the operator is both before, in between, and after the operands. Another example is `(1+2)*3`. This becomes `*+1+2+*3*`. Notice again how `*` is in all three places with respect to the operands `+1+2+` and `3`.

# The Challenge

As you may have guessed, your task in this challenge is to convert an expression from infix to panfix.

A few clarifications:

* You only have to deal with the four basic operations: `+-*/`
* You won't have to deal with the unary versions of those, only binary
* You have to deal with parenthesis
* Assume the normal precedence rules of `*/` then `+-` and left associativity for all of them.
* The numbers will be nonnegative integers
* You can optionally have a spaces in both the input and output

# Test Cases

```
1+2  ->  +1+2+
1+2+3  ->  ++1+2++3+
(1+2)*3  ->  *+1+2+*3*
10/2*5  ->  */10/2/*5*
(5+3)*((9+18)/4-1)  ->  *+5+3+*-/+9+18+/4/-1-*

```

This is , so shortest code in **bytes** wins!

# Answer
# JavaScript (ES6), ~~285~~ ~~282~~ ~~281~~ ~~267~~ ~~251~~ ~~243~~ ~~241~~ ~~238~~ ~~234~~ ~~232~~ 231 bytes

*~15 bytes thanks to Neil.*

```
f=(I,E=I.match(/\d+|./g),i=0)=>(J=T=>T.map?T.map(J).join``:T)((R=(H,l=(P=_=>(t=E[i++])<")"?R(0):t)(),C,F)=>{for(;(C=P())>")"&&(q=C>"*"&&C<"/")*H-1;)F=q+H?l=[C,l,C,P(),C]:F?l[3]=[C,l[3],C,R(1),C]:l=R(1,l,i--)
i-=C>")"
return l})(0))

```

In JavaScript this is a bit harder than in Mathematica. This is basically an over-specialized and golfed operator-precedence parser.

Causes stack overflows on invalid inputs.

### Demo

```
f=(I,E=I.match(/\d+|./g),i=0)=>(J=T=>T.map?T.map(J).join``:T)((R=(H,l=(P=_=>(t=E[i++])<")"?R(0):t)(),C,F)=>{for(;(C=P())>")"&&(q=C>"*"&&C<"/")*H-1;)F=q+H?l=[C,l,C,P(),C]:F?l[3]=[C,l[3],C,R(1),C]:l=R(1,l,i--)
i-=C>")"
return l})(0))
```

```
<input id="input" value="(5+3)*((9+18)/4-1)"/><button onclick="console.log(f(document.querySelector('#input').value))">Convert</button>
```

### Ungolfed

```
convert = input => {
  tokens = input.match(/\d+|./g);
  i = 0;
  parse_token = () => (token = tokens[i++]) == "(" ? parse_tree(false) : token;
  parse_tree = (mul_div_mode, left = parse_token()) => {
    while ((oper = parse_token()) != ")" && !((is_plus_minus = oper == "+" || oper == "-") && mul_div_mode)) {
      if (is_plus_minus || mul_div_mode)
        left = [oper, left, oper, parse_token(), oper];
      else if (non_first)
        left[3] = [oper, left[3], oper, parse_tree(true), oper];
      else
        left = parse_tree(true, left, i--);
      non_first = true;
    }
    if (oper != ")")
      i--;
    return left;
  };
  format_tree = tree => tree.map ? tree.map(format_tree).join("") : tree;
  return format_tree(parse_tree(false));
}

```
> 3 votes

# Answer
## JavaScript (ES6), 160 bytes

```
f=(s,t=s.replace(/[*-/]/g,"'$&'"),u=t.replace(/^(.*?)([*-9]+)'([*/])'([*-9]+)|([*-9]+)'([+-])'([*-9]+)|\(([*-9]+)\)/,"$1$3$2$3$4$3$6$5$6$7$6$8"))=>t==u?t:f(s,u)

```

Works by quoting all the operators (which gives them character codes before `*`), then looking for available `'*'` or `'/'` operations, `'+'` or `'-'` operations or `()`s, and replacing the first with its panfix notation. Example:

```
(5+3)*((9+18)/4-1)
(5'+'3)'*'((9'+'18)'/'4'-'1)
(+5+3+)'*'((9'+'18)'/'4'-'1)
+5+3+'*'((9'+'18)'/'4'-'1)
+5+3+'*'((+9+18+)'/'4'-'1)
+5+3+'*'(+9+18+'/'4'-'1)
+5+3+'*'(/+9+18+/4/'-'1)
+5+3+'*'(-/+9+18+/4/-1-)
+5+3+'*'-/+9+18+/4/-1-
*+5+3+*-/+9+18+/4/-1-*

```
> 3 votes

# Answer
## Mathematica, ~~203~~ 195 bytes

This is likely less than efficient, but seems to do the job.

```
Function[f,ReleaseHold[(Inactivate@f/._[Plus][a_,b_/;b<0]:>a~"-"~-b//Activate@*Hold)//.a_/b_:>a~"/"~b/.{a_Integer:>ToString@a,Plus:>"+",Times:>"*"}]//.a_String~b_~c_String:>b<>a<>b<>c<>b,HoldAll]

```

This is an anonymous function that takes an actual expression and returns a string with panfix notation. Mathematica sorts out the precedence of operators at parsing time, rather than evaluation time, so the nesting should be automagically correct. At least the test cases work as expected.

Explanation: It's easy enough to interpret the entire expression as a tree, like so:

At this stage the operators (every node that isn't a leaf) aren't operators any more, they've actually been converted to strings such as `"+"`. The integers are also cast to strings. Then a repeated replacement rule converts every node that has exactly two leafs to the panfix `parent-leaf1-parent-leaf2-parent`. After some iterations the tree reduces to a single string.

The main loss in the byte count is that Mathematica interprets

```
5 - 4 -> 5 + (-4)
9 / 3 -> 9 * (3^(-1))

```

And this happens also at parsing time.

Golfed down a bit, since the pattern `a_/b_` is also interpreted as `a_ * (b_)^(-1)`. Also some minor optimizations elsewhere.
> 2 votes

# Answer
# Prolog, 87 bytes

```
x(T)-->{T=..[O,A,B]}->[O],x(A),[O],x(B),[O];[T].
p:-read(T),x(T,L,[]),maplist(write,L).

```

This is a function (mostly because writing a full program has nightmarish levels of boilerplate in Prolog; normally, even if you *compile* a program, it produces a REPL when run), called `p`. It takes input from stdin and outputs on stdout. Note that you need to append a period to the input, which is an unfortunate consequence of the way that Prolog's input routines work (they use periods in the input in much the same way that other languages use newlines); that might or might not disqualify the answer.

## Explanation

Arithmetic operators, in Prolog, are normally interpreted as tuple constructors. However, they obey the same precedence rules as the actual arithmetic operators they're based on; you can form tuples with infix notation, and `+` and `-` bind less tightly than `*` and `/`, with precedence taken left to right within a group. This is exactly what the question asks for; thus, we can read an entire nested tuple from the input, and it already has the right structure. That's what `p` does.

Next, we need to convert it to panfix notation. `x` converts the input into a panfixed list of constructors and integers, and can be read as an English sentence almost directly: "`x` of `T` is: if `T` is a tuple with constructor `O` and arguments `A`,`B`, then `O`, `x` of `A`, `O`, `x` of `B`, `O`, else `T`". Finally, we just have to print the list without any separators (i.e. using `maplist` to call `write` on each element of the list).

I used SWI-Prolog for testing this, because my version of GNU Prolog doesn't have `maplist` yet (apparently it's been added to a newer version), but it should generally be fairly portable between Prolog implementations.
> 1 votes

# Answer
# Tamsin, 118 bytes

```
main=1->R&{("+"|"-")->O&1->E&R<-O+R+O+E+O}&R.1=2->R&{("*"|"/")->O&2->E&R<-O+R+O+E+O}&R.2="("&main->R&")"&R|$:alnum/''.

```

Try it online!

```
# implements +, - over expr1       # `main` is  (entrypoint)
main = expr1 -> R                  #   `expr1` (store in R)
      & {                          #   followed by zero or more:
        ("+" | "-") -> O           #     "+" or "-" (store in O)
        & expr1 -> E               #     `expr1` (store in E)
        & R <- O + R + O + E + O   #     R = O + R + O + E + O (i.e. to panfix)
      } & R.                       #   return R

# implements *, / over expr2; does the same thing as expr1 but we need seperate rule for operator precedence
expr1 = expr2 -> R
      & {
        ("*" | "/") -> O
        & expr2 -> E
        & R <- O + R + O + E + O
      } & R.

# implements parenthesis and numbers # `expr2` is
expr2 = "(" & main -> R & ")" & R    #   "(" followed by `main` followed by ")" (return match from `main`)
      | $:alnum/''.                  #   or zero or more alphanumeric char

# sed 's/expr\|#.*//g' panfix.tamsin | tr -d ' \n' | wl-copy

```

---

Fun Fact: Tamsin was designed by Chris Pressey, the same person who made Quylthulg (the language in the question)
> 0 votes

---
Tags: code-golf, parsing, conversion
---