pure Bash, (削除) 116 (削除ここまで) 112 bytes, or 101, or even 97?
Based on answers from iBug and Léa Gris and tips-for-golfing-in-bash (thanks, @AaronMiller and @BrowncatPrograms!):
#!/bin/bash
test116test112()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };{ ((m<x))&&m=$x;};n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test116test112 "$k"; done
Also there are two shorter variants:
#!/bin/bash
f()(shopt -s extglob;((1ドル>9))||exit 1ドル;m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;};f $[10#${1/$m/}*m])
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; f "$k"; echo "$?"; done
(Try it online! ) with 101 bytes and with 97 bytes (Try it online! ):
shopt -s extglob;((1ドル>9))||exit 1ドル;m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;};0ドル $[10#${1/$m/}*m]
But I am not entirely sure the last two apply to the rules. The latter even uses 0ドル (I neither found a rule allowing that nor denying this) to recurse to itself, so it only works if put into a script (like golf.sh), made executable and then is called like golf.sh 91273716; echo $?
Output of the scripts:
Explained first variant (112 bytes):
n=1ドル; # (*) get argument n
shopt -s extglob; # enable ${n//?()/ } below
while((n>9));do # loop until number is <=9
m=0; # preset maximum to 0
for x in ${n//?()/ };do;{ # loop over the digits
((m<x))&&m=$x; # find max
done;};
n=$[ # calculate new number
10# # force base 10 as 0N becomes octal
${n/$m/} # remove first occurance of max
*m]; # multiply m
done;
echo $n # output result
- Shebang
#!/bin/bash+LF(12 byte) is not included in the count.- We are in
bash, so this is already the default
- We are in
- IfAFAICS passing in the number can directly be passed in as variable
n, 5 bytes (marked withsee marked(*)above) can be shoved awayis not allowed. Hence these 5 bytes are needed.- InsteadElse
./golf.sh 1234it would look liken=1234 ./golf.sh - However, shell scripts usually get data passed in via argument
- A
read n;if number is passed in from STDIN would addis 2 byte. longer
- InsteadElse
shopt -s extglob;can be left away, if this option is given on commandline- Like in
n=1234 bash -Oextglob ./golf.sh - But
extglobis not set by default, hence AFAICS it ismust be included in the count
- Like in
10#is needed as${n/$m/}can leave a number with a leading0- Without the
10#input91273716wrongly returns8.
- Without the
Explained shortest variant (97 bytes):
shopt -s extglob; # see above
((1ドル>9))||exit 1ドル; # stop if goal reached
m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;}; # max calc, as above
0ドル $[10#${1/$m/}*m] # recurse to next step
Notes:
- Tested onActually the last line is a tail recursion, so bash uses
bash 5.0.17(1)-releaseexecfromand does notbash 5.0-6ubuntu1.1forkfrom Ubuntu 20.04 LTS
pure Bash, (削除) 116 (削除ここまで) 112 bytes
Based on answers from iBug and Léa Gris
#!/bin/bash
test116()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };{ ((m<x))&&m=$x;};n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test116 "$k"; done
Output
Explained:
n=1ドル; # (*) get argument n
shopt -s extglob; # enable ${n//?()/ } below
while((n>9));do # loop until number is <=9
m=0; # preset maximum to 0
for x in ${n//?()/ };do # loop over the digits
((m<x))&&m=$x; # find max
done;
n=$[ # calculate new number
10# # force base 10 as 0N becomes octal
${n/$m/} # remove first occurance of max
*m]; # multiply m
done;
echo $n # output result
- Shebang
#!/bin/bash+LF(12 byte) is not included in the count.- We are in
bash, so this is already the default
- We are in
- If number can directly be passed in as
n, 5 bytes (marked with(*)above) can be shoved away- Instead
./golf.sh 1234it would look liken=1234 ./golf.sh - However, shell scripts usually get data passed in via argument
- A
read n;if number is passed in from STDIN would add 2 byte.
- Instead
shopt -s extglob;can be left away, if this option is given on commandline- Like in
n=1234 bash -Oextglob ./golf.sh - But
extglobis not set by default, hence it is included in the count
- Like in
10#is needed as${n/$m/}can leave a number with a leading0- Without the
10#input91273716wrongly returns8.
- Without the
- Tested on
bash 5.0.17(1)-releasefrombash 5.0-6ubuntu1.1from Ubuntu 20.04 LTS
pure Bash, (削除) 116 (削除ここまで) 112 bytes, or 101, or even 97?
Based on answers from iBug and Léa Gris and tips-for-golfing-in-bash (thanks, @AaronMiller and @BrowncatPrograms!):
#!/bin/bash
test112()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };{ ((m<x))&&m=$x;};n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test112 "$k"; done
Also there are two shorter variants:
#!/bin/bash
f()(shopt -s extglob;((1ドル>9))||exit 1ドル;m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;};f $[10#${1/$m/}*m])
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; f "$k"; echo "$?"; done
(Try it online! ) with 101 bytes and with 97 bytes (Try it online! ):
shopt -s extglob;((1ドル>9))||exit 1ドル;m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;};0ドル $[10#${1/$m/}*m]
But I am not entirely sure the last two apply to the rules. The latter even uses 0ドル (I neither found a rule allowing that nor denying this) to recurse to itself, so it only works if put into a script (like golf.sh), made executable and then is called like golf.sh 91273716; echo $?
Output of the scripts:
Explained first variant (112 bytes):
n=1ドル; # (*) get argument n
shopt -s extglob; # enable ${n//?()/ } below
while((n>9));do # loop until number is <=9
m=0; # preset maximum to 0
for x in ${n//?()/ };{ # loop over the digits
((m<x))&&m=$x; # find max
};
n=$[ # calculate new number
10# # force base 10 as 0N becomes octal
${n/$m/} # remove first occurance of max
*m]; # multiply m
done;
echo $n # output result
- Shebang
#!/bin/bash+LF(12 byte) is not included in the count.- We are in
bash, so this is already the default
- We are in
- AFAICS passing in the number directly as variable
n(see marked(*)above) is not allowed. Hence these 5 bytes are needed.- Else
./golf.sh 1234would look liken=1234 ./golf.sh - A
read n;if number is passed in from STDIN is 2 byte longer
- Else
shopt -s extglob;can be left away, if this option is given on commandline- Like in
n=1234 bash -Oextglob ./golf.sh - But
extglobis not set by default, hence AFAICS it must be included in the count
- Like in
10#is needed as${n/$m/}can leave a number with a leading0- Without the
10#input91273716wrongly returns8.
- Without the
Explained shortest variant (97 bytes):
shopt -s extglob; # see above
((1ドル>9))||exit 1ドル; # stop if goal reached
m=0;for x in ${1//?()/ };{ ((m<x))&&m=$x;}; # max calc, as above
0ドル $[10#${1/$m/}*m] # recurse to next step
Notes:
- Actually the last line is a tail recursion, so bash uses
execand does notfork
pure Bash, 116(削除) 116 (削除ここまで) 112 bytes
#!/bin/bash
test116()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };do;{ ((m<x))&&m=$x;done;n=$[10#$&&m=$x;};n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test116 "$k"; done
pure Bash, 116 bytes
#!/bin/bash
test116()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };do ((m<x))&&m=$x;done;n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test116 "$k"; done
pure Bash, (削除) 116 (削除ここまで) 112 bytes
#!/bin/bash
test116()
{
n=1ドル;shopt -s extglob;while((n>9));do m=0;for x in ${n//?()/ };{ ((m<x))&&m=$x;};n=$[10#${n/$m/}*m];done;echo $n
}
for k in 9 27 757 1234 26364 432969 1234584 91273716; do printf '%d -> ' "$k"; test116 "$k"; done