13
\$\begingroup\$

Background

The monkeys need help organizing their defense and have asked you, Benjamin the code monkey, to create a program that will list all tower upgrade options. Each tower has three unique upgrade "paths", each having a tier represented by a number between 0 and 5 inclusive, 0 meaning no upgrade. Up to two paths may be chosen for upgrading, that is contain an upgrade tier 1 or greater. Additionally, only one path can can contain a tier 3 or greater.

Task

Output in some reasonable format all valid upgrade path triples in any order (the triples themselves are ordered). Triples can be represented in any reasonable way, such as 025 or 0-2-5. The triples must be distinguishable from each other in some way, so a flat list of numbers without triple delimiters is not allowed.

Here is an example list of all 64 possible triples, as they appear in-game for your insta-monkey collection:

5-2-0
5-0-2
5-1-0
5-0-1
5-0-0
2-5-0
0-5-2
1-5-0
0-5-1
0-5-0
2-0-5
0-2-5
1-0-5
0-1-5
0-0-5
4-2-0
4-0-2
4-1-0
4-0-1
4-0-0
2-4-0
0-4-2
1-4-0
0-4-1
0-4-0
2-0-4
0-2-4
1-0-4
0-1-4
0-0-4
3-2-0
3-0-2
3-1-0
3-0-1
3-0-0
2-3-0
0-3-2
1-3-0
0-3-1
0-3-0
2-0-3
0-2-3
1-0-3
0-1-3
0-0-3
2-2-0
2-0-2
2-1-0
2-0-1
2-0-0
0-2-2
1-2-0
0-2-1
0-2-0
1-0-2
0-1-2
0-0-2
1-1-0
1-0-1
1-0-0
0-1-1
0-1-0
0-0-1
0-0-0
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Are we allowed to output duplicates? (assuming no) \$\endgroup\$ Jun 30 at 23:06
  • 2
    \$\begingroup\$ @thejonymyster no, there should be exactly 64 triples \$\endgroup\$
    – qwr
    Jun 30 at 23:21

16 Answers 16

6
\$\begingroup\$

K (ngn/k), 20 18 bytes

?,/+'!'1|3*<'+!3#3

Try it online!

+!3#3 All triples with values in 0 1 2.
<' Grade up each triple. This results in all permutations of 0 1 2 with some duplicates.
1|3* Multiply by 3 and take maximum with 1 to generate all permutations of 6 3 1.
+'!' For each permutation, generate all triples where the each entry is a non-negative integer less than the number in the permutation at the same index.
?,/ Flatten into a matrix with three columns and take the unique rows.

\$\endgroup\$
5
\$\begingroup\$

Factor + math.combinatorics, 59 58 bytes

6 iota 3 selections [ natural-sort "\0"before? ] filter .

Try it online!

-1 byte from a tip by @ovs.

Note the string "\0" has literal control character 3 embedded as well as the 0; you can see it on TIO. This string is equivalent to the longer (but clearer) sequence { 0 3 }.

  • 6 iota 3 selections

    Generate all 3-selections of \$[0..5]\$: { { 0 0 0 } { 0 0 1 } ... { 5 5 5 } }

  • [ natural-sort { 0 3 } before? ] filter

    Select those that when sorted are less than { 0 3 }.

  • .

    Print them.

\$\endgroup\$
0
4
\$\begingroup\$

Python 2, 82 80 bytes

from itertools import*
print[k for k in product(*[range(6)]*3)if[0,3]>sorted(k)]

-2 bytes thanks to @ovs.

Try it online.

Explanation:

  • from itertools import*: Import itertools for the cartesian product builtin
  • range(6): Push list [0,1,2,3,4,5]
  • [^]*3: Repeat it three times: [[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5]]
  • product(*^): Use the cartesian product builtin to get all triplets
  • k for k in ^: Loop over these triplets
  • ^if: And filter to only keep the triple-tuplets k that are:
    • sorted(k): When sorted and converted to an array
    • [0,3]>^: are smaller than [0,3]
  • [^]: Wrap all these tuplets into an array
  • print^: And print it as result
\$\endgroup\$
4
  • 3
    \$\begingroup\$ I think [0,3]>sorted(k) is sufficient \$\endgroup\$
    – ovs
    Jun 30 at 21:06
  • \$\begingroup\$ @ovs Thanks! :) \$\endgroup\$ Jul 1 at 6:24
  • \$\begingroup\$ Surely [range(6] is roughly equivalent to [[0,1,2,3,4,5]], so that [range[6]]*3 is [[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5]]? \$\endgroup\$
    – Neil
    Jul 2 at 9:42
  • \$\begingroup\$ @Neil You're right. I've changed the explanation accordingly. \$\endgroup\$ Jul 2 at 11:17
4
\$\begingroup\$

Python, 71 bytes

for x in range(521):max(s:='%03d'%x)<'6'!=['0','3']>sorted(s)==print(s)

Attempt This Online!

I took the ['0','3']>sorted(s) idea from ovs.

\$\endgroup\$
3
\$\begingroup\$

Husk, 10 bytes

uΣmPΠmŀ∫ḣ3

Try it online!

Similar to my K answer.

       ∫ḣ3  -- cumulative sums of [1..3] -> [1,3,6]
     mŀ     -- lowered range of each     -> [[0],[0,1,2],[0,1,2,3,4,5]]
    Π       -- cartesian product of the three lists
  mP        -- for each triplet, get all permutations
 Σ          -- flatten into a list of triplets
u           -- get the unique ones
\$\endgroup\$
3
\$\begingroup\$

JavaScript (V8),  75  67 bytes

Saved 8 bytes thanks to @tsh

Prints one comma-separated triplet per line.

for(i=216;i--;)[...a=[i/36%6|0,i/6%6|0,i%6]].sort()<'0,3'&&print(a)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Maybe for(i=216;i--;)[...a=[i/36%6|0,i/6%6|0,i%6]].sort()<'0,3'&&print(a)? \$\endgroup\$
    – tsh
    Jul 1 at 3:31
2
\$\begingroup\$

05AB1E, 13 11 bytes

5Ý3ãʒ{₆1š‹P

-2 bytes thanks to a tip of @ovs using 136.

Outputs as a list of triplets.

Try it online.

Explanation:

5Ý           # Push a list in the range [0,5]
  3ã         # Cartesian power of 3: get all triplets using these [0,1,2,3,4,5]
    ʒ        # Filter this list by:
     {       #  Sort the triplet from lowest to highest
      ƵZ     #  Push compressed integer 136
        S    #  Convert it to a list of digits: [1,3,6]
         ‹   #  Check for sorted triplet [a,b,c] whether [a<1,b<3,c<6]
          P  #  Check if all three are truthy
             # (after which the filtered list of 64 triplets is output implicitly)

ƵZS could alternatively be ₆1š for the same byte-count: try it online.

      ₆      #  Push 36
       1š    #  Convert it to a list of digits, and prepend 1

See this 05AB1E tip of mine (section How to compress large integers?) to understand why ƵZ is 136.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ There is a 11-byter that uses a single filter. ƵZ might be a hint ;) \$\endgroup\$
    – ovs
    Jun 30 at 18:19
  • \$\begingroup\$ @ovs Smart! Thanks for the hint. :) \$\endgroup\$ Jun 30 at 18:30
2
\$\begingroup\$

Retina 0.8.2, 50 bytes


520$*¶

00$.`
.+(...)
$1
G`0
A`[3-5].*[3-5]|[6-9]

Try it online! Link includes footer that prettifies the output. Explanation:


520$*¶

00$.`
.+(...)
$1

List all the integers from 0 to 520 inclusive, padded to 3 digits.

G`0

Only keep those integers with at least one 0 digit.

A`[3-5].*[3-5]|[6-9]

Discard those with more than one digit greater than 2 or with a digit greater than 5.

\$\endgroup\$
1
  • \$\begingroup\$ I was looking forward to a regex solution! \$\endgroup\$
    – qwr
    Jul 1 at 16:28
2
\$\begingroup\$

Python 3, 75 bytes

print([r for r in[(x//36,x//6%6,x%6)for x in range(216)]if[0,3]>sorted(r)])

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 26 bytes

ΦEφ﹪%03dι∧№ι0∧›6⌈ι›²ΣEι‹2λ

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

  φ                         Predefined variable `1000`
 E                          Map over implicit range
        ι                   Current value
   ﹪%03d                    Formatted to 3 0-filled digits
Φ                           Filtered where
           ι                Current value
          №                 Contains
            0               Literal string `0`
         ∧                  Logical And
               6            Literal string `6`
              ›             Is greater than
                 ι          Current value
                ⌈           Maximum character
             ∧              Logical And
                   ²        Literal integer `2`
                  ›         Is greater than
                      ι     Current value
                     E      Map over digits
                        2   Literal string `2`
                       ‹    Is less than
                         λ  Current digit
                    Σ       Take the sum
                            Implicitly print

28 bytes for the prettier version:

ΦEφ⪫﹪%03dι-∧№ι0∧›6⌈ι›²ΣEι‹2λ

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

\$\endgroup\$
1
\$\begingroup\$

Python 3, 161 146 141 bytes

from itertools import*
for u in product(*[range(6)]*3):
 i,j,k=u
 if 0not in[i,j,k]or i>2and j>2or j>2and k>2or k>2and i>2:continue
 print(u)

Try it online!

-5 thanks to qwr

\$\endgroup\$
4
  • \$\begingroup\$ You can probably use itertools cartesian product and filter lambda to save some bytes over triple for loop \$\endgroup\$
    – qwr
    Jun 30 at 20:55
  • \$\begingroup\$ @qwr I don't know what is itertools, Can you upload a TIO link? \$\endgroup\$
    – Fmbalbuena
    Jun 30 at 21:02
  • \$\begingroup\$ See Kevin Cruijssen's answer for an example \$\endgroup\$
    – qwr
    Jun 30 at 21:04
  • \$\begingroup\$ @qwr Thanks, -5 bytes. \$\endgroup\$
    – Fmbalbuena
    Jul 1 at 0:14
1
\$\begingroup\$

Ruby, 62 bytes

p (z=*0..5).product(z,z).select{|x|x.min<1&&(x-[3,4,5])[1]}|[]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Rust, 106 bytes

for i in 0..6{for j in 0..6{for k in 0..6{let mut t=[i,j,k];t.sort();if t<[0,3,6]{print!("{i}{j}{k}
")}}}}

Actually using nested loops is barely shorter than my attempt using itertoools.

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

Pyth, 12 bytes

f>,Z3ST^U6 3

Try it online!

Port of Kevin Cruijssen's Python answer

f>,Z3ST^U6 3
        U6    Range up to 6 = [0,1,2,3,4,5]
       ^   3  Cartesian product with itself 3 times = [0,1,2,3,4,5] * [0,1,2,3,4,5] * [0,1,2,3,4,5]
f             Filter for elements T such that:
 >,Z3ST       [0,3] > sorted(T)
\$\endgroup\$
1
\$\begingroup\$

Regenerate -a, 73 64 bytes

[345]([12]0|0[012])|[12]([1-5]0|0[0-5])|0([012][0-5]|[345][012])

Attempt This Online!

Surprised nopony did this yet. Probably golfable!

EDIT: -9 thanks to math junkie for reminding me of the shorter output format. Now it's 1 byte per combination :P I still think it can be golfed further, possibly with a new approach :-)c

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think you can drop the - separators since that's allowed by the challenge rules \$\endgroup\$ Jul 11 at 1:23
  • \$\begingroup\$ @mathjunkie omg i forgot thank u \$\endgroup\$ Jul 11 at 2:40
0
\$\begingroup\$

Batch, 271 bytes

@!! 2>nul||cmd/q/v/c%0&&exit/b&for /l %%i in (0,1,5)do @(for /l %%j in (0,1,5)do @(for /l %%k in (0,1,5)do @(set s=%%i%%j%%k&set p=!s:0=!&if !p:~!==~ set p=0
if !p!. neq !s!. set/af=!p!/10&set/al=!p!%%10&if !f! lss !l! (if !f! leq 2 echo !s!)else if !l! leq 2 echo !s!)))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.