| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Elisp | 240708T134011Z | Samuel J |
| 041 | Desmos | 240706T001932Z | Aiden Ch |
| 051 | JavaScript Node.js | 240705T110815Z | l4m2 |
| 015 | Japt | 240705T080224Z | Shaggy |
| 2613 | Nibbles | 240705T145120Z | Dominic |
| 024 | Charcoal | 240705T091455Z | Neil |
| 045 | Arturo | 240704T210655Z | chunes |
| 023 | 05AB1E | 240705T084446Z | Kevin Cr |
| 041 | Picat | 240705T022349Z | Bubbler |
| 098 | JavaScript ES6 | 240704T203314Z | Arnauld |
| 068 | Google Sheets | 240705T041809Z | z.. |
| 048 | Python 3 | 240704T235711Z | xnor |
Elisp, 93 Bytes, porting xnor's answer
(defun f(n)(if(> n 1)(apply'min(cl-loop for i in'(2 3 4 5)collect(+ 1 i(f(/(float n)i)))))0))
Desmos, 41 bytes
I=[2...5]
f(n)=\{n>1:\min(f(n/I)+I+1),0\}
Port of @xnor's Python 3 answer so make sure to upvote that answer too!
JavaScript (Node.js), 51 bytes
f=(n,i=6)=>n>1&&Math.min(i+f(n/--i),i>2?f(n,i):1/0)
JavaScript (Node.js), 50 bytes by Shaggy porting xnor
f=n=>n>1&&Math.min(...[2,3,4,5].map(x=>x-~f(n/x)))
Japt, 15 bytes
Port of xnor's Python solution.
>1©5ò2ÈÒßU/XÃrm
>1©5ò2ÈÒßU/XÃrm :Implicit input of integer U
>1 :Greater than 1
© :Logical AND with
5ò2 : Range [2,5]
È : Map each X
Ò : Subtract the bitwise NOT of
ßU/X : A recursive call with argument U/X
à : End map
r : Reduce by
m : Minimum
Nibbles, 26 nibbles (13 bytes)
`; 1 -@$ 0 `/ . +~,4 + _ * @$ +$~ [
Another recursive 'try 1,2,3 or 4 pastes at each step' approach.
Nibbles only has integer arithmetic, so we can't (easily) count down & divide the target at each recursive step (as used in xnor's approach).
However, Nibbles does remember the program input as a global variable across all recursive calls, so we can simply count up the string-copies-so-far (starting at 1) and stop when we reach the program input, which is more intuitive to me anyway.
`; 1 -@$ 0 `/ . +~,4 + _ * @$ +$~ [ # full program; input is stored in variable @
`; 1 # launch recursive function starting with copies=1
# (stored in variable $)
-@$ # stop when input <= copies-so-far
0 # and return zero
# otherwise return
`/ [ # minimum of
. # map over
+~,4 # i in 2..5
+ # sum of
_ # recursive call using
* @$ # copies-so-far * i
+$~ # and i+1 (steps needed to multiply copies by i)
Charcoal, 24 bytes
FN⊞υ∨¬ι⁺³⌊E⁴⁺κ§υ÷ι⁺²κI⊟υ
Try it online! Link is to verbose version of code. Explanation: Based on @xnor's approach but using dynamic programming instead of recursion.
FN
Calculate all of the results for 1 to n. Note that the loop variable is 1 less than the index of the result being calculated but this actually saves bytes as ⌈i/k-1⌉=(i-1)//k which is simply an integer division.
⊞υ∨¬ι⁺³⌊E⁴⁺κ§υ÷ι⁺²κ
The result for 1 is just 1 while the result for other iterations is the best of four previously calculated results.
I⊟υ
Output the result for n.
Arturo, 49 45 bytes
f:$->n->(n>1)?[2..5|map=>[+1+f//n<=&]|min]->0
Port of xnor's 50-byte Python answer.
Arturo, 71 bytes
$->n->min map[0 1 3 2 7 6 4 3 8 9 12 27 16 81 6 5]=>[&+5*ceil log//n&4]
The formula in the OP.
05AB1E, 23 bytes
"D1›Di4L+DŠ/®δ.V+>ß"©.V
Port of @xnor's Python answer, so make sure to upvote that answer as well.
Still pretty long, since 05AB1E is very verbose for recursive functions.
Try it online or verify most test cases (it'll time out before it has output all test cases).
Using the given formula would be 32 bytes instead:
•¬òÃ,v₅aw°Üÿ∊•82в2ôε`Š/4.nî5*+}ß
Try it online or verify all test cases.
Explanation:
Uses recursive method:
$$f(n) = \begin{cases} 0, & \text{if $n\leq1$} \\ \min(f(\frac{n}{2})+3, f(\frac{n}{3})+4, f(\frac{n}{4})+5, f(\frac{n}{5})+6), & \text{if $n>1$} \end{cases}$$
"..." # Define the recursive string explained below
© # Store it in variable `®` (without popping)
.V # Pop and evaluate it as 05AB1E code
# (after which the result is output implicitly)
D # Duplicate the current value n
# (which will use the implicit input in the first iteration)
1› # Pop and check whether it's larger than 1
D # Duplicate this check
i # Pop the copy, and if it's truthy:
4L # Push list [1,2,3,4]
+ # Add the truthy check that's still on the stack: [2,3,4,5]
D # Duplicate this list
Š # Tripleswap to [2,3,4,5],n,[2,3,4,5]
/ # Divide [n/2,n/3,n/4,n/5]
δ # Map over each value:
® .V # And do a recursive eval to `®`
+ # Then add the values in the two lists together:
# [2+f(n/2),3+f(n/3),4+f(n/4),5+f(n/5)]
> # Increase each by 1
# [3+f(n/2),4+f(n/3),5+f(n/4),6+f(n/5)]
ß # Pop and leave the minimum
# (implicit else: use the duplicated falsey check, aka 0)
•¬òÃ,v₅aw°Üÿ∊• # Push compressed integer 50972899172091152076282460330
82в # Convert it to base-82 as list:
# [1,0,2,3,3,4,5,6,6,7,9,8,27,12,81,16]
2ô # Split it into pairs:
# [[1,0],[2,3],[3,4],[5,6],[6,7],[9,8],[27,12],[81,16]]
ε # Map over each pair [u,c]:
` # Pop and push both values to the stack
Š # Triple-swap u,c to c,i,u, where i is the implicit input
/ # Divide the input by u
4.n # Take log_4 of it
î # Ceil it
5* # Multiply by 5
+ # Add c
}ß # After the map: pop and leave the minimum
# (which is output implicitly as result)
See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •¬òÃ,v₅aw°Üÿ∊• is 50972899172091152076282460330 and •¬òÃ,v₅aw°Üÿ∊•82в is [1,0,2,3,3,4,5,6,6,7,9,8,27,12,81,16].
Picat, 41 bytes
f(1)=0.
f(N)=[f(N/>I)+I+1:I in 2..5].min.
Same approach as xnor's Python answer: recurses through the cases of ctrl+A C V{1,4} to get at least N characters as a result.
With the help of table in the header section, it computes all test cases almost instantly. Thanks to the /> operator which does ceil-ed integer division, all intermediate arguments are integers without any complications, and we can simply pattern-match the 1 as the base case.
Bitwise not operator ~ exists in Picat, but it doesn't like putting the two symbols -~ side-by-side, so the usual -~ trick does not save any bytes.
JavaScript (ES6), 98 bytes
Basically a direct implementation of the (fixed) formula given in the challenge.
with(Math)f=n=>min(...[81,27,9,6,5,3,2,1].map((v,i)=>ceil(log(n/v)/log(4))*5-~(37115838>>i*4&15)))
Google Sheets, 68 bytes
=SORTN(5*CEILING(LOG(A1/{1;2;6;3;9;27;81;5},4))+{1;3;7;4;8;12;16;6})
Python 3, 48 bytes
f=lambda n:n>1and-~min(i+f(n/i)for i in b"")
50 bytes
f=lambda n:n>1and min(i+1+f(n/i)for i in[2,3,4,5])
Doesn't bother with the formula. Instead, implements the characterization from the math SE post where each step creates 2, 3, 4, or 5 copies of the strings for that many operations plus one.
The outputs don't match the formula-derived test cases on powers of 4, but as Bubbler points out, this is due to a typo in the formula in the math SE post.