text:
The Digit Triangles
Challenge:
Input: A positive integer \$n\$
Output:
Create a list in the range \$[1,n]\$, and join it together to a string (i.e. \$n=13\$ would be the string 12345678910111213).
Now we output a triangle using the prefixes or suffixes of this string, in one of the following four orientations based on the input integer:

If \$n\equiv 0\pmod 4\$, output it in the triangle shape ◣
If \$n\equiv 1\pmod 4\$, output it in the triangle shape ◤
If \$n\equiv 2\pmod 4\$, output it in the triangle shape ◥
If \$n\equiv 3\pmod 4\$, output it in the triangle shape ◢

Example:
Input: \$n=13\$
Because \$13\equiv 1\pmod 4\$, the shape will be ◤. Here three possible valid outputs:
12345678910111213    11111111111111111    12345678910111213
1234567891011121     2222222222222222     2345678910111213
123456789101112      333333333333333      345678910111213
12345678910111       44444444444444       45678910111213
1234567891011        5555555555555        5678910111213
123456789101         666666666666         678910111213
12345678910          77777777777          78910111213
1234567891           8888888888           8910111213
123456789            999999999            910111213
12345678             11111111             10111213
1234567              0000000              0111213
123456               111111               111213
12345                11111                11213
1234                 1111                 1213
123                  222                  213
12                   11                   13
1                    3                    3

Challenge rules:

As you can see at the three valid outputs above, only the correct shape and using all the digits in the correct order is important. Apart from that you're free to use prefixes or suffixes; reverses/reflects; diagonal printing; etc. etc. Any of the six possible outputs for each shape is allowed (see the test case below to see all valid outputs based on the shape). This allows languages with rotation builtins to use it, but those without can also use an alternative approach of using the prefixes in the correct size from top-to-bottom, or using the prefixes for two of the shapes but suffixes for the other two shapes. Choosing the most appropriate output options for your language is part of the golfing process. :)
Input is guaranteed to be a positive integer. For \$n=1\$ we simply output 1.
Any amount of leading/trailing newlines/spaces are allowed, as long as it prints the correct triangle (without vertical nor horizontal delimiters!) somewhere on the screen.

General rules:

This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code (i.e. TIO).
Also, adding an explanation for your answer is highly recommended.

Test cases:
Input: \$n=5\$
All possible valid outputs:
12345    54321    12345    54321    11111    55555
1234     5432     2345     4321     2222     4444
123      543      345      321      333      333
12       54       45       21       44       22
1        5        5        1        5        1

Input: \$n=6\$
All possible outputs:
123456    654321    123456    654321    111111    666666
 12345     65432     23456     54321     22222     55555
  1234      6543      3456      4321      3333      4444
   123       654       456       321       444       333
    12        65        56        21        55        22
     1         6         6         1         6         1

Input: \$n=7\$
All possible outputs:
      1          1          7          7          7          1
     12         21         67         76         66         22
    123        321        567        765        555        333
   1234       4321       4567       7654       4444       4444
  12345      54321      34567      76543      33333      55555
 123456     654321     234567     765432     222222     666666
1234567    7654321    1234567    7654321    1111111    7777777

Input: \$n=8\$
All possible outputs:
1           1           8           8           8           1
12          21          78          87          77          22
123         321         678         876         666         333
1234        4321        5678        8765        5555        4444
12345       54321       45678       87654       44444       55555
123456      654321      345678      876543      333333      666666
1234567     7654321     2345678     8765432     2222222     7777777
12345678    87654321    12345678    87654321    11111111    88888888

Input: \$n=1\$
Only possible output:
1

Input: \$n=2\$
All possible outputs:
12    21    12    21    11    22
 1     2     2     1     2     1

Can we use other values for different triangles, like 1 for ◤, etc?

@EmbodimentofIgnorance Unfortunate example, since that's what the spec says. I think you wanted to ask if we can change the order of the four arrangements as long as we keep it consistent (I think that would be a no).

If n==13, can the topmost row be '33333333333333333' (or, equivalently, '31211101987654321')?

@EmbodimentofIgnorance Sorry, but I'd say no in this case. The shapes and their corresponding mod 4 are strict pairs for this challenge. So you may not switch the four shapes for the four mod 4 cases. But good question nonetheless.

@ChasBrown Yes, both of those are fine. I only gave three possible examples for the $n=13$, but all six options (like the $n=5$ test case) are valid outputs.

JavaScript (ES6),  93  89 bytes
Returns a matrix of characters.
n=>[...(g=n=>n?g(n-1)+n:'')(n)].map((d,y,a)=>a.map(_=>y-(n&2)*y--<0?' ':d)).sort(_=>-n%2)

Try it online!
Alternate pattern (same size):
n=>[...(g=n=>n?g(n-1)+n:'')(n)].map((_,y,a)=>a.map(d=>y-(n&2)*y--<0?' ':d)).sort(_=>-n%2)

Try it online!
Commented
n =>                 // n = input
  [...               // split the result of ...
    ( g = n =>       //   ... a call to the recursive function g, taking n
      n ?            //     if n is not equal to 0:
        g(n - 1)     //       append the result of a recursive call with n - 1
        + n          //       append n
      :              //     else:
        ''           //       stop recursion and return an empty string
    )(n)             //   initial call to g
  ].map((d, y, a) => // for each digit d at position y in this array a[]:
    a.map(_ =>       //   for each character in a[]:
      y -            //     we test either y < 0 if (n AND 2) is not set
      (n & 2)        //     or -y < 0 (i.e. y > 0) if (n AND 2) is set
      * y-- < 0      //     and we decrement y afterwards
      ?              //     if the above condition is met:
        ' '          //       append a space
      :              //     else:
        d            //       append d
    )                //   end of inner map()
  )                  // end of outer map()
  .sort(_ => -n % 2) // reverse the rows if n is odd

Shape summary
Below is a summary of the base shape (generated by the nested map loops) and the final shape (after the sort) for each \$n\bmod 4\$:
 n mod 4  | 0     | 1     | 2     | 3
----------+-------+-------+-------+-------
 n & 2    | 0     | 0     | 2     | 2
----------+-------+-------+-------+-------
 test     | y < 0 | y < 0 | y > 0 | y > 0
----------+-------+-------+-------+-------
 base     | #.... | #.... | ##### | #####
 shape    | ##... | ##... | .#### | .####
          | ###.. | ###.. | ..### | ..###
          | ####. | ####. | ...## | ...##
          | ##### | ##### | ....# | ....#
----------+-------+-------+-------+-------
 n % 2    | 0     | 1     | 0     | 1
----------+-------+-------+-------+-------
 reverse? | no    | yes   | no    | yes
----------+-------+-------+-------+-------
 final    | #.... | ##### | ##### | ....#
 shape    | ##... | ####. | .#### | ...##
          | ###.. | ###.. | ..### | ..###
          | ####. | ##... | ...## | .####
          | ##### | #.... | ....# | #####

thank you for your detail explaining.

Python 2, 94 bytes
n=0;s=''
exec"n+=1;s+=`n`;"*input()
K=k=len(s)
while k:k-=1;print s[k^n/-2%-2:].rjust(n%4/2*K)

Try it online!

Japt, 8 bytes
Returns an array of lines.
õ ¬å+ zU

Try it
Saved 2 bytes thanks to Kevin.
õ ¬å+ zU     :Implicit input of integer U
õ            :Range [1,U]
  ¬          :Join to a string
   å+        :Cumulatively reduce by concatenation
      zU     :Rotate clockwise by 90 degrees U times

Is the ú necessary? It seems the rotate does this implicitly?

@KevinCruijssen, hmm ... so it does. I always forget that; rarely get to use z.

Well, I don't know Japt at all. Was just curious what the output looked like without the padding for fun, and saw it worked exactly the same.. ;)

Canvas, 8 bytes
ŗ］∑［］⁸［↷

Try it here!

Perl 6, 94 bytes
{[o](|(&reverse xx$_/2+.5),|(*>>.flip xx$_/2+1))([\~](my@a=[~](1..$_).comb)>>.fmt("%{+@a}s"))}

Try it online!
Anonymous code block that takes a number and returns a list of lines.

R, 152 139 137 134 bytes
function(n,N=nchar(s<-Reduce(paste0,1:n,'')),A=!n%%4%%3)for(i in 1:N)cat(rep('',(M=c(N-i+1,i))[1+!A]*(n%%4>1)),substr(s,1,M[1+A]),'
')

Unrolled code :
function(n){
  s = Reduce(paste0,1:n,'')      # concat the digits from 1 to n into a string s

  N = nchar(s)                   # store the length of s

  A = !n%%4%%3                   # A = TRUE if n MOD 4 == 1 or 2

  for(i in 1:N){                 # for 1 to N (length of s)

    M = c(N-i+1,i)               # store N-i+1 and i into a vector

    nSpaces = M[1+!A]*(n%%4>1)   # if n MOD 4 == 1 or 2 then nSpaces = i else nSpaces = N-i+1,
                                 # but if n MOD 4 == 0 or 1, then force nSpaces = 0

    nDigits = M[1+A]             # if n MOD 4 == 1 or 2 then nDigits = N-i+1 else nDigits = i

    prfx = rep('',)              # create a character vector repeating '' nSpaces times

    sufx = substr(s,1,M[1+A])    # substring s by taking the first nDigits characters

    cat(pr,su,'\n')              # print prfx and sufx using space as separator for the values
                                 # contatenation (cat function default) and append a newline
  }

Try it online!

...it hasn't been my day for golfing, clearly.

@Giuseppe: ahah been there...and then you usually outgolfed me :P

Charcoal, 17 bytes
Ｎθ≔⭆θ⊕ιηＧLＬηη⟲⊗θ‖

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

Input n.
≔⭆θ⊕ιη

Create a string by concatenating the numbers 1 to n.
ＧLＬηη

Fill a triangle of that length with the string.
⟲⊗θ

Rotate the triangle anticlockwise by n*90 degrees.
‖

Reflect everything, thus ending up with a triangle that is rotated clockwise by n*90 degrees.

Ruby, 95 82 79 bytes
->n{r=(0...z=/$/=~s=[*1..n]*'').map{|i|" "*n[1]*i+s[0,z-i]};-n&2>0?r:r.reverse}

Try it online!
3 bytes saved by G B.

C# (Visual C# Interactive Compiler), 128 bytes
n=>{var s="";int i=0,j,p;for(;i<n;s+=++i);for(p=j=s.Length;;)Write("{0,"+(n%4>1?p:0)+"}\n",new string(s[--j],-~n%4>1?j+1:p-j));}

Try it online!

Suggest n%4/2*p instead of n%4>1?p:0

R, 175 172 154 bytes
function(n)write(c(" ",0:9)[1+(x=utf8ToInt(Reduce(paste0,1:n,""))-47)*!upper.tri(diag(y<-sum(x|1)))["if"(n%%4>1,1:y,y:1),"if"(!n%%4%%3,y:1,1:y)]],1,y,,"")

Try it online!
A horrible in-line mess!
-3 bytes by changing the rotation condition
-17 bytes thanks to digEmAll's suggestion, and another byte after golfing that further

I like this upper.triangle approach and can be shortened to 155 bytes... maybe even more, I'm sure I'm missing something obvious...

@digEmAll ah, much improved, but still long :-(

APL+WIN, 45 bytes
Prompts for integer
m←⊃(⍳⍴s)↑¨⊂s←(⍕⍳n←⎕)~' '⋄⍎(' ⊖⍉⌽'[1+4|n]),'m'

Try it online! Courtesy of Dyalog Classic

05AB1E (legacy), 14 12 10 bytes
Using the legacy verion as the rewrite is extremely slow on this for some reason.
Saved 2 bytes thanks to Kevin Cruijssen
LSηsFRζ}J»

Try it online!
Explanation
L           # push range [1 ... input]
 S          # split to list of individual digits
  η         # calculate prefixes
   sF  }    # input times do:
     R      # reverse list
      ζ     # and transpose it
        J   # join to list of strings
         »  # and join on newlines

You can save 2 bytes changing LJη€S to LSη, since S implicitly flattens.

@KevinCruijssen: Oh yeah, thanks! I'd forgotten about that. I tried €S which didn't work out very well ;)

PowerShell, 108 bytes
param($n)0..($y=($x=-join(1..$n)).length-1)|%{' '*(0,0,$_,($z=$y-$_))[$n%4]+-join$x[0..($_,$z,$z,$_)[$n%4]]}

Try it online!
A bit rough around the edges but works. Joins the digits 1 to n into a string then iterates from 0 to the length of that string-1. Each time, it uses list indexing to swap to the correct spacing method and number range used to slice our new string.

Jelly, 12 bytes
D€Ẏ;\z⁶U$⁸¡Y

Try it online!

Stax, 10 bytes
Ç√çZ╟84Γó║

Run and debug it

PowerShell, 105 101 95 bytes
-4 bytes thanks Arnauld for the trick with Sort.
param($n)($x=1..$n-join'')|% t*y|%{($s+="$_")}|sort -d:($n%4-in1,2)|% *ft($x.Length*($n%4-ge2))

Try it online!
Less golfed:
param($n)
$x=1..$n-join''
$x|% toCharArray |% {
    ($s+="$_")
} | sort -Descending:($n%4-in1,2) |% PadLeft ($x.Length*($n%4-ge2))

perl 5, 117 bytes
$p=$_++&2?'/ ':'$/';$s='(.*\d.\n)';$r=$_--&2?$s.'\K$':"^(?=$s)";$_=(join"",1..$_).$/;1while s,$r,'$1=~s/\d'."$p/r",ee

TIO

PHP, 116 111 109 bytes
for($m=$l=strlen($s=join(range(1,$n=$argn)));$l--;)printf('%'.($n&2?$m:-$l).'.'.($n-1&2?$m-$l:$l+1)."s
",$s);

Try it online!
Run with php -nF input from STDIN.
$ echo 6|php -nF t.php
123456
 12345
  1234
   123
    12
     1

Java (JDK), 247 209 188 186 160 148 bytes
i->{String s="";int l=0,w;for(;l<i;s+=++l);for(w=s.length(),l=0;l<w;)System.out.printf("%"+(1>i%4/2?1:w)+"s\n",s.substring(0,1>~-i%4/2?w-l++:++l));}

Try it online!
-38 bytes thanks to @KevinCruijssen
-21 bytes by letting printf handle the padding.
-2 bytes by doing substring before replace, allowing us to increment l in one location rather than two.
-26 bytes - with printf doing the padding, the string full of spaces was no longer necessary, and the digit strings could be generated in a shorter way apparently.
-12 bytes by not messing about with single digits instead of printing substrings of the perfectly servicable digit string we already have.
Ungolfed
input->{
    // Lambda expression with target type of IntConsumer
    String allDigits = "";
    int lineLength, line = 0;

    // Collect a list of all digits in order.
    for (;line < input; allDigits += ++line) {}

    // Save the max length of a line, and create a string of that many spaces.
    for (lineLength=allDigits.length(), line=0; line < lineLength;) {
        System.out.printf(   "%" // construct a format string to handle the padding
                           + (   1 > input%4/2
                               ? 1 // No padding
                               : w // Yes padding
                             )
                           + "s\n"
                         , allDigits.substring( 0
                                              ,   1 > (i-1)%4/2
                                                ? w - l++
                                                : ++l
                                              ) // A string containing only the digit we want.
                         );
    }
}

Nice answer. There are a bunch of things to golf more, though: The spaces after the for( can be removed. new String(new char[w=s.length()]).replace('\0',' ') can be " ".repeat(w=s.length()) using Java 11+. You can remove the parenthesis around the ternary-checks. 1>(i-1)%4/2 can be 1>~-i%4/2. w-1-l++ can be w+~l++. And you don't have to count the trailing semicolon in the byte-count. Which all combined becomes 209 bytes.

Wolfram Language (Mathematica), 137 bytes
(t=Table[Table[" ",If[(m=#~Mod~4)>1,Tr[1^s]-k,0]]<>ToString/@s[[;;k]],{k,Length[s=Join@@IntegerDigits/@Range@#]}];If[0<m<3,Reverse@t,t])&

Try it online!

Python 2, 116 bytes
n=input()
s=''.join(map(str,range(1,n+1)));L=len(s)
p=-~n/2%2;i=~-L*p+1
exec'print s[:i].rjust(n/2%2*L);i+=1-2*p;'*L

Try it online!

Red, 155 bytes
func[n][b: copy""repeat i n[append b i]repeat i l:
length? b[t:[l - i + 1]set[k m]pick[i t[l t][l i]]n % 4 + 1
print pad/left copy/part b do do m do do k]]

Try it online!


text:
Multiplicative persistence
Multiplicative Persistence

Multiply all the digits in a number
Repeat until you have a single digit left

As explained by Numberphile:

Numberphile "What's special about 277777788888899?"
Numberphile "Multiplicative Persistence (extra footage)"

Example

277777788888899 → 2x7x7x7x7x7x7x8x8x8x8x8x8x9x9 = 4996238671872
4996238671872 → 4x9x9x6x2x3x8x6x7x1x8x7x2 = 438939648
438939648 → 4x3x8x9x3x9x6x4x8 = 4478976
4478976 → 4x4x7x8x9x7x6 = 338688
338688 → 3x3x8x6x8x8 = 27648
27648 → 2x7x6x4x8 = 2688
2688 → 2x6x8x8 = 768
768 → 7x6x8 = 336
336 → 3x3x6 = 54
54 → 5x4 = 20
20 → 2x0 = 0

This is the current record, by the way: the smallest number with the largest number of steps.
Golf
A program that takes any whole number as input and then outputs the result of each step, starting with the input itself, until we hit a single digit. For 277777788888899 the output should be
277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

(Counting the number of steps is left as an exercise to the user).
More Examples
From A003001:
25
10
0

From A003001 as well:
68889
27648
2688
768
336
54
20
0

From the Numberphile video, showing that the single digit doesn't have to be 0:
327
42
8

So there has been a question about Additive Persistence, but this is Multiplicative Persistence. Also, that question asks for the number of steps as output, while I'm interested in seeing the intermediate results.

Bonus: find a new record: smallest number with the largest number of steps. Caveat: conjecture has it that 11 is the largest possible.

You probably should include a few more tests cases that do not end with $0$.

Came to make this post, found it already existing, gg

is a single digit valid input?

@dzaima yes, but it should only print that number and then stop.

In the Numberphile video, Matt Parker states that searches have been done to several hundred digits.

@Arnauld I've added some more examples.

For languages with type size limits, do we have to use the fancy bignum types or just fit the largest example case (277777788888899)?

Jelly, 4 bytes
DP$Ƭ

Try it online!
Explanation
D    | convert to decimal digits
 P   | take the product
  $  | previous two links as a monad
   Ƭ | loop until no change, collecting all intermediate results

As a bonus, here's a TIO which will find the numbers with the largest number of steps for a given range of numbers of digits. It scales well even on TIO.

TI-BASIC (TI-84), 30 32 31 bytes
-1 byte thanks to @SolomonUcko!
While Ans>9:Disp Ans:prod(int(10fPart(Ans10^(seq(-X-1,X,0,log(Ans:End:Ans

Input is in Ans.
Output is displayed as the challenge requests.  The trailing Ans is needed to print the last step.
I will admit, I did not think of this formula myself, rather I found it here and modified it to better fit the challenge.
EDIT:  Upon rereading the challenge, I realized that the program must terminate if the product is one digit.  Hence, 2 bytes were to be added to account for this.
Example:
24456756
        24456756
prgmCDGF8
        24456756
          201600
               0
11112
           11112
prgmCDGF8
           11112
               2

Explanation:
While Ans>9               ;loop until the product is one digit
Disp Ans                  ;display the current product
prod(                     ;get the product of...
 int(                     ; the integer part of...
  10fPart(                ; ten times the fractional part of...
  Ans                     ; each element in the following list times the
                          ;  current product
  10^(                    ; multiplied by the list generated by using each
                          ;  element of the following list as an exponent
                          ;  for 10^n
   seq(-X-1),X,0,log(Ans  ; generate a list of exponents from -1 to -L where
                          ;  L = the length of the current product
End
Ans                       ;leave the final product in "Ans" and implicitly
                          ; print it

Visual Model:
Ans starts off as 125673.
This model only covers the logic behind multiplying the digits; everything else is easier to understand.
seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,5.0992
   {-1 -2 -3 -4 -5 -6}
10^(...
   {.1 .01 .001 1E-4 1E-5 1E-6}
Ans...
   {12567.3 1256.73 125.673 12.5673 1.25673 .125673}
fPart(...
   {.3 .73 .673 .5673 .25673 .125673}
10...
   {3 7.3 6.73 5.673 2.5673 1.25673}
int(...
   {3 7 6 5 2 1}
   (the digits of the number, reversed)
prod(...
   1260
   (process is repeated again)

seq(-X-1,X,0,log(Ans  =>  seq(-X-1,X,0,3.1004
   {-1 -2 -3 -4}
10^(...
   {.1 .01 .001 1E-4}
Ans...
   {126 12.6 1.26 .126}
fPart(...
   {0 .6 .26 .126}
10...
   {0 6 2.6 1.26}
int(...
   {0 6 2 1}
prod(...
   0
   (product is less than 10.  loop ends)

Notes:
TI-BASIC is a tokenized language.  Character count does not equal byte count.
10^( is this one-byte token.
This program will not provide the correct sequence of products with integers greater than 14 digits long due to the limitations of decimal precision on the TI calculators.

Can you save a byte by moving 10^( outside seq( and omitting the closing parenthesis?

Yes, I believe so!

K (ngn/k), 9 bytes
{*/.'$x}\

Try it online!
{ }\ keep applying the function in curly braces until the sequence converges
$x format the argument as a string (list of characters)
.' evaluate each (other dialects of k require a colon, .:')
*/ times over, i.e. product

R, 59 57 bytes
n=scan();while(print(n)>9)n=prod(n%/%10^(0:log10(n))%%10)

Try it online!
Since print invisibly returns its input, we can use print(n) inside the while loop to simulate a do-while loop. This is inspired by one of my tips for golfing in R.
The header helps prevent large numbers from being printed in scientific notation.

55 bytes (with possibly room for improvement, if you can find a shorter way of converting to character).

05AB1E, 7 4 bytes
Δ=SP

Try it online or verify all test cases.
Explanation:
Δ     # Loop until the number no longer changes:
 =    #  Print the number with trailing newline (without popping the number itself)
      #  (which will be the implicit input in the first iteration)
  SP  #  Convert the number to a list of digits, and calculate its product

dzaima/APL, 14 11 bytes
∪{×/⍎¨⍕⍵}⍡≡

Try it online!

Wolfram Language (Mathematica), 47 bytes
Most@FixedPointList[Times@@IntegerDigits@#&,#]&

Try it online!

Wolfram Language (Mathematica), 39 bytes
0Print@#+#>9&&#0@@Times@@@RealDigits@#&

Try it online!
-6 bytes from @att

42 bytes if you don't mind using Echo.

39 bytes

Perl 6, 23 bytes
{$_,{[*] .comb}…10>*}

Try it online!

Python 2,  46  43 bytes
-3 thanks to xnor (chained comparison)
def f(n):print n;n>9>f(eval('*'.join(`n`)))

Try it online!

You can do > in place of and.

@xnor thanks, easy to forget that will work.

Julia 0.7, 36 33 bytes
f(n)=n>9?[n;f(prod(digits(n)))]:n

Try it online!
Thanks to H.PWiz for -3 bytes.

You can use [n;f(prod(digits(n)))]

-4 bytes by using an unary operator (for example !n=...)

V (vim), 29 bytes
qqlYp:s/./&*/g
C<C-r>=<C-r>"<BS>
<esc>|@qq@q

Try it online!

Looks like you can change the l to a h (as in Razetime's answer), to remove the |

JavaScript (ES6), 45 bytes
Returns an array of integers.
f=n=>[n,...n>9?f(eval([...n+''].join`*`)):[]]

Try it online!

Ruby, 38 35 34 bytes
f=->n{p(n)>9&&f[eval n.digits*?*]}

Try it online!
1 byte saved by by G B.

MathGolf, 9 10 bytes
h(ôo▒ε*h(→

Try it online!
Now it correctly handles inputs that are single digits. Not perfect, but at least it is correct.
Explanation
h(            check length of input number and decrease by 1
  ö       →   while true with pop using the next 6 operators
   p          print with newline
    ▒         split to list of chars/digits
     ε*       reduce list by multiplication
       h(     length of TOS without popping, subtracted by 1 (exits when len(TOS) == 1)

The output for a single digit input should be one copy of the number - clarified in the comments

@dzaima I'll look into it, and update the answer when it's solved

C# (Visual C# Interactive Compiler), 79 74 68 bytes
void f(int a){Print(a);if(a>9)f((a+"").Aggregate(1,(j,k)=>k%48*j));}

I try to stay away from recursion in C# due to how long the method declaration is, but in this case it saves compared to a loop.
Try it online!

Python 2, 61 62 59 bytes
def f(n):print n;n>9and f(reduce(int.__mul__,map(int,`n`)))

Try it online!
-3 bytes, thanks to Jonathan Allan

Doesn't work for inputs that don't end with a 0 on their last iteration, for example 23

int.__mul__ is three bytes less than lambda a,b:a*b

@JonathanAllan Thanks! I knew there had to be something like that

Change f(reduce(int.__mul__,map(int,\n`)))tof(eval('*'.join(`n`)))` to save 13 bytes.

@mypetlion ...I already did that in another post.

PowerShell, 54 bytes
for($a=$args;$a-gt9){$a;$a=("$a"|% t*y)-join"*"|iex}$a

Try it online!

Iterative method that first writes the input argument, then converts it into a string and pipes it into a character array. This array is joined by a single asterisks, and executed as a command with the invoke expression alias. Since this writes Starting number down to the last number greater than 0, (20, in the given test scenario), I add a final $a to the end to output.

PHP, 63 bytes
<?=$n=$argn;while($n>9)echo"
",$n=array_product(str_split($n));

Iterative version, call with php -nF input from STDIN.
Try it online!
PHP, 72 71 bytes
function h($n){echo"$n
",($n=array_product(str_split($n)))>9?h($n):$n;}

Try it online!
Recursive version, as function.
Input: 277777788888899
277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0

Input: 23
23
6

perl 5 (-n -M5.01), 32 30 25 bytes
say$_=eval;s/\B/*/g&&redo

25 bytes
30 bytes
32 bytes

You should mention that this uses -lpF//

@Grimy i could save 2 bytes without using -lpF//, updating

PowerShell, 51 bytes
filter f{$_
if($_-gt9){("$_"|% t*y)-join'*'|iex|f}}

Try it online!

J, 16 bytes
([:*/,.&.":)^:a:

Try it online!

This doesn’t work for very large numbers as it then switches into floating point mode, even putting x on the end doesn’t help                  ([:*/,.&.":)^:a:3777788889999977777777777x
3.77779e24
3.4448e21
0
0

@RichardDonovan Yes, you're right - thank you for your obsrevation! I don't know how to  fix it.

@GalenIvanov ([:*&x:/,.&.":)^:a: fixes it (you also need the x on the input), though I think your existing answer is still legal.

APL(NARS), 19 chars, 38 bytes
{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}

test:
   f←{⍵≤9:⍵⋄∇×/⍎¨⍕⍵⊣⎕←⍵}
   f 23
23
6
   f 27648
27648
2688
768
336
54
20
0

Haskell, 45 bytes
f n=n:[x|n>9,x<-f$product$read.pure<$>show n]

Try it online!

Japt -R, 9 bytes
Horribly inefficient - don't even try to run the first test case!
_ì ×}hN â

Try it
_ì ×}hN â     :Implicit input of integer U
      N       :Starting with the array of inputs (i.e., [U])
     h        :Do the following U times, pushing the result to N each time
_             :Take the last element in N and pass it through the following function
 ì            :  Convert to digit array
   ×          :  Reduce by multiplication
    }         :End function
        â     :Deduplicate N
              :Implicitly join with newlines and output

Chevron, 100 bytes
>^__>>^n
->+11?^n<10
>^n
^d<<1
^i<<1
^m<^i>^n
->+4??^m=^__
^d<<^d*^m
^i<<^i+1
->-4
^n<<^d
->-10
><^n

This is a fairly new language of my own creation - prototype interpreter, documentation, and example programs can be found at https://github.com/superloach/chevron.
Explanation:

>^__>>^n - take the input as a NUM, with empty prompt
->+11?^n<10 - if the number is under 10 (1 digit), skip to the end
>^n - output the current number
^d<<1 - initialise the product to 1
^i<<1 - initialise the character index to 1
^m<^i>^n - get i'th character of the number
->+4??^m=^__ - jump out of loop if no character is found
^d<<^d*^m - multiply character into product
^i<<^i+1 - increment character index
->-4 - hop back to continue getting characters
^n<<^d - once loop is done, assign product as new number
->-10 - hop all the way to the beginning for the next iteration
><^n - exit, printing the final number

Welcome. Great first answer!

@mbomb007 thank you!!

JavaScript (Babel Node), 46 bytes
f=a=>a>9?[a,...f(eval([...a+''].join`*`))]:[a]

Try it online!

JavaScript (Babel Node), 44 bytes
If the input can be taken as String
f=a=>a>9?[a,...f(''+eval([...a].join`*`))]:a

Try it online!

@Arnauld Yes, I just edited and added the wrong code. Im still looking for something using only strings instead arrays

Brachylog, 7 bytes
ẉ?Ḋ|ẹ×↰

Try it online!
Explanation
ẉ          Write the input followed by a linebreak
 ?Ḋ        If the input is a single digit, then it's over
   |       Otherwise
    ẹ      Split the input into a list of digits
     ×     Multiply them together
      ↰    Recursive call with the result of the multiplication as input

I gave it a try myself. Forgot about the Ḋ. The rest i had the same.

PowerShell, 64 59 bytes
for($a="$args";9-lt$a){$a;$a="$(($a|% t*y)-join'*'|iex)"}$a

Try it online!
Iterative method. Takes input and stores it into $a, then enters a for loop so long as the length of $a is two or more (i.e., it's bigger than 9). Inside the loop we output $a and then recalculate it by converting it toCharArray, joining it together with *, and then iex (short for Invoke-Expression and similar to eval). Once we're out of the loop, we have a single digit left to print, so we place $a onto the pipeline again.
-5 bytes thanks to KGlasier.

You could use the comparison 9-lt$a instead of $a.length-1 to save 5 bytes. And if you didn't go string based the whole time you could cut off a decent chunk. Check out my powershell attempt if you want!

Charcoal, 13 bytes
θＷ⊖Ｌθ«≔ＩΠθθ⸿θ

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

Print the input for the first time.
Ｗ⊖Ｌθ«

Repeat while the length of the input is not 1.
≔ＩΠθθ

Replace the input with its digital product cast to string.
⸿θ

Print the input on a new line.

Retina, 24 bytes
.+~(\`

.
$&$*
^
.+¶$$.(

Try it online! Explanation:
.+~(\`

Print the current value on its own line at the start of every loop until it stops changing and don't print the unchanged value twice. Evaluate the current value at the end of each loop.
.
$&$*

Add a * after each digit.
^
.+¶$$.(

Finish turning the input into an expression that evaluates to the digital product.
Just for the record, Retina can do this in one line (25 bytes):
.+"¶"<~[".+¶$.("|'*]'*L`.

Java, 112 106 bytes
"Lossy conversion" thanks Java for the extra ~15 bytes

-6 bytes thanks to @Kevin Cruijssen
Obligatory stream abuse answer
n->{for(long t=10;t>9;n=(n+"").chars().mapToLong(i->i).reduce(1,(x,y)->x*(y-48)))System.out.println(t=n);}

Try it online

I'm pretty sure you only need to support int

@EmbodimentofIgnorance then it fails for 277777788888899 since 4996238671872 is too large for an int

106 bytes by making it non-recursive.

@KevinCruijssen thanks

C (gcc), 58 bytes
f(n,t){for(;n=printf("%d\n",t=n)>2;)for(;n*=t%10,t/=10;);}

Try it online!
Iterative approach turns out to be 1 byte shorter.
f(n,t){
    for(;n=printf("%d\n",t=n)   //print and update current number
            >2;)                //until only one digit is printed
        for(;n*=t%10,t/=10;);   //n*= product of digits of t (step)
}

C (gcc), 61 59 bytes (recursive)
f(n){printf("%d\n",n)>2&&f(p(n));}p(n){n=n?n%10*p(n/10):1;}

Try it online!
Recursion seems to be shorter than iteration for both print and step...

V (vim), 43 30 29 bytes
qqhYp:s/./*&/g
x0C<C-r>=<C-r>"
<esc>@qq@q

Try it online!
-13 bytes from DJMcMayhem. Go upvote their answer!
-1 byte from user41805.
Takes advantage of the fact that this only stops on single digit numbers.
Explanation
qqhYp:s/./*&/g
qq                  create a macro @q:
  l                  move one char right
                     this is the break condition, since you cant
                     move to the right from a single digit
   Yp                duplicate the current line
     :s/./*&/g       add "*" before each digit

x0C<C-r>=<C-r>"
x                    delete first char
 0C                  cut the current line and store in " register
   <C-r>=            evaluate the following string:
         <C-r>"      the value in " register
                     and paste in current line

@qq@q
@q                   recursively call macro
  q                 close macro
   @q               call macro q

You can use *& instead to save some bytes

Swift, 115 bytes
func m(a:Int){
print("\(a)")
var b=1,c=a
while c>0{
b*=c%10
c/=10}
b>9 ? m(a:b):print("\(b)")}
m(a:277777788888899)

Try it online!

I think you can move the call to m into the Footer portion of TIO, leaving this answer as 95 bytes

Also, 81 bytes by removing some whitespace/formatting redundancy.

PicoLisp, 73 72 bytes
(de f(x)(if(> 10 x)(list x)(cons x(f(apply *(mapcar format(chop x)))))))

Try it online!

Japt, 15 bytes
I got some help from Shaggy on this one.
@pUÌì × Ì>9}f U

Run it online

Stax, 4 bytes
▒σ╛g

Run and debug it
Unpacked, it's pretty simple.
gu  use the rest of the program to generate values until a duplicate is encountered
    output implicitly
E:* calculate product of digits

Perl 6, 23 bytes
{$_,{[*] .comb}...10>*}

Try it online!

Husk, 5 bytes
U¡oΠd

Try it online!
Explanation
U¡oΠd
 ¡    iterate infinitely, collecting results of each iteration
  o   combination of 2 functions
    d get digits
   Π  multiply all of them
U     cut at first duplicate value

R, 59 55 bytes
Edit: -2 bytes thanks to Giuseppe, quickly superseded by -4 bytes (a different way) thanks to Robin Ryder
n=scan();while(print(n)>9)n=prod(utf8ToInt(c(n,""))-48)

Try it online!
A different method to Giuseppe's answer for the same number of bytes, here as a full recursive function instead of the (often-shorter) approach of taking input from the console using scan.

This (and mine) can be shortened by using 0:log10(x) instead of the nchar thing, I believe.

POSIX Shell + Utilities, 59 bytes
echo $1
[ ${#1} = 1 ]||$0 $(echo $1|fold -w1|paste -sd*|bc)

$ cat cg; echo; wc -c cg
echo $1
[ ${#1} = 1 ]||$0 $(echo $1|fold -w1|paste -sd*|bc)
59 cg
$ ./cg 277777788888899
277777788888899
4996238671872
438939648
4478976
338688
27648
2688
768
336
54
20
0
$ ./cg 25
25
10
0
$ ./cg 327
327
42
8
$ ./cg 68889
68889
27648
2688
768
336
54
20
0

Go, 87 bytes
import."fmt"
func f(n int){Println(n)
s:=1
if n<10{return}
for;n>0;n/=10{s*=n%10}
f(s)}

Attempt This Online!

05AB1E, 13 bytes
,[1svy*}Ð,gΘ#

Try it online!
Explanation:
,            //Print input
[            //Begin infinite loop
    1s       //Set 1 to the item before the input in the stack
    v        //Loop over the input
        y*   //Add the current character to the stack and multiply
    }        //End loop
    Ð        //Triplicate result
    ,        //Print result
    gΘ       //Check if length == 1
#            //If so, end

Leaving out the two prints can save two bytes while still outputting the result, thanks to implicit output. Without that restriction this would be 11.

Welcome to Code Golf, and nice answer!

java 8, 105 104 bytes
-1 byte thanks to @Benjamin Urquhart, replacing '0' with 48
i->{String s="";for(;(s+=i+"\n")!=""&i>9;){long m=1;for(byte c:(""+i).getBytes())m*=c-48;i=m;}return s;}

TIO

-1 byte by replacing '0' with 48

With java 10 you could save a few bytes by writing var instead of String and so on.

Factor, 79 72 bytes
: f ( x -- ) [ 10 >base [ 48 - ] map product dup dup . 9 > ] loop drop ;

Try it online!

ink, 66 bytes
=p(n)
{n}{n<10:->->}
~temp v=1
-(a)~v=v*n%10
~n=n/10
{n:->a}->p(v)

Try it online!
Explanation
=p(n)       // entry point - a stitch called p, with one parameter.
{n}         // print the value of n
{n<10:->->} // if n is a single digit, divert to wherever we entered from
~temp v=1   // declate a variable v, where we keep track of the product, and set it to 1
-(a)        // a labeled gather - we can jump here later
~v=v*n%10   // multiply v by (n mod 10) - the last digit in n
~n=n/10     // divide n by 10 - removing the last digit
{n:->a}     // if n is nonzero, go back to a
->p(v)      // if we reach this, divert to the top, this time with n set to the value of v

Doesn't feel very golfed, but I have no idea how you'd improve it.

Python 2, 87 bytes
b=input()
while 1:
 a=str(b);print a;b=1
 if len(a)<2:break
 for d in list(a):b*=int(d)

Try it online!

SNOBOL4 (CSNOBOL4), 100 bytes
	P =INPUT
O	OUTPUT =N =P	:(S)
S	P =GT(N,9) 1	:F(END)
D	N LEN(1) . D REM . N	:F(O)
	P =P * D	:(D)
END

Try it online!
A nice round 100 bytes!
	P =INPUT			;* Store input to P
O	OUTPUT =N =P	:(S)		;* print P and set N to P
S	P =GT(N,9) 1	:F(END)		;* if N > 9, set P (the digit product) to 1
D	N LEN(1) . D REM . N	:F(O)	;* take the first digit of N as D and set remaining digits to N
					;* if N is an empty string, goto label O
	P =P * D	:(D)		;* calculate the digit product, then return to D
END

C, 138 115 bytes
long atol(char*);main(c,v)char**v;{long z=1,n=atol(v[1]);for(;printf("%ld\n",n),n>9;n=z,z=1)for(;z*=n%10,n/=10;);}

Pass the number as a first command line argument.
Thanks to attinat for help with saving some bytes.
Ungolfed and prettyified:
long atol(char *);
main(c, v) char **v; {
    long z = 1,n = atol(v[1]);
    for(; printf("%ld\n", n), n > 9; n = z, z = 1)
        for(; z *= n % 10, n /= 10;);
}

for can save you quite a few bytes.

Suggest int**v instead of char**v

Pyth, 9 bytes
j.u*FsM`N

Try it here!
If we're allowed to output as an array, the j at the start is unnecessary, giving 8 bytes.

You can also omit the N at the end, since Pyth implicitly adds lambda variables at the end of a program if needed.

Racket, 107 bytes
(define(f n)(if(> 10 n)(list n)(cons n(f(apply *(map(λ(x)(-(char->integer x)48))(string->list(~v n))))))))

Try it online!

C# (.NET Core), 192 191 180 bytes
using C=System.Console;class A{static void Main(string[] a){long i,k;var b=a[0];for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){i=1;for(int j=0;j<k;)i*=b[j++]-48;}}}

Try it online!
Pretty much just naive looping.  I feel like that's a bit of a silly way to do it but here we are.  Had a weird issue early on where the input didn't match the output, because it was overflowing an int, so here we are with longs.  I could upgrade it to BigInteger if I needed to, though that would cost a few bytes.
I swear I always end up with off by ones when I do loops here, and it annoys me to no end.
Ungolfed-ish version:
using C=System.Console;
class A{
    static void Main(string[] a){
        long i,k;
        var b=a[0];
        for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){
            i=1;
            for(int j=0;j<k;)i*=b[j++]-48;
        }
    }
}

Works for all integers less than int.MAX_VALUE digits long, C# (.NET Core), 204 bytes
using C=System.Console;class A{static void Main(string[] a){System.Numerics.BigInteger i;int j,k;var b=a[0];for(C.WriteLine(b);(k=b.Length)>1;C.WriteLine(b=i.ToString())){i=1;for(j=0;j<k;)i*=b[j++]-48;}}}

Try it online!

Saved 1 byte - moved C.WriteLine(b) into loop opening as well as iterator

Saved 11 bytes with assorted rearrangements.

Attache, 28 27 bytes
{If[_>9,_'$@Prod@List@_,_]}

Try it online!
Oddly enough, the recursive approach, rather than a tacit approach, seems to be shortest. (There is a bug in NestListWhile involving currying, but even with the bugfix it'd be 3 bytes longer.)
Explanation
{
    If[ _ > 9 ,
        ?? if this is true, return a list
        [
            ?? with the current number
            _,
            ?? followed by this function called on the digital product
            ...$[ Prod[Digits[_]] ]
        ],
        ?? otherwise, return _
        _
    ]
}

Alternative
32 bytes: NestListWhile<~Prod@List,{_>9}~>

c++, lambda function, 72 bytes
[](auto n){while(cout<<n<<endl&&n>9){auto t=n;for(n=1;n*=t%10,t/=10;);}}

try it online

Clojure, 73 bytes
#(loop[i %](prn i)(if(> i 9)(recur(apply *(for[c(str i)](-(int c)48))))))

Scala, 83 bytes
def^(n:Long):Long={println(n);if(n>9)^((n+"").map(x=>(x-48).toLong).product)else n}

Try it online!

Befunge-98 (FBBI), 43 42 bytes
&;1\v>#;:.:9`!#@_;
>$$  ^
^#::< '*%ap25/a_

Try it online!
The first line takes input, prints the values and runs until a value <=9 is reached. The third line computes the product of digits of an integer (26 bytes on its own).

Pip, 9 bytes
W9<Pa$*:a

Try it online!
Explanation
           a is command-line argument (implicit)
W          While...
   Pa      (print a's value)
 9<        ... a is greater than 9, i.e. more than one digit:
     $      Fold
        a   (the digits of) a
      *     on multiplication
       :    and assign back to a

Printing a in the loop header lets us output its value both before the loop and when the loop terminates.

><>, 31 29 bytes
Saved 2 bytes thanks to Jo King
:nao:a),1}\~
1:,a}*{%a:/!?:-%

Try it online!

Factor + math.unicode, 40 bytes
[ [ .s >dec 48 v-n Π dup 9 > ] loop . ]

Try it online!

[ ... dup 9 > ] loop loop while top of stack is greater than nine
.s print stack non-destructively
>dec convert number to string
48 v-n convert string to list of digits
Π product of a list of numbers
. print the leftover number (which will be the final output)

Python 3, 47 bytes
def f(n):print(n);n>9>f(eval('*'.join(str(n))))

First Python 3 answer here.
Try it online!

FunStack alpha, 38 bytes
Product Minus 48 Show compose3 fixiter

Try it at Replit: pass the input number as a command-line argument and enter the program on stdin.
Explanation
The fixiter modifier iterates a function until it reaches a fixed value, returning the full list of intermediate values. This is exactly what we want; there is a slight complication because the builtin ToBase function, which returns a list of digits, converts zero to an empty list rather than a list containing 0. So instead, we convert the number to a string and then convert each character to the corresponding digit.
                      compose3          Compose these three functions:
                 Show                     Convert number to string
        Minus 48                          Subtract 48 from each character
Product                                   Take the product of the character codes
                               fixiter  Iterate that function, stopping when a fixed point
                                        is reached, and return a list of intermediate values

Vyxal 3, 2 bytes
ᵘΠ

Try it Online!
2 bytes with a new modifier. Come try Vyxal 3!

Vyxal, j, 3 bytes
⁽Π↔

Try it Online!
Very nice little 3 byter here. Uses the same method as the 05ab1e answer.
Explained
⁽Π↔
⁽Π  # lambda x: product(x) // treats numbers as a list of digits
 ↔ # repeat the above function until the result doesn't change, collecting intermediate results.

Pyt, 6 bytes
Đ`ҎĐłŕ

Try it online!
Đ         Implicit input; duplicate top of stack
 `  ł     do while top of stack is not 0 (consumes top of stack when checking)
  Ҏ       digit product of top of stack
   Đ      duplicate top of stack
     ŕ    remove top of stack (duplicate 0); implicit print

Fails for input 327 (since it does not necessarily end with 0).

it's not efficient but gets the job done
echo 777777777777777777777777777777777779999999999999999999933333333333  |

gawk -M 'function __(_){return _*_==_?+$_:$_*__(--_)}($_=__(NF*=!/0/))_' FS=

815859530632739726716133814001433680647636177446909421

source: Stack Exchange

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

sort: votes


text:
Japanese Multiplication
There's a visual method for multiplication that is taught to Japanese schoolchildren [citation needed] that uses lines and crossings to get the answer.

Image Source
Your task is to implement this in ASCII art. You will be given two numbers to multiply. The output should be the corresponding ASCII art made up of \, /, and X, padded with ASCII spaces.
The first number of the multiplication will use backslashes, starting from left to right. The second number will use forward slashes, once again from leftmost digit to rightmost. The output is made up of distinct diagonal line groupings. The number of lines within a grouping should be equal to the value of the digit. There should be at least one diagonal space between each grouping and there should be no spaces within the grouping.
Suppose 43 is the first number. Before extending lines and creating crossings, it will start like this:
       \
      \
     \

   \
  \
 \
\

If the second number is 61, it will look like this before extending and crossing:
/
 /
  /
   /
    /
     /

       /

Conceptually "extend" the lines, using X's for intersection points, to get the result:
       \ /
      \ X /
     \ X X /
      X X X /
   \ / X X X /
  \ X / X X X /
 \ X X / X X X
\ X X X / X X \ /
 X X X X / X \ X
/ X X X X / \ X \
 / X X X X   X \
  / X X X \ / \
   / X X \ X
    / X \ X \
     / \ X \
        X \
       / \

Example Test Cases
5 * 9
    \ /
   \ X /
  \ X X /
 \ X X X /
\ X X X X /
 X X X X X /
/ X X X X X /
 / X X X X X /
  / X X X X X /
   / X X X X X
    / X X X X \
     / X X X \
      / X X \
       / X \
        / \

16 * 27
       \ /
      \ X /
     \ X X
    \ X X \ /
   \ X X \ X /
  \ X X \ X X /
   X X \ X X X /
\ / X \ X X X X /
 X / \ X X X X X /
/ X   X X X X X X /
 / \ / X X X X X X
    X / X X X X X \
   / X / X X X X \
    / X / X X X \
     / X / X X \
      / X / X \
       / X / \
        / X
         / \

7 * 24
      \ /
     \ X /
    \ X X
   \ X X \ /
  \ X X \ X /
 \ X X \ X X /
\ X X \ X X X /
 X X \ X X X X
/ X \ X X X X \
 / \ X X X X \
    X X X X \
   / X X X \
    / X X \
     / X \
      / \

123 * 543
       \ /
      \ X /
     \ X X /
      X X X /
   \ / X X X /
  \ X / X X X
   X X / X X \ /
\ / X X / X \ X /
 X / X X / \ X X /
/ X / X X   X X X /
 / X / X \ / X X X
  / X / \ X / X X \ /
   / X   X X / X \ X /
    / \ / X X / \ X X /
       X / X X   X X X
      / X / X \ / X X \
       / X / \ X / X \
        / X   X X / \
         / \ / X X
            X / X \
           / X / \
            / X
             / \

735 * 21
                \ /
               \ X /
              \ X X
             \ X X \ /
            \ X X \ X
             X X \ X \
          \ / X \ X \
         \ X / \ X \
        \ X X   X \
         X X \ / \
      \ / X \ X
     \ X / \ X \
    \ X X   X \
   \ X X \ / \
  \ X X \ X
 \ X X \ X \
\ X X \ X \
 X X \ X \
/ X \ X \
 / \ X \
    X \
   / \

Rules

There should be at least one (diagonal) space between each set of lines. For the purposes of this challenge, it doesn't have to line up in any sort of pretty visual way.
Border crossings should jut out by exactly one slash.
Any amount of padding to the left or the right is allowed as long as all the crossings line up correctly.
Single-width ASCII spaces must be used as padding.
You do not need to calculate the actual result of the multiplication.
You may assume the number is in base 10 and and is at most three digits long with no zeros.
Order matters for the purposes of the output. The first number is always in the \ direction and the second number is always in the / direction.
Input and output may be in any convenient format.
Standard loopholes are banned.

Happy Golfing!

Shame about the dupe; a nice, well specced challenge that's trickier than it first appears.

@Shaggy Agreed - its a good question, and well written.

Maybe the way to go is to merge in some of the goodies into the other challenge?

Canvas, 41 bytes
（Ａ┬｛［１｝０｝┐）
⁷Ｌ├Ｘ⁷ｌＹø；｛³×？³ｙ³－╵ｘ＼╋
⁸⤢↔╶╶⁸ｎ

Try it here!

JavaScript (ES6),  207 197 196  188 bytes
Takes input as an array of two strings, e.g. ["16", "27"]. Returns a matrix of characters.
a=>([[p,H],[q]]=a.map(x=>[[W=0,...x].map(x=>'1'.repeat(x,W-=~x)).join`0`,W]),[...Array(W+H)]).map((_,y,a)=>a.map((_,x)=>' \\/X'[(d=x-y)<H&~d<H&~(x+=y-H+2)<0&x<W*2&~x&&p[d+H>>1]|2*q[x/2]]))

Try it online!

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


text:
Calculating total slots
Given a list of jobs, which must be done in order, with each taking a slot to do, how long will it take to perform them all if after doing a job the same job cannot be done for the next two slots (cooling off slots)? However, a different job can be assigned in this cooling off slots.
For example,
[9,10,9,8] => output: 5

Because jobs will be allocated as [9 10 _ 9 8].
1. First, 9 needs two cooling off spots _ _. So we start with 9 _ _.
2. Next job 10 is different from the previous job 9, so we can allocate one of _ _. Then we will have 9 10 _.
3. Third, 9 cannot be allocated now, since first job 9 is the same job and it needs cooling off time. 9 10 _ 9.
4. Last, 8 is not same as any other previous two jobs, so it can be allocated right after 9 and since this is last job, it does not need cooling off time. Final list is 9 10 _ 9 8 and expected output is 5, which is the number of spots (or number of slots)
Test cases:
[1,2,3,4,5,6,7,8,9,10] => output : 10 ([1 2 3 4 5 6 7 8 9 10])
[1,1,1] => output: 7 ([1 _ _ 1 _ _ 1])
[3,4,4,3] => output: 6 ([3 4 _ _ 4 3])
[3,4,5,3] => output: 4 ([3 4 5 3])
[3,4,3,4] => output : 5 ([3 4 _ 3 4])
[3,3,4,4] => output : 8 ([3 _ _ 3 4 _ _ 4])
[3,3,4,3] => output : 7 ([3 _ _ 3 4 _ 3])
[3,2,1,3,-4] => output : 5 ([3 2 1 3 -4])
[] => output : 0 ([])
[-1,-1] => output : 4 ([-1 _ _ -1])

Input value can be any integer (negative, 0, positive).
Length of job-list is 0 <= length <= 1,000,000.
Output will be an integer, the total number of slots, which is indicated in test case as output. The list inside the parenthesis is how the output would be generated.
Winning criterion
code-golf

Is it ok if we output nothing instead of 0 for []?

Isn’t it a bit early to accept an answer?

As @NickKennedy said, that's far, far too soon to be accepting a solution. Some even recommend never accepting a solution.

Jelly, 14 bytes
ṫ-i⁹⁶ẋ⁸;;µƒ⁶L’

Try it online!

05AB1E, 22 bytes
v¯R¬yQiõˆ}2£yåiˆ}yˆ}¯g

Try it online or verify all test cases.
Explanation:
v           # Loop over the integers `y` of the (implicit) input-list:
 ¯R         #  Push the global_array, and reverse it
   ¬        #  Get the first item (without popping the reversed global_array itself)
    yQi  }  #  If it's equal to the integer `y`:
       õˆ   #   Add an empty string to the global_array
   2£       #  Then only leave the first 2 items of the reversed global_array
     yåi }  #  If the integer `y` is in these first 2 items:
        ˆ   #   Add the (implicit) input-list to the global_array
 yˆ         #  And push the integer `y` itself to the global_array
}¯g         # After the loop: push the global array, and then pop and push its length
            # (which is output implicitly as result)

What is the global areay? Is it empty on start of the program?

@EmbodimentofIgnorance Yes, it's a single array to which I can add something, which I can push, and which I can clear. And it indeed starts empty initially.

Brachylog, 10 bytes
It's always nice to see problem where Brachylog performs best
⊆Is₃ᶠ≠ᵐ∧Il

Explanation
⊆I           # Find the minimal ordered superset of the input (and store in I) where:
   s₃ᶠ       #     each substring of length 3
      ≠ᵐ     #     has only distinct numbers
        ∧Il  # and output the length of that superset

Try it online!

R, 123 bytes
`-`=nchar;x=scan(,'');while(x!=(y=gsub("([^,]+),(([^,]*,){0,1})\\1(,|$)","\\1,\\2,\\1\\4",x)))x=y;-gsub("[^,]","",y)+(-y>1)

Try it online - single program!
Try it online - multiple examples!
A full program that reads a comma-separated list of integers as the input, and outputs the slots needed. I’m sure this could be golfed some more, and implementing this regex-based solution in some other languages would be more efficient in bytes.
Note on the second TIO I’ve wrapped it in a function to permit multiple examples to be shown. This function also shows the final list, but this is not output my the main program if run in isolation.

Charcoal, 27 23 bytes
Ｆθ«Ｗ№✂υ±²¦¦¦ι⊞υω⊞υι»ＩＬυ

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

Loop over the jobs.
Ｗ№✂υ±²¦¦¦ι⊞υω

Add cooling off spots while the job is one of the last two in the result.
⊞υι»

Add the current job to the result.
ＩＬυ

Print the number of spots.

R, 81 70 bytes
sum(l<-rle(s<-scan())$l*3-3,1-l%/%6,((r=rle(diff(s,2)))$l+1)%/%2*!r$v)

Try it online!
After several unsuccessful attempts, the code turned rather ugly and not so short, but at least it works now...
First, we evaluate the lengths of consecutive runs of the same job. E.g. for 3, 3, 4, 3 this gives:
Run Length Encoding
  lengths: int [1:3] 2 1 1
  values : num [1:3] 3 4 3

Each of these runs produces (len - 1) * 3 + 1 steps (+ 1 is handled separately).
Next, we process occurrences of the same job 2 places apart, like: x, y, x, by using diff(s, lag=2). The resulting vector is also chunked into consecutive runs (r) by rle function. Now, because of various interleaved alternations we need to add ceiling(r$len/2) steps for all runs of zeroes. E.g.:
x y x (length 1) and x y x y (length 2) both need 1 extra step: x y _ x (y)
x y x y x (length 3) and x y x y x y (length 4) both need 2 extra steps: x y _ x y _ x (y)
Finally, we need to compensate for occurrences of these alternations in the middle of a long run of the same job: x, x, x, x..., hence 1-l%/%6 instead of simply 1.

I was in the middle of commenting about using diff(s,lag=2) to detect proximity! Now you're a byte shorter than my solution...

Yeah, not giving up yet :) Now trying to get rid of some parentheses...

TSQL query, 158 bytes
Input data as a table.
The query is recursive so

OPTION(MAXRECURSION 0)

is necessary, because the list of numbers can exceed 100 although it can only go handle 32,767 recursions - is the limitation really needed in this task ?
DECLARE @ table(a int, r int identity(1,1))
INSERT @ VALUES(3),(3),(4),(4);

WITH k as(SELECT null b,null c,1p
UNION ALL
SELECT iif(a in(b,c),null,a),b,p+iif(a in(b,c),0,1)FROM @,k
WHERE p=r)SELECT sum(1)-1FROM k
OPTION(MAXRECURSION 0)

Try it online

R, 74 68 bytes
length(Reduce(function(x,y)c(y,rep("",match(y,x[2:1],0)),x),scan()))

Try it online!
Constructs the work array (in reverse), then takes the length. Just a bit shorter longer than Kirill L.'s answer, so sometimes, the naive approach is pretty good. EDIT: shorter again! I also borrowed Kirill's test template.
-6 bytes replacing max(0,which(y==x[2:1])) with match(y,x,0).

@Giuspeppe what does the c function do?

@EmbodimentofIgnorance -- c stands for combine, although concatenate might be better; it combines its arguments into a single list.

Thanks, I thought it was weird that a language not designed for golfing would have one letter functions

Python 2, 67 bytes
r=[]
for x in input():
 while x in r[-2:]:r+=r,
 r+=x,
print len(r)

Try it online!
Implements the challenge pretty literally. Uses copies of the list itself as "blanks", since these can't equal any number.

Perl 6, 98 bytes
{($!=$,|$_ Z$_ Z .[1..*+1])>>.repeated.squish(:with({$+^=[*] $! ne$^a ne$^b,$b==($!=$a)})).sum+$_}

Try it online!
Blergh, there's got to be a better way of doing this. I'm not 100% sure this is fully correct, though it passes all the edge cases I could think of.
Basically, this starts by grouping all the triplets of the input list, with padding to either side. For example, [1,2,1,2] becomes (Any,1,2), (1,2,1), (2,1,2), (1,2,Nil). We get the repeated elements in each triplet, becoming (), (1), (2), ().
It then squishes consecutive elements that are not the same list, but are the same size (to not squish something like [1,1,1]), and the first element is not equal to the element before it (because we can't merge the hours in [1,1,2,2]), and finally the element before hasn't also been squished ([1,2,1,2,1,2]). So (1), (2) in the above example above would be squished together.
Finally, we get the sum of all lengths of this list, which represent our inserted hours, and add the length of the original list.
For example:
(1,1,1) => (Any,1,1),(1,1,1),(1,1,Nil) => (1),(1,1),(1) => (no squishes) => 4+3 = 7
(1,2,1,2,1,2) => (Any,1,2), (1,2,1), (2,1,2), (1,2,1), (2,1,2), (1,2,Nil) => (),(1),(2),(1),(2),() => squish (1),(2) and (1),(2) => 2+6 = 8

JavaScript (ES6), 57 bytes
f=([x,...a],p,q)=>1/x?1+f(x!=p&x!=q?a:[x,...a,x=f],x,p):0

Try it online!
Commented
f = (             // f is a recursive function taking:
  [x,             //   x   = next job
      ...a],      //   a[] = array of remaining jobs
  p,              //   p   = previous job, initially undefined
  q               //   q   = penultimate job, initially undefined
) =>              //
  1 / x ?         // if x is defined and numeric:
    1 +           //   add 1 to the grand total
    f(            //   and do a recursive call to f:
      x != p &    //     if x is different from the previous job
      x != q ?    //     and different from the penultimate job:
        a         //       just pass the remaining jobs
      :           //     else:
        [ x,      //       pass x, which can't be assigned yet
          ...a,   //       pass the remaining jobs
          x = f   //       set x to a non-numeric value
        ],        //
      x,          //     previous job = x
      p           //     penultimate job = previous job
    )             //   end of recursive call
  :               // else:
    0             //   stop recursion

Perl 5 -pl, 42 40 bytes
$a{$_}=~s/.*/$\=$&if++$\<$&;$\+3/e}{$_=0

Try it online!

Cut it down to 35 using -p and reworking the substitution: Try it online!

@Xcali That gives nothing for empty input, but I got to 39

Doesn't seem to work for 1,1,1.

@nwellnhof Fixed

C (gcc), 69 bytes
f(j,l)int*j;{j=l>1?(*j-*++j?j[-1]==j[l>2]?j++,l--,3:1:3)+f(j,l-1):l;}

Try it online!
Straightforward recursion.
f(j,l)int*j;{               //Jobs, (array) Length
    j=l>1                   //if l > 1, do a recursion:
        ? (*j-*++j          // check if first and second elements are equal (j++)
            ? j[-1]==       //  1st!=2nd; check if first and third are equal
                j[l>2]      //  (first and second if l==2, but we already know 1st!=2nd)
                ? j++,l--,3 //   1st==3rd (j++,l--) return 3+f(j+2,l-2)
                : 1         //   1st!=3rd (or l==2) return 1+f(j+1,l-1)
            : 3             //  1st==2nd            return 3+f(j+1,l-1)
          )+f(j,l-1)        // j and l were modified as needed
        : l;                // nothing more needed  return l
}

Perl 6, 48 bytes
{$!=0;.map:{{$_=($!=$!+1 max$_)+3}((%){$_})};$!}

Try it online!
45 bytes if the list has at least two elements:
+*.reduce:{$^b,|(*xx 3-(|$^a,*,$b...$b)),|$a}

Try it online!

Smalltalk, 125 bytes
c:=0.n:=q size.1to:n-2do:[:i|(j:=q at:i)=(k:=q at:i+1)ifTrue:[c:=c+2].j=(m:=q at:i+2)ifTrue:[c:=c+1]].k=m ifTrue:[c:=c+1].c+n

Explanation
c : accumulator of proximity penalty
q : input array.
n := q length
i : iteration index from 1 to: n-2 (arrays are 1-based in Smalltalk).
j := memory for element i, saves some few bytes when reused
k := similar to j but for i+1.
m := similar to k but for i+2.

Isn't this a snippet?

Batch, 184 bytes
@echo off
@set l=-
@set p=-
@set n=0
@for %%j in (%*)do @call:c %%j
@exit/b%n%
:c
@if %1==%l% (set l=-&set/an+=2)else if %1==%p% set l=-&set/an+=1
@set p=%l%&set l=%1&set/an+=1

Input is via command-line arguments and output is via exit code. Explanation:
@set l=-
@set p=-

Track the last two jobs.
@set n=0

Initialise the count.
@for %%j in (%*)do @call:c %%j

Process each job.
@exit/b%n%

Output the final count.
:c

For each job:
@if %1==%l% (set l=-&set/an+=2)else if %1==%p% set l=-&set/an+=1

If we processed the job recently, add in an appropriate number of cooling off spots. Additionally, clear the last job so that the next job only triggers cooling off if it's the same as this job.
@set p=%l%&set l=%1&set/an+=1

Update the last two jobs and allocate a spot to this job.

Python 3, 79 75 bytes
-3 bytes thanks to mypetlion
-1 byte thanks to Sara J
f=lambda a,b=[]:a and f(*[a[1:],a,a[:1]+b,[b]+b][a[0]in b[:2]::2])or len(b)

Try it online!

a[0]in b[:2]and f(a,['']+b)or f(a[1:],[a[0]]+b) can become f(*[a[1:],a,[a[0]]+b,['']+b][a[0]in b[:2]::2]) to save 2 bytes.

[a[0]]+b can become a[:1]+b to save 1 byte.

Replacing ['']+b with [b]+b saves a byte - b is a list, so it'll never be equal to any of the values in a

Swift, 114 bytes
func t(a:[Int]){
var s=1
for i in 1...a.count-1{s = a[i-1]==a[i] ? s+3:i>1&&a[i-2]==a[i] ? s+2:s+1}
print("\(s)")}

Try it online!

Fails for 3,4,3,4, should bet 5, not 6.

In addition to the xyxy fix @KirillL. noted, s = a can be s=a, and you can do s+= rather than multiple s=s+... and remove spaces after the ?: for i in 1...a.count-1{s+=a[i-1]==a[i] ?3:i>1&&a[i-2]==a[i] ?2:1} to save 9 bytes.

Java (JDK), 110 bytes
j->{int p,q;for(p=q=j.length;p-->1;q+=j[p]==j[p-1]?2:(p>1&&j[p]==j[p-2]&(p<3||j[p-1]!=j[p-3]))?1:0);return q;}

Try it online!
Ungolfed commented code:
j -> {
    int p, q = j.length; // Run all jobs
    for (p = q; p-- > 1;) { // reverse iterate
        q += j[p] == j[p - 1] ? 2 : // add 2 if prev same
        (p > 1 && j[p] == j[p - 2] & // 1 if 2prev same
        (p < 3 || j[p - 1] != j[p - 3]) // except already done
        ) ? 1 : 0; // otherwise 0
    }
    return q;
}

Doesn't work for 3,4,3,4,3,4, returns 7 instead of 8

This is a wicked little problem.

107 bytes

Jelly, 20 bytes
ṫ-i⁹⁶x;
⁶;ç³Ṫ¤¥¥³¿L’

Try it online!
Although this is rather similar to @EriktheOutgolfer’s shorter answer, I wrote it without seeing his. In any case his is better!
Explanation
Helper dyadic link, takes current list as left item and next item as right
ṫ-            | take the last two items in the list
  i⁹          | find the index of the new item
    ⁶x        | that many space characters
      ;       | prepend to new item

Main monadic link, takes list of integers as input
⁶             | start with a single space
 ;            | append...
  ç³Ṫ¤¥       | the helper link called with the current list
              | as left item and the next input item as right
       ¥³¿    | loop the last two as a dyad until the input is empty
          L   | take the length
           ’  | subtract one for the original space

Python 2, 75 bytes
lambda a:len(reduce(lambda b,c:b+[c]*-~((c in b[-2:])+(c in b[-1:])),a,[]))

Try it online!

JavaScript (Node.js), 52 bytes
(a,i=0,h={})=>a.map(n=>h[n]=3+(i=h[n]>++i?h[n]:i))|i

Try it online!

APL (Dyalog Classic), 22 bytes
≢∊(⊢,⍨⊣,# #↓⍨⍳⍨)/⍵,⊂⍬⍬

Try it online!

Zsh, 66 60 bytes
-6 bytes from implicit "$@"
for j
{((i=$a[(I)$j]))&&a=
a=("$a[-1]" $j)
((x+=i+1))}
<<<$x

Try it online! I highly recommend adding set -x to the start so you can follow along.
for j                   # Implicit "$@"
{                       # Use '{' '}' instead of 'do' 'done'
    (( i=$a[(I)$j] )) \ # (see below)
        && a=           # if the previous returned true, empty a
    a=( "$a[-1]" $j )   # set the array to its last element and the new job
    (( x += i + 1 ))    # add number of slots we advanced
}
<<<$x                   # echo back our total

((i=$a[(I)$j]))
    $a[     ]           # Array lookup
       (I)$j            # Get highest index matched by $j, or 0 if not found
  i=                    # Set to i
((           ))         # If i was set nonzero, return true

a always contains the last two jobs, so if the lookup finds a matching job in a[2], we increment by three (since the job slots will be [... 3 _ _ 3 ...]).
If a is unset, the lookup will fail and the arithmetic expansion will return an error, but that only happens on the first job and isn't fatal.
We can save one more byte if we use $[x+=i+1] instead, and there are no commands on the users system comprised entirely of digits.

JavaScript (V8), 101 bytes
f=a=>for(var c=0,i=0;i<a.length;i++,c++)a[i-1]==a[i]?c+=2:a[i-2]==a[i]&&(c++,a[i-1]=void 0)
return c}

Try it online!
Unpacked code looks as follows:
function f(a)
{
    var c = 0;
    for (var i = 0; i < a.length; i++, c++)
    {
        if (a[i - 1] == a[i])
            c+=2;
        else if (a[i - 2] == a[i])
            c++,a[i-1]=undefined;
    }

    return c;
}

My first ever code-golf attempt, can probably be optimized a lot by shrinking the array and passing it recursively.

Welcome to PPCG! This is a pretty great first post!

K (ngn/k), 27 bytes
{#2_``{y,#[0|2-x?y;`],x}/x}

Try it online!


text:
Nearest hamming cycle period in MD5
This riddle was inspired by that thread. Consider that you are super-hacker and try to break MD5 hashing algorithm by looking for a hash collisions for a given hash string which your friend gave to you. But this is a non-trivial task and you have a migraine disorder so you try to break the problem into smaller parts. First thing which you try is to look for a hamming distance patterns in a repeated execution of MD5() feeding it's last output to an input. For example, if your friend gave to you a hash bb2afeb932cc5aafff4a3e7e31d6d3fb, then you will notice a such pattern :

e3b86f8d25e5a71a88eabef0d7ed9840=md5(bb2afeb932cc5aafff4a3e7e31d6d3fb), hamming 95
45fcdb59517b39f18d1622a84be0a301=md5(e3b86f8d25e5a71a88eabef0d7ed9840), hamming 91
0b3f2eac737b916f3b78f240e7fc97ec=md5(45fcdb59517b39f18d1622a84be0a301), hamming 77
fe56b1802722cc30b936186aacce1e01=md5(0b3f2eac737b916f3b78f240e7fc97ec), hamming 95

So after 4 iterations you arrived at hamming distance 95 between an output and a first input, which is the same 95 number which you have started from. So nearest hamming cycle period of MD5(bb2afeb932cc5aafff4a3e7e31d6d3fb) is 4. You have found a hamming collision !
Your task is to write a program which takes an arbitrary MD5 hash from the standard input, and outputs it's nearest hamming cycle period on standard output. For example:

Input:  45fcdb59517b39f18d1622a84be0a301, Output: 3
Input:  1017efa1722ba21873d79c3a215da44a, Output: 7
Input:  edc990163ff765287a4dd93ee48a1107, Output: 90
Input:  c2ca818722219e3cc5ec6197ef967f5d, Output: 293

Shortest code wins.
Notes:

If your language doesn't have an md5() built-in, feel free to implement that yourself and then write in the solution total byte count  and byte count without md5() sub-program implementation, the later will be considered as an answer.
Hamming distance is defined as number of differing bits between two strings. If strings converted to binary (by character ASCII code) has different lengths - smaller one is padded from the left with 0. Example:

Word1: nice Binary1: 01101110011010010110001101100101
Word2: car  Binary2: 00000000011000110110000101110010
Hamming distance (differing bits): 12

In this task you should calculate hamming distance between a FIRST input in a cycle and current output. So according to a given hamming cycle example above you should calculate

hamming(bb2afeb932cc5aafff4a3e7e31d6d3fb,e3b86f8d25e5a71a88eabef0d7ed9840)
hamming(bb2afeb932cc5aafff4a3e7e31d6d3fb,45fcdb59517b39f18d1622a84be0a301)
hamming(bb2afeb932cc5aafff4a3e7e31d6d3fb,0b3f2eac737b916f3b78f240e7fc97ec)
hamming(bb2afeb932cc5aafff4a3e7e31d6d3fb,fe56b1802722cc30b936186aacce1e01)

I feel like the note favors languages with non-built-in md5 hashing, as one can practically choose the required bytes for calling the hashing.

@JonathanFrech I'm not sure about this really. Calling hash sub-program should take relatively small amount of bytes in relation to total program source. So this is not an important factor. Important is - how the rest will be coded, and it should be minimized. So can you elaborate more on this ?

I think what Jonathan means that if you choose to use a language, that does not have builtin md5 hashing, you can just define a function with a short name, while calling the builtin function in a different language might cost a lot of bytes (example in Python).

Actually, it seems like you're computing the Hamming distance between the ASCII codes of the hexadecimal representation of the MD5 digests in lower case. This should definitely be specified in the challenge.

I'm not the downvoter, but the question seems to be just asking us to implement the md5 algorithm, with an extra part tacked on. It would be fine if it was one or the other, but as it is, it discourages languages without md5 built-ins (and therefore the people using them). This is exacerbated by letting people not count the code to implement the md5 algorithm, but forcing them to implement it anyway

Jelly, 37 bytes
Ç,³OBU+0x8¤_/FAS,Ç
Ç;0ịÇƊ$⁺-ịn1ị$Ʋ¿LH

Try it online!
Try it online! - using full implementation of MD5
I'll comment it when I have time. Jelly doesn't have an MD5 built-in, so the header for the first TIO implements MD5 for a fixed length (32 bytes) input. I've also now extended this to a general purpose MD5 routine (second TIO link). For the purposes of the challenge, there is a monadic link just above the challenge code that takes a 32 character string and returns the MD5 hash. The remaining code (as displayed above here) calculates the hamming distance between the original input and sequential hashes until it matches the first one.

Python 2, 199 196 bytes
-3 bytes thanks to Kevin Cruijssen
from md5 import*
B=bytearray
h=lambda a,b:sum(bin(i^j).count('1')for i,j in zip(B(a),B(b)))
m=lambda a:new(a).hexdigest()
def f(x):
 a=b=m(x);i=1
 while 1:
    b=m(b);i+=1
    if h(x,a)==h(x,b):return i

Try it online!

The two space-indentations before b=.. and if h... can be a single tab to save 2 bytes. :) Also, return(i) can be return i to save an additional byte.

perl 5 (-MDigest::MD5=md5_hex -M5.01 -pl), 83 bytes
may be golfed
$x=$_;$h=(unpack'B*',($x=md5_hex($x))^$_)=~y/1//,$i||=$h while$c++<2|$i!=$h;$_=$c-1

TIO

Why you say that there is no cycle ? Isn't it that we get to the same hamming number we started from ? Call it as you like, but it is a loop - hamming output mapped to the same starting hamming input

i mean it's not a cycle with the meaning : it depends from the point we start, if we start from next md5 we don't get the same result

Should we ? Of course not, because we are searching a hash (hamming) collision - duplicated input which when hashed gives us the same output. Now when you change starting MD5 - this means you begin looking for other colliding input pairs. And in general - every loop in the world depends on starting conditions. So it's not a problem with a cycle, but rather with your understanding about it.

admitted, i remove from the answer

You can leave your answer, it's valid. Suppose we are saving our passwords as CRC32 trimmed to higher 16 bits. Now we want to crack it - find a fake password which matches the same hash. Look here .

Changing starting hash in my example code above, means that we are trying to break other password, than we had before. By analogy, same holds for a hamming loop - changing starting MD5 means finding a hamming collision to other password than we had before. Hope this makes sense to you.

ok, but using hamming distance between md5 hex string and md5 hex string of md5 hex string as hash would be a weak hash

I don't completely understood your point, but yes it can be called a "weak-collision". In reality it would be much more fun to find true colliding MD5 hashes. So it's just a tool to find some repeated patterns in MD5 algo before applying full-scale attack to MD5. But it's non-trivial like I said in original post, so ...

JavaScript (Node.js), 157 bytes
f=(s,n,a=(B=Buffer)(s))=>a.map((x,i)=>r+=(g=x=>x&&x%2+g(x/2))(x^B(s)[i]),s=require('crypto').createHash('md5').update(s).digest`hex`,r=0)|r==n||1+f(s,n||r,a)

Try it online!

I'm thinking should I add a new rule that language can't use it's deprecated features. Anyway It would be good if you could eliminate deprecation warning Buffer() is deprecated due to security and usability issues

@AgniusVasiliauskas Golfed code is basically the exact opposite of clean code and if could save a few more bytes by doing even more ugly things, I definitely would. As pointed out by Jo King in the comments, you may want to have a look at other winning criteria for your future challenges.

Fixing the deprecation warning would cost 10 bytes.

Ok, agree, that cleaning a code is not a point here :-)


text:
Sub-pixel Zooming
Your task is to take a 24 BPP sRGB image and output the same image upscaled 3x into red, green, and blue subpixels. The resulting image will be made entirely of pure black, red, green, and blue pixels.
Each pixel from the source image, when zoomed, produces an arrangement of 9 sub-pixels that can be either on or off (i.e. their respective color or black). The specific arrangement uses three columns of red, green, and blue, in that order, like so:

(Note that the borders on these "pixels" are for demonstration only.)
Since each of the nine subpixels can only be on or off, you will have to quantize the input image and use different subpixel patterns to achieve 3 levels of brightness.
For each subpixel in the image:

For color levels 0-74, all subpixels should be black.
For color levels 75-134, the middle subpixel should be the respective color and the other two should be black.
For color levels 135-179, the middle subpixel should be black and the other two should be the respective color
For color levels 180-255, all three subpixels should be their respective color

I chose these level ranges because those are what happened to look good
Apply this transformation to every pixel in the image and output the subpixel-upscaled image.
Single-pixel examples
rgb(40, 130, 175) will produce this pattern:

rgb(160, 240, 100) will produce this pattern:

Full Image Examples

Images sourced from Wikipedia
Rules and notes

Input and output may be in any convenient format, whether that's actual image files or (possibly nested) lists of RGB values.
You may assume the pixels are in the sRGB colorspace with 24BPP.

Happy golfing!

The initial description sounds like un-Bayering. It turns out that it isn't, partly because of the unconventional 3x3 mask but mainly because of the quantisation, but IMO it's still closer to un-Bayering than to subpixel zooming (which would be upscaling with some kind of edge detection to anti-alias).

thanks for an interesting challenege.... is this actually used for anything in the real life?

JavaScript (Node, Chrome, Firefox), 111 bytes
I/O format: matrix of [R,G,B] values.
a=>[...a,...a,...a].map((r,y)=>r.flat().map((_,x)=>a[y/3|0][x/3|0].map(v=>x--%3|511+y%3%2*3104>>v/15&1?0:255)))

Try it online! (just a single pixel)
How?
All threshold values are multiples of 15. Instead of doing explicit comparison tests, it's a bit shorter to test a bitmask where each bit represents an interval of 15 values (except the most significant bit which is mapped to a single value).
 bit | range   | top/bottom | middle
-----+---------+------------+--------
  0  |   0- 14 |     off    |   off
  1  |  15- 29 |     off    |   off
  2  |  30- 44 |     off    |   off
  3  |  45- 59 |     off    |   off
  4  |  60- 74 |     off    |   off
  5  |  75- 89 |     off    |    on
  6  |  90-104 |     off    |    on
  7  | 105-119 |     off    |    on
  8  | 120-134 |     off    |    on
  9  | 135-149 |      on    |   off
 10  | 150-164 |      on    |   off
 11  | 165-179 |      on    |   off
 12  | 180-194 |      on    |    on
 13  | 195-209 |      on    |    on
 14  | 210-224 |      on    |    on
 15  | 225-239 |      on    |    on
 16  | 240-254 |      on    |    on
 17  |   255   |      on    |    on

We encode off as \$1\$ and on as \$0\$ in order to maximize the number of leading zeros.
We get:

000000000111111111 for top and bottom pixels (\$511\$ in decimal)
000000111000011111 for the middle pixel (\$3615\$ in decimal)

Commented
a =>                      // a[] = input matrix
  [...a, ...a, ...a]      // create a new matrix with 3 times more rows
  .map((r, y) =>          // for each row r[] at position y:
    r.flat()              //   turn [[R,G,B],[R,G,B],...] into [R,G,B,R,G,B,...]
                          //   i.e. create a new list with 3 times more columns
    .map((_, x) =>        //   for each value at position x:
      a[y / 3 | 0]        //     get [R,G,B] from the original matrix
       [x / 3 | 0]        //     for the pixel at position (floor(x/3), floor(y/3))
      .map(v =>           //     for each component v:
        x-- % 3 |         //       1) yield a non-zero value if this is not the component
                          //          that we're interested in at this position
        511 +             //       2) use either 511 for top and bottom pixels
        y % 3 % 2 * 3104  //          or 3615 for the middle pixel (y mod 3 = 1)
        >> v / 15         //          divide v by 15
        & 1               //          and test the corresponding bit
        ?                 //       if either of the above tests is truthy:
          0               //         yield 0
        :                 //       else:
          255             //         yield 255
      )                   //     end of map() over RGB components
    )                     //   end of map() over columns
  )                       // end of map() over rows

Example
The following code snippet processes the head of Mona Lisa (64x64). Doesn't work on Edge.

f=
a=>[...a,...a,...a].map((r,y)=>r.flat().map((_,x)=>a[y/3|0][x/3|0].map(v=>x--%3|511+y%3%2*3104>>v/15&1?0:255)))

var img;

(img = new Image).onload = function(){
  var ctx = document.getElementById('c').getContext('2d');
  ctx.drawImage(img, 0, 0);
  var data = ctx.getImageData(0, 0, 192, 192), x, y, ptr, a = [];
  for(ptr = y = 0; y < 64; y++) {
    for(a[y] = [], x = 0; x < 64; x++) {
      a[y][x] = [data.data[ptr++], data.data[ptr++], data.data[ptr++]];
      ptr++;
    }
    ptr += 512;
  }
  a = f(a);
  for(ptr = y = 0; y < 192; y++) {
    for(x = 0; x < 192; x++) {
      data.data[ptr++] = a[y][x][0];
      data.data[ptr++] = a[y][x][1];
      data.data[ptr++] = a[y][x][2];
      data.data[ptr++] = 255;
    }
  }
  ctx.putImageData(data, 0, 0);
};

document.getElementById('img').src = img.src = "data:image/png;base64,[encoded data, 17752 characters]";
<img id="img" />
<canvas id="c" width=192 height=192></canvas>

Jelly, 27 bytes
<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ

A monadic Link accepting a list (picture) of lists (rows) of lists (pixels). Each pixel being three integers in \$[0,255]\$, [r, g, b], which yields the result in the same format.
Try it online! This example is taking a two by two image where the top-left pixel is the first example pixel, the top-right pixel is the second example pixel, the bottom-left pixel is a black pixel and the bottom-right pixel is a white pixel.
How?
<“⁷KṆ‘‘Ḅœ?Ɗo⁹’)×€"3⁼þ¤)ẎZ)Ẏ - Link: list of lists of lists of integers, I
                         )  - for each row, R, in I:
                      )     -   for each pixel, P, in R:
              )             -     for each integer, C, in P:
 “⁷KṆ‘                      -       list of code-page indices = [135,75,180]
<                           -       less than -> [C<135,C<75,C<180]
          Ɗ                 -       last three links as a monad:
      ‘                     -         increment -> [1+(C<135),1+(C<75),1+(C<180)]
       Ḅ                    -         from binary -> 4*(1+(C<135))+2*(1+(C<75))+1+(C<180)
        œ?                  -         permutation at that index of [C<135,C<75,C<180]
                            -         when all permutations sorted lexicographically
                            -       ... a no-op for all but [0,0,1]->[0,1,0]
            ⁹               -       256
           o                -       logical OR  e.g. [0,1,0]->[256,1,256]
             ’              -       decrement               ->[255,0,255]
                     ¤      -     nilad followed by link(s) as a nilad:
                  3         -       three
                    þ       -       table with: (i.e. [1,2,3] . [1,2,3])
                   ⁼        -         equal?    -> [[1,0,0],[0,1,0],[0,0,1]]
                 "          -     zip with:
                €           -       for each:
               ×            -         multiply
                       Ẏ    -   tighten (reduce with concatenation)
                        Z   -   transpose
                          Ẏ - tighten

im trying to figure out where it encodes [[1,0,0].[0,1,0],[0,0,1]] and i am baffled.

@donbright 3⁼þ¤ performs an outer product of [1,2,3]=[1,2,3] yielding [[1=1,2=1,3=1],[2=1,2=2,2=3],[3=1,3=2,3=3]] which is [[1,0,0],[0,1,0],[0,0,1]].

Wolfram Language (Mathematica), 186 bytes
Input and Output are lists of RGB values
(g=#;Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@g[[#]],1]&/@Range[Length@g],1])&

Try it online!

Wolfram Language (Mathematica), 243 bytes
this second code is a function that takes as input an image and outputs an image
(I don't know why people were confused in the comments)
So, if you feed this img

into this function
(i=#;Image[Flatten[(T=Transpose)@Flatten[T/@{{#,v={0,0,0},v},{v,#2,v},{v,v,#3}}&@@(If[(l=Max@#)<75,v,If[74<l<135,{0,l,0},If[134<l<179,{l,0,l},{l,l,l}]]]&/@#)&/@ImageData[i,"Byte"][[#]],1]&/@Range[Last@ImageDimensions@i],1],ColorSpace->"RGB"])&

you will get this output

Wouldn't this count as a hardcoded input?

"Input and output may be in any convenient format, whether that's actual image files ...". No, i is an image.

I would agree with @attinat, this looks like hardcoding.

I made some changes and I hope that everything is clear now.

C# (Visual C# Interactive Compiler), 157 bytes
n=>{int i=0,j=n[0].Length;for(;;Write(z(0)+",0,0|0,"+z(1)+",0|0,0,"+z(2)+"\n|"[++i%j&1]));int z(int k)=>(((511^i/j%3%2*4064)>>n[i/j/3][i%j][k]/15)&1^1)*255;}

Prints the RGB of the output. The output is newline separated and not aligned. Originally, I used a bit-mask with 1 being on and 0 being off, but then I saw Arnauld's answer, and I realized using 0 as on and 1 as off could save bytes in the number. The TIO link contains a 4 by 2 pixel sample "image".
Try it online!

APL+WIN, 102 bytes
Prompts for a 2d matrix of pixels as 24 bit integers as they would appear in the image
((⍴a)⍴,3 3⍴255*⍳3)×a←(3 1×⍴m)⍴∊⍉((1↓⍴m)/⍳↑⍴m)⊂n←(-+⌿n)⊖n←1 0↓0 75 135 180∘.≤,m←(1 3×⍴m)⍴,⍉(3⍴256)⊤,m←⎕

Try it online! Courtesy of Dyalog Classic
Outputs a 2d matrix of 24 bit integers of the transformed image.
Most of the code is handling the formatting of the input and output.
Example: Take a 2 x 2 image made up of the sample pixels
Input:
2654895 10547300
2654895 10547300

Output:.
0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0
0     0 16581375 255 65025        0
0 65025        0   0 65025 16581375
0     0 16581375 255 65025        0

Rust - 281 bytes
fn z(p:Vec<u8>,wh:[usize;2])->Vec<u8>{let mut o=vec![0;wh[0]*wh[1]*27];for m in 0..wh[0]{for n in 0..wh[1]{for i in 1..=3{for j in 0..3{o[m*9+n*wh[0]*27+j*wh[0]*9+i*2]=match p[18+m*3+n*wh[0]*3+3-i]{75..=134=>[0,1,0],135..=179=>[1,0,1],180..=255=>[1,1,1],_=>[0,0,0],}[j]*255;}}}}o}

This line is a function that meets the challenge, however it's input is actually data in the TGA file format as described at paulbourke.net, along with pre-parsed width and height, in pixels, of the image. It returns pixel data for the output, as bytes, in a vector 9 times the size of the input pixel data.
use std::fs::File;use std::io::{Read,Write};fn main(){let mut p=vec![];let mut o=vec![0u8;18];File::open("i.tga").unwrap().read_to_end(&mut p).unwrap();let mut wh=[0;2];let h=|x|p[x] as usize;let g=|x|(3*x/256) as u8;for i in 0..2{wh[i]=h(12+i*2)+256*h(13+i*2);o[12+i*2]=g(wh[i]*256);o[13+i*2]=g(wh[i]);}let mut f=File::create("o.tga").unwrap();o[2]=2;o[16]=24;o.extend(z(p,wh));f.write(&o).unwrap();}

This second line is a main() function that can transform an input file named i.tga into an output file named o.tga, by calling the function z from the first line, without using any external libraries. It handles parsing of width/height, creating a header for the output file, and file reading + writing. It would add 402 bytes if the challenge required File I/O, for a total of 683. It is useful for testing.


text:
Tips for golfing in Turing Machine But Way Worse
What are some tips for golfing in Turing Machine But Way Worse, a language made by MilkyWay90 and ASCII-only?
Tips should be Turing Machine But Way Worse-specific and not be trivial (For examples that you shouldn't post, removing unnecessary whitespace or using shorter state names).
EDIT: Added documentation to TMBWW

Do enough people use this language for this post to be necessary?

@Quintec Not really, but I will be using it in golfing a lot and I guess in the future other people may too

Not with a comment like this, they won't: "I am way too lazy to put documentation here, so just look at the code and learn Python 3."

@Shaggy Right, I should probably change the "documentation"

I will actually edit the documentation

@Shaggy Okay, added documentation

Use the negative tape
For code-golf questions where you need to process input, it is easier to move onto the negative tape to push a bit to the tape instead of having to travel to the end of the input on the positive tape (and sometimes that way may even be impossible when you need to support NUL bytes).
For example, when you need to push  to the tape and you have input, going on the negative tape would be much shorter than having to go to the end of the input.
0 0 0 0 1 0 0
1 0 1 0 1 0 0
0 1 0 0 2 1 1

would be much shorter than
0 0 0 1 1 0 0
1 0 1 1 0 0 0
0 1 0 1 2 0 0
1 1 1 1 0 0 0
0 2 0 1 3 0 0
1 2 1 1 0 0 0
0 3 0 1 4 0 0
1 3 1 1 0 0 0
0 4 0 1 5 0 0
1 4 1 1 0 0 0
0 5 0 1 6 0 0
1 5 1 1 0 0 0
0 6 0 1 7 0 0
1 6 1 1 0 0 0
0 7 0 1 8 0 0
1 7 1 1 0 0 0
0 8 0 0 9 0 0
0 9 1 0 a 1 1

and the second solution doesn't even work with NUL bytes.


text:
Draw these shapes
Given: a width, a height, and a set of sets of points. Output: An image where each set of points is connected and colored in (like a shape). Each shape must be a different color from all of the other shapes, but the actual color doesn't matter as long as each color is distinct. The shapes must be in order; whether you start at the end or the beginning of the set doesn't matter, though. The dots must be connected in the order they're given in the set.
Output formats are in accordance with standard image rules.
Examples

//the code here has nothing to do with the actual challenge and just shows examples

document.getElementById("one").getContext("2d").fillRect(0, 0, 300, 300)
const ctx = document.getElementById("two").getContext("2d")
ctx.fillStyle = "black"
ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(0,300);ctx.lineTo(300,0);ctx.closePath();ctx.fill()
ctx.fillStyle = "lime"
ctx.beginPath();ctx.moveTo(200,0);ctx.lineTo(600,0);ctx.lineTo(300,300);ctx.closePath();ctx.fill()
canvas {border: 1px dotted black}

Width: 500, Height: 500, Set: [[[0, 0], [0, 300], [300, 300], [300, 0]]]

<canvas id="one" width="500" height="500"></canvas>

Width: 600, Height: 300, Set:
[
  [[0,0], [0,300], [300,0]],
  [[200,0], [600,0], [300,300]]
]

<canvas id="two" width="600" height="300"></canvas>

Scoring is code-golf.

I meant to ask this question in the Sandbox but what qualities as a "different" colour? Is #000000 different to #000001?

Also, what output formats are allowed? Is a base-64 encoded PNG outputted as s string OK? Or the XML markup of an SVG?

How are we supposed to connect the shapes? Suppose it's a pentagon. Which points go with which points?

@SHaggy I am assuming that this question is using a standard image I/O format

I am voting to close because it doesn't say how we should connect the dots.

I'm sorry, I had stuff to do. The colors can be different but the difference between them doesn't matter. Output formats are in accordance with standard image rules. The dots should be connected in the order they're given in the set

What winding rule should be used?

What do you mean by "winding rule"?

R, 122 71 bytes
function(w,h,p){plot.new();plot.window(c(0,w),c(0,h));polygon(p,c=1:8)}

Try it online!
RDRR - actually shows graphics
A function that takes arguments width, height and a matrix of points detailing the shapes. Each shape is separated by a row of NAs. Output is a plot to the screen of the shapes.