text:
Talk interpreter
"Talk" is a baroquified accumulator-based language that is created in response to Dennis's quote on talk.tryitonline.net.
Waiting for someone to create an esolang called talk.

. The "Talk" language has 4 commands:

00 If the accumulator is 0, set the accumulator to 0.
01 If the accumulator is 0, set the accumulator to 1.
10 If the accumulator is 1, set the accumulator to 0.
11 If the accumulator is 1, set the accumulator to 1.

Input:

The input can be taken via any acceptable input method by our standard I/O rules.
There are two inputs, the initial accumulator value and the program. You can merge these two inputs into one input or split your input into valid commands (e.g. taking them as a list; e.g. [00, 01, 00]) if you like.

Output:

On the end of a command execution, the accumulator is outputted implicitly.

Rules:

The input can be a single string or character list.
As this is code-golf, the shortest answer, in bytes, wins.
We take digits or strings/characters.

Test cases:

0 0001111101 -> 1
0 000100 -> 1
0 11001000 -> 0

Leaderboards
Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.
To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:
# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:
# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:
# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:
# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=190819;
var OVERRIDE_USER=8478;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(d){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(d,e){return"https://api.stackexchange.com/2.2/answers/"+e.join(";")+"/comments?page="+d+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){answers.push.apply(answers,d.items),answers_hash=[],answer_ids=[],d.items.forEach(function(e){e.comments=[];var f=+e.share_link.match(/\d+/);answer_ids.push(f),answers_hash[f]=e}),d.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(d){d.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),d.has_more?getComments():more_answers?getAnswers():process()}})}getAnswers();var SCORE_REG=function(){var d=String.raw`h\d`,e=String.raw`\-?\d+\.?\d*`,f=String.raw`[^\n<>]*`,g=String.raw`<s>${f}</s>|<strike>${f}</strike>|<del>${f}</del>`,h=String.raw`[^\n\d<>]*`,j=String.raw`<[^\n<>]+>`;return new RegExp(String.raw`<${d}>`+String.raw`\s*([^\n,]*[^\s,]),.*?`+String.raw`(${e})`+String.raw`(?=`+String.raw`${h}`+String.raw`(?:(?:${g}|${j})${h})*`+String.raw`</${d}>`+String.raw`)`)}(),OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(d){return d.owner.display_name}function process(){var d=[];answers.forEach(function(n){var o=n.body;n.comments.forEach(function(q){OVERRIDE_REG.test(q.body)&&(o="
"+q.body.replace(OVERRIDE_REG,"")+"
")});var p=o.match(SCORE_REG);p&&d.push({user:getAuthorName(n),size:+p[2],language:p[1],link:n.share_link})}),d.sort(function(n,o){var p=n.size,q=o.size;return p-q});var e={},f=1,g=null,h=1;d.forEach(function(n){n.size!=g&&(h=f),g=n.size,++f;var o=jQuery("#answer-template").html();o=o.replace("{{PLACE}}",h+".").replace("{{NAME}}",n.user).replace("{{LANGUAGE}}",n.language).replace("{{SIZE}}",n.size).replace("{{LINK}}",n.link),o=jQuery(o),jQuery("#answers").append(o);var p=n.language;p=jQuery(""+n.language+"").text().toLowerCase(),e[p]=e[p]||{lang:n.language,user:n.user,size:n.size,link:n.link,uniq:p}});var j=[];for(var k in e)e.hasOwnProperty(k)&&j.push(e[k]);j.sort(function(n,o){return n.uniq>o.uniq?1:n.uniq<o.uniq?-1:0});for(var l=0;l<j.length;++l){var m=jQuery("#language-template").html(),k=j[l];m=m.replace("{{LANGUAGE}}",k.lang).replace("{{NAME}}",k.user).replace("{{SIZE}}",k.size).replace("{{LINK}}",k.link),m=jQuery(m),jQuery("#languages").append(m)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
  <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654">

Winners by Language

Language	User	Score

Leaderboard

	Author	Language	Size

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}

{{LANGUAGE}}	{{NAME}}	{{SIZE}}

So there's two inputs, the sequence of commands and the initial accumulator value?

Test cases would be very helpful here.

If the accumulator condition is not met, its state remains unchanged, right?

Some test cases that don't change the accumulator, start with 1 in the accumulator or have no instructions would be good

Can Talk really be considered a programming language?

@A_ That comment was probably meant as a joke. Back in the day, a language called Lang would have a URL lang.tryitonline.net (now it's tio.run/#lang). So a language called Talk would cause confusion with the URL for the then-recently created chatroom, which is talk.tryitonline.net

In the future, please refrain from changing I/O after a number of answers have been posted. I came back today and having mapped inputs allowed makes this an entirely different challenge from what I answered.

I appreciate it, thank you.

Are we allowed to take the program as individual integers, such as [0, 1, 1, 0]?

@TheOnlyMrCat Yes.

@A_ does the program have to write characters 0/1 (ASCII 48/49) or can it output ASCII 0/1 (NUL or SOH)?

@osuka_ Both, as people are already using ASCII 0/1 in this challenge.

This seems kinds similar to boolfuck.

Can the accumulator be 2?

@Helena No, the accumulator can only save binary values.

Jelly, 3 bytes
y@/

Input is a single list: the accumulator, followed by the pairs.
Try it online!
How it works
The y atom performs transliteration; [a,b]yc replaces a with b, so it returns b if a=c and c if a≠c.
y@/ folds/reduces the input by y with swapped arguments, performing one transliteration per pair.

This is the only Jelly answer that I have seen so far that only uses ASCII characters.

There were a few. Look ma, no Unicode!

Python 3, 43 bytes
lambda s:re.sub("00|11","",s)[-1]
import re

Try it online!
The function takes a single string as input, where the first character is the  initial state and the rest of the string represents the commands. This solution can be easily ported to other languages that have better support for regular expressions.
The difficult part is to prove the solution yields the correct outcome. To see this, we need a deep analysis of the commands. Firstly, we can see the commands have the following properties:

Property (1): commands 00 and 11 retain the accumulator state.
Property (2): commands 01 and 10 make the accumulator state the same as the second bit regardless of its original state.

Therefore, the final accumulator state is:

Case 1: If no 01 or 10 command exists, the final state is the same as the initial state.
Case 2: Otherwise, the last bit of the last 10 or 01 command.

Next we will show the solution yields the correct outcome in both cases. We will prove the statement for the final state 0 and the final state of 1 can be proved analogously. If the final state is 0 the input is in either of the following forms:

^0{2k+1}11(11|00)*
For Case 1, the input string s must start with 2k+1 0s, followed by 11 and 00 commands. Eliminating 00s and 11s yields a single 0, which is the final state.
.+10{2k+1}11(11|00)*
For Case 2, the input string ends with a 10 command, followed by zero or more 00 and 11 s. This pattern is equivalent to a 1 followed by 2k+1 0s, and then zero or more 11s and 00s. Eliminating 00s and 11s leaves behind the last one of the 2k+1 0s at the end of the string, which represents the final state.

Based on all the above, after eliminating 00s and 11s simultaneously in one single pass (01001 is a counter-example if 00 is eliminated in one pass and then 11 in another pass) from the input s, the last character is the final state. Hence the correctness of the solution is proved.

Welcome to PPCG! Excellent answer, and a nice formal proof to go with it!

Thanks. I feel that people may doubt such a simple solution yields the correct outcome at the first glance. So there is a need to provide a proof for that.

Perl 6, 17 bytes
{m/.)>[(.)$0]*$/}

Try it online!
Takes advantage of "You can merge these two inputs into one input if you like" by taking input as the accumulator value concatenated with the commands e.g. 1,[00,11] is 10011. If this isn't okay, than it's only 5 extra bytes to take it as f(accumulator, commands). Returns a match object that can be coerced to a string.
Explanation:
{                }  # Anonymous code block
 m/             /   # Find the first match from the input
   .)>              # Capture a number
      [     ]*      # Followed by any number of
       (.)$0        # Pairs of identical characters
              $     # Ending the string

Basically this works because the 00 and 11 commands do literally nothing, while the 01 and 10 commands just set the accumulator to the second digit of the command. If there are no commands, then it takes the initial value of the accumulator instead.

Zsh, 33 bytes
The character list is passed as arguments, the initial value of the accumulator is passed as stdin.
read a
for x y;a=$[x^a?a:y]
<<<$a

Try it online!

39 bytes: If the commands must be a single string
Input is accumulator commands as arguments.

for x y (${(s::)2})1=$[x^$1?$1:y]
<<<$1

Try it online!

For fun, here's a 50 byte recursive one-liner (TIO):
<<<${${2+`f $[$1^${2[1]}?$1:${2[2]}] ${2:2}`}:-$1}

Python 3, 52 bytes
f=lambda a,s:s and f([s[1],a][s[0]==s[1]],s[2:])or a

Try it online!
Fixed inconsistent return type thanks to Chas Brown
Takes input as two strings; the accumulator and the code.

Oh no, that was fast.

Nice but it has this potential problem - f(1,'11')==f(1,'01') is False; it sometimes returns an int and sometimes a str. So maybe specify it takes acc input as a string?

@ChasBrown Good call, that's much simpler than what I was thinking about.

Nice, but since your function is recursive, it cannot be anonymous. It should be 52 bytes.

Brachylog, 11 9 bytes
tġ₂≠ˢtt|h

Try it online!
Since it's been long enough that I've been able to forget the notion of printing the accumulator after each command, I've formulated a significantly less naïve solution with some inspiration from Jo King's Perl answer.
       |     The output is
     tt      the last element of the last element of
t            the last element of the input
 ġ₂          split into length-2 slices
   ≠ˢ        with equal pairs removed.
       |     If there is no such element, the input
        h    's first element is the output.

Old solution:
Brachylog, 18 16 bytes
ġ₂ᵗc{th~h?tt|h}ˡ

Try it online!
-2 bytes from changing the input format.

JavaScript (ES6), 27 bytes
Takes input as (a)(code), where code is a is list of 2-bit integers.
a=>c=>c.map(x=>a^=x==a+1)|a

Try it online!

JavaScript (ES6),  47  40 bytes
Takes input as (a)(code), where code is a string.
a=>c=>c.replace(/../g,x=>a^=x%4==a+1)&&a

Try it online!
How?
All possible cases are summarized below. The only two cases where we need to toggle the accumulator are \$(a=0,x=01_2)\$ and \$(a=1,x=10_2)\$.
  a | x (bin) | int(x) % 4 | a + 1 | equal?
----+---------+------------+-------+--------
  0 |   "00"  |  0 % 4 = 0 |   1   |   N
  1 |   "00"  |  0 % 4 = 0 |   2   |   N
  0 |   "01"  |  1 % 4 = 1 |   1   |   Y
  1 |   "01"  |  1 % 4 = 1 |   2   |   N
  0 |   "10"  | 10 % 4 = 2 |   1   |   N
  1 |   "10"  | 10 % 4 = 2 |   2   |   Y
  0 |   "11"  | 11 % 4 = 3 |   1   |   N
  1 |   "11"  | 11 % 4 = 3 |   2   |   N

sed -E, 26 19 bytes
A whopping -7 bytes from @Cowsquack by realizing removing all pairs works as well.
s/(.)\1//g
s/.*\B//

Takes input concatenated together on stdin. Inspired by Jo King's Perl answer.
Strip trailing pairs Remove all pairs, then get last digit.
Try it online!
Try it online!

The last line can be simply s/.*\B//, but anyways changing the approach slightly gives an even shorter 19 bytes Try it online!

Huh, I didn't think that s/(.)\1//g would work, since it could remove the end of one pair and the start of the next, but it still works out. Excellent!

@GammaFunction s/(.)\1//g is equivalent to s/00|11//g as shown in my solution.

Retina 0.8.2, 18 11 bytes
(.)\1

!`.$

Try it online! Link includes test cases. Takes input concatenated. Saved 6 bytes thanks to @CowsQuack for pointing out that removing all doubled characters and then taking the last remaining character works, although in fact the port of @JoKing's original answer could have been golfed by 3 bytes even without that trick.

12 bytes Try it online!

@Cowsquack D'oh, once you think about separating the stages, that's a 2-byte saving already, then another byte saved because you can use !`.$, and then another 4 bytes because you don't have to limit to trailing pairs...

Haskell, 29 bytes
Defines an unnamed function on the first line with type (Foldable t, Eq b) => b -> t [b] -> b. For the purposes of this code golf, we can instantiate it as Char -> [String] -> Char where the first argument is the accumulator and the second is a list of string with each string being a single command.
foldl(#)
a#[x,y]|a==x=y|1>0=a

Try it online!

Same bytecount if you define it using prefix notation. I can't believe I wrote almost the exact same answer at the same time, even including the type signature explanation…

Python 3, 38 bytes
lambda l:[y for*x,y in l if[y]!=x][-1]

Try it online!
Based on Joel's solution. Takes input as a list of the initial accumulator value (length-one string) followed by the commands (length-two strings). Finds the last command with two unequal values, and outputs its second character.
To make this fall through to the initial accumulator value when there are no such commands, we make it so that the single-char initial value string passes the test. We do so by checking if a singleton list with the last character is unequal to a list of all preceding characters, which is passed by any length-one string or length-two string with two different characters.

Perl 5 -p, 37 33 bytes
$\=<>;s/(.)(.)/$\=$2if$\==$1/ge}{

Try it online!
Input is two lines: first line is the command sequence, second is the accumulator.

Jelly, 8 6 bytes
EÐḟṪṪo

Try it online!
-2 bytes thanks to Nick Kennedy informing me of a rules change. (His proposed golf, EÐḟFȯṪ, seems somewhat more clever but has the same length as my previous solution minus s2.) The input format now takes the commands as a list of two-character strings, but the testing footer translates from the old format for convenience.
Translated from my newer Brachylog solution.
Old version:
Jelly, 13 bytes
ḢẎ⁼⁹a⁸o
s2ç@ƒ

Try it online!
I'm not 100% sure this is correct, but it succeeds on all three test cases. Takes the commands as the left argument and the initial accumulator as the right argument.

The input is allowed to be split into a list, so you could have EÐḟFȯṪ with the input as e.g. [[0,0],[0,1],[1,1],[1,1],[0,1]].

Wow, the changes to the spec really were quite large...

Python 2, 56 bytes
f=lambda a,c:f([a,1,0,a][int(c[:2],2)],c[2:])if c else a

Try it online!

APL (Dyalog Unicode), 16 bytes
(+⌷13⍴0 1,9/⊢)/⌽

A tacit function which takes initial accumulator value and the program as a single integer list.
Maps the relevant sums of instruction and accumulator to an array.
Table: (a→accumulator, i→instruction)
a  i a+i result
00 0 0   0
01 0 1   1
10 1 11  0
11 1 12  1

All other cases return the same value, so they are assigned to the preexisting value of a.
Try it online!
Explanation
(+⌷13⍴0 1,9/⊢)/⌽ accumulator→a
              /⌽ reduce the reversed array using th following function: (reducing happens from the right)
          9/⊢)   replicate a 9 times
   13⍴0 1,       concatenate with (0,1) and expand to 13 elements → (0 1 a a a a a a a a a 0 1)
(+⌷              sum first two elements and find element at that index in the array

Solution which accepts a string
{{(13⍴0 1,9/⍺)[⍺+⍵]}/⌽(⍎¨((⍴⍵)⍴1 0)⊂('0',⍵))}

It was pretty ambiguous how the input was supposed to be taken, so I decided I'd leave this one in as well.
This was the original dfn, which was golfed down using Adám and Bubbler's advice.

Regex (JS flavor), 32 bytes
^(0(..)*01|1((..)*01)?)(00|11)*$

Try it online!
Matches if output is 1, doesn't if output is 0. Global and multiline flags enabled in link to verify multiple test cases at once, but not necessary for solution. Did I format this submission correctly?

Python, 111 bytes
def f(a,b):
    c=a
    for i in range(0,len(b)-1,2):
        c=(not b[i])*(c or b[i] or b[i+1]) or c*b[i]*b[i+1]
    return c

Ungolfed. EDIT: AHHH Someone beat me to it!

Keg, -ir, 16 bytes
"(!;½|':"=['_"|_

Try it online!
Explained:

Takes the implicit input and right shifts the accumulators value to the bottom
Repeat the following (length of stack - 1 divided by 2) times

2.1. Shift the accumulator back to the top
2.2. Compare for equality with the first part of the command
2.2.1. If true, replace the accumulator, otherwise pop the replacement
Input is taken as the initial acc value concatenated with the source. E.g.
010011000

First char is acc value
Rest is program

Haskell, 36 bytes
f(x:y:s)=f s.last.(:[y|x/=y])
f _=id

Try it online!
Takes input as f(string)(char) where the character is the accumulator and the string is the list of commands.

05AB1E, 3 bytes
ø`:

Try it online!
Zip, dump on the stack, replace.

Stax, 3 bytes
F|t

Run and debug it
For each instruction, perform character translation.

CJam, 8 bytes
{{)er}/}

Try it online!
Takes input on the stack in the form of "0" ["00" "01" "11" "11" "01"]. Does string replacement using every command.

Headass, 22 bytes
U[{N-()]PNE:U(])U[:U;}

Try It Online!
U[{N-()]PNE:U(])U[:U;} full program

U[                     save initial state of accumulator to storage register
  {        :         } while
   N-()                input remains
            U(])    ;    if input == accumulator state
                U[         set accumulator to next input
                  :      else
                   U       discard next input
       ]P              print final state of accumulator
         NE            go to code block 1
                       block does not exist, exits with error

There is room for golfing maybe if I can avoid storing anything in the comparison register (i.e. having it remain 0 for the entirety of the program and never using (), but it might not be possible.

Regex (any flavor), 15 bytes
(^|0)1(00|11)*$

Try it on regex101!
It was pointed out before that the problem can be simplified:

00 and 11 are no-ops. 01 unconditionally sets the value to 1 while 10 sets to 0.
The output is 1 if and only if the input is 1 and the entire code is no-op or the last non-no-op command is 01.

The regex precisely does the job: (00|11)*$ after discarding no-ops at the end, the last thing found is (^|0)1 the input 1 or a 01 command.
1(00|11)*$ does not work because the 1 may be part of another no-op command 11.

Bash, 58 40 bytes
Add one byte for a full program: change f to $0.
(($1=$2-a?a:$3,1))&&f $1 ${@:4}||echo $1

58 bytes
Try it online!
The ternary will return false when $1 is set to 0, but the ,1 at the end ensures the whole ((expression)) will return true, except a syntax error.
When all the arguments are consumed, a syntax error happens and the recursion ends.

Charcoal, 16 bytes
Ｆ⪪η²Ｆ⁼θ§ι⁰≔§ι¹θθ

Try it online! Link is to verbose version of code. Takes separate arguments. Explanation:
Ｆ⪪η²

Split the instructions into pairs of digits and loop over them.
Ｆ⁼θ§ι⁰

If the accumulator is equal to the first digit...
≔§ι¹θ

... then assign the second digit to it.
θ

Print the accumulator at the end of the loop.

MATL, 13 12 bytes
!dh2Ol4$Ys0)

Takes the input as a 2-column matrix where each row is a command, and a number
Try it online! Or verify all test cases

Jelly, 7 bytes
fØ½Ḃ⁹;Ṫ

A dyadic Link accepting the program as a list of integers on the left and the initial accumulator on the right which yields an integer.
Try it online! Or see a test-suite

I am removing input-mapping because @GammaFunction recommended me to do this.

@A_ ah OK cant delete on mobile so will have to address this later

@A_ fixed up to work with 0,1,2,3 the unmapped version of the instructions as digits is that OK?

Yes, that's OK.

C (gcc), 45 41 bytes
f(a,i)char*i;{a=*i?f(a^*i?a:i[1],i+2):a;}

Try it online!
4 bytes shaved off thanks to @ErikF!

You can save 4 bytes by using the usual trick of storing the return value in the first parameter: Try it online!

I don't see how this fulfils "On the end of a command execution, the accumulator is outputted implicitly". You have outsourced that part to the caller, so you should then count the caller too.

@Lundin: it also says the standard I/O rules apply, and those mention that functions may output via return value. Also, most answers here do this.

@G.Sliepen Ok well there's another function solution including the printing put they aren't really comparable this way. Either way, a parameter is not a function's return value in C.

@Lundin: It's a standard code golf trick: https://codegolf.stackexchange.com/a/106067/46301. At code golf we don't care about standards conformance; if TIO runs it it's valid :)

In this case it's rather about re-defining the language to some local standard only used on this site. But it is what it is.

PHP, 38 bytes
<?=strtr($argn,['00'=>'',11=>''])[-1];

Try it online!
Basically port of Jo King's idea.

Runic Enchantments, 28 bytes
/~@/i~/i<
/=?/~iR:l}i{l1-=?!

Try it online!
Takes input as a series of space separated bytes (Runic does not understand lists). The first byte is the initial state and every other byte is the program. No validation is performed (i.e. it assumes only valid programs are given as input and it doesn't care what value is used to represent 0 and 1).

Ruby, 33 bytes
->a,s{s[/(00|11)*$/]="";s[-1]||a}

Try it online!

x86 Assembly, 33 Bytes
Takes the initial accumulator state in CL (integer 0 or 1) and the address of the commands as a zero-terminated ASCII String in ESI. Leaves the final accumulator state in CL.
Point the call instruction at offset 0x1B (label interpret in the Explanation).
3C 30 74 03 B0 01 C3 30 C0 C3 E8 F1 FF FF FF 38
C8 AC 75 07 E8 E7 FF FF FF 88 C1 AC 84 C0 75 EA
C3

Explanation (Using Intel Syntax):
; function to convert ASCII '1'/'0' into 0 or 1 int values (from AL to AL)
ctob:
        CMP AL, 0x30 ; '0'
        JE .zero
        MOV AL, 1
        RET
        .zero:
        XOR AL, AL
        RET

; interpreting function
        interp_lp:
                CALL ctob     ; convert to number
                CMP AL, CL    ; compare to current accumulator
                LODSB         ; read the next character of the string
                              ; this doesn't affect any flags and we need to do
                              ; it in both cases anyway
                JNE interpret ; if AL != CL (from above, not the new value of AL), skip forward
                CALL ctob     ; convert AL to number
                MOV CL, AL    ; store AL in CL
interpret:      LODSB         ; read the next character of the string
                TEST AL, AL   ; check if it is a zero byte
                JNZ interp_lp ; if not, jump back into the loop
        RET

APL(Dyalog Unicode), 9 bytes SBCS
1∊11+\⍤|⌽

Try it on APLgolf!
Input format is the same as Razetime's.
1∊11+\⍤|⌽
        ⌽  Reverse the input list
  11   |    Modulo 11 (change 11 to 0)
            Now the program outputs 1 iff the list starts with 0 0 ... 0 1
    +\⍤     Cumulative sum
1∊          Test if it contains a 1

The proof of the statement

a list starts with 0 0 ... 0 1 <=> its cumulative sum contains 1

is left as an exercise to the reader.

C (clang), 68 62 bytes
t(s,e,a)char*s,*e;{for(;s<e;++s)a=*s++-48^a?a:*s-48;puts(&a);}

Try it online!
Takes a pointer to the start of the source string, a pointer to the end of the source string (start + strlen(start)), and the initial accumulator value.
Old version (prints ASCII 48/49 for 0/1):
t(s,e,a)char*s,*e;{for(;s<e;++s)a=*s++-48^a?a:*s-48;putchar(a+48);}

Crystal, 46 bytes
With commands in an Array(Tuple(Int32,Int32)), such as [{0,0}, {0,1}, {0,0}].
def f(s,i);i.map{|c,v|s+=~(s^c)&(s^v)%2};s;end
Try it online!
It's pretty simple to understand in a more readable form:
def f(state, instructions)
  instructions.map do |check, value|
    state += ~(state ^ check) & (state ^ value) % 2
  end
  state
end

The function loops through each command, automatically unpacking the tuple values into c and v. It then sets the state by the formula
state = state + NOT(state XOR check) AND (state XOR value) mod 2

which I arrived at mostly by trial and error. Once all commands have been processed, it returns the state value.

Java (JDK), 38 bytes
a->p->p.reduce(a,(s,c)->c<1|c>2?s:c%2)

Try it online!
The inputs are an int and an IntStream of 0, 1, 2 or 3, which correspond to 00, 01, 10, 11 from binary.


text:
Billiard balls collision
Given the 2-dimensional positions and velocities of a pair of billiard balls right before impact, calculate their velocities after a perfectly elastic collision. The balls are assumed to be ideal spheres (or equivalently: circles) with the same radius, same mass, uniform density, and no friction.
Input consists of 8 numbers: p0x,p0y,v0x,v0y,p1x,p1y,v1x,v1y where p0x,p0y is the centre of the first ball, v0x,v0y its velocity, and similarly p1x,p1y,v1x,v1y for the second ball. You can accept input in any order and structured in any convenient way, e.g. as a 2x2x2 array, or maybe a 2x2 array for p and two length-2 arrays for v0 and v1. It's also fine to take complex numbers (if your language supports them) instead of xy pairs. However, you should not take input in a coordinate system other than Cartesian, i.e. polar is not allowed.
Note that the radius of a billiard ball is half the distance between p0x,p0y and p1x,p1y, so it's not given as an explicit part of the input.
Write a program or function that outputs or returns 4 numbers in any convenient Cartesian representation: the post-collision values of v0x,v0y,v1x,v1y.

A possible algorithm is:

find the normal line that passes through both centres
find the tangent line that passes through the midpoint between the two centres and is perpendicular to the normal line
change coordinate system and break down v0x,v0y and v1x,v1y into their tangential and normal components v0t,v0n and v1t,v1n
swap the normal components of v0 and v1, preserving their tangential components
change back to the original coordinate system

Tests (results rounded to 5 decimal places):
   p0x   p0y   v0x   v0y   p1x   p1y   v1x   v1y ->      v0x'       v0y'       v1x'       v1y'
[-34.5,-81.8, 34.7,-76.1, 96.2,-25.2, 59.2,-93.3] [  49.05873, -69.88191,  44.84127, -99.51809]
[ 36.9, 77.7,-13.6,-80.8, -7.4, 34.4, 15.1,-71.8] [   5.57641, -62.05647,  -4.07641, -90.54353]
[-51.0, 17.6, 46.1,-80.1, 68.6, 54.0,-35.1,-73.9] [ -26.48927,-102.19239,  37.48927, -51.80761]
[-21.1,-52.6,-77.7, 91.5, 46.0, 94.1, 83.8, 93.7] [ -48.92598, 154.40834,  55.02598,  30.79166]
[ 91.3, -5.3, 72.6, 89.0, 97.8, 50.5, 36.2, 85.7] [  71.73343,  81.56080,  37.06657,  93.13920]
[-79.9, 54.9, 92.5,-40.7,-20.8,-46.9,-16.4, -0.9] [  47.76727,  36.35232,  28.33273, -77.95232]
[ 29.1, 80.7, 76.9,-85.1,-29.3,-49.5,-29.0,-13.0] [  86.08581, -64.62067, -38.18581, -33.47933]
[ 97.7,-89.0, 72.5, 12.4, 77.8,-88.2, 31.5,-34.0] [  33.42847,  13.97071,  70.57153, -35.57071]
[-22.2, 22.6,-61.3, 87.1, 67.0, 57.6,-15.3,-23.1] [ -58.90816,  88.03850, -17.69184, -24.03850]
[-95.4, 15.0,  5.3, 39.5,-54.7,-28.5, -0.7,  0.8] [  21.80656,  21.85786, -17.20656,  18.44214]
[ 84.0,-26.8,-98.6,-85.6,-90.1, 30.9,-48.1, 37.2] [ -89.76828, -88.52700, -56.93172,  40.12700]
[ 57.8, 90.4, 53.2,-74.1, 76.4,-94.4,-68.1,-69.3] [  51.50525, -57.26181, -66.40525, -86.13819]
[ 92.9, 69.8,-31.3, 72.6,-49.1,-78.8,-62.3,-81.6] [-123.11680, -23.48435,  29.51680,  14.48435]
[-10.3,-84.5,-93.5,-95.6, 35.0, 22.6, 44.8, 75.5] [ -11.12485,  99.15449, -37.57515,-119.25449]
[ -3.9, 55.8,-83.3,  9.1, -2.7,-95.6, 37.7,-47.8] [ -82.84144, -48.75541,  37.24144,  10.05541]
[-76.5,-88.4,-76.7,-49.9, 84.5, 38.0,  4.2, 18.4] [   6.52461,  15.43907, -79.02461, -46.93907]
[ 64.2,-19.3, 67.2, 45.4,-27.1,-28.7, 64.7, -4.3] [  59.66292,  44.62400,  72.23708,  -3.52400]
[  9.8, 70.7,-66.2, 63.0,-58.7, 59.5, 83.7,-10.6] [  68.07646,  84.95469, -50.57646, -32.55469]
[ 62.9, 46.4, 85.0, 87.4, 36.3,-29.0,-63.0,-56.3] [  23.53487, -86.82822,  -1.53487, 117.92822]
[ -5.5, 35.6, 17.6,-54.3, -2.2, 66.8,-15.2, 11.8] [  24.15112,   7.63786, -21.75112, -50.13786]

Shortest wins. No loopholes.

thanks @Anush for helping fix the diagram's background colour

Python 3, 67 66 bytes, 53 bytes
def f(p,v,q,w):p-=q;d=((v-w)/p).real*p;return v-d,w+d

Try it online!
-1 byte thanks to @ngn
-13 bytes thanks to @Neil
This function f takes four complex numbers as input and returns two complex numbers. The ungolfed version is shown in the following.
Ungolfed
def elastic_collision_complex(p1, v1, p2, v2):
    p12 = p1 - p2
    d = ((v1 - v2) / p12).real * p12
    return v1 - d, v2 + d

Try it online!
The computation formula is derived based on the 2D-vector formula on wiki.
Since \$m_1=m_2\$, the formula can be simplified to
$$\left\{\begin{array}{l} v_1'=v_1-dv \\ v_2'=v_2+dv\end{array}\right.$$
Let \$x_{12}=x_1-x_2\$ and \$v_{12}=v_1-v_2\$, we have
$$dv=\frac{\langle v_{12}, x_{12}\rangle}{\|x_{12}\|^2}x_{12} = \frac{Re(v_{12}\cdot\overline{x_{12}})}{x_{12}\cdot \overline{x_{12}}}x_{12}=Re\left(\frac{v_{12}\cdot\overline{x_{12}}}{x_{12}\cdot \overline{x_{12}}}\right)x_{12}=Re\left(\frac{v_{12}}{x_{12}}\right)x_{12}$$
In the ungolfed program, p12, v1 - v2, d correspond to \$x_{12}\$, \$y_{12}\$, and \$dv\$, respectively.

well done! this approach looks different from Ramillies' perl6 answer which also uses complex numbers. you could save a byte if you replace r=p-q with p-=q and further use p instead of r, like in Neil's js answer

@ngn Thanks. I've updated the answer. The formula looks different partially because in Python the conjugate function p.conjugate() is very long so I tried to replaced them with abs(p) computations for golfing purpose.

@ngn, it looks different but it is the same, as Joel correctly notes. I wrote the formula in a form that was good for Perl 6 golfing, and Joel presumably used one that was better for Python. Anyway, I didn't think that anybody else would come up with a solution using complex numbers independently. Good job!

Nice but if you used the algorithm in the question it would only take 53 bytes...

@Neil Thanks for your hint. The computation is greatly simplified now.

I'm really liking all your great solutions and detailed explanations!

JavaScript (Node.js), 90 88 bytes
(m,n,o,p,q,r,s,t,u=(q-=m)*q+(r-=n)*r,v=o*q+p*r-s*q-t*r)=>[o-(q*=v/u),p-(v*=r/u),s+q,t+v]

Try it online! Link includes test suite. Explanation: q,r are repurposed as the difference vector between the centres, and u is the square of its length. v is the difference in the dot products of o,p and s,t with q,r, so v/u is the scaling factor for q,r that gives the amount of velocity transferred from o,p to s,t. Edit: Saved 2 bytes thanks to @Arnauld.

i didn't expect someone would simplify the algorithm so much so quickly, well done! here's a visualization of your solution (with Arnauld's improvement)

@ngn Wrong link?

@Neil gitlab's pipelines log says it should be there. ctrl+f5? arrows control the red ball. shift accelerates. tested in firefox and chromium. warning: sound.

@ngn Ah, working now, thanks! (I got a 404 before. Also, I was using a private tab, so I had no sound by default, although I didn't find it intrusive. And I'm useless at Asteroids, otherwise I'd ask for a "shoot" key...)

Perl 6, 75 64 63 61 bytes
11 bytes saved by switching from map to for, dispensing with the need to put things into intermediate variables for the map to see.
1 byte saved by changing ($^a-$^c)².&{$_/abs} to ($^a-$^c).&{$_/.conj}.
2 bytes saved thanks to @nwellnhof.
{(.($^b+$^d,{$_/.conj}($^a-$^c)*($b-$d).conj)/2 for *-*,*+*)}

Try it online!

Explanation
When the original post said that the input could be complex numbers, it was too hard to resist... So this takes 4 complex numbers (position 1, velocity 1, position 2, velocity 2) and returns the velocities as complex numbers.
The program uses just the same algorithm as described in the OP. However, with complex numbers, that is quite simple. First, let's notice that the complex number \$d = p_1 - p_0\$ points from the first ball to the second. So if we divide all the velocities by it, the normal direction suddenly coincides with the real axis and the tangent direction with the imaginary axis. (This messes up the magnitudes but we don't care.)
Now, we need to switch the normal (i. e. real) parts of the velocities \$v_0/d\$ and \$v_1/d\$, and after that, multiply it by \$d\$ again to make the normal (and the velocities) point in the correct direction (and to unmess the magnitudes). So we need to calculate
$$ \begin{align*} v_0' &= d \left( \Re \frac{v_1}{d} + \mathrm{i} \Im \frac{v_0}{d} \right), \\ v_1' &= d \left( \Re \frac{v_0}{d} + \mathrm{i} \Im \frac{v_1}{d} \right) \end{align*} $$
(where \$\Re\$ = real part, \$\Im\$ = imaginary part). Let's shuffle the first one a bit (using \$\star\$ for complex conjugation):
$$ v_0' = d \left( \Re \frac{v_1}{d} + \mathrm{i} \Im \frac{v_0}{d} \right) = d \left[ \frac 1 2 \left( \frac{v_1}{d} + \frac{v_1^\star}{d^\star} \right) + \frac 1 2 \left( \frac{v_0}{d} - \frac{v_0^\star}{d^\star} \right) \right] =\ = \frac d 2 \left( \frac{v_0 + v_1}{d} - \frac{v_0^\star - v_1^\star}{d^\star} \right) = \frac 1 2 \left( v_0 + v_1 - \frac{d}{d^\star} (v_0^\star - v_1^\star) \right).$$
The result for \$v_1'\$ can be obtained just by switching \$v_0 \leftrightarrow v_1\$. All that does is changing a sign:
$$ v_1' = \frac 1 2 \left[ v_0 + v_1 + \frac{d}{d^\star} \left(v_0^\star - v_1^\star\right) \right]. $$
And that's it. All the program does is just this calculation, golfed a bit.

very cool!

I don't know much about Perl, but I think you could merge the two conjugate computations into one to save some bytes.

@Joel — Sadly, I'm pretty sure I can't. The first conjugate is acting on ($^a-$^c) (and only inside a lambda that normalizes this number), the second acts on ($b-$d). So they can't really be reconciled. I could make a function that would just call .conj, but that would only add bytes (because I heavily use the $_ variable, which has the nice property that you can call methods on it without specifying it: .conj instead of $_.conj).

@Ramillies Thanks for the explanation.

How is the δ's magnitude relevant? You're just dividing by δ, switching the real components, and then multiplying by δ again.

@Neil, I'm sorry, that's very poor wording on my part. I just wanted to use dd* = 1 to get the nice d² in the formula (and using the normalized d was what first occurred to me when I was calculating it). By the way, using δ and writing δ/δ* instead of d² saves one byte, and that's what the program currently does. I've updated the explanation.

Thanks, I understand the explanation now. By the way, @Joel was able to save 13 bytes from his code just now; I just mention it in case there's something there applicable to your answer.

{$_/.conj}($^a-$^c) saves two bytes.

A port of Joel's Python 3 answer is 46 bytes: {$^b-($!=(($b-$^d)/($/=$^a-$^c)).re*$/),$d+$!}

@nwellnhof — Thank you very much. However, I don't like just blindly copying other answers, so I won't use the port.

C (gcc), 140 132 bytes
f(m,n,o,p,q,r,s,t,a)float*a,m,n,o,p,q,r,s,t;{q-=m;r-=n;m=q*q+r*r,n=o*q+p*r-s*q-t*r;q*=n/m;*a++=o-q;n*=r/m;*a++=p-n;*a++=s+q;*a=t+n;}

Try it online!
Basically a port of @Neil's JavaScript answer, but then @ceilingcat shaved off 8 bytes by cleverly reusing m and n to store temporaries.

Python 2, 97 92 bytes
m,n,o,p,q,r,s,t=input()
q-=m
r-=n
a=o*q+p*r-s*q-t*r
a/=q*q+r*r
print o-a*q,p-a*r,s+a*q,t+a*r

Try it online!
Modified version of Neil's approach.

Jelly, 16 bytes
_/×ḋ÷²S¥_/ʋ¥N,$+

Try it online!
A dyadic link taking as its left argument a list of the initial positions [[p0x, p0y], [p1x, p1y]] and its right argument the initial velocities [[v0x, v0y], [v1x, v2y]]. Returns a list of the final velocities [[v0x', v0y'], [v1x', v2y']]
Based on the algorithm used by @Neil’s JavaScript answer so be sure to upvote that one too!

C (gcc), 77 72 bytes
f(p,v,q,w,a)_Complex*a,p,v,q,w;{p-=q;p*=creal((v-w)/p);*a=v-p;a[1]=w+p;}

Try it online!
Based on the python implementation of @Joel

APL (Dyalog Classic), 21 bytes
⊢/-{,∘-⍨×/(9○÷⍨)\-⌿⍵}

Try it online!
based on @Joel's answer
in: 2x2 complex matrix, out: complex pair

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Count the number of triangles
Given a list of positive integers, find the number of triangles we can form such that their side lengths are represented by three distinct entries of the input list.
(Inspiration comes from CR.)
Details

A triangle can be formed if all permutations of the three side lengths \$a,b,c\$ satisfy the strict triangle inequality $$a + b > c.$$ (This means \$a+b > c\$, \$a+c>b\$ and \$b+c>a\$ must all hold.)
The three side lengths \$a,b,c\$ must appear at distinct positions in the list, but do not necessarily have to be pairwise distinct.
The order of the three numbers in the input list does not matter. If we consider a list a and the three numbers a[i], a[j], a[k] (where i,j,k are pairwise different), then (a[i],a[j],a[k]), (a[i],a[k],a[j]), (a[j], a[i], a[k]) etc. all are considered as the same triangle.
The input list can assumed to contain at least 3 entries.
You can assume that the input list is sorted in ascending order.

Examples
A small test program can be found here on Try it online!
Input, Output:
[1,2,3]  0
[1,1,1]  1
[1,1,1,1] 4
[1,2,3,4] 1
[3,4,5,7] 3
[1,42,69,666,1000000] 0
[12,23,34,45,56,67,78,89] 34
[1,2,3,4,5,6,7,8,9,10] 50

For the input of [1,2,3,...,n-1,n] this is A002623.
For the input of [1,1,...,1] (length n) this is A000292.
For the input of the first n Fibonacci numbers (A000045) this is A000004.

I think the challenge could be clearer about what counts as a distinct triangle. From the A000292 link, I take it [1,1,1,1] allows 4 "different" triangles, all [1,1,1], to be chosen using any three of the 1's? But, it's not 24 because the three 1's are chosen unordered, i.e. it's a subset of three indices rather than an ordered list?

@xnor Thatnks for pointing this out, that all seems correct - I just added a point in the details. I hope that makes it clearer now.

R, 62 52 40 34 bytes
sum(c(1,1,-1)%*%combn(scan(),3)>0)

Try it online!
Port of Luis Mendo's Octave solution
Since a<=b<=c, the triangle condition is equivalent to a+b-c>0. The a+b-c is succinctly captured by the matrix product [1,1,-1] * X, where X is the 3-combinations of the input array.
There were a lot of suggestions for improvements made by 3 different people in the comments:

Robert S. for suggesting scan.
Robin Ryder for suggesting improvements to the triangle inequality and this odd one which requires the input to be in descending order (which just goes to show how important a flexible input format is).
and finally Nick Kennedy for the following:

R, 40 bytes
y=combn(scan(),3);sum(y[3,]<y[1,]+y[2,])

Try it online!

What about this?

x[3]<x[1]+x[2] is equivalent to 2*x[3]<sum(x): 51 bytes

47 bytes by calling combn twice and avoiding the inner function definition.

Actually, make that 45 bytes. Sorry for the multiple comments!

@RobinRyder That [ alias is slick, really cleans up the approach.

@CriminallyVulgar Giuseppe is the one who taught me that trick! Using scan() as suggested by Robert S. makes it 43 bytes. If input can be read in descending rather than ascending order, it can go down to 42.

40

brilliant suggestions all! Clearly I need to work on golfing if I missed out on all those golfs.

Stax, 8 7 bytes
Thanks to recursive for -1!
é═rê÷┐↨

Run and debug it at staxlang.xyz!
Unpacked (8 bytes) and explanation:
r3SFE+<+
r           Reverse
 3S         All length-3 combinations
   F        For each combination:
    E         Explode: [5,4,3] -> 3 4 5, with 3 atop the stack
     +        Add the two shorter sides
      <       Long side is shorter? 0 or 1
       +      Add result to total

That's a neat trick. If you have a sequence of instructions that will always result in 0 or 1 and you need to count the items from an array that yield the truthy result at the end of your program, F..+ is a byte shorter than {..f%.
Assumes the initial list is sorted ascending. Without this assumption, stick an o at the beginning for 8 bytes.

r3SFE+<+ packs to 7.  It uses a foreach loop to add the filter results.  Addition is one of the operations that's a no-op when only a single element is present.

Haskell, 49 bytes
([]%)
[c,b,a]%l|a+b>c=1
p%(h:l)=(h:p)%l+p%l
_%_=0

Try it online!
Recursively generates all subsequences of l (reversed), and checks which length-3 ones form triangles.
50 bytes
f l=sum[1|[a,b,c]<-filter(>0)<$>mapM(:[0])l,a+b>c]

Try it online!
The same idea, generating the subsequences with mapM, by mapping each value in l either to itself (include) or 0 (exclude).
50 bytes
([]%)
p%(b:t)=sum[1|c<-t,a<-p,a+b>c]+(b:p)%t
_%_=0

Try it online!
Tries every partition point to take the middle element b.
51 bytes
f(a:t)=f t+sum[1|b:r<-scanr(:)[]t,c<-r,a+b>c]
f _=0

Try it online!
The function q=scanr(:)[] generates the list of suffixes. A lot of trouble comes from needing to consider including equal elements the right number of times.
52 bytes
q=scanr(:)[]
f l=sum[1|a:r<-q l,b:s<-q r,c<-s,a+b>c]

Try it online!
The helper function q=scanr(:)[] generates the list of suffixes.
57 bytes
import Data.List
f l=sum[1|[a,b,c]<-subsequences l,a+b>c]

Try it online!

Brachylog, 11 bytes
{⊇Ṫ.k+>~t}ᶜ

Try it online!
I may have forgotten to take advantage of the sorted input in my old solution:
Brachylog, 18 17 15 bytes
{⊇Ṫ¬{p.k+≤~t}}ᶜ

Try it online!
{            }ᶜ    The output is the number of ways in which
 ⊇                 a sublist of the input can be selected
  Ṫ                with three elements
   ¬{       }      such that it is not possible to show that
     p             for some permutation of the sublist
       k+          the sum of the first two elements
         ≤         is less than or equal to
      .   ~t}      the third element.

Perl 6, 35 bytes
+*.combinations(3).flat.grep(*+*>*)

Try it online!
Explanation
It's a Whatever code, i. e. a concise notation for lambda functions (that works only in very simple cases). Each * is a placeholder for one argument. So we take the list of lengths (that appears at the first *), make all combinations of 3 elements (they always come out in the same order as in the original list, so that means the combinations are sorted too), flatten the list, and then take the list 3-by-3, and filter (grep) only those triplets that satisfy *+*>*, i. e. that the sum of the first two arguments is greater than the third. That gives all the triplets, and we finally count them with forcing numeric context with a +.
(Of course we need to test it only for the case of "sum of two smaller > the largest". If this holds, the other hold trivially, if this does not, the triplet does not denote correct triangle lengths and we don't need to look further.)

Python 3, 73 bytes
lambda l:sum(a+b>c for a,b,c in combinations(l,3))
from itertools import*

Try it online!
This is the first naive, brute-force approach that comes to my mind. I'll update the post if I find a shorter solution using a different approach. Note that since the input is sorted, the tuple \$(a,b,c)\$ is also in the ascending order so it suffices to only check whether \$a+b>c\$ holds.

Retina, 55 bytes
\d+
*
L$`_+
$<'
%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_
_

Try it online! Link includes test cases, but with the values in the 5th case reduced to allow it to finish today. Assumes sorted input. Explanation: Regexes don't really like matching more than one thing. A normal regex would be able to find all of the values that could be a shortest leg of a triangle. Retina's v option doesn't help here, except to avoid a lookahead. However Retina's w option is slightly more helpful, as it would be able to find both the shortest and longest leg at the same time. That's not enough for this challenge though, as there might be multiple middle legs.
\d+
*

Convert the input to unary.
L$`_+

For each input number...
$<'

... create a line that's the original array truncated to start at that number. $' normally means the string after the match, but the < modifies it to mean the string after the previous separator, avoiding wasting 2 bytes on $&. Each line therefore represents all potential solutions using that number as the shortest leg.
%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_

For each of those lines, find all possible middle and longest legs, but ensuring that the difference is less than the first leg. Output a _ for each matching combination of legs.
_

Count the total number of triangles found.

05AB1E, 12 10 9 bytes
My first time using 05AB1E! Thanks to Grimmy for -1!
3.Æʒ`α›}g

Try it online! or test suite
A direct port of my Stax answer. Get all combinations of three entries and count those that could possibly form triangles. It's that counting part that really got me. I spend a load of bytes there. Bound to be some rookie mistake there.
3.Æʒ`α›}g
3.Æ          List of length-3 combinations
   ʒ   }g    Count truthy results under operation:
    `          Push the two shorter sides, then the long one
     α         Absolute difference (negated subtraction in this case)
      ›        Remaining short side is longer?

I'm sure Grimy will come up with something shorter, since he usually does on my answers. ;) But your answer looks fairly similar what I had in mind. Only difference  is that I've used ì (reverse each) before the filter instead of the Š (triple swap) inside the filter. Alternatively, you could also use ε...}O instead of ʒ...}g, but the byte-count remains the same. PS: Your byte count of 10 and TIO are correct, but your actual answer still has an unnecessary explicit y which can be removed. :) Nice first answer though, so +1 from me.

Sorry to disappoint @KevinCruijssen, all I have is 3.ÆʒRÆd_}g, which is the same bytecount.

@KevinCruijssen Oh actually I guess 3.Æʒ`α›}g is 9.

@Grimy Haha, knew it. xD Pretty straight-forward golf now that I see it.. But you're usually better in coming up with those kind of golfs (or golfs in general..), as I mentioned in my first comment. ;p

Python 2, 72 bytes
f=lambda l,p=[]:l>[]and(p==p[:2]<[sum(p)]>l)+f(l[1:],p)+f(l[1:],p+l[:1])

Try it online!
73 bytes
lambda l:sum(a+b>c for j,b in enumerate(l)for a in l[:j]for c in l[j+1:])

Try it online!

Octave / MATLAB, 33 bytes
@(x)sum(nchoosek(x,3)*[1;1;-1]>0)

Try it online!

Excel VBA, 171 164 152 bytes
-26 bytes thanks to TaylorScott
Sub z
t=[A:A]
u=UBound(t)
For i=1To u-2
For j=i+1To u-1
For k=j+1To u
a=t(i,1):b=t(j,1):c=t(k,1)
r=r-(a+b>c)*(b+c>a)*(c+a>b)
Next k,j,i
Debug.?r
End Sub

Input is in the range A:A of the active sheet. Output is to the immediate window.
Since this looks at every combination of every cell in a column that's 220 cells tall (which is nearly 260 combinations), this code is... not fast. You could make it much faster but at the expense of bytes.

You can drop the () in the sub statement, the space in Debug.? r and can drop Next:Next:Next to Next k,j,i. aside from that - well its still doing 2**60 combinations but it works

Oh and hey, you can drop out some more by replacing the if line with r=r-(a+b>c)*(b+c>a)*(c+a>b)

JavaScript (ES6), 63 bytes
f=([v,...a],p=[])=>v?(!p[2]&p[0]+p[1]>v)+f(a,p)+f(a,[...p,v]):0

Try it online!

Zsh, 66 bytes
for a;z=$y&&for b (${@:2+y++})for c (${@:3+z++})((t+=c<a+b))
<<<$t

Try it online!
Relatively straightforward, taking advantage of the sorted input, and incrementing in the for header (the increment happens once per parent loop).
for a;{
  z=$y
  for b (${@:2+y++});{   # subarray starting at element after $a
    for c (${@:3+z++})   # subarray starting at element after $b
      ((t+=c<a+b))
  }
}

Pyth, 14 bytes
*1sm>sPded.cQ3

Try it online!
          .cQ3  # All combinations of length 3 from Q (input), sorted in ascending order
   m            # map over that lambda d:
     sPd        #   sum(d[:-1])
    >   ed      #     > d[-1]
  s             # sum all of those (uses the fact that True = 1)
*1              # multiply by 1 so it doesn't output True if there's only one triangle

Alternative (also 14 bytes):
lfTm>sPded.cQ3

C (clang), 83 bytes
x,y,q;f(*a,z){for(x=y=q=0;z;q+=z>1&a[x-=x?1:2-y--]+a[y]>a[z])y=y>1?y:--z;return q;}

Try it online!
Saved 1 thanks to @ceilingcat

Java 8, 131 130 126 bytes
a->{int r=0,i=a.length,j,k,I,J,K;for(;i-->0;)for(I=a[j=i];j-->0;)for(J=a[k=j];k-->0;r+=I+J>K&I+K>J&J+K>I?1:0)K=a[k];return r;}

Straightforward approach. The triangle check is the same as my answer for the Is this a triangle? challenge.
-4 bytes thanks to @ceilingcat.
Try it online.
Explanation:
a->{                  // Method with integer-array parameter and integer return-type
  int r=0,            //  Result-integer, starting at 0
      i=a.length,j,k, //  Index-integers
      I,J,K;          //  Temp-integers
  for(;i-->0;)        //  Loop `i` in the range (length,0]:
    for(I=a[j=i];     //   Set `I` to the `i`th value
        j-->0;)       //   Inner loop `j` in the range (i,0]:
      for(J=a[k=j];   //    Set `J` to the `j`'th value
          k-->0       //    Inner loop `k` in the range (j,0]:
          ;           //      After every iteration:
           r+=        //       Increase the result by:
              I+J>K&I+K>J&J+K>I?
                      //        If `I`, `J`, and `K` form a triangle:
               1      //         Increase the result by 1
              :       //        Else:
               0)     //         Keep the result the same by increasing with 0
        K=a[k];       //     Set `K` to the `k`'th value
  return r;}          //  After the nested loops, return the result

@ceilingcat Thanks

Wolfram Language (Mathematica), 37 35 bytes
Tr@Boole[2#3<+##&@@@#~Subsets~{3}]&

Try it online!

Jelly, 9 bytes
œc3+>ƭ/€S

Try it online!
A monadic link taking a sorted list of integers as its argument and returning the number of triangles.
Explanation
œc3       | Combinations of length 3
     ƭ/€  | Reduce each using each of the following in turn:
   +      | - Add
    >     | - Greater than
        S | Sum (counts the 1s)

Alternative 9s:
œc3Ṫ€<§ƊS
œc3Ṫ<SƊ€S

Charcoal, 17 bytes
ＩΣ⭆θ⭆…θκ⭆…θμ›⁺νλι

Try it online! Link is to verbose version of code. Assumes sorted input. Explanation:
   θ                Input array
  ⭆                 Map over elements and join
      θ             Input array
     …              Truncated to length
       κ            Outer index
    ⭆               Map over elements and join
          θ         Input array
         …          Truncated to length
           μ        Inner index
        ⭆           Map over elements and join
              ν     Innermost value
             ⁺      Plus
               λ    Inner value
            ›       Is greater than
                ι   Outer value
 Σ                  Take the digital sum
Ｉ                   Cast to string for implicit print

Japt -x, 9 bytes
à3 ËÌÑ<Dx

Try it
à3 ®o <Zx

Try it

Ruby, 41 bytes
->l{l.combination(3).count{|a,b,c|c<a+b}}

Try it online!

Perl 5 (-p), 55 52 bytes
using regex backtracking, -3 bytes thanks to @Cows quack using ^ instead of (?!) to fail and backtrack.
$d='(\d++)';$_=/$d.* $d.* $d(?{$n++if$1+$2>$3})^/+$n

or
$_=/(\d++).* (\d++).* (\d++)(?{$n++if$1+$2>$3})^/+$n

TIO

Can (?!) be ^?

thanks it fails/backtrack well

Bash, 123 bytes
for a;do for((i=2;i<=$#;i++)){ b=${!i};for((j=$[i+1];j<=$#;j++)){ c=${!j};T=$[T+(a<b+c&b<a+c&c<a+b)];};};shift;done;echo $T

Try it online!
A fun one.

J, 40 bytes
1#.](+/*/@(->])])@#~2(#~3=1&#.)@#:@i.@^#

Try it online!

Nekomata + -n, 6 bytes
SƆ$đ+<

Attempt This Online!
SƆ$đ+<
S       Find a subset of the input
 Ɔ      Split the subset into the last element and the rest
  $đ    Check if the rest has exactly two elements
    +   Add these two elements
     <  Check if the last element is less than the sum

-n counts the number of solutions.

SNOBOL4 (CSNOBOL4), 181 bytes
	S =TABLE()
R	X =X + 1
	S<X> =INPUT	:S(R)
I	I =J =K =I + 1	LT(I,X)	:F(O)
J	J =K =J + 1	LT(J,X)	:F(I)
K	K =K + 1	LT(K,X - 1)	:F(J)
	T =T + 1 GT(S<I> + S<J>,S<K>)	:(K)
O	OUTPUT =T
END

Try it online!
Brute force \$O(n^3)\$ algorithm. Takes input as a newline separated list and outputs the number of triangles, or an empty line for 0. This is probably allowable since SNOBOL treats the empty string as 0 for numerical calculations.

Scala, 280 bytes
280 bytes, it can be golfed much more.

Golfed version. Try it online!
def c(n:Int,l:List[Int]):List[List[Int]]=if(n==0)List(List())else if(n>l.size)List()else if(n==1)l.map(List(_))else{(for(i<-l.indices)yield{val h=l(i);val t=l.drop(i+1);c(n-1,t).map(h::_)}).toList.flatten}
def V(l:List[Int]):Int=c(3,l).count{case List(a,b,c)=>a+b>c&&a+c>b&&b+c>a}

Ungolfed version. Try it online!
import scala.collection.mutable.ArrayBuffer
import scala.util.control.Breaks._

object Main {
  def combination(n: Int, lst: List[Int]): List[List[Int]] = {
    if (n == 0) List(List())
    else if (n > lst.size) List()
    else if (n == 1) lst.map(List(_))
    else {
      (for (i <- lst.indices) yield {
        val head = lst(i)
        val tail = lst.drop(i + 1)
        combination(n - 1, tail).map(head :: _)
      }).toList.flatten
    }
  }

  def countValidTriangles(lst: List[Int]): Int = {
    val combinations = combination(3, lst)
    combinations.count {
      case List(a, b, c) => a + b > c && a + c > b && b + c > a
    }
  }

  def main(args: Array[String]): Unit = {
    val testCases = List(
      (List(1, 2, 3), 0),
      (List(1, 1, 1), 1),
      (List(1, 2, 3, 4), 1),
      (List(3, 4, 5, 7), 3),
      (List(1, 42, 69, 666, 1000000), 0),
      (List(12, 23, 34, 45, 56, 67, 78, 89), 34),
      (List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 50)
    )

    for ((lst, expected) <- testCases) {
      val output = countValidTriangles(lst)
      assert(output == expected, (lst, output, expected))
    }
  }
}

JavaScript (Node.js), 49 bytes
f=([v,...x],a,b)=>v?f(x,a,b)+(b?a+b>v:f(x,v,a)):0

Try it online!

Uiua, 27 bytes (SBCS)
/+≡(|1<+/∘⇌)≐▽▽=3≡/+.⋯⇡ⁿ⧻,2

Try it online!
Explanation
            ≐▽▽=3≡/+.⋯⇡ⁿ⧻,2   # Get all length 3 combinations
                           2   # Put 2 on the stack
                          ,    # Copy the array onto the stack
                         ⧻     # Get the length of the array
                        ⁿ      # Raise 2 to the power of the length
                       ⇡       # Create an array of all natural numbers less than the result
                     ⋯         # Convert to binary
                    .          # Copy the result
                 ≡/+           # For each binary number, add up the bits
               =3              # Check which add up to three
              ▽                # Keep rows of the binary array where the number of 1s is 3
            ≐▽                 # For each of the remaining binary numbers,
                               # keep items in the original array
/+≡(|1<+/∘⇌)                   # Calculate number of triangles
  ≡(|1     )                   # For each row in the resulting array:
          ⇌                    # Reverse the array
        /∘                     # Put the items onto the stack
       +                       # Add the first two numbers
      <                        # Check if the third number is less than the result
/+                             # Add up all the triangles

As part of this, I made the combinations part generic. This might be useful for future golfing. If someone can find a shorter way of doing this part, it may help many people.
≐▽▽=⊙(≡/+.⋯⇡ⁿ⧻,2)

Try it online!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Normalized Malbolge to Malbolge translator
In this task, you will write a program/function that takes a Normalized Malbolge program and outputs the resulting Malbolge program. (This is a secret tool that all Malbolge programmers are using!)
Input
A data structure that (somehow) represents a Normalized Malbolge program.
Output
A data structure that represents the resulting Malbolge program.
Examples
jpoo*pjoooop*ojoopoo*ojoooooppjoivvvo/i<ivivi<vvvvvvvvvvvvvoji
(=BA#9"=<;:3y7x54-21q/p-,+*)"!h%B0/.~P<<:(8&66#"!~}|{zyxwvugJ%

jjjj*<jjjj*<v
('&%#^"!~}{XE

jjjjjjjjjjjjjjjjjjjjjjj*<jjjjjjjjjjjjjjjjjjjjjjjj*<v
('&%$#"!~}|{zyxwvutsrqpnKmlkjihgfedcba`_^]\[ZYXWVT1|

How to convert
Iterate over the normalized Malbolge program, performing the following steps for each character:

Replace the characters in the string *jpovi</ with the corresponding character in '(>DQbcu. (That is, map * to ', j to (, and so on.)
Then subtract the current position of the program counter (i.e. the number of characters before the current one) from the character's ASCII code.
If the resulting ASCII code is less than 33, increment it by 94 and repeat until it is at least 33.
Append the resulting character to the output.

Rules

This is a code-golf contest; the shortest answer wins.
No standard loopholes please.
The default I/O methods are allowed.
Input will only contain the characters *jpovi</.

Does the input contain only characters from "*jpovi</"?

I don't understand what "Then, minus the position." means. I probably could figure it out from the pseudocode, but the explanation should be self-contained.

Is there a reason to say "the ASCII code of "~" minus 32" rather than just 94? I was confused at first why the incrementing is a "while" and not just an "if", but if the position is really large, the decremented "code" could become far below zero. Test cases would also help, including something to cover this situation.

It's not quite what normalized malbolge and normal malbolge are. The real range is quite long, defined by this xlat: char * x = "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI.v%{gJh4G\\-=O@5\_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha"`

"While the temporary Malbolge representations' ASCII code is less than 33, increment the char by the 94." What do you mean by this? How I understood the challenge is: 1) map characters; 2) convert to unicode value; 3) decrease each by program counter (we now have what you call the 'temporary Malbolge representations' ASCII code'); 4) if any value is less than 33, increment that by 94; 5) convert these values back to characters. But using this approach the output clearly isn't correct.. So could you clarify what you mean by this for inputs longer than 33 characters?

a: if ascii_code(temporary Malbolge representation) < 33: char := char + 94; goto a;

I'll happily give a bounty to anyone who can write one of these things in Malbolge :)

@JDL done :), I'll happily accept this bounty

The link in the OP currently leads to a page that just says nope. Archive.org link, from 2020: https://web.archive.org/web/20200807093255/http://acooke.org:80/malbolge.html

Jelly, 29 22 bytes
Oị“%þV DCµ2®  ‘_JịØṖḊ¤

Try it online!
A monadic link taking a Jelly string as its argument and returning a Jelly string.
Thanks to @JonathanAllan for saving 2 bytes!
Explanation
O                      | Convert to Unicode code points
 ị“%þV DCµ2®  ‘        | Index into compressed integer list [37, 31, 86, 32, 68, 67, 9, 50, 8, 32, 32] (note the 32s are never actually used because the input mod 11 will be one of 1,2,3,5,6,7,8,9)
               _J      | Subtract position of character in original string
                 ị   ¤ | Index into the following as a nilad:
                  ØṖ   | - Printable ASCII characters
                    Ḋ  | - With the first character (space) removed

..._J‘ịØṖḊ¤ saves one byte.

@JonathanAllan thanks, good call!

oh, and we can increment inside our lookup >.< saving another byte: Oị“%þV DCµ2®  ‘_JịØṖḊ¤

Malbolge Unshackled (20-trit rotation variant), 7,784e6 bytes
Size of this answer exceeds maximum postable program size (eh), so the code is located in my GitHub repository.
How to run this?
This might be a tricky part, because naive Haskell interpreter will take ages upon ages to run this. TIO has decent Malbogle Unshackled interpreter, but sadly I won't be able to use it (limitations).
The best one I could find is the fixed 20-trit rotation width variant, that performs very well, converting 0,5 characters per second.
To make the interpreter a bit faster, I've removed all the checks from Matthias Lutter's Malbolge Unshackled interpreter.
My modified version can run around 6,3% faster.
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char* translation = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72Fh"
        "OA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";

typedef struct Word {
    unsigned int area;
    unsigned int high;
    unsigned int low;
} Word;

void word2string(Word w, char* s, int min_length) {
    if (!s) return;
    if (min_length < 1) min_length = 1;
    if (min_length > 20) min_length = 20;
    s[0] = (w.area%3) + '0';
    s[1] = 't';
    char tmp[20];
    int i;
    for (i=0;i<10;i++) {
        tmp[19-i] = (w.low % 3) + '0';
        w.low /= 3;
    }
    for (i=0;i<10;i++) {
        tmp[9-i] = (w.high % 3) + '0';
        w.high /= 3;
    }
    i = 0;
    while (tmp[i] == s[0] && i < 20 - min_length) i++;
    int j = 2;
    while (i < 20) {
        s[j] = tmp[i];
        i++;
        j++;
    }
    s[j] = 0;
}

unsigned int crazy_low(unsigned int a, unsigned int d){
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    int position = 0;
    unsigned int output = 0;
    while (position < 10){
        unsigned int i = a%3;
        unsigned int j = d%3;
        unsigned int out = crz[i+3*j];
        unsigned int multiple = 1;
        int k;
        for (k=0;k<position;k++)
            multiple *= 3;
        output += multiple*out;
        a /= 3;
        d /= 3;
        position++;
    }
    return output;
}

Word zero() {
    Word result = {0, 0, 0};
    return result;
}

Word increment(Word d) {
    d.low++;
    if (d.low >= 59049) {
        d.low = 0;
        d.high++;
        if (d.high >= 59049) {
            fprintf(stderr,"error: overflow\n");
            exit(1);
        }
    }
    return d;
}

Word decrement(Word d) {
    if (d.low == 0) {
        d.low = 59048;
        d.high--;
    }else{
        d.low--;
    }
    return d;
}

Word crazy(Word a, Word d){
    Word output;
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    output.area = crz[a.area+3*d.area];
    output.high = crazy_low(a.high, d.high);
    output.low = crazy_low(a.low, d.low);
    return output;
}

Word rotate_r(Word d){
    unsigned int carry_h = d.high%3;
    unsigned int carry_l = d.low%3;
    d.high = 19683 * carry_l + d.high / 3;
    d.low = 19683 * carry_h + d.low / 3;
    return d;
}

// last_initialized: if set, use to fill newly generated memory with preinitial values...
Word* ptr_to(Word** mem[], Word d, unsigned int last_initialized) {
    if ((mem[d.area])[d.high]) {
        return &(((mem[d.area])[d.high])[d.low]);
    }
    (mem[d.area])[d.high] = (Word*)malloc(59049 * sizeof(Word));
    if (!(mem[d.area])[d.high]) {
        fprintf(stderr,"error: out of memory.\n");
        exit(1);
    }
    if (last_initialized) {
        Word repitition[6];
        repitition[(last_initialized-1) % 6] =
                ((mem[0])[(last_initialized-1) / 59049])
                    [(last_initialized-1) % 59049];
        repitition[(last_initialized) % 6] =
                ((mem[0])[last_initialized / 59049])
                    [last_initialized % 59049];
        unsigned int i;
        for (i=0;i<6;i++) {
            repitition[(last_initialized+1+i) % 6] =
                    crazy(repitition[(last_initialized+i) % 6],
                        repitition[(last_initialized-1+i) % 6]);
        }
        unsigned int offset = (59049*d.high) % 6;
        i = 0;
        while (1){
            ((mem[d.area])[d.high])[i] = repitition[(i+offset)%6];
            if (i == 59048) {
                break;
            }
            i++;
        }
    }
    return &(((mem[d.area])[d.high])[d.low]);
}

unsigned int get_instruction(Word** mem[], Word c,
        unsigned int last_initialized,
        int ignore_invalid) {
    Word* instr = ptr_to(mem, c, last_initialized);
    unsigned int instruction = instr->low;
    instruction = (instruction+c.low + 59049 * c.high
            + (c.area==1?52:(c.area==2?10:0)))%94;
    return instruction;
}

int main(int argc, char* argv[]) {
    Word** memory[3];
    int i,j;
    for (i=0; i<3; i++) {
        memory[i] = (Word**)malloc(59049 * sizeof(Word*));
        if (!memory) {
            fprintf(stderr,"not enough memory.\n");
            return 1;
        }
        for (j=0; j<59049; j++) {
            (memory[i])[j] = 0;
        }
    }
    Word a, c, d;
    unsigned int result;
    FILE* file;
    if (argc < 2) {
        // read program code from STDIN
        file = stdin;
    }else{
        file = fopen(argv[1],"rb");
    }
    if (file == NULL) {
        fprintf(stderr, "File not found: %s\n",argv[1]);
        return 1;
    }
    a = zero();
    c = zero();
    d = zero();
    result = 0;
    while (!feof(file)){
        unsigned int instr;
        Word* cell = ptr_to(memory, d, 0);
        (*cell) = zero();
        result = fread(&cell->low,1,1,file);
        if (result > 1)
            return 1;
        if (result == 0 || cell->low == 0x1a || cell->low == 0x04)
            break;
        instr = (cell->low + d.low + 59049*d.high)%94;
        if (cell->low == ' ' || cell->low == '\t' || cell->low == '\r'
                || cell->low == '\n');
        else if (cell->low >= 33 && cell->low < 127 &&
                (instr == 4 || instr == 5 || instr == 23 || instr == 39
                    || instr == 40 || instr == 62 || instr == 68
                    || instr == 81)) {
            d = increment(d);
        }
    }
    if (file != stdin) {
        fclose(file);
    }
    unsigned int last_initialized = 0;
    while (1){
        *ptr_to(memory, d, 0) = crazy(*ptr_to(memory, decrement(d), 0),
                *ptr_to(memory, decrement(decrement(d)), 0));
        last_initialized = d.low + 59049*d.high;
        if (d.low == 59048) {
            break;
        }
        d = increment(d);
    }
    d = zero();

    unsigned int step = 0;
    while (1) {
        unsigned int instruction = get_instruction(memory, c,
                last_initialized, 0);
        step++;
        switch (instruction){
            case 4:
                c = *ptr_to(memory,d,last_initialized);
                break;
            case 5:
                if (!a.area) {
                    printf("%c",(char)(a.low + 59049*a.high));
                }else if (a.area == 2 && a.low == 59047
                        && a.high == 59048) {
                    printf("\n");
                }
                break;
            case 23:
                a = zero();
                a.low = getchar();
                if (a.low == EOF) {
                    a.low = 59048;
                    a.high = 59048;
                    a.area = 2;
                }else if (a.low == '\n'){
                    a.low = 59047;
                    a.high = 59048;
                    a.area = 2;
                }
                break;
            case 39:
                a = (*ptr_to(memory,d,last_initialized)
                        = rotate_r(*ptr_to(memory,d,last_initialized)));
                break;
            case 40:
                d = *ptr_to(memory,d,last_initialized);
                break;
            case 62:
                a = (*ptr_to(memory,d,last_initialized)
                        = crazy(a, *ptr_to(memory,d,last_initialized)));
                break;
            case 81:
                return 0;
            case 68:
            default:
                break;
        }

        Word* mem_c = ptr_to(memory, c, last_initialized);
        mem_c->low = translation[mem_c->low - 33];

        c = increment(c);
        d = increment(d);
    }
    return 0;
}

It's working!

This is just insane.

To passersby, the byte count is 7.784MB, not 7.784GB. I interpreted the comma as as grouping the thousands rather than a decimal point at first.

Python 3, 82 bytes
p=0
for c in input():print(end=chr((b"de{#0ABT"["*jpovi<".find(c)]-p)%94+33));p+=1

Try it online!
Thanks to @Joel for replacing the ugly unprintable characters in the bytestring with printable ones.
I'm looking for a mod-chain to replace "*jpovi<".find(c), but I don't think there is one that's shorter, and a non-exhaustive brute-force search hasn't found anything so far.
82 bytes
f=lambda s,p=0:s and chr((b"de{#0ABT"["*jpovi<".find(s[0])]-p)%94+33)+f(s[1:],p+1)

Try it online!

The unprintable ASCII characters can be offset by 94 to be made into printable ones for better readability.

You could try to find a math function to replace the mapping b"de{#0ABT"["*jpovi<".find(c)] if you have a program for that.

@Joel Unfortunately, I think that mapping is far too wide a search space for an arithmetic function, at least with the tools I have. I had just been searching modulo chains like x%84%15%7 for the right half of the mapping, but I think I can recycle some code I wrote for another challenge to search including * and / terms.

@Joel I'm not finding anything mod-chain-style for the right side using % and * (// in Python 3 probably isn't worth it.) In fact, nothing has matched the first 6 of 7 values. I hoped this would work because a rough entropy estimate says there's probably enough expressions ending in %7`, but it's close. And maybe these chains give outputs that are far from evenly distributed, especially since once two inputs collapse to the same value, no further operations can separate them. The stuff I'm trying is still far too dumb to search the larger expression, but if you have any ideas, go for it.

I think a better algorithm is probably needed for arbitrary inputs like map(ord, "*jpovi<"). If the output does not preserve the order for most of inputs (i.e. f(m)>=f(n) if m>=n), some carefully crafted constants for % and * are likely needed and a brute-force search is unlikely to yield a positive outcome.

I overlooked that a replacement of "*jpovi<".find(c) does not need to have the exact same value as it. See @Arnauld's answer.

Python 3, 84 83 bytes
f=lambda p,i=0:p and chr(126-(i+b"WV@:-zyg"["*jpovi<".find(p[0])])%94)+f(p[1:],i+1)

Try it online!
This is mostly a math problem about simplifying the computation, plus some golfing after getting the math done. The ungolfed version of code is shown below.
Ungolfed, non-recursive version
def convert(prog):
    offsets = dict(zip("*jpovi</", [87, 86, 64, 58, 45, 122, 121, 103]))  # ASCII encoded to "WV@:-zyg"
    output = ""
    for pos, c in enumerate(prog):
        output += chr(126-(offsets[c]+pos)%94)
    return output

Try it online!

JavaScript (Node.js), 69 bytes
s=>(B=Buffer)(s).map((c,i)=>33+(B(" #{T BAe0d")[c%11]+94-i%94)%94)+''

Try it online!
How?
Conveniently, Malbolge commands can easily be turned into a value in \$[1..9]\$ by just taking their ASCII code modulo \$11\$.
 char. | ASCII code | mod 11
-------+------------+--------
  '*'  |      42    |   9
  'j'  |     106    |   7
  'p'  |     112    |   2
  'o'  |     111    |   1
  'v'  |     118    |   8
  'i'  |     105    |   6
  '<'  |      60    |   5
  '/'  |      47    |   3

Perl 6, 65 55 53 bytes
*.ords>>.&{(' #{T BAe0d'.ords[$_%11]-$++)%94+33}.chrs

Try it online!
Uses the mod 11 trick from Arnaud's answer

05AB1E, 32 31 23 22 bytes
žQ¦•4¡ˆ¶ü]₁η₃•₃вIÇèā-è

-8 bytes creating a port of NickKennedy's Jelly answer, so make sure to upvote him!!
-1 byte thanks to @Grimy.
Outputs as a list of characters.
Try it online or verify all test cases.
Explanation:
   •4¡ˆ¶ü]₁η₃•          # Push compressed integer 82767635194143615015
              ₃в        # Converted to base-95 as list: [1,36,30,85,0,67,66,8,49,7,0]
                IÇ      # Push the input and convert each character to its unicode value
                  è     # Index each into the list we created
                   ā    # Push an integer list in the range [0, length]
                        # (without popping the list itself)
                    -   # Subtract it from the previous list
žQ                      # Push builtin with all printable ASCII characters,
  ¦                     # and remove the leading space
                     è  # Index the values of the list into the ASCII characters
                        # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers? and How to compress integer lists?) to understand why •4¡ˆ¶ü]₁η₃• is 82767635194143615015 and •4¡ˆ¶ü]₁η₃•₃в is [1,36,30,85,0,67,66,8,49,7,0].

•1ÃQWý₂Ýδ9•86в -> •4¡ˆ¶ü]₁η₃•₃в

Perl 5 (-p), 53, 51 bytes
saving 2 bytes, using de{#0ABT instead of '(>DQbcu so that 61 no longer needed
y;*jpovi</;de{#0ABT;;s/./chr 33+(-"@-"+ord$&)%94/ge

TIO
first answer was
y;*jpovi</;'(>DQbcu;;s/./chr 33+(61-"@-"+ord$&)%94/ge

TIO

Japt, 24 23 bytes
Port of Nick's Jelly solution
;£EÅgYn" #T BA0 "cXc

Try it
;£EÅgYn"..."cXc     :Implicit input of string
 £                  :Map each character X at 0-based index Y
; E                 :ASCII
   Å                :Slice of the first character (space)
    g               :Get character at index
     Y              :  Increment Y
      n             :  Subtract from
       "..."        :    Literal string (Codepoints: 32,35,29,84,32,66,65,7,48,6,32)
            c       :    Codepoint at index
             Xc     :      Codepoint of X

C# (Visual C# Interactive Compiler), 59 bytes
s=>s.Select((c,i)=>(char)(33+(" #{T BAe0d"[c%11]+94-i)%94))

Try it online!
Port of @Arnaulds JavaScript answer. One if the rare instances where C# is shorter!
-3 bytes thanks to @ceilingcat!

Haskell, 135 bytes
t=h"*jpovi</"(fromEnum<$>"'(>DQbcu")
h(x:m)(y:n)i|i==x=y|1<2=h m n i
a n|n<33=a(n+94)|1<2=n
f=(toEnum.a<$>).(zipWith(+)[0,-1..]).(t<$>)

Try it online!

Retina 0.8.2, 50 bytes
T`*j\p\ovi</`'(>DQbcu
.
$.`$* $&¶
+T`!p`~_p` .¶
¶

Try it online! Link includes test cases. Explanation:
T`*j\p\ovi</`'(>DQbcu

Make the transliteration as described in the question. p (described below) and o have special meaning to Transliterate so they need to be quoted.
.
$.`$* $&¶

List each character on its own line, preceded by a number of spaces according to its index i.e. what the program counter would be.
+T`!p`~_p` .¶

Repeatedly cyclically decrement the last character on each line, deleting the preceding space each time, until all of the spaces have been deleted. The p stands for printable ASCII i.e.  -~, however we want the ! to map to ~ so that is transliterated first, and then the _ causes the space in the match  .¶ to be deleted, while the remaining characters get transliterated one character code at a time.
¶

Join all of the characters back together.

Charcoal, 23 bytes
⭆Ｓ§Φγμ⁻℅§ #{T BAe0d ℅ικ

Try it online! Link is to verbose version of code. Port of @Arnauld's JavaScript answer. Explanation:
 Ｓ                      Input string
⭆                       Map over characters and join
                     ι  Current character
                    ℅   ASCII code
        §               Cyclically indexed into
          #{T BAe0d     Literal string ` #{T BAe0d `
       ℅                ASCII code
      ⁻                 Subtract
                      κ Current index
  §                     Cyclically indexed into
    γ                   Printable ASCII
   Φ                    Filtered on
     μ                  Inner index (i.e. skip initial space)
                        Implicitly print


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

 Smalltalk is a purely object-oriented language created by Alan Kay. The two links are GNU Smalltalk and a general Smalltalk page respectively. You do not have to pay attention on this "spoiler".

Use the ; operator to refer to the previous object
There is a convenient shorthand in Smalltalk used to refer to the previous object. Say we want to add 3 items to the set x.
x:=Set new
x add:5.x add:7.x add:'foo'

However, we can save a few bytes by using the ; operator:
x:=Set new
x add:5;add:7;add:'foo'


text:
Compute height of Bowl Pile
Bowl Pile Height
The goal of this puzzle is to compute the height of a stack of bowls.

A bowl is defined to be a radially symmetric device without thickness.
Its silhouette shape is an even polynomial. The stack is described by a list of radii, each associated with an even polynomial, given as input as a list of coefficients (e.g. the list 3.1 4.2 represents the polynomial \$3.1x^2+4.2x^4\$).
The polynomial may have arbitrary degree. For simplicity, the height of the pile is defined as the altitude of the center of the top-most bowl (see plot of Example 3 for an illustration).
Test cases are in the format radius:coeff1 coeff2 ...: each line starts with a float number representing the radius of the bowl, followed by a colon and a space-separated list containing the coefficients for the even powers, starting with power 2 (zero constant part is implied). For example, the line 2.3:3.1 4.2 describes a bowl of radius 2.3 and the shape-polynomial 3.1 * x^2 + 4.2 * x^4.
Example 1
42:3.141

describes a pile of zero height since a single bowl has no height.
Example 2
1:1 2
1.2:5
1:3

describes a pile of height 2.0 (see plot).

Example 3
1:1.0
0.6:0.2
0.6:0.4
1.4:0.2
0.4:0 10

describes a pile of height 0.8 (see green arrow in the plot).

This is code golf, so the shortest code wins.
I have reference code.
Edit:
The reference implementation relies on a library to compute the roots of polynomials.
You may do that as well but you don't need to.
Since the reference implementation is only a (quite good) numerical approximation, I will accept any code which produces correct results within common floating-point tolerances.
The idea counts. I don't care if there are small erros \$<\varepsilon\$.

Another variant of this puzzle is to minimize the height by reordering the bowls. I'm not sure if there's a fast solution (I guess it's NP-hard). If anyone has a better idea (or can prove NP-completeness), please tell me!

Comments are not for extended discussion; this conversation has been moved to chat.

In your reference code, I believe the body of is_maximum should be e.g. return evaluate(differentiate(shape_0), root) > 0.0. Currently, it evaluates the root using dd (derivative of the difference between shapes), which should always return 0 (for roots). Due to floating point errors, the result is occasionally a positive value close to 0, which is why the code outputs a correct or more accurate result some of the time. Check the input 1:0.2, 1:0.1 0.2 which should output 0.0125

@redundancy it’s actually redundant anyway. The max y value is chosen and 0 will always be in the compares values.

In example 3, the final height should be 0.801. The final two bowls touch at radius 0.1.

Yes, I got the same result.

@Joel agree, now I’ve fixed a bug in my Jelly code

Jelly, 54 53 bytes
J×$ÆrAƑƇ«⁹;⁹*€J{ḋ⁸ŻṀ
Œcz€0ḢṂç@I0;ⱮFƲƲ€ṚṁL’R€Ɗ;+Ṁ¥¥ƒ0Ṁ

Try it online!
A monadic link that takes as its argument the list of bowls from top to bottom in the format [[b1_radius, b1_coef1, ...], [b2_radius, b2_coef1, ...]] and returns the y position of the bottom of the top bowl.
Now correctly handles bowls which meet at places other than the minimal radius.
Explanation
Helper link: takes as left argument l the differences in coefficients of the polynomials representing the bowls from 1 upwards, and its right argument r the minimum radius; returns the maximum y value where the two bowls meet
  $                   | Following as a monad:
J                     | - Sequence from 1..<len(l)>
 ×                    | - Multiply (by l)
   Ær                 | Roots of polynomial
     AƑƇ              | Keep only those invariant when passed through absolute function (excludes negative, imaginary and complex numbers)
        «⁹            | Min of these filtered roots and r
          ;⁹          | Concatenate r to the list
            *€        | Each root/radius to the power of:
              J{      | - Sequence from 1..<len(l)>
                ḋ⁸    | Dot product with l
                  Ż   | Prepend zero
                   Ṁ  | Maximum

Main link, takes a bowl pile as its argument and returns y value of base of top bowl
Œc                               | Combinations length 2
  z€0                            | Transpose each using 0 as a filler
               Ʋ€                | For each one, do the following as a monad:
     Ḣ                           | - Take the head (the radii)
      Ṃ                          | - Minimum
       ç@     Ʋ                  | - Call the helper link with this (min radius) as right argument and the following as left argument:
         I                       |   - Increments (difference between second and first polynomial for each coefficient)
          0;Ɱ                    |   - Prepend each with a zero (odd coefficients are all zero)
             F                   |   - Flatten
                 Ṛ               | Reverse
                  ṁ    Ɗ         | Mould to the following as a monad:
                   L             | Length
                    ’            | Decrease by 1
                     R€          | Range of each (e.g. [1],[1,2],[1,2,3],[1,2,3,4]
                            ¥ƒ0  | Reduce using the following as a dyad and starting with 0
                        ;  ¥     | - Concatenate the following as a dyad
                         +       |   - Add
                          Ṁ      |   - Take the maximum
                               Ṁ | Finally take the overall maximum

Python reference
Finally, here’s a TIO version of the Python reference that @pasbi included for the main problem.  It reads from stdin.

I do not understand the language at all. Based on the explanation, it looks like you only compare each bowl pair (r1, p1) and (r2, p2) at the point min(r1, r2)? If so, that would be a wrong solution because two bowls can touch between 0 and min(r1, r2)). You need to find max(p1(x)-p2(x), 0) over the entire range [0, min(r1, r2)] for x. That is why @pasbi's reference solution computes derivatives for finding the local maximum.

@Joel fixed now. All of the original test cases touched at min(r1, r2). This now solves @attinat’s additional challenge

It would be nice to see a commented version of the code for those who have no knowledge of the golfing language, if you have time.

@Joel will do when I get time

Python 3 + numpy + scipy, 248 240 bytes
from scipy.optimize import*
from numpy import*
def f(b,i=0):
 for r,c in b:p=zeros(2*len(c)+1);p[-3::-2]=c;p[-1]=h=max([0,*(-fminbound(lambda x:polyval(polysub(p,d),x),0,min(s,r),full_output=1)[1]for s,d in b[:i])]);b[i][1]=p;i+=1
 return h

Try it online!
-8 bytes thanks to @xnor
The function takes a list of [radius, polynomial] pairs as input and returns the pile height.
This solution uses more or less the same algorithm as the reference code except that it does not compute the maximum using derivatives. Meanwhile, it is written using built-in numpy and scipy functions in Python. The ungolfed version is shown in the following. This serves as an alternative version of the reference code for those who wants a shorter version to capture the idea quickly.
from scipy.optimize import fminbound
import numpy as np

def compute_pile_height(bowl_data):
    for i, (r, curve) in enumerate(bowl_data):
        distances = [0]  # Initialize the distances array with 0 as the lower bound for max
        # Construct a complete polynominal coefficient array
        curve_poly = np.zeros(2 * len(curve) + 1)
        curve_poly[-3::-2] = curve

        # Iterate over all bowls under the current bowl
        for j in range(i):
            b_r, b_curve_poly = bowl_data[j]

            # Calculate the difference polynominal between the current bowl and bowl j
            diff = np.polysub(curve_poly, b_curve_poly)

            # Find the maximum height difference between bowl j and the current bowl in the range [0, min(b_r, r)]
            max_height_diff = -fminbound(lambda x:np.polyval(diff, x), 0, min(b_r, r), full_output=True)[1]
            distances.append(max_height_diff)

        # Compute the maximum distance as the height for the current bowl,
        # update the polynominal using the height as the constant coefficient
        curve_poly[-1] = height = max(distances)

        # Update stored data for the current bowl
        bowl_data[i][1] = curve_poly
    return height

Try it online!

To save on whitespace, you can put the whole for loop on its line after the colon, and put i=0 as an optional argument.

@xnor Ah, thanks. I did not put too much effort to golf this because saving a couple of bytes in a 200+byte solution would not change it much. And it seems that there is no better algorithm for this one that can significantly simplify the computation.

Technically this should be described in the header as Python3 + numpy + sympy since neither are part of the base Python3 install.

@NickKennedy Thanks. Description updated.

R, 451 436 bytes
function(x){x=c(x[1],x);a=rev(pmax(0,c(combn(x,2,function(y,z=sapply(y,"length<-",max(lengths(y)))){z[is.na(z)]=0
b=rep(0,2*(n=nrow(z)-1))
b[2*1:n]=e=z[-1,2]-z[-1,1]
b=b*1:(2*n)
while(!c(b,1)[1])b=b[-1]
b=rev(b)
s=`if`(length(b)>1,eigen(rbind(-(b/b[1])[-1],cbind(diag(length(b)-2),0)))$va,0)
max(outer(c(pmin(abs(s[s==abs(s)]),r<-min(z[1,])),r),2*1:n,`^`)%*%e)}))))
o={}
for(i in seq(a=x[-1])){o=c(o,max(c(0,o)+a[1:i+F]));F=F+i}
max(o)}

Try it online!
Try it online!
Broadly speaking an R port of my Jelly answer, though since base R has no function to find the roots of polynomials this is implemented using the method found in polynom::solve.polynomial.
A function taking a list of numeric vectors from top to bottom of pile.
Thanks to @RobinRyder for golfing off 15 bytes!

I don't understand everything that is going on here (explanation would be nice!), but here is a 436 byte version.

Wolfram Language (Mathematica), 104 93 bytes
FoldPair[{(R=#;F=#2)&@@#2;H=Max[0,{#2-F,0<x<#~Min~R}~MaxValue~x&@@@#],#~Join~{R|H+F}}&,{},#]&

Try it online!
Takes input as a List of {radius, polynomial} pairs representing bowls, with polynomials in terms of \$x\$.
For decimal instead of symbolic output, use NMaxValue instead (or just call N on the result).
(* Step through a list of bowls: *)
(* At each step, calls a function taking {previous-bowls-list},current-bowl *)
(*  which returns {height,{bowls-list}} *)
(* and returns the final height *)
FoldPair[
  (R=#;F=#2)&@@#2;          (*  extract Radius and Function*)
  {
    H=Max[0,                (*  Height - at least zero; the greatest of *)
      MaxValue[{#2-F,       (*   the required heights *)
          0<x<#~Min~R},x]   (*     within the relevant domain *)
      &@@@#]                (*   given all previous bowls *)
  ,
    #~Join~{R|H+F}          (*   append to list of bowls *)
  }&,
  {},                       (* initial list of bowls (empty) *)
  #                         (* list of bowls *)
]&