| Bytes | Lang | Time | Link |
|---|---|---|---|
| 511 | Python3 | 240625T013316Z | Ajax1234 |
| 113 | Charcoal | 230407T010301Z | Neil |
| 036 | Jelly | 230406T182352Z | Jonathan |
| 159 | JavaScript ES6 | 230406T001809Z | Arnauld |
| 040 | 05AB1E | 230406T084205Z | Kevin Cr |
Python3, 511 bytes
u=lambda x:int(''.join(map(str,x)))
def f(d,n):
D={}
for i in d:D[i]=D.get(i,0)+1
q,s=[([],D)],[]
for a,D in q:
if len(a)>n:continue
if len(a)<3:
for i in D:
if D[i]:q+=[(a+[i],{**D,i:D[i]-1})]
else:
for i in range(len(a)):
for I in range(i+1,len(a)):
x,y=u(a[i:I]),u(a[I:])
for j in[int(V:=x/y),x+y,x-y,x*y][int(V)!=V:]:
if j>0 and(D.get(T:=int(str(j)[-1]))or(T==9 and len(a)==n)):
if T==9:return a
elif a+[T]not in s:q+=[(a+[T],{**D,j:D[T]-1})];s+=[a+[T]]
Python3, 549 bytes
Finds all possible hyperjumps for each input.
u=lambda x:int(''.join(map(str,x)))
def f(d,n):
D={}
for i in d:D[i]=D.get(i,0)+1
q,s=[([],D)],[]
for a,D in q:
if len(a)>n:continue
if len(a)<3:
for i in D:
if D[i]:q+=[(a+[i],{**D,i:D[i]-1})]
else:
for i in range(len(a)):
for I in range(i+1,len(a)):
x,y=u(a[i:I]),u(a[I:])
for j in[int(V:=x/y),x+y,x-y,x*y][int(V)!=V:]:
if j>0 and(D.get(T:=int(str(j)[-1]))or(T==9 and len(a)==n)):
if T==9:yield tuple(a);continue
elif a+[T]not in s:q+=[(a+[T],{**D,j:D[T]-1})];s+=[a+[T]]
k=lambda d,n:{*f(d,n)}
Charcoal, 125 114 113 bytes
⊞υ⟦⟦⟧θ⟧F⊕η«≔υθ≔⟦⟧υFθ«≔⊟κε≔⌊κδ≔↨δ⁰ζF⎇⁼ηι⟦⁹⟧Φχ№ελ¿∨‹ι²⊙Eδ↨✂δν⊖ι¹χ№﹪⟦∧μ⁺μζ∧›μζ⁻μζ×μζ∧¬﹪μζ÷μζ⟧χλ¿⁼ηιIκ⊞υ⟦⁺δ⟦λ⟧Φε⁻⌕ελν
Try it online! Link is to verbose version of code. Outputs all solutions. Explanation:
⊞υ⟦⟦⟧θ⟧
Start a breadth-first search with a position of no digits in the list yet and the starting set.
F⊕η«
Loop over each step in the trip plus one for the last hyperjump to 9.
≔υθ
Save the list of previously found positions.
≔⟦⟧υ
Start recording a list of new positions.
Fθ«
Loop over the previous list of positions.
≔⊟κε
Get the set of remaining digits.
≔⌊κδ
Get the list of jumps so far.
≔↨δ⁰ζ
Get the last jump made, if any.
F⎇⁼ηι⟦⁹⟧Φχ№ελ
Loop over the remaining digits, or just 9 if this is the final hyperjump.
¿∨‹ι²
If this is one of the first two steps, or...
⊙Eδ↨✂δν⊖ι¹χ
... for any suffix of the previous jumps ...
№﹪⟦∧μ⁺μζ∧›μζ⁻μζ×μζ∧¬﹪μζ÷μζ⟧χλ
... any of the arithmetic operations results in a positive integer that ends with the desired digit, then:
¿⁼ηι
If this is the final hyperjump, then...
Iκ
... output the list, otherwise...
⊞υ⟦⁺δ⟦λ⟧Φε⁻⌕ελν
... save the position of the extended list and reduced set.
Jelly, 36 bytes
ṖṪṭḌƊÐƤṖjþ“+_×÷”ẎVDṪ€
œ!;9e"ÇƤ$ṫ3ẠƲƇ
A dyadic Link that accepts the list of positive digits as integers on the left and the proposed length on the right and yields a list of all possible hyperjump solutions, including the duplicates available when there are repeated digits that may be used.
How?
Brute force checking.
ṖṪṭḌƊÐƤṖjþ“+_×÷”ẎVDṪ€ - Helper Link, get possibles for last digit: list, X
Ṗ - pop off the last digit (since it's the one we're aiming for)
ÐƤ - for each suffix:
Ɗ - last three links as a monad - f(S=suffix=[..., r]):
Ṫ - tail (S) and yield -> right operand = r (and S=[...])
Ḍ - convert (S) from base ten -> left operand = int([...])
(or 0 when nothing remains)
ṭ - tack -> [left operand, right operand]
Ṗ - pop off the last result (removing the [0, r] which would
become e.g. "0+r", allowing any
repeated digit)
“+_×÷” - list of characters = "+_×÷"
þ - (operands list) table (characters) applying:
j - (operands) join with (character)
Ẏ - tighten to a list of equations
V - evaluate as jelly code -> list of results of the equations
D - convert the results to decimal
Ṫ€ - tail each - note that this will be a negative digit if
the equation result was negative
(hence `DṪ€` rather than `%⁵`)
œ!;9e"ÇƤ$ṫ3ẠƲƇ - Main Link: list, L; integer N
œ! - all permutations choosing N elements
Ƈ - filter keep those of these "potentials" for which:
Ʋ - last four links as a monad - f(potential):
;9 - concatenate a nine
$ - last two links as a monad - f(potential):
Ƥ - for each prefix:
Ç - call the helper Link, above
" - (potential) zip (that) applying:
e - exists in?
ṫ3 - tail from index 3 on (remove the first two exists in checks)
Ạ - all truthy?
JavaScript (ES6), 159 bytes
A version always using a single digit for the right operand, which apparently is the correct rule of the game.
a=>g=(n,o='',p,m)=>(n?a:[9]).some((v,i)=>m>>i&v<9|o>9&!a.some((_,i)=>[...'+-*/'].some(c=>(s=o.slice(i,-1))&&eval(s+c+p)%10==v))?0:n?g(n-1,o+v,v,m|1<<i):O=o)&&O
JavaScript (ES6), 175 bytes
Expects (list)(n). Returns either a string of digits, or false if there's no solution.
a=>g=(n,o='',m)=>(n?a:[9]).some((v,i)=>m>>i&v<9|o>9&!a.some((_,i)=>(h=j=>(s=o.slice(j))&&eval(o.slice(i,j)+'+-*/'[j*4&3]+s)%10==v|h(j+1/4))(i+1))?0:n?g(n-1,o+v,m|1<<i):O=o)&&O
Commented
a => // a[] = input list of digits
g = ( // g is a recursive function taking:
n, // n = counter
o = '', // o = output string
m // m = bit mask of already used digits
) => //
(n ? a : [9]) // using [9] for the last iteration or a[] otherwise,
.some((v, i) => // for each value v at index i:
m >> i & v < 9 | // is the i-th bit of m set with v not equal to 9?
o > 9 & // does o have at least 2 digits?
!a.some((_, i) => // for each entry in a[] at index i:
( h = j => // h is a recursive function taking a pointer j
(s = o.slice(j)) // using j, extract the right operand s from o
&& eval( // unless s is empty, evaluate as JS code:
o.slice(i, j) // the left operand (from i to j-1)
+ '+-*/' // followed by an operator
[j * 4 & 3] // chosen according to the decimal part of j
+ s // followed by the right operand
) % 10 == v | // and test whether the result modulo 10 is v
h(j + 1 / 4) // do a recursive call with j + 1/4
)(i + 1) // initial call to h with j = i + 1
) ? // end of some(); if the test fails:
0 // do nothing
: // else:
n ? // if there are more digits to add:
g( // do a recursive call:
n - 1, // decrement n
o + v, // append v to o
m | 1 << i // set the i-th bit of m
) // end of recursive call
: // else:
O = o // success: save o in O
) && O // end of some(); return either false or O
05AB1E, 40 bytes
.ÆʒV"+-*/"¹<ãεUYćsvyXNè.VDïθ}9Ê;)Ðd*ïQ}à
Slow brute-force. Inputs in the order \$n,list\$, and will output a list of all possible results (including duplicates); not because it's mentioned as Bonus point in the challenge description, but simply because it's 1 byte shorter. 😉
Try it online or verify all test cases with only the first valid result instead of all.
Explanation:
.Æ # Get all n-sized lists using items of the list, where `n` and
# the list are the first/second (implicit) inputs respectively
ʒ # Filter this list of lists by:
V # Pop and store the current list in variable `Y`
# (since we're gonna use it within an inner iterator)
"+-*/" # Push the string of the four operands
¹< # Push the first input - 1
ã # Get all input-1 sized combinations of operands
ε # Map over each list of operands:
U # Pop and store the current list of operands in variable `X`
Y # Push digit-list `Y`
ć # Extract head; push remainder-list and first item separately
s # Swap so the remainder-list is at the top
v # Loop over each digit of the remainder-list:
y # Push the current digit
XNè # Push the loop-index'th operand of list `X`
.V # Evaluate and execute this operand as 05AB1E code
D # Duplicate the result
ï # Cast the copy to an integer to remove decimal values
θ # Pop and leave just its last digit
} # After the loop:
9Ê # Check that the final digit is NOT 9 (0 if 9; 1 if [0-8])
; # Halve this 0 or 1 to 0 or 0.5 respectively
) # Wrap all values on the stack into a list
Ð # Triplicate this list
d # Check for each value whether it's non-negative (>=0)
* # Multiply so all negative values in the list become 0s
ï # Cast all values to integers to remove decimal values
Q # Equals-check to verify the list is still the same
}à # After the map: check whether any is truthy by taking the max
# (after which the filtered list is output implicitly as result)